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:
Daosheng Mu 2017-10-05 18:12:45 +08:00
parent 8ee548e499
commit e41dc03f86
8 changed files with 206 additions and 2 deletions

View File

@ -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();
}

View File

@ -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);

View File

@ -117,6 +117,9 @@ private:
mozilla::Monitor mSetNeedsCompositeMonitor;
RefPtr<CancelableRunnable> mSetNeedsCompositeTask;
mozilla::Monitor mCurrentVRListenerTaskMonitor;
RefPtr<CancelableRunnable> mCurrentVRListenerTask;
};
} // namespace layers

View File

@ -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
View 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
View 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

View File

@ -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

View File

@ -344,6 +344,8 @@ SpinEventLoopUntil(Pred&& aPredicate, nsIThread* aThread = nullptr)
*/
extern bool NS_IsInCompositorThread();
extern bool NS_IsInVRThread();
//-----------------------------------------------------------------------------
// Helpers that work with nsCOMPtr: