Bug 1406327 - Part 2: When loading VR content, launching the VR listener thread; r=kip

MozReview-Commit-ID: IyBzJyDEVdv

--HG--
extra : rebase_source : c4d11a77045d8baef94002e4f42e8cea5148e900
This commit is contained in:
Daosheng Mu 2017-10-26 17:28:37 +08:00
Родитель 2a5a8b7872
Коммит 03cf16992f
6 изменённых файлов: 105 добавлений и 40 удалений

Просмотреть файл

@ -227,6 +227,7 @@ VRManager::NotifyVsync(const TimeStamp& aVsyncTimestamp)
if (bHaveEventListener || bHaveControllerListener) {
// We are using a VR device, keep it alive
mLastActiveTime = TimeStamp::Now();
mLastVRListenerThreadActiveTime = mLastActiveTime;
} else if (mLastActiveTime.IsNull()) {
Shutdown();
} else {
@ -259,7 +260,7 @@ void
VRManager::RefreshVRDisplays(bool aMustDispatch)
{
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,
@ -308,13 +309,20 @@ VRManager::RefreshVRDisplays(bool aMustDispatch)
}
if (displayInfoChanged || displaySetChanged || aMustDispatch) {
DispatchVRDisplayInfoUpdate();
// Due to PVRManager is at Compositor thread. We have to post tasks
// to Compositor thread when sending to them the content processes.
MessageLoop* loop = CompositorThreadHolder::Loop();
loop->PostTask(
NewRunnableMethod("gfx::VRManager::DispatchVRDisplayInfoUpdate",
this,
&VRManager::DispatchVRDisplayInfoUpdate));
}
}
void
VRManager::DispatchVRDisplayInfoUpdate()
{
MOZ_ASSERT(NS_IsInCompositorThread());
nsTArray<VRDisplayInfo> update;
GetVRDisplayInfo(update);
@ -323,7 +331,6 @@ VRManager::DispatchVRDisplayInfoUpdate()
}
}
/**
* Get any VR displays that have already been enumerated without
* activating any new devices.
@ -368,6 +375,12 @@ VRManager::GetVRControllerInfo(nsTArray<VRControllerInfo>& aControllerInfo)
}
}
TimeStamp
VRManager::GetLastVRListenerThreadActiveTime()
{
return mLastVRListenerThreadActiveTime;
}
void
VRManager::RefreshVRControllers()
{
@ -442,8 +455,22 @@ 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));
}
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(e);
Unused << iter.Get()->GetKey()->SendGamepadUpdate(aEvent);
}
}
@ -469,6 +496,20 @@ VRManager::StopVibrateHaptic(uint32_t aControllerIdx)
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));
}
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);
}
@ -477,6 +518,7 @@ VRManager::NotifyVibrateHapticCompleted(uint32_t aPromiseID)
void
VRManager::DispatchSubmitFrameResult(uint32_t aDisplayID, const VRSubmitFrameResultInfo& aResult)
{
MOZ_ASSERT(NS_IsInCompositorThread());
for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) {
Unused << iter.Get()->GetKey()->SendDispatchSubmitFrameResult(aDisplayID, aResult);
}

Просмотреть файл

@ -15,8 +15,8 @@
#include "gfxVR.h"
namespace mozilla {
namespace layers {
class TextureHost;
namespace dom {
class GamepadChangeEvent;
}
namespace gfx {
@ -52,6 +52,7 @@ public:
void StopVibrateHaptic(uint32_t aControllerIdx);
void NotifyVibrateHapticCompleted(uint32_t aPromiseID);
void DispatchSubmitFrameResult(uint32_t aDisplayID, const VRSubmitFrameResultInfo& aResult);
TimeStamp GetLastVRListenerThreadActiveTime();
protected:
VRManager();
@ -64,6 +65,8 @@ private:
void Shutdown();
void DispatchVRDisplayInfoUpdate();
void NotifyGamepadChangeEventsToContent(const dom::GamepadChangeEvent& aEvent);
void NotifyVibrateHapticCompletedToContent(uint32_t aPromiseID);
typedef nsTHashtable<nsRefPtrHashKey<VRManagerParent>> VRManagerParentSet;
VRManagerParentSet mVRManagerParents;
@ -81,6 +84,7 @@ private:
TimeStamp mLastRefreshTime;
TimeStamp mLastActiveTime;
TimeStamp mLastVRListenerThreadActiveTime;
bool mVRTestSystemCreated;
};

Просмотреть файл

@ -8,7 +8,6 @@
#include "VRLayerParent.h"
#include "mozilla/Unused.h"
#include "VRDisplayHost.h"
#include "mozilla/layers/CompositorThread.h"
namespace mozilla {
using namespace layers;
@ -65,18 +64,11 @@ VRLayerParent::RecvSubmitFrame(const layers::SurfaceDescriptor &aTexture,
const gfx::Rect& aRightEyeRect)
{
if (mVRDisplayID) {
MessageLoop* loop = layers::CompositorThreadHolder::Loop();
VRManager* vm = VRManager::Get();
RefPtr<VRDisplayHost> display = vm->GetDisplay(mVRDisplayID);
if (display) {
// 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));
// TODO: Move SubmitFrame to VRSubmitFrame thread in Bug 1392217.
SubmitFrame(display, aTexture, aFrameId, aLeftEyeRect, aRightEyeRect);
}
}

Просмотреть файл

@ -118,7 +118,7 @@ VRManagerChild::InitSameProcess()
sVRManagerChildSingleton = new VRManagerChild();
sVRManagerParentSingleton = VRManagerParent::CreateSameProcess();
sVRManagerChildSingleton->Open(sVRManagerParentSingleton->GetIPCChannel(),
VRListenerThreadHolder::Loop(),
mozilla::layers::CompositorThreadHolder::Loop(),
mozilla::ipc::ChildSide);
}

Просмотреть файл

@ -86,15 +86,13 @@ VRManagerParent::UnregisterFromManager()
/* static */ bool
VRManagerParent::CreateForContent(Endpoint<PVRManagerParent>&& aEndpoint)
{
MessageLoop* loop = VRListenerThreadHolder::Loop();
MessageLoop* loop = CompositorThreadHolder::Loop();
RefPtr<VRManagerParent> vmp = new VRManagerParent(aEndpoint.OtherPid(), true);
loop->PostTask(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
"gfx::VRManagerParent::Bind",
vmp,
&VRManagerParent::Bind,
Move(aEndpoint)));
return true;
}
@ -110,7 +108,7 @@ VRManagerParent::Bind(Endpoint<PVRManagerParent>&& aEndpoint)
}
/*static*/ void
VRManagerParent::RegisterVRManagerInVRListenerThread(VRManagerParent* aVRManager)
VRManagerParent::RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager)
{
aVRManager->RegisterWithManager();
}
@ -118,21 +116,21 @@ VRManagerParent::RegisterVRManagerInVRListenerThread(VRManagerParent* aVRManager
/*static*/ VRManagerParent*
VRManagerParent::CreateSameProcess()
{
MessageLoop* loop = VRListenerThreadHolder::Loop();
MessageLoop* loop = CompositorThreadHolder::Loop();
RefPtr<VRManagerParent> vmp = new VRManagerParent(base::GetCurrentProcId(), false);
vmp->mVRListenerThreadHolder = VRListenerThreadHolder::GetSingleton();
vmp->mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
vmp->mSelfRef = vmp;
loop->PostTask(NewRunnableFunction(RegisterVRManagerInVRListenerThread, vmp.get()));
loop->PostTask(NewRunnableFunction(RegisterVRManagerInCompositorThread, vmp.get()));
return vmp.get();
}
bool
VRManagerParent::CreateForGPUProcess(Endpoint<PVRManagerParent>&& aEndpoint)
{
MessageLoop* loop = VRListenerThreadHolder::Loop();
MessageLoop* loop = CompositorThreadHolder::Loop();
RefPtr<VRManagerParent> vmp = new VRManagerParent(aEndpoint.OtherPid(), false);
vmp->mVRListenerThreadHolder = VRListenerThreadHolder::GetSingleton();
vmp->mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
loop->PostTask(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
"gfx::VRManagerParent::Bind",
vmp,
@ -144,10 +142,25 @@ VRManagerParent::CreateForGPUProcess(Endpoint<PVRManagerParent>&& aEndpoint)
void
VRManagerParent::DeferredDestroy()
{
mVRListenerThreadHolder = nullptr;
mCompositorThreadHolder = nullptr;
mSelfRef = nullptr;
}
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));
}
void
VRManagerParent::ActorDestroy(ActorDestroyReason why)
{
@ -161,21 +174,25 @@ VRManagerParent::ActorDestroy(ActorDestroyReason why)
void
VRManagerParent::OnChannelConnected(int32_t aPid)
{
mVRListenerThreadHolder = VRListenerThreadHolder::GetSingleton();
mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
}
mozilla::ipc::IPCResult
VRManagerParent::RecvRefreshDisplays()
{
// TODO: Bug 1406327, Launch VR listener thread here.
MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
MOZ_ASSERT(NS_IsInCompositorThread());
// 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);
// When receiving refresh display messages at the first time,
// it is time to start the VR listener thread.
// Spawning threads needs to be at the main thread.
if (!VRListenerThreadHolder::IsActive()) {
RefPtr<Runnable> runnable = NewRunnableMethod(
"gfx::VRManagerParent::StartVRListenerThread",
this, &VRManagerParent::StartVRListenerThread);
NS_DispatchToMainThread(runnable.forget());
} else {
RefreshDisplays();
}
return IPC_OK();
}
@ -203,6 +220,13 @@ VRManagerParent::RecvSetGroupMask(const uint32_t& aDisplayID, const uint32_t& aG
return IPC_OK();
}
void
VRManagerParent::StartVRListenerThread()
{
VRListenerThreadHolder::Start();
RefreshDisplays();
}
bool
VRManagerParent::HaveEventListener()
{

Просмотреть файл

@ -7,7 +7,7 @@
#ifndef MOZILLA_GFX_VR_VRMANAGERPARENT_H
#define MOZILLA_GFX_VR_VRMANAGERPARENT_H
#include "mozilla/layers/CompositableTransactionParent.h" // need?
#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
#include "mozilla/gfx/PVRManagerParent.h" // for PVRManagerParent
#include "mozilla/gfx/PVRLayerParent.h" // for PVRLayerParent
#include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol
@ -16,7 +16,6 @@
#include "VRThread.h" // for VRListenerThreadHolder
namespace mozilla {
using namespace layers;
namespace gfx {
class VRManager;
@ -41,6 +40,7 @@ public:
bool HaveControllerListener();
bool SendGamepadUpdate(const GamepadChangeEvent& aGamepadEvent);
bool SendReplyGamepadVibrateHaptic(const uint32_t& aPromiseID);
void StartVRListenerThread();
protected:
~VRManagerParent();
@ -80,14 +80,17 @@ private:
void Bind(Endpoint<PVRManagerParent>&& aEndpoint);
static void RegisterVRManagerInVRListenerThread(VRManagerParent* aVRManager);
static void RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager);
void DeferredDestroy();
void RefreshDisplays();
// This keeps us alive until ActorDestroy(), at which point we do a
// deferred destruction of ourselves.
RefPtr<VRManagerParent> mSelfRef;
RefPtr<VRListenerThreadHolder> mVRListenerThreadHolder;
// Keep the compositor thread alive, until we have destroyed ourselves.
RefPtr<layers::CompositorThreadHolder> mCompositorThreadHolder;
// Keep the VRManager alive, until we have destroyed ourselves.
RefPtr<VRManager> mVRManagerHolder;