diff options
Diffstat (limited to '')
-rw-r--r-- | gfx/vr/ipc/VRParent.cpp | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/gfx/vr/ipc/VRParent.cpp b/gfx/vr/ipc/VRParent.cpp new file mode 100644 index 0000000000..234352ba08 --- /dev/null +++ b/gfx/vr/ipc/VRParent.cpp @@ -0,0 +1,191 @@ +/* -*- 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 "VRParent.h" +#include "VRGPUParent.h" +#include "gfxConfig.h" +#include "nsDebugImpl.h" +#include "nsThreadManager.h" +#include "nsPrintfCString.h" + +#include "mozilla/dom/MemoryReportRequest.h" +#include "mozilla/gfx/gfxVars.h" +#include "mozilla/ipc/CrashReporterClient.h" +#include "mozilla/ipc/ProcessChild.h" +#include "mozilla/ipc/ProcessUtils.h" +#include "mozilla/Preferences.h" + +#if defined(XP_WIN) +# include <process.h> +# include "mozilla/gfx/DeviceManagerDx.h" +#else +# include <unistd.h> +#endif + +namespace mozilla { +namespace gfx { + +using mozilla::ipc::IPCResult; + +VRParent::VRParent() : mVRGPUParent(nullptr) {} + +IPCResult VRParent::RecvNewGPUVRManager(Endpoint<PVRGPUParent>&& aEndpoint) { + RefPtr<VRGPUParent> vrGPUParent = + VRGPUParent::CreateForGPU(std::move(aEndpoint)); + if (!vrGPUParent) { + return IPC_FAIL_NO_REASON(this); + } + + mVRGPUParent = std::move(vrGPUParent); + return IPC_OK(); +} + +IPCResult VRParent::RecvInit(nsTArray<GfxVarUpdate>&& vars, + const DevicePrefs& devicePrefs) { + Unused << SendInitComplete(); + + for (const auto& var : vars) { + gfxVars::ApplyUpdate(var); + } + + // Inherit device preferences. + gfxConfig::Inherit(Feature::HW_COMPOSITING, devicePrefs.hwCompositing()); + gfxConfig::Inherit(Feature::D3D11_COMPOSITING, + devicePrefs.d3d11Compositing()); + gfxConfig::Inherit(Feature::OPENGL_COMPOSITING, devicePrefs.oglCompositing()); + gfxConfig::Inherit(Feature::DIRECT2D, devicePrefs.useD2D1()); + +#if defined(XP_WIN) + if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) { + DeviceManagerDx::Get()->CreateCompositorDevices(); + } +#endif + return IPC_OK(); +} + +IPCResult VRParent::RecvUpdateVar(const GfxVarUpdate& aUpdate) { + gfxVars::ApplyUpdate(aUpdate); + return IPC_OK(); +} + +mozilla::ipc::IPCResult VRParent::RecvPreferenceUpdate(const Pref& aPref) { + Preferences::SetPreference(aPref); + return IPC_OK(); +} + +mozilla::ipc::IPCResult VRParent::RecvOpenVRControllerActionPathToVR( + const nsCString& aPath) { + mOpenVRControllerAction = aPath; + return IPC_OK(); +} + +mozilla::ipc::IPCResult VRParent::RecvOpenVRControllerManifestPathToVR( + const VRControllerType& aType, const nsCString& aPath) { + mOpenVRControllerManifest.InsertOrUpdate(static_cast<uint32_t>(aType), aPath); + return IPC_OK(); +} + +mozilla::ipc::IPCResult VRParent::RecvRequestMemoryReport( + const uint32_t& aGeneration, const bool& aAnonymize, + const bool& aMinimizeMemoryUsage, const Maybe<FileDescriptor>& aDMDFile, + const RequestMemoryReportResolver& aResolver) { + MOZ_ASSERT(XRE_IsVRProcess()); + nsPrintfCString processName("VR (pid %u)", (unsigned)getpid()); + + mozilla::dom::MemoryReportRequestClient::Start( + aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName, + [&](const MemoryReport& aReport) { + Unused << SendAddMemoryReport(aReport); + }, + aResolver); + return IPC_OK(); +} + +void VRParent::ActorDestroy(ActorDestroyReason aWhy) { + if (AbnormalShutdown == aWhy) { + NS_WARNING("Shutting down VR process early due to a crash!"); + ipc::ProcessChild::QuickExit(); + } + if (mVRGPUParent && !mVRGPUParent->IsClosed()) { + mVRGPUParent->Close(); + } + mVRGPUParent = nullptr; + +#ifndef NS_FREE_PERMANENT_DATA + // No point in going through XPCOM shutdown because we don't keep persistent + // state. + ipc::ProcessChild::QuickExit(); +#endif + +#if defined(XP_WIN) + DeviceManagerDx::Shutdown(); +#endif + gfxVars::Shutdown(); + gfxConfig::Shutdown(); + ipc::CrashReporterClient::DestroySingleton(); + // Only calling XRE_ShutdownChildProcess() at the child process + // instead of the main process. Otherwise, it will close all child processes + // that are spawned from the main process. + XRE_ShutdownChildProcess(); +} + +bool VRParent::Init(mozilla::ipc::UntypedEndpoint&& aEndpoint, + const char* aParentBuildID) { + // Initialize the thread manager before starting IPC. Otherwise, messages + // may be posted to the main thread and we won't be able to process them. + if (NS_WARN_IF(NS_FAILED(nsThreadManager::get().Init()))) { + return false; + } + + // Now it's safe to start IPC. + if (NS_WARN_IF(!aEndpoint.Bind(this))) { + return false; + } + + nsDebugImpl::SetMultiprocessMode("VR"); + + // This must be checked before any IPDL message, which may hit sentinel + // errors due to parent and content processes having different + // versions. + MessageChannel* channel = GetIPCChannel(); + if (channel && !channel->SendBuildIDsMatchMessage(aParentBuildID)) { + // We need to quit this process if the buildID doesn't match the parent's. + // This can occur when an update occurred in the background. + ipc::ProcessChild::QuickExit(); + } + + // Init crash reporter support. + ipc::CrashReporterClient::InitSingleton(this); + + gfxConfig::Init(); + gfxVars::Initialize(); +#if defined(XP_WIN) + DeviceManagerDx::Init(); +#endif + if (NS_FAILED(NS_InitMinimalXPCOM())) { + return false; + } + + mozilla::ipc::SetThisProcessName("VR Process"); + return true; +} + +bool VRParent::GetOpenVRControllerActionPath(nsCString* aPath) { + if (!mOpenVRControllerAction.IsEmpty()) { + *aPath = mOpenVRControllerAction; + return true; + } + + return false; +} + +bool VRParent::GetOpenVRControllerManifestPath(VRControllerType aType, + nsCString* aPath) { + return mOpenVRControllerManifest.Get(static_cast<uint32_t>(aType), aPath); +} + +} // namespace gfx +} // namespace mozilla |