Bug 1392216 - Part 2: Support VR listener thread in VR; r?kip
MozReview-Commit-ID: 62PZ5opXoZ6
--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -3,16 +3,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "VRDisplayHost.h"
#include "gfxVR.h"
#include "ipc/VRLayerParent.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/dom/GamepadBinding.h" // For GamepadMappingType
+#include "VRThread.h"
#if defined(XP_WIN)
#include <d3d11.h>
#include "gfxWindowsPlatform.h"
#include "../layers/d3d11/CompositorD3D11.h"
#include "mozilla/gfx/DeviceManagerDx.h"
#include "mozilla/layers/TextureD3D11.h"
@@ -340,30 +341,33 @@ VRDisplayHost::SubmitFrame(VRLayerParent
#endif
default: {
NS_WARNING("Unsupported SurfaceDescriptor type for VR layer texture");
return;
}
}
#if defined(XP_WIN) || defined(XP_MACOSX)
-
/**
* Trigger the next VSync immediately after we are successfully
* submitting frames. As SubmitFrame is responsible for throttling
* the render loop, if we don't successfully call it, we shouldn't trigger
* NotifyVRVsync immediately, as it will run unbounded.
* If NotifyVRVsync is not called here due to SubmitFrame failing, the
* fallback "watchdog" code in VRDisplayHost::NotifyVSync() will cause
* frames to continue at a lower refresh rate until frame submission
* succeeds again.
*/
- VRManager *vm = VRManager::Get();
- MOZ_ASSERT(vm);
- vm->NotifyVRVsync(mDisplayInfo.mDisplayID);
+ VRManager* vm = VRManager::Get();
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+
+ loop->PostTask(NewRunnableMethod<const uint32_t>(
+ "gfx::VRLayerParent::SubmitFrame",
+ vm, &VRManager::NotifyVRVsync, mDisplayInfo.mDisplayID
+ ));
#endif
}
bool
VRDisplayHost::CheckClearDisplayInfoDirty()
{
if (mDisplayInfo == mLastUpdateDisplayInfo) {
return false;
--- a/gfx/vr/VRManager.cpp
+++ b/gfx/vr/VRManager.cpp
@@ -1,21 +1,23 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "VRManager.h"
#include "VRManagerParent.h"
+#include "VRThread.h"
#include "gfxVR.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/VRDisplay.h"
#include "mozilla/dom/GamepadEventTypes.h"
#include "mozilla/layers/TextureHost.h"
+#include "mozilla/layers/CompositorThread.h"
#include "mozilla/Unused.h"
#include "gfxPrefs.h"
#include "gfxVR.h"
#if defined(XP_WIN)
#include "gfxVROculus.h"
#endif
#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
@@ -156,16 +158,17 @@ VRManager::RemoveVRManagerParent(VRManag
if (mVRManagerParents.IsEmpty()) {
Destroy();
}
}
void
VRManager::NotifyVsync(const TimeStamp& aVsyncTimestamp)
{
+ MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
const double kVRDisplayRefreshMaxDuration = 5000; // milliseconds
const double kVRDisplayInactiveMaxDuration = 30000; // milliseconds
bool bHaveEventListener = false;
bool bHaveControllerListener = false;
for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) {
VRManagerParent *vmp = iter.Get()->GetKey();
@@ -231,16 +234,17 @@ VRManager::NotifyVsync(const TimeStamp&
Shutdown();
}
}
}
void
VRManager::NotifyVRVsync(const uint32_t& aDisplayID)
{
+ MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
for (const auto& manager: mManagers) {
if (manager->GetIsPresenting()) {
manager->HandleInput();
}
}
RefPtr<VRDisplayHost> display = GetDisplay(aDisplayID);
if (display) {
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -22,18 +22,18 @@
#include "mozilla/gfx/Quaternion.h"
#include <d3d11.h>
#include "CompositorD3D11.h"
#include "TextureD3D11.h"
#include "gfxVROculus.h"
+#include "VRThread.h"
-#include "mozilla/layers/CompositorThread.h"
#include "mozilla/dom/GamepadEventTypes.h"
#include "mozilla/dom/GamepadBinding.h"
#include "mozilla/Telemetry.h"
/** XXX The DX11 objects and quad blitting could be encapsulated
* into a separate object if either Oculus starts supporting
* non-Windows platforms or the blit is needed by other HMD\
* drivers.
@@ -1380,19 +1380,19 @@ VRControllerOculus::VibrateHapticComplet
printf_stderr("%s Haptics skipped.\n",
GamepadHandValues::strings[uint32_t(GetHand())].value);
}
}
VRManager *vm = VRManager::Get();
MOZ_ASSERT(vm);
- CompositorThreadHolder::Loop()->PostTask(NewRunnableMethod<uint32_t>(
- "VRManager::NotifyVibrateHapticCompleted",
- vm, &VRManager::NotifyVibrateHapticCompleted, aPromiseID));
+ VRListenerThreadHolder::Loop()->PostTask(NewRunnableMethod<uint32_t>(
+ "VRManager::NotifyVibrateHapticCompleted",
+ vm, &VRManager::NotifyVibrateHapticCompleted, aPromiseID));
}
void
VRControllerOculus::VibrateHaptic(ovrSession aSession,
uint32_t aHapticIndex,
double aIntensity,
double aDuration,
uint32_t aPromiseID)
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -16,21 +16,21 @@
#include "CompositorD3D11.h"
#include "TextureD3D11.h"
#elif defined(XP_MACOSX)
#include "mozilla/gfx/MacIOSurface.h"
#endif
#include "gfxVROpenVR.h"
#include "VRManager.h"
+#include "VRThread.h"
#include "nsServiceManagerUtils.h"
#include "nsIScreenManager.h"
-#include "mozilla/layers/CompositorThread.h"
#include "mozilla/dom/GamepadEventTypes.h"
#include "mozilla/dom/GamepadBinding.h"
#include "mozilla/Telemetry.h"
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
@@ -526,19 +526,19 @@ VRControllerOpenVR::UpdateVibrateHaptic(
}
}
void
VRControllerOpenVR::VibrateHapticComplete(uint32_t aPromiseID)
{
VRManager *vm = VRManager::Get();
- CompositorThreadHolder::Loop()->PostTask(NewRunnableMethod<uint32_t>
- ("VRManager::NotifyVibrateHapticCompleted",
- vm, &VRManager::NotifyVibrateHapticCompleted, aPromiseID));
+ VRListenerThreadHolder::Loop()->PostTask(NewRunnableMethod<uint32_t>(
+ "VRManager::NotifyVibrateHapticCompleted",
+ vm, &VRManager::NotifyVibrateHapticCompleted, aPromiseID));
}
void
VRControllerOpenVR::VibrateHaptic(::vr::IVRSystem* aVRSystem,
uint32_t aHapticIndex,
double aIntensity,
double aDuration,
uint32_t aPromiseID)
--- a/gfx/vr/ipc/VRLayerParent.cpp
+++ b/gfx/vr/ipc/VRLayerParent.cpp
@@ -2,18 +2,20 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "VRLayerParent.h"
#include "mozilla/Unused.h"
#include "VRDisplayHost.h"
+#include "mozilla/layers/CompositorThread.h"
namespace mozilla {
+using namespace layers;
namespace gfx {
VRLayerParent::VRLayerParent(uint32_t aVRDisplayID, const uint32_t aGroup)
: mIPCOpen(true)
, mVRDisplayID(aVRDisplayID)
, mGroup(aGroup)
{
}
@@ -57,22 +59,36 @@ VRLayerParent::Destroy()
mozilla::ipc::IPCResult
VRLayerParent::RecvSubmitFrame(const layers::SurfaceDescriptor &aTexture,
const uint64_t& aFrameId,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
{
if (mVRDisplayID) {
+ MessageLoop* loop = layers::CompositorThreadHolder::Loop();
VRManager* vm = VRManager::Get();
RefPtr<VRDisplayHost> display = vm->GetDisplay(mVRDisplayID);
if (display) {
- display->SubmitFrame(this, aTexture, aFrameId,
- aLeftEyeRect, aRightEyeRect);
+ // Because VR compositor still shares the same graphics device with Compositor thread.
+ // We have to post sumbit frame tasks to Compositor thread.
+ // TODO: Move SubmitFrame to Bug 1392217.
+ loop->PostTask(NewRunnableMethod<VRDisplayHost*, const layers::SurfaceDescriptor&, uint64_t,
+ const gfx::Rect&, const gfx::Rect&>(
+ "gfx::VRLayerParent::SubmitFrame",
+ this,
+ &VRLayerParent::SubmitFrame, display, aTexture, aFrameId, aLeftEyeRect, aRightEyeRect));
}
}
return IPC_OK();
}
+void
+VRLayerParent::SubmitFrame(VRDisplayHost* aDisplay, const layers::SurfaceDescriptor& aTexture,
+ uint64_t aFrameId, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect)
+{
+ aDisplay->SubmitFrame(this, aTexture, aFrameId,
+ aLeftEyeRect, aRightEyeRect);
+}
} // namespace gfx
} // namespace mozilla
--- a/gfx/vr/ipc/VRLayerParent.h
+++ b/gfx/vr/ipc/VRLayerParent.h
@@ -34,14 +34,18 @@ protected:
void Destroy();
bool mIPCOpen;
uint32_t mVRDisplayID;
gfx::Rect mLeftEyeRect;
gfx::Rect mRightEyeRect;
uint32_t mGroup;
+
+private:
+ void SubmitFrame(VRDisplayHost* aDisplay, const layers::SurfaceDescriptor& aTexture,
+ uint64_t aFrameId, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect);
};
} // namespace gfx
} // namespace mozilla
#endif
--- a/gfx/vr/ipc/VRManagerChild.cpp
+++ b/gfx/vr/ipc/VRManagerChild.cpp
@@ -2,16 +2,17 @@
* vim: sw=2 ts=8 et :
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "VRManagerChild.h"
#include "VRManagerParent.h"
+#include "VRThread.h"
#include "VRDisplayClient.h"
#include "nsGlobalWindow.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/layers/CompositorThread.h" // for CompositorThread
#include "mozilla/dom/Navigator.h"
#include "mozilla/dom/VREventObserver.h"
#include "mozilla/dom/WindowBinding.h" // for FrameRequestCallback
#include "mozilla/dom/ContentChild.h"
@@ -114,17 +115,17 @@ VRManagerChild::ReinitForContent(Endpoin
VRManagerChild::InitSameProcess()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!sVRManagerChildSingleton);
sVRManagerChildSingleton = new VRManagerChild();
sVRManagerParentSingleton = VRManagerParent::CreateSameProcess();
sVRManagerChildSingleton->Open(sVRManagerParentSingleton->GetIPCChannel(),
- mozilla::layers::CompositorThreadHolder::Loop(),
+ VRListenerThreadHolder::Loop(),
mozilla::ipc::ChildSide);
}
/* static */ void
VRManagerChild::InitWithGPUProcess(Endpoint<PVRManagerChild>&& aEndpoint)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!sVRManagerChildSingleton);
--- a/gfx/vr/ipc/VRManagerParent.cpp
+++ b/gfx/vr/ipc/VRManagerParent.cpp
@@ -6,19 +6,19 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "VRManagerParent.h"
#include "ipc/VRLayerParent.h"
#include "mozilla/gfx/PVRManagerParent.h"
#include "mozilla/ipc/ProtocolTypes.h"
#include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol
#include "mozilla/TimeStamp.h" // for TimeStamp
-#include "mozilla/layers/CompositorThread.h"
#include "mozilla/Unused.h"
#include "VRManager.h"
+#include "VRThread.h"
#include "gfxVRPuppet.h"
namespace mozilla {
using namespace layers;
namespace gfx {
VRManagerParent::VRManagerParent(ProcessId aChildProcessId, bool aIsContentChild)
: mDisplayTestID(0)
@@ -82,17 +82,17 @@ VRManagerParent::UnregisterFromManager()
VRManager* vm = VRManager::Get();
vm->RemoveVRManagerParent(this);
mVRManagerHolder = nullptr;
}
/* static */ bool
VRManagerParent::CreateForContent(Endpoint<PVRManagerParent>&& aEndpoint)
{
- MessageLoop* loop = layers::CompositorThreadHolder::Loop();
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
RefPtr<VRManagerParent> vmp = new VRManagerParent(aEndpoint.OtherPid(), true);
loop->PostTask(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
"gfx::VRManagerParent::Bind",
vmp,
&VRManagerParent::Bind,
Move(aEndpoint)));
@@ -106,73 +106,76 @@ VRManagerParent::Bind(Endpoint<PVRManage
return;
}
mSelfRef = this;
RegisterWithManager();
}
/*static*/ void
-VRManagerParent::RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager)
+VRManagerParent::RegisterVRManagerInVRListenerThread(VRManagerParent* aVRManager)
{
aVRManager->RegisterWithManager();
}
/*static*/ VRManagerParent*
VRManagerParent::CreateSameProcess()
{
- MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
RefPtr<VRManagerParent> vmp = new VRManagerParent(base::GetCurrentProcId(), false);
- vmp->mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
+ vmp->mVRListenerThreadHolder = VRListenerThreadHolder::GetSingleton();
vmp->mSelfRef = vmp;
- loop->PostTask(NewRunnableFunction(RegisterVRManagerInCompositorThread, vmp.get()));
+ loop->PostTask(NewRunnableFunction(RegisterVRManagerInVRListenerThread, vmp.get()));
return vmp.get();
}
bool
VRManagerParent::CreateForGPUProcess(Endpoint<PVRManagerParent>&& aEndpoint)
{
- MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
RefPtr<VRManagerParent> vmp = new VRManagerParent(aEndpoint.OtherPid(), false);
- vmp->mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
+ vmp->mVRListenerThreadHolder = VRListenerThreadHolder::GetSingleton();
loop->PostTask(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
"gfx::VRManagerParent::Bind",
vmp,
&VRManagerParent::Bind,
Move(aEndpoint)));
return true;
}
void
VRManagerParent::DeferredDestroy()
{
- mCompositorThreadHolder = nullptr;
+ mVRListenerThreadHolder = nullptr;
mSelfRef = nullptr;
}
void
VRManagerParent::ActorDestroy(ActorDestroyReason why)
{
UnregisterFromManager();
MessageLoop::current()->PostTask(
NewRunnableMethod("gfx::VRManagerParent::DeferredDestroy",
this,
&VRManagerParent::DeferredDestroy));
}
void
VRManagerParent::OnChannelConnected(int32_t aPid)
{
- mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
+ mVRListenerThreadHolder = VRListenerThreadHolder::GetSingleton();
}
mozilla::ipc::IPCResult
VRManagerParent::RecvRefreshDisplays()
{
+ // TODO: Bug 1406327, Launch VR listener thread here.
+ MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
+
// This is called to refresh the VR Displays for Navigator.GetVRDevices().
// We must pass "true" to VRManager::RefreshVRDisplays()
// to ensure that the promise returned by Navigator.GetVRDevices
// can resolve even if there are no changes to the VR Displays.
VRManager* vm = VRManager::Get();
vm->RefreshVRDisplays(true);
return IPC_OK();
--- a/gfx/vr/ipc/VRManagerParent.h
+++ b/gfx/vr/ipc/VRManagerParent.h
@@ -3,23 +3,23 @@
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_VR_VRMANAGERPARENT_H
#define MOZILLA_GFX_VR_VRMANAGERPARENT_H
-#include "mozilla/layers/CompositableTransactionParent.h"
-#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
+#include "mozilla/layers/CompositableTransactionParent.h" // need?
#include "mozilla/gfx/PVRManagerParent.h" // for PVRManagerParent
#include "mozilla/gfx/PVRLayerParent.h" // for PVRLayerParent
#include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol
#include "mozilla/TimeStamp.h" // for TimeStamp
#include "gfxVR.h" // for VRFieldOfView
+#include "VRThread.h" // for VRListenerThreadHolder
namespace mozilla {
using namespace layers;
namespace gfx {
class VRManager;
namespace impl {
@@ -76,26 +76,24 @@ protected:
virtual mozilla::ipc::IPCResult RecvNewPoseMoveToMockController(const uint32_t& aDeviceID, const GamepadPoseState& pose) override;
private:
void RegisterWithManager();
void UnregisterFromManager();
void Bind(Endpoint<PVRManagerParent>&& aEndpoint);
- static void RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager);
+ static void RegisterVRManagerInVRListenerThread(VRManagerParent* aVRManager);
void DeferredDestroy();
// This keeps us alive until ActorDestroy(), at which point we do a
// deferred destruction of ourselves.
RefPtr<VRManagerParent> mSelfRef;
-
- // Keep the compositor thread alive, until we have destroyed ourselves.
- RefPtr<layers::CompositorThreadHolder> mCompositorThreadHolder;
+ RefPtr<VRListenerThreadHolder> mVRListenerThreadHolder;
// Keep the VRManager alive, until we have destroyed ourselves.
RefPtr<VRManager> mVRManagerHolder;
nsRefPtrHashtable<nsUint32HashKey, impl::VRDisplayPuppet> mVRDisplayTests;
nsRefPtrHashtable<nsUint32HashKey, impl::VRControllerPuppet> mVRControllerTests;
uint32_t mDisplayTestID;
uint32_t mControllerTestID;
bool mHaveEventListener;