mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1392216 - Part 1: Create VR listener thread in GPU process; r=dvander,kip
MozReview-Commit-ID: Img0HT9ax90 --HG-- extra : rebase_source : ef3e2dac31f498454121639aa46657c0cd16f949
This commit is contained in:
parent
8ee548e499
commit
e41dc03f86
@ -37,6 +37,7 @@
|
||||
#include "ProcessUtils.h"
|
||||
#include "VRManager.h"
|
||||
#include "VRManagerParent.h"
|
||||
#include "VRThread.h"
|
||||
#include "VsyncBridgeParent.h"
|
||||
#if defined(XP_WIN)
|
||||
# include "mozilla/gfx/DeviceManagerDx.h"
|
||||
@ -120,6 +121,8 @@ GPUParent::Init(base::ProcessId aParentPid,
|
||||
}
|
||||
|
||||
CompositorThreadHolder::Start();
|
||||
// TODO: Bug 1406327, Start VRListenerThreadHolder when loading VR content.
|
||||
VRListenerThreadHolder::Start();
|
||||
APZThreadUtils::SetControllerThread(CompositorThreadHolder::Loop());
|
||||
APZCTreeManager::InitializeGlobalState();
|
||||
LayerTreeOwnerTracker::Initialize();
|
||||
@ -431,6 +434,7 @@ GPUParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
}
|
||||
dom::VideoDecoderManagerParent::ShutdownVideoBridge();
|
||||
CompositorThreadHolder::Shutdown();
|
||||
VRListenerThreadHolder::Shutdown();
|
||||
if (gfxVars::UseWebRender()) {
|
||||
wr::RenderThread::ShutDown();
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
#endif
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
#include "VRManager.h"
|
||||
#include "VRThread.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -83,6 +84,8 @@ CompositorVsyncScheduler::CompositorVsyncScheduler(CompositorVsyncSchedulerOwner
|
||||
, mCurrentCompositeTask(nullptr)
|
||||
, mSetNeedsCompositeMonitor("SetNeedsCompositeMonitor")
|
||||
, mSetNeedsCompositeTask(nullptr)
|
||||
, mCurrentVRListenerTaskMonitor("CurrentVRTaskMonitor")
|
||||
, mCurrentVRListenerTask(nullptr)
|
||||
{
|
||||
mVsyncObserver = new Observer(this);
|
||||
|
||||
@ -130,6 +133,16 @@ CompositorVsyncScheduler::PostCompositeTask(TimeStamp aCompositeTimestamp)
|
||||
mCurrentCompositeTask = task;
|
||||
ScheduleTask(task.forget(), 0);
|
||||
}
|
||||
if (mCurrentVRListenerTask == nullptr && VRListenerThreadHolder::Loop()) {
|
||||
RefPtr<CancelableRunnable> task = NewCancelableRunnableMethod<TimeStamp>(
|
||||
"layers::CompositorVsyncScheduler::DispatchVREvents",
|
||||
this,
|
||||
&CompositorVsyncScheduler::DispatchVREvents,
|
||||
aCompositeTimestamp);
|
||||
mCurrentVRListenerTask = task;
|
||||
MOZ_ASSERT(VRListenerThreadHolder::Loop());
|
||||
VRListenerThreadHolder::Loop()->PostDelayedTask(Move(task.forget()), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -254,7 +267,6 @@ CompositorVsyncScheduler::Composite(TimeStamp aVsyncTimestamp)
|
||||
}
|
||||
|
||||
DispatchTouchEvents(aVsyncTimestamp);
|
||||
DispatchVREvents(aVsyncTimestamp);
|
||||
|
||||
if (mNeedsComposite || mAsapScheduling) {
|
||||
mNeedsComposite = 0;
|
||||
@ -327,7 +339,11 @@ CompositorVsyncScheduler::DispatchTouchEvents(TimeStamp aVsyncTimestamp)
|
||||
void
|
||||
CompositorVsyncScheduler::DispatchVREvents(TimeStamp aVsyncTimestamp)
|
||||
{
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
|
||||
{
|
||||
MonitorAutoLock lock(mCurrentVRListenerTaskMonitor);
|
||||
mCurrentVRListenerTask = nullptr;
|
||||
}
|
||||
|
||||
VRManager* vm = VRManager::Get();
|
||||
vm->NotifyVsync(aVsyncTimestamp);
|
||||
|
@ -117,6 +117,9 @@ private:
|
||||
|
||||
mozilla::Monitor mSetNeedsCompositeMonitor;
|
||||
RefPtr<CancelableRunnable> mSetNeedsCompositeTask;
|
||||
|
||||
mozilla::Monitor mCurrentVRListenerTaskMonitor;
|
||||
RefPtr<CancelableRunnable> mCurrentVRListenerTask;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "gfxUserFontSet.h"
|
||||
#include "gfxConfig.h"
|
||||
#include "MediaPrefs.h"
|
||||
#include "VRThread.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include <process.h>
|
||||
@ -1038,6 +1039,7 @@ gfxPlatform::InitLayersIPC()
|
||||
}
|
||||
|
||||
layers::CompositorThreadHolder::Start();
|
||||
gfx::VRListenerThreadHolder::Start();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1066,6 +1068,7 @@ gfxPlatform::ShutdownLayersIPC()
|
||||
layers::ImageBridgeChild::ShutDown();
|
||||
// This has to happen after shutting down the child protocols.
|
||||
layers::CompositorThreadHolder::Shutdown();
|
||||
gfx::VRListenerThreadHolder::Shutdown();
|
||||
if (gfxVars::UseWebRender()) {
|
||||
wr::RenderThread::ShutDown();
|
||||
|
||||
|
123
gfx/vr/VRThread.cpp
Normal file
123
gfx/vr/VRThread.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
/* -*- 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 "VRThread.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace gfx {
|
||||
|
||||
static StaticRefPtr<VRListenerThreadHolder> sVRListenerThreadHolder;
|
||||
static bool sFinishedVRListenerShutDown = false;
|
||||
|
||||
VRListenerThreadHolder* GetVRListenerThreadHolder()
|
||||
{
|
||||
return sVRListenerThreadHolder;
|
||||
}
|
||||
|
||||
base::Thread*
|
||||
VRListenerThread()
|
||||
{
|
||||
return sVRListenerThreadHolder
|
||||
? sVRListenerThreadHolder->GetThread()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
/* static */ MessageLoop*
|
||||
VRListenerThreadHolder::Loop()
|
||||
{
|
||||
return VRListenerThread() ? VRListenerThread()->message_loop() : nullptr;
|
||||
}
|
||||
|
||||
VRListenerThreadHolder*
|
||||
VRListenerThreadHolder::GetSingleton()
|
||||
{
|
||||
return sVRListenerThreadHolder;
|
||||
}
|
||||
|
||||
VRListenerThreadHolder::VRListenerThreadHolder()
|
||||
: mThread(CreateThread())
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
VRListenerThreadHolder::~VRListenerThreadHolder()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
DestroyThread(mThread);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
VRListenerThreadHolder::DestroyThread(base::Thread* aThread)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!sVRListenerThreadHolder,
|
||||
"We shouldn't be destroying the VR listener thread yet.");
|
||||
delete aThread;
|
||||
sFinishedVRListenerShutDown = true;
|
||||
}
|
||||
|
||||
/* static */ base::Thread*
|
||||
VRListenerThreadHolder::CreateThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!sVRListenerThreadHolder, "The VR listener thread has already been started!");
|
||||
|
||||
base::Thread* vrThread = new base::Thread("VRListener");
|
||||
base::Thread::Options options;
|
||||
/* Timeout values are powers-of-two to enable us get better data.
|
||||
128ms is chosen for transient hangs because 8Hz should be the minimally
|
||||
acceptable goal for Compositor responsiveness (normal goal is 60Hz). */
|
||||
options.transient_hang_timeout = 128; // milliseconds
|
||||
/* 2048ms is chosen for permanent hangs because it's longer than most
|
||||
* Compositor hangs seen in the wild, but is short enough to not miss getting
|
||||
* native hang stacks. */
|
||||
options.permanent_hang_timeout = 2048; // milliseconds
|
||||
|
||||
if (!vrThread->StartWithOptions(options)) {
|
||||
delete vrThread;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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!");
|
||||
|
||||
sVRListenerThreadHolder = new VRListenerThreadHolder();
|
||||
}
|
||||
|
||||
void
|
||||
VRListenerThreadHolder::Shutdown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread!");
|
||||
MOZ_ASSERT(sVRListenerThreadHolder, "The VR listener thread has already been shut down!");
|
||||
|
||||
sVRListenerThreadHolder = nullptr;
|
||||
|
||||
SpinEventLoopUntil([&]() { return sFinishedVRListenerShutDown; });
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
VRListenerThreadHolder::IsInVRListenerThread()
|
||||
{
|
||||
return VRListenerThread() &&
|
||||
VRListenerThread()->thread_id() == PlatformThread::CurrentId();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
bool
|
||||
NS_IsInVRListenerThread()
|
||||
{
|
||||
return mozilla::gfx::VRListenerThreadHolder::IsInVRListenerThread();
|
||||
}
|
51
gfx/vr/VRThread.h
Normal file
51
gfx/vr/VRThread.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef GFX_VR_THREAD_H
|
||||
#define GFX_VR_THREAD_H
|
||||
|
||||
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||
#include "base/thread.h" // for Thread
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class VRListenerThreadHolder final
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(VRListenerThreadHolder)
|
||||
|
||||
public:
|
||||
VRListenerThreadHolder();
|
||||
|
||||
base::Thread* GetThread() const {
|
||||
return mThread;
|
||||
}
|
||||
|
||||
static VRListenerThreadHolder* GetSingleton();
|
||||
|
||||
static bool IsActive() {
|
||||
return !!GetSingleton();
|
||||
}
|
||||
|
||||
static void Start();
|
||||
static void Shutdown();
|
||||
static MessageLoop* Loop();
|
||||
static bool IsInVRListenerThread();
|
||||
|
||||
private:
|
||||
~VRListenerThreadHolder();
|
||||
|
||||
base::Thread* const mThread;
|
||||
|
||||
static base::Thread* CreateThread();
|
||||
static void DestroyThread(base::Thread* aThread);
|
||||
};
|
||||
|
||||
base::Thread* VRListenerThread();
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_VR_THREAD_H
|
@ -13,6 +13,7 @@ EXPORTS += [
|
||||
'VRDisplayClient.h',
|
||||
'VRDisplayPresentation.h',
|
||||
'VRManager.h',
|
||||
'VRThread.h',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
@ -31,6 +32,7 @@ UNIFIED_SOURCES += [
|
||||
'VRDisplayClient.cpp',
|
||||
'VRDisplayPresentation.cpp',
|
||||
'VRManager.cpp',
|
||||
'VRThread.cpp',
|
||||
]
|
||||
|
||||
# VRDisplayHost includes MacIOSurface.h which includes Mac headers
|
||||
|
@ -344,6 +344,8 @@ SpinEventLoopUntil(Pred&& aPredicate, nsIThread* aThread = nullptr)
|
||||
*/
|
||||
extern bool NS_IsInCompositorThread();
|
||||
|
||||
extern bool NS_IsInVRThread();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helpers that work with nsCOMPtr:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user