summaryrefslogtreecommitdiffstats
path: root/gfx/vr/ipc/VRChild.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/vr/ipc/VRChild.cpp')
-rw-r--r--gfx/vr/ipc/VRChild.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/gfx/vr/ipc/VRChild.cpp b/gfx/vr/ipc/VRChild.cpp
new file mode 100644
index 0000000000..747cf16326
--- /dev/null
+++ b/gfx/vr/ipc/VRChild.cpp
@@ -0,0 +1,214 @@
+/* -*- 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 "VRChild.h"
+#include "VRProcessManager.h"
+#include "VRProcessParent.h"
+#include "gfxConfig.h"
+
+#include "mozilla/gfx/gfxVars.h"
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/Telemetry.h"
+#include "mozilla/VsyncDispatcher.h"
+#include "mozilla/dom/MemoryReportRequest.h"
+
+namespace mozilla {
+namespace gfx {
+
+class OpenVRControllerManifestManager {
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OpenVRControllerManifestManager)
+ public:
+ explicit OpenVRControllerManifestManager() = default;
+
+ void SetOpenVRControllerActionPath(const nsCString& aPath) {
+ mAction = aPath;
+ }
+
+ void SetOpenVRControllerManifestPath(VRControllerType aType,
+ const nsCString& aPath) {
+ mManifest.InsertOrUpdate(static_cast<uint32_t>(aType), aPath);
+ }
+
+ bool GetActionPath(nsCString* aPath) {
+ if (!mAction.IsEmpty()) {
+ *aPath = mAction;
+ return true;
+ }
+ return false;
+ }
+
+ bool GetManifestPath(VRControllerType aType, nsCString* aPath) {
+ return mManifest.Get(static_cast<uint32_t>(aType), aPath);
+ }
+
+ private:
+ ~OpenVRControllerManifestManager() {
+ if (!mAction.IsEmpty() && remove(mAction.BeginReading()) != 0) {
+ MOZ_ASSERT(false, "Delete controller action file failed.");
+ }
+ mAction = "";
+
+ for (const auto& path : mManifest.Values()) {
+ if (!path.IsEmpty() && remove(path.BeginReading()) != 0) {
+ MOZ_ASSERT(false, "Delete controller manifest file failed.");
+ }
+ }
+ mManifest.Clear();
+ }
+
+ nsCString mAction;
+ nsTHashMap<nsUint32HashKey, nsCString> mManifest;
+ OpenVRControllerManifestManager(const OpenVRControllerManifestManager&) =
+ delete;
+
+ const OpenVRControllerManifestManager& operator=(
+ const OpenVRControllerManifestManager&) = delete;
+};
+
+StaticRefPtr<OpenVRControllerManifestManager> sOpenVRControllerManifestManager;
+
+VRChild::VRChild(VRProcessParent* aHost) : mHost(aHost), mVRReady(false) {
+ MOZ_ASSERT(XRE_IsParentProcess());
+}
+
+VRChild::~VRChild() = default;
+
+mozilla::ipc::IPCResult VRChild::RecvAddMemoryReport(
+ const MemoryReport& aReport) {
+ if (mMemoryReportRequest) {
+ mMemoryReportRequest->RecvReport(aReport);
+ }
+ return IPC_OK();
+}
+
+void VRChild::ActorDestroy(ActorDestroyReason aWhy) {
+ if (aWhy == AbnormalShutdown) {
+ GenerateCrashReport(OtherPid());
+
+ Telemetry::Accumulate(
+ Telemetry::SUBPROCESS_ABNORMAL_ABORT,
+ nsDependentCString(XRE_GeckoProcessTypeToString(GeckoProcessType_VR)),
+ 1);
+ }
+ gfxVars::RemoveReceiver(this);
+ mHost->OnChannelClosed();
+}
+
+void VRChild::Init() {
+ nsTArray<GfxVarUpdate> updates = gfxVars::FetchNonDefaultVars();
+
+ DevicePrefs devicePrefs;
+ devicePrefs.hwCompositing() = gfxConfig::GetValue(Feature::HW_COMPOSITING);
+ devicePrefs.d3d11Compositing() =
+ gfxConfig::GetValue(Feature::D3D11_COMPOSITING);
+ devicePrefs.oglCompositing() =
+ gfxConfig::GetValue(Feature::OPENGL_COMPOSITING);
+ devicePrefs.useD2D1() = gfxConfig::GetValue(Feature::DIRECT2D);
+
+ SendInit(updates, devicePrefs);
+
+ if (!sOpenVRControllerManifestManager) {
+ sOpenVRControllerManifestManager = new OpenVRControllerManifestManager();
+ NS_DispatchToMainThread(NS_NewRunnableFunction(
+ "ClearOnShutdown OpenVRControllerManifestManager",
+ []() { ClearOnShutdown(&sOpenVRControllerManifestManager); }));
+ }
+
+ nsCString output;
+ if (sOpenVRControllerManifestManager->GetActionPath(&output)) {
+ SendOpenVRControllerActionPathToVR(output);
+ }
+ if (sOpenVRControllerManifestManager->GetManifestPath(
+ VRControllerType::HTCVive, &output)) {
+ SendOpenVRControllerManifestPathToVR(VRControllerType::HTCVive, output);
+ }
+ if (sOpenVRControllerManifestManager->GetManifestPath(VRControllerType::MSMR,
+ &output)) {
+ SendOpenVRControllerManifestPathToVR(VRControllerType::MSMR, output);
+ }
+ if (sOpenVRControllerManifestManager->GetManifestPath(
+ VRControllerType::ValveIndex, &output)) {
+ SendOpenVRControllerManifestPathToVR(VRControllerType::ValveIndex, output);
+ }
+ gfxVars::AddReceiver(this);
+}
+
+bool VRChild::EnsureVRReady() {
+ if (!mVRReady) {
+ return false;
+ }
+
+ return true;
+}
+
+mozilla::ipc::IPCResult VRChild::RecvOpenVRControllerActionPathToParent(
+ const nsCString& aPath) {
+ sOpenVRControllerManifestManager->SetOpenVRControllerActionPath(aPath);
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRChild::RecvOpenVRControllerManifestPathToParent(
+ const VRControllerType& aType, const nsCString& aPath) {
+ sOpenVRControllerManifestManager->SetOpenVRControllerManifestPath(aType,
+ aPath);
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult VRChild::RecvInitComplete() {
+ // We synchronously requested VR parameters before this arrived.
+ mVRReady = true;
+ return IPC_OK();
+}
+
+bool VRChild::SendRequestMemoryReport(const uint32_t& aGeneration,
+ const bool& aAnonymize,
+ const bool& aMinimizeMemoryUsage,
+ const Maybe<FileDescriptor>& aDMDFile) {
+ mMemoryReportRequest = MakeUnique<MemoryReportRequestHost>(aGeneration);
+
+ PVRChild::SendRequestMemoryReport(
+ aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile,
+ [&](const uint32_t& aGeneration2) {
+ if (VRProcessManager* vpm = VRProcessManager::Get()) {
+ if (VRChild* child = vpm->GetVRChild()) {
+ if (child->mMemoryReportRequest) {
+ child->mMemoryReportRequest->Finish(aGeneration2);
+ child->mMemoryReportRequest = nullptr;
+ }
+ }
+ }
+ },
+ [&](mozilla::ipc::ResponseRejectReason) {
+ if (VRProcessManager* vpm = VRProcessManager::Get()) {
+ if (VRChild* child = vpm->GetVRChild()) {
+ child->mMemoryReportRequest = nullptr;
+ }
+ }
+ });
+
+ return true;
+}
+
+void VRChild::OnVarChanged(const GfxVarUpdate& aVar) { SendUpdateVar(aVar); }
+
+class DeferredDeleteVRChild : public Runnable {
+ public:
+ explicit DeferredDeleteVRChild(RefPtr<VRChild>&& aChild)
+ : Runnable("gfx::DeferredDeleteVRChild"), mChild(std::move(aChild)) {}
+
+ NS_IMETHODIMP Run() override { return NS_OK; }
+
+ private:
+ RefPtr<VRChild> mChild;
+};
+
+/* static */
+void VRChild::Destroy(RefPtr<VRChild>&& aChild) {
+ NS_DispatchToMainThread(new DeferredDeleteVRChild(std::move(aChild)));
+}
+
+} // namespace gfx
+} // namespace mozilla