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/. */
8 #include "VRProcessManager.h"
9 #include "VRProcessParent.h"
10 #include "gfxConfig.h"
12 #include "mozilla/gfx/gfxVars.h"
13 #include "mozilla/ClearOnShutdown.h"
14 #include "mozilla/Telemetry.h"
15 #include "mozilla/VsyncDispatcher.h"
16 #include "mozilla/dom/MemoryReportRequest.h"
21 class OpenVRControllerManifestManager
{
22 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OpenVRControllerManifestManager
)
24 explicit OpenVRControllerManifestManager() = default;
26 void SetOpenVRControllerActionPath(const nsCString
& aPath
) {
30 void SetOpenVRControllerManifestPath(VRControllerType aType
,
31 const nsCString
& aPath
) {
32 mManifest
.InsertOrUpdate(static_cast<uint32_t>(aType
), aPath
);
35 bool GetActionPath(nsCString
* aPath
) {
36 if (!mAction
.IsEmpty()) {
43 bool GetManifestPath(VRControllerType aType
, nsCString
* aPath
) {
44 return mManifest
.Get(static_cast<uint32_t>(aType
), aPath
);
48 ~OpenVRControllerManifestManager() {
49 if (!mAction
.IsEmpty() && remove(mAction
.BeginReading()) != 0) {
50 MOZ_ASSERT(false, "Delete controller action file failed.");
54 for (const auto& path
: mManifest
.Values()) {
55 if (!path
.IsEmpty() && remove(path
.BeginReading()) != 0) {
56 MOZ_ASSERT(false, "Delete controller manifest file failed.");
63 nsTHashMap
<nsUint32HashKey
, nsCString
> mManifest
;
64 OpenVRControllerManifestManager(const OpenVRControllerManifestManager
&) =
67 const OpenVRControllerManifestManager
& operator=(
68 const OpenVRControllerManifestManager
&) = delete;
71 StaticRefPtr
<OpenVRControllerManifestManager
> sOpenVRControllerManifestManager
;
73 VRChild::VRChild(VRProcessParent
* aHost
) : mHost(aHost
), mVRReady(false) {
74 MOZ_ASSERT(XRE_IsParentProcess());
77 VRChild::~VRChild() = default;
79 mozilla::ipc::IPCResult
VRChild::RecvAddMemoryReport(
80 const MemoryReport
& aReport
) {
81 if (mMemoryReportRequest
) {
82 mMemoryReportRequest
->RecvReport(aReport
);
87 void VRChild::ActorDestroy(ActorDestroyReason aWhy
) {
88 if (aWhy
== AbnormalShutdown
) {
89 GenerateCrashReport(OtherPid());
91 Telemetry::Accumulate(
92 Telemetry::SUBPROCESS_ABNORMAL_ABORT
,
93 nsDependentCString(XRE_GeckoProcessTypeToString(GeckoProcessType_VR
)),
96 gfxVars::RemoveReceiver(this);
97 mHost
->OnChannelClosed();
100 void VRChild::Init() {
101 nsTArray
<GfxVarUpdate
> updates
= gfxVars::FetchNonDefaultVars();
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 devicePrefs
.useD2D1() = gfxConfig::GetValue(Feature::DIRECT2D
);
111 SendInit(updates
, devicePrefs
);
113 if (!sOpenVRControllerManifestManager
) {
114 sOpenVRControllerManifestManager
= new OpenVRControllerManifestManager();
115 NS_DispatchToMainThread(NS_NewRunnableFunction(
116 "ClearOnShutdown OpenVRControllerManifestManager",
117 []() { ClearOnShutdown(&sOpenVRControllerManifestManager
); }));
121 if (sOpenVRControllerManifestManager
->GetActionPath(&output
)) {
122 SendOpenVRControllerActionPathToVR(output
);
124 if (sOpenVRControllerManifestManager
->GetManifestPath(
125 VRControllerType::HTCVive
, &output
)) {
126 SendOpenVRControllerManifestPathToVR(VRControllerType::HTCVive
, output
);
128 if (sOpenVRControllerManifestManager
->GetManifestPath(VRControllerType::MSMR
,
130 SendOpenVRControllerManifestPathToVR(VRControllerType::MSMR
, output
);
132 if (sOpenVRControllerManifestManager
->GetManifestPath(
133 VRControllerType::ValveIndex
, &output
)) {
134 SendOpenVRControllerManifestPathToVR(VRControllerType::ValveIndex
, output
);
136 gfxVars::AddReceiver(this);
139 bool VRChild::EnsureVRReady() {
147 mozilla::ipc::IPCResult
VRChild::RecvOpenVRControllerActionPathToParent(
148 const nsCString
& aPath
) {
149 sOpenVRControllerManifestManager
->SetOpenVRControllerActionPath(aPath
);
153 mozilla::ipc::IPCResult
VRChild::RecvOpenVRControllerManifestPathToParent(
154 const VRControllerType
& aType
, const nsCString
& aPath
) {
155 sOpenVRControllerManifestManager
->SetOpenVRControllerManifestPath(aType
,
160 mozilla::ipc::IPCResult
VRChild::RecvInitComplete() {
161 // We synchronously requested VR parameters before this arrived.
166 bool VRChild::SendRequestMemoryReport(const uint32_t& aGeneration
,
167 const bool& aAnonymize
,
168 const bool& aMinimizeMemoryUsage
,
169 const Maybe
<FileDescriptor
>& aDMDFile
) {
170 mMemoryReportRequest
= MakeUnique
<MemoryReportRequestHost
>(aGeneration
);
172 PVRChild::SendRequestMemoryReport(
173 aGeneration
, aAnonymize
, aMinimizeMemoryUsage
, aDMDFile
,
174 [&](const uint32_t& aGeneration2
) {
175 if (VRProcessManager
* vpm
= VRProcessManager::Get()) {
176 if (VRChild
* child
= vpm
->GetVRChild()) {
177 if (child
->mMemoryReportRequest
) {
178 child
->mMemoryReportRequest
->Finish(aGeneration2
);
179 child
->mMemoryReportRequest
= nullptr;
184 [&](mozilla::ipc::ResponseRejectReason
) {
185 if (VRProcessManager
* vpm
= VRProcessManager::Get()) {
186 if (VRChild
* child
= vpm
->GetVRChild()) {
187 child
->mMemoryReportRequest
= nullptr;
195 void VRChild::OnVarChanged(const GfxVarUpdate
& aVar
) { SendUpdateVar(aVar
); }
197 class DeferredDeleteVRChild
: public Runnable
{
199 explicit DeferredDeleteVRChild(RefPtr
<VRChild
>&& aChild
)
200 : Runnable("gfx::DeferredDeleteVRChild"), mChild(std::move(aChild
)) {}
202 NS_IMETHODIMP
Run() override
{ return NS_OK
; }
205 RefPtr
<VRChild
> mChild
;
209 void VRChild::Destroy(RefPtr
<VRChild
>&& aChild
) {
210 NS_DispatchToMainThread(new DeferredDeleteVRChild(std::move(aChild
)));
214 } // namespace mozilla