VRParent.cpp (5701B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "VRParent.h" 8 #include "VRGPUParent.h" 9 #include "gfxConfig.h" 10 #include "nsDebugImpl.h" 11 #include "nsThreadManager.h" 12 #include "nsPrintfCString.h" 13 14 #include "mozilla/dom/MemoryReportRequest.h" 15 #include "mozilla/gfx/gfxVars.h" 16 #include "mozilla/ipc/CrashReporterClient.h" 17 #include "mozilla/ipc/ProcessChild.h" 18 #include "mozilla/ipc/ProcessUtils.h" 19 #include "mozilla/Preferences.h" 20 21 #if defined(XP_WIN) 22 # include <process.h> 23 # include "mozilla/gfx/DeviceManagerDx.h" 24 #else 25 # include <unistd.h> 26 #endif 27 28 namespace mozilla { 29 namespace gfx { 30 31 using mozilla::ipc::IPCResult; 32 33 VRParent::VRParent() : mVRGPUParent(nullptr) {} 34 35 IPCResult VRParent::RecvNewGPUVRManager(Endpoint<PVRGPUParent>&& aEndpoint) { 36 RefPtr<VRGPUParent> vrGPUParent = 37 VRGPUParent::CreateForGPU(std::move(aEndpoint)); 38 if (!vrGPUParent) { 39 return IPC_FAIL_NO_REASON(this); 40 } 41 42 mVRGPUParent = std::move(vrGPUParent); 43 return IPC_OK(); 44 } 45 46 IPCResult VRParent::RecvInit(nsTArray<GfxVarUpdate>&& vars, 47 const DevicePrefs& devicePrefs) { 48 (void)SendInitComplete(); 49 50 gfxVars::ApplyUpdate(vars); 51 52 // Inherit device preferences. 53 gfxConfig::Inherit(Feature::HW_COMPOSITING, devicePrefs.hwCompositing()); 54 gfxConfig::Inherit(Feature::D3D11_COMPOSITING, 55 devicePrefs.d3d11Compositing()); 56 gfxConfig::Inherit(Feature::OPENGL_COMPOSITING, devicePrefs.oglCompositing()); 57 58 #if defined(XP_WIN) 59 if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) { 60 DeviceManagerDx::Get()->CreateCompositorDevices(); 61 } 62 #endif 63 return IPC_OK(); 64 } 65 66 IPCResult VRParent::RecvUpdateVar(const nsTArray<GfxVarUpdate>& aUpdate) { 67 gfxVars::ApplyUpdate(aUpdate); 68 return IPC_OK(); 69 } 70 71 mozilla::ipc::IPCResult VRParent::RecvPreferenceUpdate(const Pref& aPref) { 72 Preferences::SetPreference(aPref); 73 return IPC_OK(); 74 } 75 76 mozilla::ipc::IPCResult VRParent::RecvOpenVRControllerActionPathToVR( 77 const nsCString& aPath) { 78 mOpenVRControllerAction = aPath; 79 return IPC_OK(); 80 } 81 82 mozilla::ipc::IPCResult VRParent::RecvOpenVRControllerManifestPathToVR( 83 const VRControllerType& aType, const nsCString& aPath) { 84 mOpenVRControllerManifest.InsertOrUpdate(static_cast<uint32_t>(aType), aPath); 85 return IPC_OK(); 86 } 87 88 mozilla::ipc::IPCResult VRParent::RecvRequestMemoryReport( 89 const uint32_t& aGeneration, const bool& aAnonymize, 90 const bool& aMinimizeMemoryUsage, const Maybe<FileDescriptor>& aDMDFile, 91 const RequestMemoryReportResolver& aResolver) { 92 MOZ_ASSERT(XRE_IsVRProcess()); 93 nsPrintfCString processName("VR (pid %u)", (unsigned)getpid()); 94 95 mozilla::dom::MemoryReportRequestClient::Start( 96 aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName, 97 [&](const MemoryReport& aReport) { (void)SendAddMemoryReport(aReport); }, 98 aResolver); 99 return IPC_OK(); 100 } 101 102 void VRParent::ActorDestroy(ActorDestroyReason aWhy) { 103 if (AbnormalShutdown == aWhy) { 104 NS_WARNING("Shutting down VR process early due to a crash!"); 105 ipc::ProcessChild::QuickExit(); 106 } 107 if (mVRGPUParent && !mVRGPUParent->IsClosed()) { 108 mVRGPUParent->Close(); 109 } 110 mVRGPUParent = nullptr; 111 112 #ifndef NS_FREE_PERMANENT_DATA 113 // No point in going through XPCOM shutdown because we don't keep persistent 114 // state. 115 ipc::ProcessChild::QuickExit(); 116 #endif 117 118 #if defined(XP_WIN) 119 DeviceManagerDx::Shutdown(); 120 #endif 121 gfxVars::Shutdown(); 122 gfxConfig::Shutdown(); 123 ipc::CrashReporterClient::DestroySingleton(); 124 // Only calling XRE_ShutdownChildProcess() at the child process 125 // instead of the main process. Otherwise, it will close all child processes 126 // that are spawned from the main process. 127 XRE_ShutdownChildProcess(); 128 } 129 130 bool VRParent::Init(mozilla::ipc::UntypedEndpoint&& aEndpoint, 131 const char* aParentBuildID) { 132 // Initialize the thread manager before starting IPC. Otherwise, messages 133 // may be posted to the main thread and we won't be able to process them. 134 if (NS_WARN_IF(NS_FAILED(nsThreadManager::get().Init()))) { 135 return false; 136 } 137 138 // Now it's safe to start IPC. 139 if (NS_WARN_IF(!aEndpoint.Bind(this))) { 140 return false; 141 } 142 143 nsDebugImpl::SetMultiprocessMode("VR"); 144 145 // This must be checked before any IPDL message, which may hit sentinel 146 // errors due to parent and content processes having different 147 // versions. 148 MessageChannel* channel = GetIPCChannel(); 149 if (channel && !channel->SendBuildIDsMatchMessage(aParentBuildID)) { 150 // We need to quit this process if the buildID doesn't match the parent's. 151 // This can occur when an update occurred in the background. 152 ipc::ProcessChild::QuickExit(); 153 } 154 155 // Init crash reporter support. 156 ipc::CrashReporterClient::InitSingleton(this); 157 158 gfxConfig::Init(); 159 gfxVars::Initialize(); 160 #if defined(XP_WIN) 161 DeviceManagerDx::Init(); 162 #endif 163 if (NS_FAILED(NS_InitMinimalXPCOM())) { 164 return false; 165 } 166 167 mozilla::ipc::SetThisProcessName("VR Process"); 168 return true; 169 } 170 171 bool VRParent::GetOpenVRControllerActionPath(nsCString* aPath) { 172 if (!mOpenVRControllerAction.IsEmpty()) { 173 *aPath = mOpenVRControllerAction; 174 return true; 175 } 176 177 return false; 178 } 179 180 bool VRParent::GetOpenVRControllerManifestPath(VRControllerType aType, 181 nsCString* aPath) { 182 return mOpenVRControllerManifest.Get(static_cast<uint32_t>(aType), aPath); 183 } 184 185 } // namespace gfx 186 } // namespace mozilla