VRChild.cpp (6778B)
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 "VRChild.h" 8 #include "VRProcessManager.h" 9 #include "VRProcessParent.h" 10 #include "gfxConfig.h" 11 12 #include "mozilla/gfx/gfxVars.h" 13 #include "mozilla/ClearOnShutdown.h" 14 #include "mozilla/glean/IpcMetrics.h" 15 #include "mozilla/VsyncDispatcher.h" 16 #include "mozilla/dom/MemoryReportRequest.h" 17 18 namespace mozilla { 19 namespace gfx { 20 21 class OpenVRControllerManifestManager { 22 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OpenVRControllerManifestManager) 23 public: 24 explicit OpenVRControllerManifestManager() = default; 25 26 void SetOpenVRControllerActionPath(const nsCString& aPath) { 27 mAction = aPath; 28 } 29 30 void SetOpenVRControllerManifestPath(VRControllerType aType, 31 const nsCString& aPath) { 32 mManifest.InsertOrUpdate(static_cast<uint32_t>(aType), aPath); 33 } 34 35 bool GetActionPath(nsCString* aPath) { 36 if (!mAction.IsEmpty()) { 37 *aPath = mAction; 38 return true; 39 } 40 return false; 41 } 42 43 bool GetManifestPath(VRControllerType aType, nsCString* aPath) { 44 return mManifest.Get(static_cast<uint32_t>(aType), aPath); 45 } 46 47 private: 48 ~OpenVRControllerManifestManager() { 49 if (!mAction.IsEmpty() && remove(mAction.BeginReading()) != 0) { 50 MOZ_ASSERT(false, "Delete controller action file failed."); 51 } 52 mAction = ""; 53 54 for (const auto& path : mManifest.Values()) { 55 if (!path.IsEmpty() && remove(path.BeginReading()) != 0) { 56 MOZ_ASSERT(false, "Delete controller manifest file failed."); 57 } 58 } 59 mManifest.Clear(); 60 } 61 62 nsCString mAction; 63 nsTHashMap<nsUint32HashKey, nsCString> mManifest; 64 OpenVRControllerManifestManager(const OpenVRControllerManifestManager&) = 65 delete; 66 67 const OpenVRControllerManifestManager& operator=( 68 const OpenVRControllerManifestManager&) = delete; 69 }; 70 71 StaticRefPtr<OpenVRControllerManifestManager> sOpenVRControllerManifestManager; 72 73 VRChild::VRChild(VRProcessParent* aHost) : mHost(aHost), mVRReady(false) { 74 MOZ_ASSERT(XRE_IsParentProcess()); 75 } 76 77 VRChild::~VRChild() = default; 78 79 mozilla::ipc::IPCResult VRChild::RecvAddMemoryReport( 80 const MemoryReport& aReport) { 81 if (mMemoryReportRequest) { 82 mMemoryReportRequest->RecvReport(aReport); 83 } 84 return IPC_OK(); 85 } 86 87 void VRChild::ActorDestroy(ActorDestroyReason aWhy) { 88 if (aWhy == AbnormalShutdown) { 89 GenerateCrashReport(); 90 91 glean::subprocess::abnormal_abort 92 .Get(nsDependentCString( 93 XRE_GeckoProcessTypeToString(GeckoProcessType_VR))) 94 .Add(1); 95 } 96 gfxVars::RemoveReceiver(this); 97 mHost->OnChannelClosed(); 98 } 99 100 void VRChild::Init() { 101 nsTArray<GfxVarUpdate> updates = gfxVars::FetchNonDefaultVars(); 102 103 DevicePrefs devicePrefs; 104 devicePrefs.hwCompositing() = gfxConfig::GetValue(Feature::HW_COMPOSITING); 105 devicePrefs.d3d11Compositing() = 106 gfxConfig::GetValue(Feature::D3D11_COMPOSITING); 107 devicePrefs.oglCompositing() = 108 gfxConfig::GetValue(Feature::OPENGL_COMPOSITING); 109 110 SendInit(updates, devicePrefs); 111 112 if (!sOpenVRControllerManifestManager) { 113 sOpenVRControllerManifestManager = new OpenVRControllerManifestManager(); 114 NS_DispatchToMainThread(NS_NewRunnableFunction( 115 "ClearOnShutdown OpenVRControllerManifestManager", 116 []() { ClearOnShutdown(&sOpenVRControllerManifestManager); })); 117 } 118 119 nsCString output; 120 if (sOpenVRControllerManifestManager->GetActionPath(&output)) { 121 SendOpenVRControllerActionPathToVR(output); 122 } 123 if (sOpenVRControllerManifestManager->GetManifestPath( 124 VRControllerType::HTCVive, &output)) { 125 SendOpenVRControllerManifestPathToVR(VRControllerType::HTCVive, output); 126 } 127 if (sOpenVRControllerManifestManager->GetManifestPath(VRControllerType::MSMR, 128 &output)) { 129 SendOpenVRControllerManifestPathToVR(VRControllerType::MSMR, output); 130 } 131 if (sOpenVRControllerManifestManager->GetManifestPath( 132 VRControllerType::ValveIndex, &output)) { 133 SendOpenVRControllerManifestPathToVR(VRControllerType::ValveIndex, output); 134 } 135 gfxVars::AddReceiver(this); 136 } 137 138 bool VRChild::EnsureVRReady() { 139 if (!mVRReady) { 140 return false; 141 } 142 143 return true; 144 } 145 146 mozilla::ipc::IPCResult VRChild::RecvOpenVRControllerActionPathToParent( 147 const nsCString& aPath) { 148 sOpenVRControllerManifestManager->SetOpenVRControllerActionPath(aPath); 149 return IPC_OK(); 150 } 151 152 mozilla::ipc::IPCResult VRChild::RecvOpenVRControllerManifestPathToParent( 153 const VRControllerType& aType, const nsCString& aPath) { 154 sOpenVRControllerManifestManager->SetOpenVRControllerManifestPath(aType, 155 aPath); 156 return IPC_OK(); 157 } 158 159 mozilla::ipc::IPCResult VRChild::RecvInitComplete() { 160 // We synchronously requested VR parameters before this arrived. 161 mVRReady = true; 162 return IPC_OK(); 163 } 164 165 bool VRChild::SendRequestMemoryReport(const uint32_t& aGeneration, 166 const bool& aAnonymize, 167 const bool& aMinimizeMemoryUsage, 168 const Maybe<FileDescriptor>& aDMDFile) { 169 mMemoryReportRequest = MakeUnique<MemoryReportRequestHost>(aGeneration); 170 171 PVRChild::SendRequestMemoryReport( 172 aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, 173 [&](const uint32_t& aGeneration2) { 174 if (VRProcessManager* vpm = VRProcessManager::Get()) { 175 if (VRChild* child = vpm->GetVRChild()) { 176 if (child->mMemoryReportRequest) { 177 child->mMemoryReportRequest->Finish(aGeneration2); 178 child->mMemoryReportRequest = nullptr; 179 } 180 } 181 } 182 }, 183 [&](mozilla::ipc::ResponseRejectReason) { 184 if (VRProcessManager* vpm = VRProcessManager::Get()) { 185 if (VRChild* child = vpm->GetVRChild()) { 186 child->mMemoryReportRequest = nullptr; 187 } 188 } 189 }); 190 191 return true; 192 } 193 194 void VRChild::OnVarChanged(const nsTArray<GfxVarUpdate>& aVar) { 195 SendUpdateVar(aVar); 196 } 197 198 class DeferredDeleteVRChild : public Runnable { 199 public: 200 explicit DeferredDeleteVRChild(RefPtr<VRChild>&& aChild) 201 : Runnable("gfx::DeferredDeleteVRChild"), mChild(std::move(aChild)) {} 202 203 NS_IMETHODIMP Run() override { return NS_OK; } 204 205 private: 206 RefPtr<VRChild> mChild; 207 }; 208 209 /* static */ 210 void VRChild::Destroy(RefPtr<VRChild>&& aChild) { 211 NS_DispatchToMainThread(new DeferredDeleteVRChild(std::move(aChild))); 212 } 213 214 } // namespace gfx 215 } // namespace mozilla