зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1555188 - Enable PuppetVRSession to work when VR process is enabled r=thomasmo
Differential Revision: https://phabricator.services.mozilla.com/D72059
This commit is contained in:
Родитель
de3c9ae058
Коммит
f1e15241c4
|
@ -362,6 +362,7 @@ NS_IMPL_RELEASE_INHERITED(VRMockController, DOMEventTargetHelper)
|
|||
VRMockController::VRMockController(VRServiceTest* aVRServiceTest,
|
||||
uint32_t aControllerIdx)
|
||||
: DOMEventTargetHelper(aVRServiceTest->GetOwner()),
|
||||
mVRServiceTest(aVRServiceTest),
|
||||
mControllerIdx(aControllerIdx) {
|
||||
MOZ_ASSERT(aControllerIdx < kVRControllerMaxCount);
|
||||
}
|
||||
|
|
|
@ -534,13 +534,19 @@ void VRManager::CheckForPuppetCompletion() {
|
|||
}
|
||||
// Notify content process about completion of puppet test scripts
|
||||
if (mManagerParentRunningPuppet) {
|
||||
if (mServiceHost->PuppetHasEnded()) {
|
||||
Unused << mManagerParentRunningPuppet
|
||||
->SendNotifyPuppetCommandBufferCompleted(true);
|
||||
mManagerParentRunningPuppet = nullptr;
|
||||
}
|
||||
mServiceHost->CheckForPuppetCompletion();
|
||||
}
|
||||
}
|
||||
|
||||
void VRManager::NotifyPuppetComplete() {
|
||||
// Notify content process about completion of puppet test scripts
|
||||
if (mManagerParentRunningPuppet) {
|
||||
Unused << mManagerParentRunningPuppet
|
||||
->SendNotifyPuppetCommandBufferCompleted(true);
|
||||
mManagerParentRunningPuppet = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !defined(MOZ_WIDGET_ANDROID)
|
||||
|
||||
void VRManager::StartFrame() {
|
||||
|
|
|
@ -65,6 +65,7 @@ class VRManager : nsIObserver {
|
|||
bool RunPuppet(const nsTArray<uint64_t>& aBuffer,
|
||||
VRManagerParent* aManagerParent);
|
||||
void ResetPuppet(VRManagerParent* aManagerParent);
|
||||
void NotifyPuppetComplete();
|
||||
#endif
|
||||
void AddLayer(VRLayerParent* aLayer);
|
||||
void RemoveLayer(VRLayerParent* aLayer);
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace mozilla::gfx {
|
|||
|
||||
static StaticRefPtr<VRPuppetCommandBuffer> sVRPuppetCommandBufferSingleton;
|
||||
|
||||
/* static */
|
||||
VRPuppetCommandBuffer& VRPuppetCommandBuffer::Get() {
|
||||
if (sVRPuppetCommandBufferSingleton == nullptr) {
|
||||
sVRPuppetCommandBufferSingleton = new VRPuppetCommandBuffer();
|
||||
|
@ -20,6 +21,11 @@ VRPuppetCommandBuffer& VRPuppetCommandBuffer::Get() {
|
|||
return *sVRPuppetCommandBufferSingleton;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool VRPuppetCommandBuffer::IsCreated() {
|
||||
return sVRPuppetCommandBufferSingleton != nullptr;
|
||||
}
|
||||
|
||||
VRPuppetCommandBuffer::VRPuppetCommandBuffer()
|
||||
: mMutex("VRPuppetCommandBuffer::mMutex") {
|
||||
MOZ_COUNT_CTOR(VRPuppetCommandBuffer);
|
||||
|
@ -188,8 +194,7 @@ bool VRPuppetCommandBuffer::RunCommand(uint64_t aCommand, double aDeltaTime) {
|
|||
(uint8_t*)&mPendingState + (aCommand & 0x00000000ffffffff);
|
||||
break;
|
||||
case VRPuppet_Command::VRPuppet_UpdateControllers:
|
||||
mDataOffset = (uint8_t*)&mPendingState
|
||||
.controllerState[aCommand & 0x00000000000000ff] -
|
||||
mDataOffset = (uint8_t*)&mPendingState.controllerState -
|
||||
(uint8_t*)&mPendingState + (aCommand & 0x00000000ffffffff);
|
||||
break;
|
||||
case VRPuppet_Command::VRPuppet_Commit:
|
||||
|
|
|
@ -178,6 +178,7 @@ class VRPuppetCommandBuffer {
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::gfx::VRPuppetCommandBuffer)
|
||||
static VRPuppetCommandBuffer& Get();
|
||||
static bool IsCreated();
|
||||
|
||||
// Interface to VRTestSystem
|
||||
void Submit(const nsTArray<uint64_t>& aBuffer);
|
||||
|
|
|
@ -34,15 +34,12 @@ VRServiceHost* VRServiceHost::Get() {
|
|||
}
|
||||
|
||||
VRServiceHost::VRServiceHost(bool aEnableVRProcess)
|
||||
: mPuppetActive(false)
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
,
|
||||
mVRService(nullptr),
|
||||
: mVRService(nullptr),
|
||||
mVRProcessEnabled(aEnableVRProcess),
|
||||
mVRProcessStarted(false),
|
||||
mVRServiceReadyInVRProcess(false),
|
||||
mVRServiceRequested(false)
|
||||
|
||||
#endif
|
||||
{
|
||||
MOZ_COUNT_CTOR(VRServiceHost);
|
||||
}
|
||||
|
@ -88,8 +85,6 @@ void VRServiceHost::Refresh() {
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
|
||||
void VRServiceHost::CreateService(volatile VRExternalShmem* aShmem) {
|
||||
MOZ_ASSERT(!mVRProcessEnabled);
|
||||
mVRService = VRService::Create(aShmem);
|
||||
|
@ -99,13 +94,7 @@ bool VRServiceHost::NeedVRProcess() {
|
|||
if (!mVRProcessEnabled) {
|
||||
return false;
|
||||
}
|
||||
if (mVRServiceRequested) {
|
||||
return true;
|
||||
}
|
||||
if (mPuppetActive) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return mVRServiceRequested;
|
||||
}
|
||||
|
||||
void VRServiceHost::RefreshVRProcess() {
|
||||
|
@ -146,6 +135,36 @@ void VRServiceHost::CreateVRProcess() {
|
|||
Unused << gpu->SendCreateVRProcess();
|
||||
}
|
||||
|
||||
void VRServiceHost::NotifyVRProcessStarted() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mVRProcessEnabled);
|
||||
if (!mVRProcessStarted) {
|
||||
// We have received this after the VR process
|
||||
// has been stopped; the VR service is no
|
||||
// longer running in the VR process.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VRGPUChild::IsCreated()) {
|
||||
return;
|
||||
}
|
||||
VRGPUChild* vrGPUChild = VRGPUChild::Get();
|
||||
|
||||
// The VR service has started in the VR process
|
||||
// If there were pending puppet commands, we
|
||||
// can send them now.
|
||||
// This must occur before the VRService
|
||||
// is started so the buffer can be seen
|
||||
// by VRPuppetSession::Initialize().
|
||||
if (!mPuppetPendingCommands.IsEmpty()) {
|
||||
vrGPUChild->SendPuppetSubmit(mPuppetPendingCommands);
|
||||
mPuppetPendingCommands.Clear();
|
||||
}
|
||||
|
||||
vrGPUChild->SendStartVRService();
|
||||
mVRServiceReadyInVRProcess = true;
|
||||
}
|
||||
|
||||
void VRServiceHost::ShutdownVRProcess() {
|
||||
// This is only allowed to run in the main thread of the GPU process
|
||||
if (!XRE_IsGPUProcess()) {
|
||||
|
@ -176,55 +195,129 @@ void VRServiceHost::ShutdownVRProcess() {
|
|||
MOZ_ASSERT(gpu);
|
||||
Unused << gpu->SendShutdownVRProcess();
|
||||
mVRProcessStarted = false;
|
||||
mVRServiceReadyInVRProcess = false;
|
||||
}
|
||||
|
||||
#endif // !defined(MOZ_WIDGET_ANDROID)
|
||||
|
||||
void VRServiceHost::PuppetSubmit(const nsTArray<uint64_t>& aBuffer) {
|
||||
mPuppetActive = true;
|
||||
if (mVRProcessEnabled) {
|
||||
// TODO - Implement VR puppet support for VR process (Bug 1555188)
|
||||
MOZ_ASSERT(false); // Not implemented
|
||||
} else {
|
||||
if (!mVRProcessEnabled) {
|
||||
// Puppet is running in this process, submit commands directly
|
||||
VRPuppetCommandBuffer::Get().Submit(aBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to send the buffer to the VR process
|
||||
SendPuppetSubmitToVRProcess(aBuffer);
|
||||
}
|
||||
|
||||
void VRServiceHost::SendPuppetSubmitToVRProcess(
|
||||
const nsTArray<uint64_t>& aBuffer) {
|
||||
// This is only allowed to run in the main thread of the GPU process
|
||||
if (!XRE_IsGPUProcess()) {
|
||||
return;
|
||||
}
|
||||
// Forward this to the main thread if not already there
|
||||
if (!NS_IsMainThread()) {
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction(
|
||||
"VRServiceHost::SendPuppetSubmitToVRProcess",
|
||||
[buffer{aBuffer.Clone()}]() -> void {
|
||||
VRServiceHost::Get()->SendPuppetSubmitToVRProcess(buffer);
|
||||
});
|
||||
NS_DispatchToMainThread(task.forget());
|
||||
return;
|
||||
}
|
||||
if (!mVRServiceReadyInVRProcess) {
|
||||
// Queue the commands to be sent to the VR process once it is started
|
||||
mPuppetPendingCommands.AppendElements(aBuffer);
|
||||
return;
|
||||
}
|
||||
if (VRGPUChild::IsCreated()) {
|
||||
VRGPUChild* vrGPUChild = VRGPUChild::Get();
|
||||
vrGPUChild->SendPuppetSubmit(aBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void VRServiceHost::PuppetReset() {
|
||||
if (mVRProcessEnabled) {
|
||||
mPuppetActive = false;
|
||||
if (!mVRProcessStarted) {
|
||||
// Process is stopped, so puppet state is already clear
|
||||
return;
|
||||
}
|
||||
// TODO - Implement VR puppet support for VR process (Bug 1555188)
|
||||
MOZ_ASSERT(false); // Not implemented
|
||||
} else if (mPuppetActive) {
|
||||
if (!mVRProcessEnabled) {
|
||||
// Puppet is running in this process, tell it to reset directly.
|
||||
VRPuppetCommandBuffer::Get().Reset();
|
||||
mPuppetActive = false;
|
||||
}
|
||||
|
||||
mPuppetPendingCommands.Clear();
|
||||
if (!mVRProcessStarted) {
|
||||
// Process is stopped, so puppet state is already clear
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to tell the VR process to reset the puppet
|
||||
SendPuppetResetToVRProcess();
|
||||
}
|
||||
|
||||
void VRServiceHost::SendPuppetResetToVRProcess() {
|
||||
// This is only allowed to run in the main thread of the GPU process
|
||||
if (!XRE_IsGPUProcess()) {
|
||||
return;
|
||||
}
|
||||
// Forward this to the main thread if not already there
|
||||
if (!NS_IsMainThread()) {
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction(
|
||||
"VRServiceHost::SendPuppetResetToVRProcess",
|
||||
[]() -> void { VRServiceHost::Get()->SendPuppetResetToVRProcess(); });
|
||||
NS_DispatchToMainThread(task.forget());
|
||||
return;
|
||||
}
|
||||
if (VRGPUChild::IsCreated()) {
|
||||
VRGPUChild* vrGPUChild = VRGPUChild::Get();
|
||||
vrGPUChild->SendPuppetReset();
|
||||
}
|
||||
}
|
||||
|
||||
bool VRServiceHost::PuppetHasEnded() {
|
||||
if (mVRProcessEnabled) {
|
||||
if (!mVRProcessStarted) {
|
||||
// The VR process will be kept alive as long
|
||||
// as there is a queue in the puppet command
|
||||
// buffer. If the process is stopped, we can
|
||||
// infer that the queue has been cleared and
|
||||
// puppet state is reset.
|
||||
return true;
|
||||
void VRServiceHost::CheckForPuppetCompletion() {
|
||||
if (!mVRProcessEnabled) {
|
||||
// Puppet is running in this process, ask it directly
|
||||
if (VRPuppetCommandBuffer::Get().HasEnded()) {
|
||||
VRManager::Get()->NotifyPuppetComplete();
|
||||
}
|
||||
// TODO - Implement VR puppet support for VR process (Bug 1555188)
|
||||
MOZ_ASSERT(false); // Not implemented
|
||||
return false;
|
||||
}
|
||||
if (!mPuppetPendingCommands.IsEmpty()) {
|
||||
// There are puppet commands pending to be sent to the
|
||||
// VR process once its started, thus it has not ended.
|
||||
return;
|
||||
}
|
||||
if (!mVRProcessStarted) {
|
||||
// The VR process will be kept alive as long
|
||||
// as there is a queue in the puppet command
|
||||
// buffer. If the process is stopped, we can
|
||||
// infer that the queue has been cleared and
|
||||
// puppet state is reset.
|
||||
VRManager::Get()->NotifyPuppetComplete();
|
||||
}
|
||||
|
||||
if (mPuppetActive) {
|
||||
return VRPuppetCommandBuffer::Get().HasEnded();
|
||||
}
|
||||
// We need to ask the VR process if the puppet has ended
|
||||
SendPuppetCheckForCompletionToVRProcess();
|
||||
|
||||
return true;
|
||||
// VRGPUChild::RecvNotifyPuppetComplete will call
|
||||
// VRManager::NotifyPuppetComplete if the puppet has completed
|
||||
// in the VR Process.
|
||||
}
|
||||
|
||||
void VRServiceHost::SendPuppetCheckForCompletionToVRProcess() {
|
||||
// This is only allowed to run in the main thread of the GPU process
|
||||
if (!XRE_IsGPUProcess()) {
|
||||
return;
|
||||
}
|
||||
// Forward this to the main thread if not already there
|
||||
if (!NS_IsMainThread()) {
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction(
|
||||
"VRServiceHost::SendPuppetCheckForCompletionToVRProcess", []() -> void {
|
||||
VRServiceHost::Get()->SendPuppetCheckForCompletionToVRProcess();
|
||||
});
|
||||
NS_DispatchToMainThread(task.forget());
|
||||
return;
|
||||
}
|
||||
if (VRGPUChild::IsCreated()) {
|
||||
VRGPUChild* vrGPUChild = VRGPUChild::Get();
|
||||
vrGPUChild->SendPuppetCheckForCompletion();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
|
|
|
@ -19,6 +19,17 @@ namespace gfx {
|
|||
struct VRExternalShmem;
|
||||
class VRService;
|
||||
|
||||
/**
|
||||
* VRServiceHost is allocated as a singleton in the GPU process.
|
||||
* It is responsible for allocating VRService either within the GPU process
|
||||
* or in the VR process.
|
||||
* When the VR process is enabled, it maintains the state of the VR process,
|
||||
* starting and stopping it as needed.
|
||||
* VRServiceHost provides an interface that enables communication of the
|
||||
* VRService in the same way regardless of it running within the GPU process
|
||||
* or the VR process.
|
||||
*/
|
||||
|
||||
class VRServiceHost {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::gfx::VRServiceHost)
|
||||
public:
|
||||
|
@ -29,32 +40,51 @@ class VRServiceHost {
|
|||
void StartService();
|
||||
void StopService();
|
||||
void Shutdown();
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
void CreateService(volatile VRExternalShmem* aShmem);
|
||||
#endif
|
||||
void NotifyVRProcessStarted();
|
||||
void CheckForPuppetCompletion();
|
||||
|
||||
void PuppetSubmit(const nsTArray<uint64_t>& aBuffer);
|
||||
void PuppetReset();
|
||||
bool PuppetHasEnded();
|
||||
|
||||
protected:
|
||||
private:
|
||||
explicit VRServiceHost(bool aEnableVRProcess);
|
||||
~VRServiceHost();
|
||||
|
||||
bool mPuppetActive;
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
void RefreshVRProcess();
|
||||
bool NeedVRProcess();
|
||||
void CreateVRProcess();
|
||||
void ShutdownVRProcess();
|
||||
void SendPuppetResetToVRProcess();
|
||||
void SendPuppetCheckForCompletionToVRProcess();
|
||||
void SendPuppetSubmitToVRProcess(const nsTArray<uint64_t>& aBuffer);
|
||||
|
||||
// Commands pending to be sent to the puppet device
|
||||
// once the VR service is started.
|
||||
nsTArray<uint64_t> mPuppetPendingCommands;
|
||||
|
||||
RefPtr<VRService> mVRService;
|
||||
// mVRProcessEnabled indicates that a separate, VR Process, should be used.
|
||||
// This may be false if the VR process is disabled with the
|
||||
// dom.vr.process.enabled preference or when the GPU process is disabled.
|
||||
// mVRProcessEnabled will not change once the browser is started and does not
|
||||
// reflect the started / stopped state of the VR Process.
|
||||
bool mVRProcessEnabled;
|
||||
// mVRProcessStarted is true when the VR Process is running.
|
||||
bool mVRProcessStarted;
|
||||
// mVRServiceReadyInVRProcess is true when the VR Process is running and the
|
||||
// VRService in the VR Process is ready to accept commands.
|
||||
bool mVRServiceReadyInVRProcess;
|
||||
// mVRServiceRequested is true when the VRService is needed. This can be due
|
||||
// to Web API activity (WebXR, WebVR), browser activity (eg, VR Video
|
||||
// Playback), or a request to simulate a VR device with the VRServiceTest /
|
||||
// puppet API. mVRServiceRequested indicates the intended state of the VR
|
||||
// Service and is not an indication that the VR Service is ready to accept
|
||||
// requests or that the VR Process is enabled or running. Toggling the
|
||||
// mVRServiceRequested flag will result in the VR Service and/or the VR
|
||||
// Process either starting or stopping as needed.
|
||||
bool mVRServiceRequested;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
|
|
@ -6,12 +6,18 @@
|
|||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
// IPC for VR-Content process
|
||||
// The parent process is the VR process.
|
||||
// The child process is the GPU process.
|
||||
async protocol PVRGPU
|
||||
{
|
||||
parent:
|
||||
async StartVRService();
|
||||
async StopVRService();
|
||||
async PuppetSubmit(uint64_t[] aBuffer);
|
||||
async PuppetReset();
|
||||
async PuppetCheckForCompletion();
|
||||
child:
|
||||
async NotifyPuppetComplete();
|
||||
};
|
||||
|
||||
} // gfx
|
||||
|
|
|
@ -25,13 +25,15 @@ bool VRGPUChild::InitForGPUProcess(Endpoint<PVRGPUChild>&& aEndpoint) {
|
|||
}
|
||||
sVRGPUChildSingleton = child;
|
||||
|
||||
RefPtr<Runnable> task =
|
||||
NS_NewRunnableFunction("VRGPUChild::SendStartVRService", []() -> void {
|
||||
VRGPUChild* vrGPUChild = VRGPUChild::Get();
|
||||
vrGPUChild->SendStartVRService();
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction(
|
||||
"VRServiceHost::NotifyVRProcessStarted", []() -> void {
|
||||
VRServiceHost* host = VRServiceHost::Get();
|
||||
host->NotifyVRProcessStarted();
|
||||
});
|
||||
|
||||
NS_DispatchToMainThread(task.forget());
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -62,6 +64,15 @@ void VRGPUChild::ActorDestroy(ActorDestroyReason aWhy) {
|
|||
mClosed = true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult VRGPUChild::RecvNotifyPuppetComplete() {
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
VRManager* vm = VRManager::Get();
|
||||
mozilla::layers::CompositorThread()->Dispatch(NewRunnableMethod(
|
||||
"VRManager::NotifyPuppetComplete", vm, &VRManager::NotifyPuppetComplete));
|
||||
#endif
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
bool VRGPUChild::IsClosed() { return mClosed; }
|
||||
|
||||
} // namespace gfx
|
||||
|
|
|
@ -21,6 +21,9 @@ class VRGPUChild final : public PVRGPUChild {
|
|||
static bool IsCreated();
|
||||
static void Shutdown();
|
||||
|
||||
mozilla::ipc::IPCResult RecvNotifyPuppetComplete();
|
||||
mozilla::ipc::IPCResult RecvNotifyServiceStarted();
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
bool IsClosed();
|
||||
|
||||
|
|
|
@ -78,6 +78,30 @@ mozilla::ipc::IPCResult VRGPUParent::RecvStopVRService() {
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult VRGPUParent::RecvPuppetReset() {
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
VRPuppetCommandBuffer::Get().Reset();
|
||||
#endif
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult VRGPUParent::RecvPuppetSubmit(
|
||||
const nsTArray<uint64_t>& aBuffer) {
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
VRPuppetCommandBuffer::Get().Submit(aBuffer);
|
||||
#endif
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult VRGPUParent::RecvPuppetCheckForCompletion() {
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
if (VRPuppetCommandBuffer::Get().HasEnded()) {
|
||||
Unused << SendNotifyPuppetComplete();
|
||||
}
|
||||
#endif
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
bool VRGPUParent::IsClosed() { return mClosed; }
|
||||
|
||||
} // namespace gfx
|
||||
|
|
|
@ -27,6 +27,9 @@ class VRGPUParent final : public PVRGPUParent {
|
|||
void Bind(Endpoint<PVRGPUParent>&& aEndpoint);
|
||||
mozilla::ipc::IPCResult RecvStartVRService();
|
||||
mozilla::ipc::IPCResult RecvStopVRService();
|
||||
mozilla::ipc::IPCResult RecvPuppetReset();
|
||||
mozilla::ipc::IPCResult RecvPuppetSubmit(const nsTArray<uint64_t>& aBuffer);
|
||||
mozilla::ipc::IPCResult RecvPuppetCheckForCompletion();
|
||||
|
||||
private:
|
||||
explicit VRGPUParent(ProcessId aChildProcessId);
|
||||
|
|
|
@ -30,6 +30,12 @@ bool PuppetSession::Initialize(mozilla::gfx::VRSystemState& aSystemState,
|
|||
if (!StaticPrefs::dom_vr_enabled() || !StaticPrefs::dom_vr_puppet_enabled()) {
|
||||
return false;
|
||||
}
|
||||
if (!VRPuppetCommandBuffer::IsCreated()) {
|
||||
// We only want to initialize VRPuppetCommandBuffer on the main thread.
|
||||
// We can assume if it is not initialized, that the puppet display
|
||||
// would not be enumerated.
|
||||
return false;
|
||||
}
|
||||
if (aDetectRuntimesOnly) {
|
||||
aSystemState.displayState.capabilityFlags |=
|
||||
VRDisplayCapabilityFlags::Cap_ImmersiveVR;
|
||||
|
|
Загрузка…
Ссылка в новой задаче