summaryrefslogtreecommitdiffstats
path: root/gfx/vr/ipc/VRManagerParent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/vr/ipc/VRManagerParent.cpp')
-rw-r--r--gfx/vr/ipc/VRManagerParent.cpp308
1 files changed, 308 insertions, 0 deletions
diff --git a/gfx/vr/ipc/VRManagerParent.cpp b/gfx/vr/ipc/VRManagerParent.cpp
new file mode 100644
index 0000000000..01a2f4e6a5
--- /dev/null
+++ b/gfx/vr/ipc/VRManagerParent.cpp
@@ -0,0 +1,308 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 "VRManagerParent.h"
+
+#include "ipc/VRLayerParent.h"
+#include "mozilla/gfx/PVRManagerParent.h"
+#include "mozilla/ipc/Endpoint.h"
+#include "mozilla/ipc/ProtocolTypes.h"
+#include "mozilla/StaticPrefs_dom.h"
+#include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol
+#include "mozilla/TimeStamp.h" // for TimeStamp
+#include "mozilla/Unused.h"
+#include "VRManager.h"
+#include "VRThread.h"
+
+using mozilla::dom::GamepadHandle;
+
+namespace mozilla {
+using namespace layers;
+namespace gfx {
+
+// See VRManagerChild.cpp
+void ReleaseVRManagerParentSingleton();
+
+VRManagerParent::VRManagerParent(ProcessId aChildProcessId,
+ bool aIsContentChild)
+ : mHaveEventListener(false),
+ mHaveControllerListener(false),
+ mIsContentChild(aIsContentChild),
+ mVRActiveStatus(false) {
+ MOZ_COUNT_CTOR(VRManagerParent);
+ MOZ_ASSERT(NS_IsMainThread());
+
+ SetOtherProcessId(aChildProcessId);
+}
+
+VRManagerParent::~VRManagerParent() {
+ MOZ_ASSERT(!mVRManagerHolder);
+
+ MOZ_COUNT_DTOR(VRManagerParent);
+}
+
+PVRLayerParent* VRManagerParent::AllocPVRLayerParent(const uint32_t& aDisplayID,
+ const uint32_t& aGroup) {
+ if (!StaticPrefs::dom_vr_enabled() && !StaticPrefs::dom_vr_webxr_enabled()) {
+ return nullptr;
+ }
+
+ RefPtr<VRLayerParent> layer;
+ layer = new VRLayerParent(aDisplayID, aGroup);
+ VRManager* vm = VRManager::Get();
+ vm->AddLayer(layer);
+ return layer.forget().take();
+}
+
+bool VRManagerParent::DeallocPVRLayerParent(PVRLayerParent* actor) {
+ delete actor;
+ return true;
+}
+
+bool VRManagerParent::IsSameProcess() const {
+ return OtherPid() == base::GetCurrentProcId();
+}
+
+void VRManagerParent::RegisterWithManager() {
+ VRManager* vm = VRManager::Get();
+ vm->AddVRManagerParent(this);
+ mVRManagerHolder = vm;
+}
+
+void VRManagerParent::UnregisterFromManager() {
+ VRManager* vm = VRManager::Get();
+ vm->RemoveVRManagerParent(this);
+ mVRManagerHolder = nullptr;
+}
+
+/* static */
+bool VRManagerParent::CreateForContent(Endpoint<PVRManagerParent>&& aEndpoint) {
+ if (!CompositorThread()) {
+ return false;
+ }
+
+ RefPtr<VRManagerParent> vmp = new VRManagerParent(aEndpoint.OtherPid(), true);
+ CompositorThread()->Dispatch(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
+ "gfx::VRManagerParent::Bind", vmp, &VRManagerParent::Bind,
+ std::move(aEndpoint)));
+
+ return true;
+}
+
+void VRManagerParent::Bind(Endpoint<PVRManagerParent>&& aEndpoint) {
+ if (!aEndpoint.Bind(this)) {
+ return;
+ }
+ mSelfRef = this;
+
+ RegisterWithManager();
+}
+
+/*static*/
+void VRManagerParent::RegisterVRManagerInCompositorThread(
+ VRManagerParent* aVRManager) {
+ aVRManager->RegisterWithManager();
+}
+
+/*static*/
+VRManagerParent* VRManagerParent::CreateSameProcess() {
+ RefPtr<VRManagerParent> vmp =
+ new VRManagerParent(base::GetCurrentProcId(), false);
+ vmp->mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
+ vmp->mSelfRef = vmp;
+ CompositorThread()->Dispatch(
+ NewRunnableFunction("RegisterVRManagerIncompositorThreadRunnable",
+ RegisterVRManagerInCompositorThread, vmp.get()));
+ return vmp.get();
+}
+
+bool VRManagerParent::CreateForGPUProcess(
+ Endpoint<PVRManagerParent>&& aEndpoint) {
+ RefPtr<VRManagerParent> vmp =
+ new VRManagerParent(aEndpoint.OtherPid(), false);
+ vmp->mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
+ vmp->mSelfRef = vmp;
+ CompositorThread()->Dispatch(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
+ "gfx::VRManagerParent::Bind", vmp, &VRManagerParent::Bind,
+ std::move(aEndpoint)));
+ return true;
+}
+
+/*static*/
+void VRManagerParent::Shutdown() {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(
+ CompositorThread(),
+ "Shutdown() must gets called before the compositor thread is shutdown");
+ ReleaseVRManagerParentSingleton();
+ CompositorThread()->Dispatch(NS_NewRunnableFunction(
+ "VRManagerParent::Shutdown",
+ [vm = RefPtr<VRManager>(VRManager::MaybeGet())]() -> void {
+ if (!vm) {
+ return;
+ }
+ vm->ShutdownVRManagerParents();
+ }));
+}
+
+void VRManagerParent::ActorDestroy(ActorDestroyReason why) {}
+
+void VRManagerParent::ActorAlloc() {
+ // FIXME: This actor should probably use proper refcounting instead of manual
+ // reference management, and probably shouldn't manage
+ // `mCompositorThreadHolder` in the alloc/dealloc methods.
+ PVRManagerParent::ActorAlloc();
+ mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
+}
+
+void VRManagerParent::ActorDealloc() {
+ UnregisterFromManager();
+ mCompositorThreadHolder = nullptr;
+ mSelfRef = nullptr;
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvDetectRuntimes() {
+ // Detect runtime capabilities. This will return the presense of VR and/or AR
+ // runtime software, without enumerating or activating any hardware devices.
+ // UpdateDisplayInfo will be sent to VRManagerChild with the results of the
+ // detection.
+ VRManager* vm = VRManager::Get();
+ vm->DetectRuntimes();
+
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvRefreshDisplays() {
+ // This is called to activate the VR runtimes, detecting the
+ // presence and capabilities of XR hardware.
+ // UpdateDisplayInfo will be sent to VRManagerChild with the results of the
+ // enumerated hardware.
+ VRManager* vm = VRManager::Get();
+ vm->EnumerateDevices();
+
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvSetGroupMask(
+ const uint32_t& aDisplayID, const uint32_t& aGroupMask) {
+ VRManager* vm = VRManager::Get();
+ vm->SetGroupMask(aGroupMask);
+ return IPC_OK();
+}
+
+bool VRManagerParent::HaveEventListener() { return mHaveEventListener; }
+
+bool VRManagerParent::HaveControllerListener() {
+ return mHaveControllerListener;
+}
+
+bool VRManagerParent::GetVRActiveStatus() { return mVRActiveStatus; }
+
+mozilla::ipc::IPCResult VRManagerParent::RecvSetHaveEventListener(
+ const bool& aHaveEventListener) {
+ mHaveEventListener = aHaveEventListener;
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvControllerListenerAdded() {
+ // Force update the available controllers for GamepadManager,
+ VRManager* vm = VRManager::Get();
+ vm->StopAllHaptics();
+ mHaveControllerListener = true;
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvControllerListenerRemoved() {
+ mHaveControllerListener = false;
+ VRManager* vm = VRManager::Get();
+ vm->StopAllHaptics();
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvRunPuppet(
+ const nsTArray<uint64_t>& aBuffer) {
+#if defined(MOZ_WIDGET_ANDROID)
+ // Not yet implemented for Android / GeckoView
+ // See Bug 1555192
+ Unused << SendNotifyPuppetCommandBufferCompleted(false);
+#else
+ VRManager* vm = VRManager::Get();
+ if (!vm->RunPuppet(aBuffer, this)) {
+ // We have immediately failed, need to resolve the
+ // promise right away
+ Unused << SendNotifyPuppetCommandBufferCompleted(false);
+ }
+#endif // defined(MOZ_WIDGET_ANDROID)
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvResetPuppet() {
+#if defined(MOZ_WIDGET_ANDROID)
+ // Not yet implemented for Android / GeckoView
+ // See Bug 1555192
+#else
+ VRManager* vm = VRManager::Get();
+ vm->ResetPuppet(this);
+#endif // defined(MOZ_WIDGET_ANDROID)
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvVibrateHaptic(
+ const mozilla::dom::GamepadHandle& aGamepadHandle,
+ const uint32_t& aHapticIndex, const double& aIntensity,
+ const double& aDuration, const uint32_t& aPromiseID) {
+ VRManager* vm = VRManager::Get();
+ VRManagerPromise promise(this, aPromiseID);
+
+ vm->VibrateHaptic(aGamepadHandle, aHapticIndex, aIntensity, aDuration,
+ promise);
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvStopVibrateHaptic(
+ const mozilla::dom::GamepadHandle& aGamepadHandle) {
+ VRManager* vm = VRManager::Get();
+ vm->StopVibrateHaptic(aGamepadHandle);
+ return IPC_OK();
+}
+
+bool VRManagerParent::SendReplyGamepadVibrateHaptic(
+ const uint32_t& aPromiseID) {
+ // GamepadManager only exists at the content process
+ // or the same process in non-e10s mode.
+ if (mHaveControllerListener && (mIsContentChild || IsSameProcess())) {
+ return PVRManagerParent::SendReplyGamepadVibrateHaptic(aPromiseID);
+ }
+
+ return true;
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvStartVRNavigation(
+ const uint32_t& aDeviceID) {
+ VRManager* vm = VRManager::Get();
+ vm->StartVRNavigation(aDeviceID);
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvStopVRNavigation(
+ const uint32_t& aDeviceID, const TimeDuration& aTimeout) {
+ VRManager* vm = VRManager::Get();
+ vm->StopVRNavigation(aDeviceID, aTimeout);
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvStartActivity() {
+ mVRActiveStatus = true;
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRManagerParent::RecvStopActivity() {
+ mVRActiveStatus = false;
+ return IPC_OK();
+}
+
+} // namespace gfx
+} // namespace mozilla