mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
Bug 1287944 - Improve interaction with Oculus Home r=daoshengmu
- Now destroying and re-creating Oculus sessions when switching between magic window and immersive WebVR (BeginPresent / ExitPresent) - Now sending flags to Oculus ovr_initilize to specify if Firefox will be presenting to the VR display or just using tracking - Now coordinating oculus session shutdown and restart between the VR controllers and the VR display with reference counting. - Now able to return to Oculus home after using WebVR - Magic window / non-exclusive sessions no longer take over the VR headset causing it to display a message that Firefox.exe is not responding. MozReview-Commit-ID: EnRsxt6ZSzg --HG-- extra : rebase_source : d1ecf52e064ffe88c2cdebb011b8ffa9beb7b46e
This commit is contained in:
parent
90de18de8a
commit
d4f04befed
@ -355,6 +355,8 @@ private:
|
||||
DECL_GFX_PREF(Live, "dom.vr.controller_trigger_threshold", VRControllerTriggerThreshold, float, 0.1f);
|
||||
DECL_GFX_PREF(Live, "dom.vr.navigation.timeout", VRNavigationTimeout, int32_t, 1000);
|
||||
DECL_GFX_PREF(Once, "dom.vr.oculus.enabled", VROculusEnabled, bool, true);
|
||||
DECL_GFX_PREF(Live, "dom.vr.oculus.present.timeout", VROculusPresentTimeout, int32_t, 10000);
|
||||
DECL_GFX_PREF(Live, "dom.vr.oculus.quit.timeout", VROculusQuitTimeout, int32_t, 30000);
|
||||
DECL_GFX_PREF(Once, "dom.vr.openvr.enabled", VROpenVREnabled, bool, false);
|
||||
DECL_GFX_PREF(Once, "dom.vr.osvr.enabled", VROSVREnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "dom.vr.poseprediction.enabled", VRPosePredictionEnabled, bool, true);
|
||||
|
@ -264,20 +264,26 @@ VRManager::RefreshVRDisplays(bool aMustDispatch)
|
||||
* in the future.
|
||||
*/
|
||||
for (uint32_t i = 0; i < mManagers.Length() && displays.Length() == 0; ++i) {
|
||||
mManagers[i]->GetHMDs(displays);
|
||||
if (mManagers[i]->GetHMDs(displays)) {
|
||||
// GetHMDs returns true to indicate that no further enumeration from
|
||||
// other managers should be performed. This prevents erraneous
|
||||
// redundant enumeration of the same HMD by multiple managers.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool displayInfoChanged = false;
|
||||
bool displaySetChanged = false;
|
||||
|
||||
if (displays.Length() != mVRDisplays.Count()) {
|
||||
// Catch cases where a VR display has been removed
|
||||
displayInfoChanged = true;
|
||||
displaySetChanged = true;
|
||||
}
|
||||
|
||||
for (const auto& display: displays) {
|
||||
if (!GetDisplay(display->GetDisplayInfo().GetDisplayID())) {
|
||||
// This is a new display
|
||||
displayInfoChanged = true;
|
||||
displaySetChanged = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -288,14 +294,15 @@ VRManager::RefreshVRDisplays(bool aMustDispatch)
|
||||
}
|
||||
}
|
||||
|
||||
if (displayInfoChanged) {
|
||||
// Rebuild the HashMap if there are additions or removals
|
||||
if (displaySetChanged) {
|
||||
mVRDisplays.Clear();
|
||||
for (const auto& display: displays) {
|
||||
mVRDisplays.Put(display->GetDisplayInfo().GetDisplayID(), display);
|
||||
}
|
||||
}
|
||||
|
||||
if (displayInfoChanged || aMustDispatch) {
|
||||
if (displayInfoChanged || displaySetChanged || aMustDispatch) {
|
||||
DispatchVRDisplayInfoUpdate();
|
||||
}
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ public:
|
||||
|
||||
virtual void Destroy() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) = 0;
|
||||
virtual bool GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) = 0;
|
||||
virtual bool GetIsPresenting() = 0;
|
||||
virtual void HandleInput() = 0;
|
||||
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult) = 0;
|
||||
|
@ -514,21 +514,23 @@ VRSystemManagerOSVR::Shutdown()
|
||||
osvr_ClientShutdown(m_ctx);
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
VRSystemManagerOSVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
|
||||
{
|
||||
// make sure context, interface and display are initialized
|
||||
CheckOSVRStatus();
|
||||
|
||||
if (!Init()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
mHMDInfo = new VRDisplayOSVR(&m_ctx, &m_iface, &m_display);
|
||||
|
||||
if (mHMDInfo) {
|
||||
aHMDResult.AppendElement(mHMDInfo);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
static already_AddRefed<VRSystemManagerOSVR> Create();
|
||||
virtual void Destroy() override;
|
||||
virtual void Shutdown() override;
|
||||
virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) override;
|
||||
virtual bool GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) override;
|
||||
virtual bool GetIsPresenting() override;
|
||||
virtual void HandleInput() override;
|
||||
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>&
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,6 +7,7 @@
|
||||
#define GFX_VR_OCULUS_H
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "nsISupportsImpl.h" // For NS_INLINE_DECL_REFCOUNTING
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
@ -33,6 +34,49 @@ enum class OculusControllerAxisType : uint16_t {
|
||||
NumVRControllerAxisType
|
||||
};
|
||||
|
||||
class VROculusSession
|
||||
{
|
||||
NS_INLINE_DECL_REFCOUNTING(VROculusSession);
|
||||
public:
|
||||
VROculusSession();
|
||||
void Refresh();
|
||||
bool IsTrackingReady() const;
|
||||
bool IsRenderReady() const;
|
||||
ovrSession Get();
|
||||
void StartPresentation(const IntSize& aSize);
|
||||
void StopPresentation();
|
||||
void StopTracking();
|
||||
bool IsQuitTimeoutActive();
|
||||
already_AddRefed<layers::CompositingRenderTargetD3D11> GetNextRenderTarget();
|
||||
ovrTextureSwapChain GetSwapChain();
|
||||
|
||||
private:
|
||||
PRLibrary* mOvrLib;
|
||||
ovrSession mSession;
|
||||
ovrInitFlags mInitFlags;
|
||||
ovrTextureSwapChain mTextureSet;
|
||||
nsTArray<RefPtr<layers::CompositingRenderTargetD3D11>> mRenderTargets;
|
||||
bool mPresenting;
|
||||
IntSize mPresentationSize;
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
// The timestamp of the last time Oculus set ShouldQuit to true.
|
||||
TimeStamp mLastShouldQuit;
|
||||
// The timestamp of the last ending presentation
|
||||
TimeStamp mLastPresentationEnd;
|
||||
|
||||
~VROculusSession();
|
||||
void Uninitialize(bool aUnloadLib);
|
||||
bool Initialize(ovrInitFlags aFlags);
|
||||
bool LoadOvrLib();
|
||||
void UnloadOvrLib();
|
||||
bool StartSession();
|
||||
void StopSession();
|
||||
bool StartLib(ovrInitFlags aFlags);
|
||||
void StopLib();
|
||||
bool StartRendering();
|
||||
void StopRendering();
|
||||
};
|
||||
|
||||
class VRDisplayOculus : public VRDisplayHost
|
||||
{
|
||||
public:
|
||||
@ -50,24 +94,17 @@ protected:
|
||||
void UpdateStageParameters();
|
||||
|
||||
public:
|
||||
explicit VRDisplayOculus(ovrSession aSession);
|
||||
explicit VRDisplayOculus(VROculusSession* aSession);
|
||||
void Destroy();
|
||||
|
||||
protected:
|
||||
virtual ~VRDisplayOculus();
|
||||
void Destroy();
|
||||
|
||||
bool RequireSession();
|
||||
const ovrHmdDesc& GetHmdDesc();
|
||||
|
||||
already_AddRefed<layers::CompositingRenderTargetD3D11> GetNextRenderTarget();
|
||||
|
||||
VRHMDSensorState GetSensorState(double absTime);
|
||||
|
||||
ovrHmdDesc mDesc;
|
||||
ovrSession mSession;
|
||||
RefPtr<VROculusSession> mSession;
|
||||
ovrFovPort mFOVPort[2];
|
||||
ovrTextureSwapChain mTextureSet;
|
||||
nsTArray<RefPtr<layers::CompositingRenderTargetD3D11>> mRenderTargets;
|
||||
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
RefPtr<ID3D11DeviceContext> mContext;
|
||||
@ -81,7 +118,6 @@ protected:
|
||||
RefPtr<ID3D11Buffer> mVertexBuffer;
|
||||
RefPtr<ID3D11InputLayout> mInputLayout;
|
||||
|
||||
bool mIsPresenting;
|
||||
float mEyeHeight;
|
||||
|
||||
bool UpdateConstantBuffers();
|
||||
@ -137,7 +173,7 @@ public:
|
||||
static already_AddRefed<VRSystemManagerOculus> Create();
|
||||
virtual void Destroy() override;
|
||||
virtual void Shutdown() override;
|
||||
virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost> >& aHMDResult) override;
|
||||
virtual bool GetHMDs(nsTArray<RefPtr<VRDisplayHost> >& aHMDResult) override;
|
||||
virtual bool GetIsPresenting() override;
|
||||
virtual void HandleInput() override;
|
||||
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>&
|
||||
@ -149,13 +185,7 @@ public:
|
||||
virtual void StopVibrateHaptic(uint32_t aControllerIdx) override;
|
||||
|
||||
protected:
|
||||
VRSystemManagerOculus()
|
||||
: mOvrLib(nullptr), mSession(nullptr), mStarted(false)
|
||||
{}
|
||||
|
||||
bool Startup();
|
||||
bool LoadOvrLib();
|
||||
void UnloadOvrLib();
|
||||
VRSystemManagerOculus();
|
||||
|
||||
private:
|
||||
void HandleButtonPress(uint32_t aControllerIdx,
|
||||
@ -172,12 +202,9 @@ private:
|
||||
void HandleHandTriggerPress(uint32_t aControllerIdx, uint32_t aButton, float aValue);
|
||||
void HandleTouchEvent(uint32_t aControllerIdx, uint32_t aButton,
|
||||
uint64_t aTouchMask, uint64_t aTouched);
|
||||
PRLibrary* mOvrLib;
|
||||
RefPtr<impl::VRDisplayOculus> mHMDInfo;
|
||||
RefPtr<impl::VRDisplayOculus> mDisplay;
|
||||
nsTArray<RefPtr<impl::VRControllerOculus>> mOculusController;
|
||||
RefPtr<nsIThread> mOculusThread;
|
||||
ovrSession mSession;
|
||||
bool mStarted;
|
||||
RefPtr<impl::VROculusSession> mSession;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
@ -549,7 +549,7 @@ VRSystemManagerOpenVR::Shutdown()
|
||||
mVRSystem = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
VRSystemManagerOpenVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
|
||||
{
|
||||
if (!::vr::VR_IsHmdPresent() ||
|
||||
@ -563,23 +563,23 @@ VRSystemManagerOpenVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
|
||||
|
||||
::vr::VR_Init(&err, ::vr::EVRApplicationType::VRApplication_Scene);
|
||||
if (err) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
::vr::IVRSystem *system = (::vr::IVRSystem *)::vr::VR_GetGenericInterface(::vr::IVRSystem_Version, &err);
|
||||
if (err || !system) {
|
||||
::vr::VR_Shutdown();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
::vr::IVRChaperone *chaperone = (::vr::IVRChaperone *)::vr::VR_GetGenericInterface(::vr::IVRChaperone_Version, &err);
|
||||
if (err || !chaperone) {
|
||||
::vr::VR_Shutdown();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
::vr::IVRCompositor *compositor = (::vr::IVRCompositor*)::vr::VR_GetGenericInterface(::vr::IVRCompositor_Version, &err);
|
||||
if (err || !compositor) {
|
||||
::vr::VR_Shutdown();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
mVRSystem = system;
|
||||
@ -588,7 +588,9 @@ VRSystemManagerOpenVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
|
||||
|
||||
if (mOpenVRHMD) {
|
||||
aHMDResult.AppendElement(mOpenVRHMD);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -108,7 +108,7 @@ public:
|
||||
|
||||
virtual void Destroy() override;
|
||||
virtual void Shutdown() override;
|
||||
virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost> >& aHMDResult) override;
|
||||
virtual bool GetHMDs(nsTArray<RefPtr<VRDisplayHost> >& aHMDResult) override;
|
||||
virtual bool GetIsPresenting() override;
|
||||
virtual void HandleInput() override;
|
||||
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>&
|
||||
|
@ -622,13 +622,14 @@ VRSystemManagerPuppet::Shutdown()
|
||||
mPuppetHMD = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
VRSystemManagerPuppet::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
|
||||
{
|
||||
if (mPuppetHMD == nullptr) {
|
||||
mPuppetHMD = new VRDisplayPuppet();
|
||||
}
|
||||
aHMDResult.AppendElement(mPuppetHMD);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -103,7 +103,7 @@ public:
|
||||
|
||||
virtual void Destroy() override;
|
||||
virtual void Shutdown() override;
|
||||
virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) override;
|
||||
virtual bool GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) override;
|
||||
virtual bool GetIsPresenting() override;
|
||||
virtual void HandleInput() override;
|
||||
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>&
|
||||
|
@ -40,6 +40,17 @@ VRLayerParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
void
|
||||
VRLayerParent::Destroy()
|
||||
{
|
||||
if (mVRDisplayID) {
|
||||
VRManager* vm = VRManager::Get();
|
||||
RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(mVRDisplayID);
|
||||
if (display) {
|
||||
display->RemoveLayer(this);
|
||||
}
|
||||
// 0 will never be a valid VRDisplayID; we can use it to indicate that
|
||||
// we are destroyed and no longer associated with a display.
|
||||
mVRDisplayID = 0;
|
||||
}
|
||||
|
||||
if (mIPCOpen) {
|
||||
Unused << PVRLayerParent::Send__delete__(this);
|
||||
}
|
||||
@ -48,8 +59,10 @@ VRLayerParent::Destroy()
|
||||
mozilla::ipc::IPCResult
|
||||
VRLayerParent::RecvSubmitFrame(PTextureParent* texture)
|
||||
{
|
||||
VRManager* vm = VRManager::Get();
|
||||
vm->SubmitFrame(this, texture, mLeftEyeRect, mRightEyeRect);
|
||||
if (mVRDisplayID) {
|
||||
VRManager* vm = VRManager::Get();
|
||||
vm->SubmitFrame(this, texture, mLeftEyeRect, mRightEyeRect);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -84,14 +84,6 @@ VRManagerParent::AllocPVRLayerParent(const uint32_t& aDisplayID,
|
||||
bool
|
||||
VRManagerParent::DeallocPVRLayerParent(PVRLayerParent* actor)
|
||||
{
|
||||
gfx::VRLayerParent* layer = static_cast<gfx::VRLayerParent*>(actor);
|
||||
|
||||
VRManager* vm = VRManager::Get();
|
||||
RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(layer->GetDisplayID());
|
||||
if (display) {
|
||||
display->RemoveLayer(layer);
|
||||
}
|
||||
|
||||
delete actor;
|
||||
return true;
|
||||
}
|
||||
|
@ -5155,6 +5155,22 @@ pref("dom.vr.controller_trigger_threshold", "0.1");
|
||||
pref("dom.vr.navigation.timeout", 5000);
|
||||
// Oculus device
|
||||
pref("dom.vr.oculus.enabled", true);
|
||||
// Minimum number of milliseconds after content has stopped VR presentation
|
||||
// before the Oculus session is re-initialized to an invisible / tracking
|
||||
// only mode. If this value is too high, users will need to wait longer
|
||||
// after stopping WebVR presentation before automatically returning to the
|
||||
// Oculus home interface. (They can immediately return to the Oculus Home
|
||||
// interface through the Oculus HUD without waiting this duration)
|
||||
// If this value is too low, the Oculus Home interface may be visible
|
||||
// momentarily during VR link navigation.
|
||||
pref("dom.vr.oculus.present.timeout", 10000);
|
||||
// Minimum number of milliseconds that the browser will wait before
|
||||
// reloading the Oculus OVR library after seeing a "ShouldQuit" flag set.
|
||||
// Oculus requests that we shut down and unload the OVR library, by setting
|
||||
// a "ShouldQuit" flag. To ensure that we don't interfere with
|
||||
// Oculus software auto-updates, we will not attempt to re-load the
|
||||
// OVR library until this timeout has elapsed.
|
||||
pref("dom.vr.oculus.quit.timeout", 30000);
|
||||
// OSVR device
|
||||
pref("dom.vr.osvr.enabled", false);
|
||||
// OpenVR device
|
||||
|
Loading…
Reference in New Issue
Block a user