--- a/dom/vr/test/reftest/draw_rect.html
+++ b/dom/vr/test/reftest/draw_rect.html
@@ -31,34 +31,34 @@ If this fails, something is seriously wr
var img = null;
function setStatus(text) {
var elem = document.getElementById('status');
elem.innerHTML = text;
}
function initVRMock() {
- VRServiceTest = navigator.requestVRServiceTest();
- if (!VRServiceTest) {
- setStatus('VRServiceTest get failed.');
- return;
- }
-
- VRSimulationDriver.AttachWebVRDisplay().then(() => {
- // Looking for VR displays
- if (navigator.getVRDisplays) {
- submitResult = new VRSubmitFrameResult();
- navigator.getVRDisplays().then(function (displays) {
- if (displays.length > 0) {
- vrDisplay = displays[0];
- vrDisplay.requestPresent([{ source: webglCanvas }]);
- vrDisplay.requestAnimationFrame(onAnimationFrame);
- }
- });
+ navigator.getVRDisplays().then(function (displays) {
+ VRServiceTest = navigator.requestVRServiceTest();
+ if (!VRServiceTest) {
+ setStatus('VRServiceTest get failed.');
+ return;
}
+ }).then(function (displays) {
+ // Looking for VR displays
+ if (navigator.getVRDisplays) {
+ submitResult = new VRSubmitFrameResult();
+ navigator.getVRDisplays().then(function (displays) {
+ if (displays.length > 0) {
+ vrDisplay = displays[0];
+ vrDisplay.requestPresent([{ source: webglCanvas }]);
+ vrDisplay.requestAnimationFrame(onAnimationFrame);
+ }
+ });
+ }
});
}
function onAnimationFrame() {
if (!vrDisplay.isPresenting) {
return;
}
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -426,18 +426,18 @@ GPUParent::ActorDestroy(ActorDestroyReas
}
#endif
if (mVsyncBridge) {
mVsyncBridge->Shutdown();
mVsyncBridge = nullptr;
}
dom::VideoDecoderManagerParent::ShutdownVideoBridge();
+ VRListenerThreadHolder::Shutdown();
CompositorThreadHolder::Shutdown();
- VRListenerThreadHolder::Shutdown();
if (gfxVars::UseWebRender()) {
wr::RenderThread::ShutDown();
}
Factory::ShutDown();
#if defined(XP_WIN)
DeviceManagerDx::Shutdown();
#endif
LayerTreeOwnerTracker::Shutdown();
--- a/gfx/layers/ipc/CompositorVsyncScheduler.cpp
+++ b/gfx/layers/ipc/CompositorVsyncScheduler.cpp
@@ -138,22 +138,24 @@ CompositorVsyncScheduler::PostCompositeT
VRManager* vm = VRManager::Get();
TimeStamp activeTime(vm->GetLastVRListenerThreadActiveTime());
// Shutdown VR listener thread when no VR content in 45 sec. Shutdown threads
// only allows to be run at the main thread.
if (!activeTime.IsNull() && ((aCompositeTimestamp - activeTime) > timeout)) {
VRListenerThreadHolder::Shutdown();
} else {
+ MonitorAutoLock lockVR(mCurrentVRListenerTaskMonitor);
RefPtr<CancelableRunnable> task = NewCancelableRunnableMethod<TimeStamp>(
"layers::CompositorVsyncScheduler::DispatchVREvents",
this,
&CompositorVsyncScheduler::DispatchVREvents,
aCompositeTimestamp);
mCurrentVRListenerTask = task;
+ // vm->mCurrentVRListenerTaskCom = task;
MOZ_ASSERT(VRListenerThreadHolder::Loop());
VRListenerThreadHolder::Loop()->PostTask(Move(task.forget()));
}
}
}
void
CompositorVsyncScheduler::ScheduleComposition()
@@ -240,21 +242,26 @@ CompositorVsyncScheduler::NotifyVsync(Ti
PostCompositeTask(aVsyncTimestamp);
return true;
}
void
CompositorVsyncScheduler::CancelCurrentCompositeTask()
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread() || NS_IsMainThread());
- MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
+ MonitorAutoLock lockComposite(mCurrentCompositeTaskMonitor);
if (mCurrentCompositeTask) {
mCurrentCompositeTask->Cancel();
mCurrentCompositeTask = nullptr;
}
+// MonitorAutoLock lockVR(mCurrentVRListenerTaskMonitor);
+ if (mCurrentVRListenerTask) {
+ mCurrentVRListenerTask->Cancel();
+ mCurrentVRListenerTask = nullptr;
+ }
}
void
CompositorVsyncScheduler::Composite(TimeStamp aVsyncTimestamp)
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
{
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -1066,18 +1066,18 @@ gfxPlatform::ShutdownLayersIPC()
if (gfxVars::UseOMTP()) {
layers::PaintThread::Shutdown();
}
} else if (XRE_IsParentProcess()) {
gfx::VRManagerChild::ShutDown();
layers::CompositorManagerChild::Shutdown();
layers::ImageBridgeChild::ShutDown();
// This has to happen after shutting down the child protocols.
+ gfx::VRListenerThreadHolder::Shutdown();
layers::CompositorThreadHolder::Shutdown();
- gfx::VRListenerThreadHolder::Shutdown();
if (gfxVars::UseWebRender()) {
wr::RenderThread::ShutDown();
Preferences::UnregisterCallback(WebRenderDebugPrefChangeCallback, WR_DEBUG_PREF);
}
} else {
// TODO: There are other kind of processes and we should make sure gfx
--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -349,22 +349,23 @@ VRDisplayHost::SubmitFrame(VRLayerParent
* 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();
- MessageLoop* loop = VRListenerThreadHolder::Loop();
-
- loop->PostTask(NewRunnableMethod<const uint32_t>(
- "gfx::VRManager::NotifyVRVsync",
- vm, &VRManager::NotifyVRVsync, mDisplayInfo.mDisplayID
- ));
+ if (VRListenerThreadHolder::IsActive()) {
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ loop->PostTask(NewRunnableMethod<const uint32_t>(
+ "gfx::VRManager::NotifyVRVsync",
+ vm, &VRManager::NotifyVRVsync, mDisplayInfo.mDisplayID
+ ));
+ }
#endif
}
bool
VRDisplayHost::CheckClearDisplayInfoDirty()
{
if (mDisplayInfo == mLastUpdateDisplayInfo) {
return false;
--- a/gfx/vr/VRManager.cpp
+++ b/gfx/vr/VRManager.cpp
@@ -45,17 +45,20 @@ VRManager::ManagerInit()
if (sVRManagerSingleton == nullptr) {
sVRManagerSingleton = new VRManager();
ClearOnShutdown(&sVRManagerSingleton);
}
}
VRManager::VRManager()
- : mInitialized(false)
+ : mCurrentVRListenerTaskMonitor("vrListenerMonitor")
+ , mCurrentVRListenerTask(nullptr)
+ , mMutex("VRManager.Mutex")
+ , mInitialized(false)
, mVRTestSystemCreated(false)
{
MOZ_COUNT_CTOR(VRManager);
MOZ_ASSERT(sVRManagerSingleton == nullptr);
RefPtr<VRSystemManager> mgr;
/**
@@ -97,36 +100,52 @@ VRManager::VRManager()
// Preference only can be set at the Parent process.
if (XRE_IsParentProcess() && gfxPrefs::VREnabled()) {
Preferences::SetBool("dom.gamepad.extensions.enabled", true);
}
}
VRManager::~VRManager()
{
+ printf_stderr("~VRManager.................\n");
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mInitialized);
MOZ_COUNT_DTOR(VRManager);
}
void
VRManager::Destroy()
{
+ // TODO::remove the refreshVRDisplayInternal cancelablerunnable.
+ printf_stderr("VRManager::Destroy().................\n");
+
+ mPuppetManager = nullptr;
mVRDisplays.Clear();
mVRControllers.Clear();
for (uint32_t i = 0; i < mManagers.Length(); ++i) {
mManagers[i]->Destroy();
}
mInitialized = false;
+
+ //MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
+ MonitorAutoLock lockVR(mCurrentVRListenerTaskMonitor);
+ if (mCurrentVRListenerTask) {
+ mCurrentVRListenerTask->Cancel();
+ mCurrentVRListenerTask = nullptr;
+ }
}
void
VRManager::Shutdown()
{
+ MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
+ return;
+ printf_stderr("VRManager::Shutdown().................\n");
+ // MutexAutoLock autoLock(mMutex);
mVRDisplays.Clear();
mVRControllers.Clear();
for (uint32_t i = 0; i < mManagers.Length(); ++i) {
mManagers[i]->Shutdown();
}
}
void
@@ -252,35 +271,59 @@ VRManager::NotifyVRVsync(const uint32_t&
if (display) {
display->StartFrame();
}
RefreshVRDisplays();
}
void
+VRManager::RefreshPuppetDisplay()
+{
+ MutexAutoLock autoLock(mMutex);
+ MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
+ // Force to refresh VRPuppet display here
+ // because we need it to setup data early.
+ nsTArray<RefPtr<gfx::VRDisplayHost> > displays;
+ mPuppetManager->GetHMDs(displays);
+ for (const auto& display: displays) {
+ mVRDisplays.Put(display->GetDisplayInfo().GetDisplayID(), display);
+ }
+}
+
+void
VRManager::RefreshVRDisplays(bool aMustDispatch)
{
+ if (!VRListenerThreadHolder::IsActive()) {
+ return;
+ }
+
if (VRListenerThreadHolder::IsInVRListenerThread()) {
RefreshVRDisplaysInternal(aMustDispatch);
} else {
- if (VRListenerThreadHolder::IsActive()) {
- MessageLoop* loop = VRListenerThreadHolder::Loop();
- loop->PostTask(NewRunnableMethod<bool>(
- "gfx::VRManager::RefreshVRDisplaysInternal",
- this, &VRManager::RefreshVRDisplaysInternal, aMustDispatch
- ));
- }
+ MonitorAutoLock lock(mCurrentVRListenerTaskMonitor);
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ RefPtr<CancelableRunnable> task = NewCancelableRunnableMethod<bool>(
+ "gfx::VRManager::RefreshVRDisplaysInternal",
+ this, &VRManager::RefreshVRDisplaysInternal, aMustDispatch
+ );
+ MOZ_ASSERT(loop);
+ mCurrentVRListenerTask = task;
+ loop->PostTask(task.forget());
}
}
void
VRManager::RefreshVRDisplaysInternal(bool aMustDispatch)
{
MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
+
+ MonitorAutoLock lock(mCurrentVRListenerTaskMonitor);
+ mCurrentVRListenerTask = nullptr;
+
nsTArray<RefPtr<gfx::VRDisplayHost> > displays;
mLastVRListenerThreadActiveTime = TimeStamp::Now();
/** We don't wish to enumerate the same display from multiple managers,
* so stop as soon as we get a display.
* It is still possible to get multiple displays from a single manager,
* but do not wish to mix-and-match for risk of reporting a duplicate.
*
* XXX - Perhaps there will be a better way to detect duplicate displays
@@ -323,89 +366,114 @@ VRManager::RefreshVRDisplaysInternal(boo
for (const auto& display: displays) {
mVRDisplays.Put(display->GetDisplayInfo().GetDisplayID(), display);
}
}
if (displayInfoChanged || displaySetChanged || aMustDispatch) {
// Due to PVRManager is at Compositor thread. We have to post tasks
// to Compositor thread when sending to them the content processes.
+ nsTArray<VRDisplayInfo> update;
+ GetVRDisplayInfo(update);
MessageLoop* loop = CompositorThreadHolder::Loop();
- loop->PostTask(
- NewRunnableMethod("gfx::VRManager::DispatchVRDisplayInfoUpdate",
- this,
- &VRManager::DispatchVRDisplayInfoUpdate));
+ if (loop) {
+ loop->PostTask(
+ NewRunnableMethod<nsTArray<VRDisplayInfo>&&>(
+ "gfx::VRManager::DispatchVRDisplayInfoUpdate",
+ this, &VRManager::DispatchVRDisplayInfoUpdate, Move(update)));
+ }
}
}
void
-VRManager::DispatchVRDisplayInfoUpdate()
+VRManager::DispatchVRDisplayInfoUpdate(nsTArray<VRDisplayInfo>&& displays)
{
MOZ_ASSERT(NS_IsInCompositorThread());
- nsTArray<VRDisplayInfo> update;
- GetVRDisplayInfo(update);
-
for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) {
- Unused << iter.Get()->GetKey()->SendUpdateDisplayInfo(update);
+ Unused << iter.Get()->GetKey()->SendUpdateDisplayInfo(displays);
}
}
/**
* Get any VR displays that have already been enumerated without
* activating any new devices.
*/
void
VRManager::GetVRDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayInfo)
{
+ MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
aDisplayInfo.Clear();
for (auto iter = mVRDisplays.Iter(); !iter.Done(); iter.Next()) {
gfx::VRDisplayHost* display = iter.UserData();
aDisplayInfo.AppendElement(VRDisplayInfo(display->GetDisplayInfo()));
}
}
RefPtr<gfx::VRDisplayHost>
VRManager::GetDisplay(const uint32_t& aDisplayID)
{
+ MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
RefPtr<gfx::VRDisplayHost> display;
if (mVRDisplays.Get(aDisplayID, getter_AddRefs(display))) {
return display;
}
return nullptr;
}
RefPtr<gfx::VRControllerHost>
VRManager::GetController(const uint32_t& aControllerID)
{
+ MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
RefPtr<gfx::VRControllerHost> controller;
if (mVRControllers.Get(aControllerID, getter_AddRefs(controller))) {
return controller;
}
return nullptr;
}
void
VRManager::GetVRControllerInfo(nsTArray<VRControllerInfo>& aControllerInfo)
{
+ MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
aControllerInfo.Clear();
for (auto iter = mVRControllers.Iter(); !iter.Done(); iter.Next()) {
gfx::VRControllerHost* controller = iter.UserData();
aControllerInfo.AppendElement(VRControllerInfo(controller->GetControllerInfo()));
}
}
TimeStamp
VRManager::GetLastVRListenerThreadActiveTime()
{
return mLastVRListenerThreadActiveTime;
}
void
VRManager::RefreshVRControllers()
{
+ if (!VRListenerThreadHolder::IsActive()) {
+ return;
+ }
+
+ if (VRListenerThreadHolder::IsInVRListenerThread()) {
+ RefreshVRControllersInternal();
+ } else {
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ MOZ_ASSERT(loop);
+ loop->PostTask(
+ NewRunnableMethod(
+ "gfx::VRManager::RefreshVRControllersInternal",
+ this, &VRManager::RefreshVRControllersInternal));
+ }
+}
+
+void
+VRManager::RefreshVRControllersInternal()
+{
+ MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
nsTArray<RefPtr<gfx::VRControllerHost>> controllers;
ScanForControllers();
for (uint32_t i = 0; i < mManagers.Length()
&& controllers.Length() == 0; ++i) {
mManagers[i]->GetControllers(controllers);
}
@@ -440,59 +508,73 @@ VRManager::ScanForControllers()
for (uint32_t i = 0; i < mManagers.Length(); ++i) {
mManagers[i]->ScanForControllers();
}
}
void
VRManager::RemoveControllers()
{
+ if (VRListenerThreadHolder::IsActive()) {
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ loop->PostTask(
+ NewRunnableMethod(
+ "gfx::VRManager::RemoveControllersInternal",
+ this, &VRManager::RemoveControllersInternal));
+ }
+}
+
+void
+VRManager::RemoveControllersInternal()
+{
+ MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
for (uint32_t i = 0; i < mManagers.Length(); ++i) {
mManagers[i]->RemoveControllers();
}
mVRControllers.Clear();
}
void
VRManager::CreateVRTestSystem()
{
if (mVRTestSystemCreated) {
return;
}
- RefPtr<VRSystemManager> mgr = VRSystemManagerPuppet::Create();
- if (mgr) {
- mManagers.AppendElement(mgr);
+ mPuppetManager = VRSystemManagerPuppet::Create();
+ if (mPuppetManager) {
+ mManagers.AppendElement(mPuppetManager);
mVRTestSystemCreated = true;
- }
- // Force to refresh VRPuppet display here
- // because we need it to setup data early.
- nsTArray<RefPtr<gfx::VRDisplayHost> > displays;
- mgr->GetHMDs(displays);
- for (const auto& display: displays) {
- mVRDisplays.Put(display->GetDisplayInfo().GetDisplayID(), display);
+ // Force to refresh VRPuppet display here
+ // because we need it to setup data early.
+ nsTArray<RefPtr<gfx::VRDisplayHost> > displays;
+ mPuppetManager->GetHMDs(displays);
+ for (const auto& display: displays) {
+ mVRDisplays.Put(display->GetDisplayInfo().GetDisplayID(), display);
+ }
}
}
template<class T>
void
VRManager::NotifyGamepadChange(uint32_t aIndex, const T& aInfo)
{
dom::GamepadChangeEventBody body(aInfo);
dom::GamepadChangeEvent e(aIndex, dom::GamepadServiceType::VR, body);
// Due to PVRManager is at Compositor thread. We have to post
// tasks to Compositor thread.
MessageLoop* loop = CompositorThreadHolder::Loop();
- loop->PostTask(
- NewRunnableMethod<dom::GamepadChangeEvent>(
- "gfx::VRManager::NotifyGamepadChangeEventsToContent",
- this,
- &VRManager::NotifyGamepadChangeEventsToContent, e));
+ if (loop) {
+ loop->PostTask(
+ NewRunnableMethod<dom::GamepadChangeEvent>(
+ "gfx::VRManager::NotifyGamepadChangeEventsToContent",
+ this, &VRManager::NotifyGamepadChangeEventsToContent, e));
+ }
}
void
VRManager::NotifyGamepadChangeEventsToContent(const dom::GamepadChangeEvent& aEvent)
{
MOZ_ASSERT(NS_IsInCompositorThread());
for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) {
Unused << iter.Get()->GetKey()->SendGamepadUpdate(aEvent);
@@ -519,21 +601,22 @@ VRManager::StopVibrateHaptic(uint32_t aC
}
void
VRManager::NotifyVibrateHapticCompleted(uint32_t aPromiseID)
{
// Due to PVRManager is at Compositor thread. We have to post
// tasks to Compositor thread.
MessageLoop* loop = CompositorThreadHolder::Loop();
- loop->PostTask(
- NewRunnableMethod<uint32_t>(
- "gfx::VRManager::NotifyVibrateHapticCompletedToContent",
- this,
- &VRManager::NotifyVibrateHapticCompletedToContent, aPromiseID));
+ if (loop) {
+ loop->PostTask(
+ NewRunnableMethod<uint32_t>(
+ "gfx::VRManager::NotifyVibrateHapticCompletedToContent",
+ this, &VRManager::NotifyVibrateHapticCompletedToContent, aPromiseID));
+ }
}
void
VRManager::NotifyVibrateHapticCompletedToContent(uint32_t aPromiseID)
{
MOZ_ASSERT(NS_IsInCompositorThread());
for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) {
Unused << iter.Get()->GetKey()->SendReplyGamepadVibrateHaptic(aPromiseID);
--- a/gfx/vr/VRManager.h
+++ b/gfx/vr/VRManager.h
@@ -33,59 +33,67 @@ public:
static VRManager* Get();
void AddVRManagerParent(VRManagerParent* aVRManagerParent);
void RemoveVRManagerParent(VRManagerParent* aVRManagerParent);
void NotifyVsync(const TimeStamp& aVsyncTimestamp);
void NotifyVRVsync(const uint32_t& aDisplayID);
void RefreshVRDisplays(bool aMustDispatch = false);
+ void RefreshPuppetDisplay();
void RefreshVRControllers();
void ScanForControllers();
void RemoveControllers();
template<class T> void NotifyGamepadChange(uint32_t aIndex, const T& aInfo);
RefPtr<gfx::VRDisplayHost> GetDisplay(const uint32_t& aDisplayID);
void GetVRDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayInfo);
RefPtr<gfx::VRControllerHost> GetController(const uint32_t& aControllerID);
void GetVRControllerInfo(nsTArray<VRControllerInfo>& aControllerInfo);
void CreateVRTestSystem();
void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
double aIntensity, double aDuration, uint32_t aPromiseID);
void StopVibrateHaptic(uint32_t aControllerIdx);
void NotifyVibrateHapticCompleted(uint32_t aPromiseID);
void DispatchSubmitFrameResult(uint32_t aDisplayID, const VRSubmitFrameResultInfo& aResult);
TimeStamp GetLastVRListenerThreadActiveTime();
+ RefPtr<CancelableRunnable> mCurrentVRListenerTaskCom;
protected:
VRManager();
~VRManager();
private:
void Init();
void Destroy();
void Shutdown();
- void DispatchVRDisplayInfoUpdate();
+ void DispatchVRDisplayInfoUpdate(nsTArray<VRDisplayInfo>&& displays);
void RefreshVRDisplaysInternal(bool aMustDispatch);
+ void RefreshVRControllersInternal();
+ void RemoveControllersInternal();
void NotifyGamepadChangeEventsToContent(const dom::GamepadChangeEvent& aEvent);
void NotifyVibrateHapticCompletedToContent(uint32_t aPromiseID);
typedef nsTHashtable<nsRefPtrHashKey<VRManagerParent>> VRManagerParentSet;
VRManagerParentSet mVRManagerParents;
typedef nsTArray<RefPtr<VRSystemManager>> VRSystemManagerArray;
VRSystemManagerArray mManagers;
typedef nsRefPtrHashtable<nsUint32HashKey, gfx::VRDisplayHost> VRDisplayHostHashMap;
VRDisplayHostHashMap mVRDisplays;
typedef nsRefPtrHashtable<nsUint32HashKey, gfx::VRControllerHost> VRControllerHostHashMap;
VRControllerHostHashMap mVRControllers;
+ RefPtr<VRSystemManager> mPuppetManager;
+ mozilla::Monitor mCurrentVRListenerTaskMonitor;
+ RefPtr<CancelableRunnable> mCurrentVRListenerTask;
+ Mutex mMutex;
Atomic<bool> mInitialized;
TimeStamp mLastRefreshTime;
TimeStamp mLastActiveTime;
TimeStamp mLastVRListenerThreadActiveTime;
bool mVRTestSystemCreated;
};
--- a/gfx/vr/VRThread.cpp
+++ b/gfx/vr/VRThread.cpp
@@ -90,17 +90,17 @@ VRListenerThreadHolder::CreateThread()
return vrThread;
}
void
VRListenerThreadHolder::Start()
{
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread!");
MOZ_ASSERT(!sVRListenerThreadHolder, "The VR listener thread has already been started!");
-
+ printf_stderr("VRListenerThreadHolder::Start.................\n");
sVRListenerThreadHolder = new VRListenerThreadHolder();
sStartTime = TimeStamp::Now();
sShutdowning = false;
}
TimeStamp
VRListenerThreadHolder::GetStartTime()
{
@@ -108,16 +108,17 @@ VRListenerThreadHolder::GetStartTime()
}
/* static */ void
VRListenerThreadHolder::Shutdown()
{
if (!IsActive()) {
return;
}
+ printf_stderr("VRListenerThreadHolder::Shutdown.................\n");
sShutdowning = true;
RefPtr<Runnable> runnable = NewRunnableFunction(
&VRListenerThreadHolder::ShutdownInternal);
NS_DispatchToMainThread(runnable.forget());
}
/* static */ void
--- a/gfx/vr/ipc/VRLayerParent.cpp
+++ b/gfx/vr/ipc/VRLayerParent.cpp
@@ -36,52 +36,96 @@ void
VRLayerParent::ActorDestroy(ActorDestroyReason aWhy)
{
mIPCOpen = false;
}
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 (!VRListenerThreadHolder::IsActive()) {
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ loop->PostTask(NewRunnableMethod(
+ "gfx::VRLayerParent::DestroyInternal",
+ this, &VRLayerParent::DestroyInternal));
+ }
+
+ if (mIPCOpen) {
+ Unused << PVRLayerParent::Send__delete__(this);
+ }
+}
+
+void
+VRLayerParent::DestroyInternal()
+{
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);
- }
}
mozilla::ipc::IPCResult
VRLayerParent::RecvSubmitFrame(const layers::SurfaceDescriptor &aTexture,
const uint64_t& aFrameId,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
{
if (mVRDisplayID) {
- VRManager* vm = VRManager::Get();
- RefPtr<VRDisplayHost> display = vm->GetDisplay(mVRDisplayID);
- if (display) {
- // TODO: Move SubmitFrame to VRSubmitFrame thread in Bug 1392217.
- SubmitFrame(display, aTexture, aFrameId, aLeftEyeRect, aRightEyeRect);
+ if (VRListenerThreadHolder::IsActive()) {
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ loop->PostTask(NewRunnableMethod<const layers::SurfaceDescriptor, uint64_t,
+ const gfx::Rect&, const gfx::Rect&>(
+ "gfx::VRLayerParent::SubmitFrame",
+ this,
+ &VRLayerParent::SubmitFrame, aTexture, aFrameId, aLeftEyeRect, aRightEyeRect));
}
}
return IPC_OK();
}
void
-VRLayerParent::SubmitFrame(VRDisplayHost* aDisplay, const layers::SurfaceDescriptor& aTexture,
+VRLayerParent::SubmitFrame(const layers::SurfaceDescriptor& aTexture,
uint64_t aFrameId, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect)
{
+ VRManager* vm = VRManager::Get();
+ RefPtr<VRDisplayHost> display = vm->GetDisplay(mVRDisplayID);
+ if (display) {
+ // TODO: Move SubmitFrame to VRSubmitFrame thread in Bug 1392217.
+ // SubmitFrame(display, aTexture, aFrameId, aLeftEyeRect, aRightEyeRect);
+
+ MessageLoop* loop = layers::CompositorThreadHolder::Loop();
+ loop->PostTask(NewRunnableMethod<VRDisplayHost*, const layers::SurfaceDescriptor, uint64_t,
+ const gfx::Rect&, const gfx::Rect&>(
+ "gfx::VRLayerParent::SubmitFrameInternal",
+ this,
+ &VRLayerParent::SubmitFrameInternal, display, aTexture, aFrameId, aLeftEyeRect, aRightEyeRect));
+ // display->SubmitFrame(this, aTexture, aFrameId, aLeftEyeRect, aRightEyeRect);
+ }
+}
+
+void
+VRLayerParent::SubmitFrameInternal(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
@@ -37,16 +37,19 @@ protected:
bool mIPCOpen;
uint32_t mVRDisplayID;
gfx::Rect mLeftEyeRect;
gfx::Rect mRightEyeRect;
uint32_t mGroup;
private:
- void SubmitFrame(VRDisplayHost* aDisplay, const layers::SurfaceDescriptor& aTexture,
+ void SubmitFrame(const layers::SurfaceDescriptor& aTexture,
uint64_t aFrameId, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect);
+ void SubmitFrameInternal(VRDisplayHost* aDisplay, const layers::SurfaceDescriptor& aTexture,
+ uint64_t aFrameId, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect);
+ void DestroyInternal();
};
} // namespace gfx
} // namespace mozilla
#endif
--- a/gfx/vr/ipc/VRManagerParent.cpp
+++ b/gfx/vr/ipc/VRManagerParent.cpp
@@ -41,22 +41,34 @@ VRManagerParent::~VRManagerParent()
PVRLayerParent*
VRManagerParent::AllocPVRLayerParent(const uint32_t& aDisplayID,
const uint32_t& aGroup)
{
RefPtr<VRLayerParent> layer;
layer = new VRLayerParent(aDisplayID,
aGroup);
+
+ if (!VRListenerThreadHolder::IsActive()) {
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ loop->PostTask(NewRunnableMethod<RefPtr<VRLayerParent>, uint32_t>(
+ "gfx::VRManagerParent::GetDisplay",
+ this, &VRManagerParent::GetDisplay, layer, aDisplayID));
+ }
+ return layer.forget().take();
+}
+
+void
+VRManagerParent::GetDisplay(RefPtr<VRLayerParent> aLayer, uint32_t aDisplayID)
+{
VRManager* vm = VRManager::Get();
RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(aDisplayID);
if (display) {
- display->AddLayer(layer);
+ display->AddLayer(aLayer);
}
- return layer.forget().take();
}
bool
VRManagerParent::DeallocPVRLayerParent(PVRLayerParent* actor)
{
delete actor;
return true;
}
@@ -149,21 +161,23 @@ VRManagerParent::DeferredDestroy()
void
VRManagerParent::RefreshDisplays()
{
// 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();
- MessageLoop* loop = VRListenerThreadHolder::Loop();
- loop->PostTask(
- NewRunnableMethod<bool>(
- "gfx::VRManager::RefreshVRDisplays",
- vm, &VRManager::RefreshVRDisplays, true));
+ if (VRListenerThreadHolder::IsActive()) {
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ loop->PostTask(
+ NewRunnableMethod<bool>(
+ "gfx::VRManager::RefreshVRDisplays",
+ vm, &VRManager::RefreshVRDisplays, true));
+ }
}
void
VRManagerParent::ActorDestroy(ActorDestroyReason why)
{
UnregisterFromManager();
MessageLoop::current()->PostTask(
NewRunnableMethod("gfx::VRManagerParent::DeferredDestroy",
@@ -195,36 +209,74 @@ VRManagerParent::RecvRefreshDisplays()
}
return IPC_OK();
}
mozilla::ipc::IPCResult
VRManagerParent::RecvResetSensor(const uint32_t& aDisplayID)
{
+ // VRManager* vm = VRManager::Get();
+ // RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(aDisplayID);
+ // if (display != nullptr) {
+ // display->ZeroSensor();
+ // }
+
+ if (VRListenerThreadHolder::IsActive()) {
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ loop->PostTask(
+ NewRunnableMethod<bool>(
+ "gfx::VRManagerParent::ResetSensor",
+ this, &VRManagerParent::ResetSensor, aDisplayID));
+ }
+
+ return IPC_OK();
+}
+
+void
+VRManagerParent::ResetSensor(uint32_t aDisplayID)
+{
VRManager* vm = VRManager::Get();
RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(aDisplayID);
if (display != nullptr) {
display->ZeroSensor();
}
+}
+
+mozilla::ipc::IPCResult
+VRManagerParent::RecvSetGroupMask(const uint32_t& aDisplayID, const uint32_t& aGroupMask)
+{
+ // VRManager* vm = VRManager::Get();
+ // RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(aDisplayID);
+ // if (display != nullptr) {
+ // display->SetGroupMask(aGroupMask);
+ // }
+
+ if (VRListenerThreadHolder::IsActive()) {
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ loop->PostTask(
+ NewRunnableMethod<uint32_t, uint32_t>(
+ "gfx::VRManagerParent::SetGroupMask",
+ this, &VRManagerParent::SetGroupMask, aDisplayID, aGroupMask));
+ }
return IPC_OK();
}
-mozilla::ipc::IPCResult
-VRManagerParent::RecvSetGroupMask(const uint32_t& aDisplayID, const uint32_t& aGroupMask)
+void
+VRManagerParent::SetGroupMask(uint32_t aDisplayID, uint32_t aGroupMask)
{
VRManager* vm = VRManager::Get();
RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(aDisplayID);
if (display != nullptr) {
display->SetGroupMask(aGroupMask);
}
- return IPC_OK();
}
+
void
VRManagerParent::StartVRListenerThread()
{
VRListenerThreadHolder::Start();
RefreshDisplays();
}
bool
@@ -268,88 +320,47 @@ VRManagerParent::RecvControllerListenerR
mozilla::ipc::IPCResult
VRManagerParent::RecvCreateVRTestSystem()
{
VRManager* vm = VRManager::Get();
vm->CreateVRTestSystem();
mDisplayTestID = 0;
mControllerTestID = 0;
+ mVRDisplayTests.Clear();
+ mVRControllerTests.Clear();
return IPC_OK();
}
mozilla::ipc::IPCResult
VRManagerParent::RecvCreateVRServiceTestDisplay(const nsCString& aID, const uint32_t& aPromiseID)
{
- nsTArray<VRDisplayInfo> displayInfoArray;
- impl::VRDisplayPuppet* displayPuppet = nullptr;
- VRManager* vm = VRManager::Get();
+ MOZ_ASSERT(VRListenerThreadHolder::IsActive());
- // Get VRDisplayPuppet from VRManager
- vm->GetVRDisplayInfo(displayInfoArray);
- for (auto& displayInfo : displayInfoArray) {
- if (displayInfo.GetType() == VRDeviceType::Puppet) {
- displayPuppet = static_cast<impl::VRDisplayPuppet*>(
- vm->GetDisplay(displayInfo.GetDisplayID()).get());
- break;
- }
- }
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ loop->PostTask(
+ NewRunnableMethod<nsCString, uint32_t>(
+ "gfx::VRManagerParent::RefreshPuppetDisplay",
+ this, &VRManagerParent::RefreshPuppetDisplay, aID, aPromiseID));
- MOZ_ASSERT(displayPuppet);
- MOZ_ASSERT(!mDisplayTestID); // We have only one display in VRSystemManagerPuppet.
-
- if (!mVRDisplayTests.Get(mDisplayTestID, nullptr)) {
- mVRDisplayTests.Put(mDisplayTestID, displayPuppet);
- }
-
- if (SendReplyCreateVRServiceTestDisplay(aID, aPromiseID, mDisplayTestID)) {
- return IPC_OK();
- }
-
- return IPC_FAIL(this, "SendReplyCreateVRServiceTestController fail");
+ return IPC_OK();
}
mozilla::ipc::IPCResult
VRManagerParent::RecvCreateVRServiceTestController(const nsCString& aID, const uint32_t& aPromiseID)
{
- uint32_t controllerIdx = 0;
- nsTArray<VRControllerInfo> controllerInfoArray;
- impl::VRControllerPuppet* controllerPuppet = nullptr;
- VRManager* vm = VRManager::Get();
-
- if (mHaveControllerListener) {
- vm->RefreshVRControllers();
- }
+ MOZ_ASSERT(VRListenerThreadHolder::IsActive());
+
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ loop->PostTask(
+ NewRunnableMethod<nsCString, uint32_t>(
+ "gfx::VRManagerParent::RefreshPuppetController",
+ this, &VRManagerParent::RefreshPuppetController, aID, aPromiseID));
- // Get VRControllerPuppet from VRManager
- vm->GetVRControllerInfo(controllerInfoArray);
- for (auto& controllerInfo : controllerInfoArray) {
- if (controllerInfo.GetType() == VRDeviceType::Puppet) {
- if (controllerIdx == mControllerTestID) {
- controllerPuppet = static_cast<impl::VRControllerPuppet*>(
- vm->GetController(controllerInfo.GetControllerID()).get());
- break;
- }
- ++controllerIdx;
- }
- }
-
- MOZ_ASSERT(controllerPuppet);
- MOZ_ASSERT(mControllerTestID < 2); // We have only two controllers in VRSystemManagerPuppet.
-
- if (!mVRControllerTests.Get(mControllerTestID, nullptr)) {
- mVRControllerTests.Put(mControllerTestID, controllerPuppet);
- }
-
- if (SendReplyCreateVRServiceTestController(aID, aPromiseID, mControllerTestID)) {
- ++mControllerTestID;
- return IPC_OK();
- }
-
- return IPC_FAIL(this, "SendReplyCreateVRServiceTestController fail");
+ return IPC_OK();
}
mozilla::ipc::IPCResult
VRManagerParent::RecvSetDisplayInfoToMockDisplay(const uint32_t& aDeviceID,
const VRDisplayInfo& aDisplayInfo)
{
RefPtr<impl::VRDisplayPuppet> displayPuppet;
mVRDisplayTests.Get(aDeviceID,
@@ -423,16 +434,111 @@ VRManagerParent::RecvVibrateHaptic(const
mozilla::ipc::IPCResult
VRManagerParent::RecvStopVibrateHaptic(const uint32_t& aControllerIdx)
{
VRManager* vm = VRManager::Get();
vm->StopVibrateHaptic(aControllerIdx);
return IPC_OK();
}
+void
+VRManagerParent::RefreshPuppetDisplay(nsCString aID, uint32_t aPromiseID)
+{
+ nsTArray<VRDisplayInfo> displayInfoArray;
+ impl::VRDisplayPuppet* displayPuppet = nullptr;
+ VRManager* vm = VRManager::Get();
+
+ // Get VRDisplayPuppet from VRManager
+ vm->GetVRDisplayInfo(displayInfoArray);
+ for (auto& displayInfo : displayInfoArray) {
+ if (displayInfo.GetType() == VRDeviceType::Puppet) {
+ displayPuppet = static_cast<impl::VRDisplayPuppet*>(
+ vm->GetDisplay(displayInfo.GetDisplayID()).get());
+ break;
+ }
+ }
+
+ MOZ_ASSERT(displayPuppet);
+ MOZ_ASSERT(!mDisplayTestID); // We have only one display in VRSystemManagerPuppet.
+
+ if (!mVRDisplayTests.Get(mDisplayTestID, nullptr)) {
+ mVRDisplayTests.Put(mDisplayTestID, displayPuppet);
+ }
+
+ //SendReplyCreateVRServiceTestDisplay(aID, aPromiseID, mDisplayTestID);
+ MessageLoop* loop = CompositorThreadHolder::Loop();
+ if (loop) {
+ loop->PostTask(
+ NewRunnableMethod<nsCString, uint32_t, uint32_t>(
+ "gfx::VRManagerParent::ReplyCreateVRServiceTestDisplayToContent",
+ this, &VRManagerParent::ReplyCreateVRServiceTestDisplayToContent,
+ aID, aPromiseID, mDisplayTestID));
+ }
+}
+
+void
+VRManagerParent::ReplyCreateVRServiceTestDisplayToContent(nsCString aID,
+ uint32_t aPromiseID,
+ uint32_t aDisplayTestID)
+{
+ Unused << SendReplyCreateVRServiceTestDisplay(aID, aPromiseID, aDisplayTestID);
+}
+
+void
+VRManagerParent::RefreshPuppetController(nsCString aID, uint32_t aPromiseID)
+{
+ uint32_t controllerIdx = 0;
+ nsTArray<VRControllerInfo> controllerInfoArray;
+ impl::VRControllerPuppet* controllerPuppet = nullptr;
+ VRManager* vm = VRManager::Get();
+
+ if (mHaveControllerListener) {
+ vm->RefreshVRControllers();
+ }
+
+ // Get VRControllerPuppet from VRManager
+ vm->GetVRControllerInfo(controllerInfoArray);
+ for (auto& controllerInfo : controllerInfoArray) {
+ if (controllerInfo.GetType() == VRDeviceType::Puppet) {
+ if (controllerIdx == mControllerTestID) {
+ controllerPuppet = static_cast<impl::VRControllerPuppet*>(
+ vm->GetController(controllerInfo.GetControllerID()).get());
+ break;
+ }
+ ++controllerIdx;
+ }
+ }
+
+ MOZ_ASSERT(controllerPuppet);
+ MOZ_ASSERT(mControllerTestID < 2); // We have only two controllers in VRSystemManagerPuppet.
+
+ if (!mVRControllerTests.Get(mControllerTestID, nullptr)) {
+ mVRControllerTests.Put(mControllerTestID, controllerPuppet);
+ }
+
+ MessageLoop* loop = CompositorThreadHolder::Loop();
+ if (loop) {
+ loop->PostTask(
+ NewRunnableMethod<nsCString, uint32_t, uint32_t>(
+ "gfx::VRManagerParent::ReplyCreateVRServiceTestControllerToContent",
+ this, &VRManagerParent::ReplyCreateVRServiceTestControllerToContent,
+ aID, aPromiseID, mControllerTestID));
+ }
+
+ ++mControllerTestID;
+}
+
+void
+VRManagerParent::ReplyCreateVRServiceTestControllerToContent(nsCString aID,
+ uint32_t aPromiseID,
+ uint32_t aControllerTestID)
+{
+ Unused << SendReplyCreateVRServiceTestController(aID, aPromiseID, aControllerTestID);
+}
+
bool
VRManagerParent::SendGamepadUpdate(const GamepadChangeEvent& aGamepadEvent)
{
// GamepadManager only exists at the content process
// or the same process in non-e10s mode.
if (mHaveControllerListener &&
(mIsContentChild || IsSameProcess())) {
return PVRManagerParent::SendGamepadUpdate(aGamepadEvent);
--- a/gfx/vr/ipc/VRManagerParent.h
+++ b/gfx/vr/ipc/VRManagerParent.h
@@ -79,16 +79,25 @@ private:
void UnregisterFromManager();
void Bind(Endpoint<PVRManagerParent>&& aEndpoint);
static void RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager);
void DeferredDestroy();
void RefreshDisplays();
+ void RefreshPuppetDisplay(nsCString aID, uint32_t aPromiseID);
+ void RefreshPuppetController(nsCString aID, uint32_t aPromiseID);
+ void GetDisplay(RefPtr<VRLayerParent> aLayer, uint32_t aDisplayID);
+ void ResetSensor(uint32_t aDisplayID);
+ void SetGroupMask(uint32_t aDisplayID, uint32_t aGroupMask);
+ void ReplyCreateVRServiceTestDisplayToContent(nsCString aID, uint32_t aPromiseID,
+ uint32_t aDisplayTestID);
+ void ReplyCreateVRServiceTestControllerToContent(nsCString aID, uint32_t aPromiseID,
+ uint32_t aControllerTestID);
// 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;