/src/mozilla-central/gfx/ipc/GPUParent.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | #ifdef XP_WIN |
7 | | #include "WMF.h" |
8 | | #endif |
9 | | #include "GPUParent.h" |
10 | | #include "gfxConfig.h" |
11 | | #include "gfxCrashReporterUtils.h" |
12 | | #include "gfxPlatform.h" |
13 | | #include "gfxPrefs.h" |
14 | | #include "GLContextProvider.h" |
15 | | #include "GPUProcessHost.h" |
16 | | #include "GPUProcessManager.h" |
17 | | #include "mozilla/Assertions.h" |
18 | | #include "mozilla/Telemetry.h" |
19 | | #include "mozilla/TimeStamp.h" |
20 | | #include "mozilla/dom/MemoryReportRequest.h" |
21 | | #include "mozilla/dom/VideoDecoderManagerChild.h" |
22 | | #include "mozilla/dom/VideoDecoderManagerParent.h" |
23 | | #include "mozilla/gfx/2D.h" |
24 | | #include "mozilla/gfx/gfxVars.h" |
25 | | #include "mozilla/ipc/CrashReporterClient.h" |
26 | | #include "mozilla/ipc/ProcessChild.h" |
27 | | #include "mozilla/layers/APZInputBridgeParent.h" |
28 | | #include "mozilla/layers/APZThreadUtils.h" |
29 | | #include "mozilla/layers/APZUtils.h" // for apz::InitializeGlobalState |
30 | | #include "mozilla/layers/CompositorBridgeParent.h" |
31 | | #include "mozilla/layers/CompositorManagerParent.h" |
32 | | #include "mozilla/layers/CompositorThread.h" |
33 | | #include "mozilla/layers/ImageBridgeParent.h" |
34 | | #include "mozilla/layers/LayerTreeOwnerTracker.h" |
35 | | #include "mozilla/layers/UiCompositorControllerParent.h" |
36 | | #include "mozilla/layers/MemoryReportingMLGPU.h" |
37 | | #include "mozilla/webrender/RenderThread.h" |
38 | | #include "mozilla/webrender/WebRenderAPI.h" |
39 | | #include "mozilla/HangDetails.h" |
40 | | #include "nsDebugImpl.h" |
41 | | #include "nsIGfxInfo.h" |
42 | | #include "nsThreadManager.h" |
43 | | #include "prenv.h" |
44 | | #include "ProcessUtils.h" |
45 | | #include "VRGPUChild.h" |
46 | | #include "VRManager.h" |
47 | | #include "VRManagerParent.h" |
48 | | #include "VRThread.h" |
49 | | #include "VsyncBridgeParent.h" |
50 | | #if defined(XP_WIN) |
51 | | # include "mozilla/gfx/DeviceManagerDx.h" |
52 | | # include <process.h> |
53 | | # include <dwrite.h> |
54 | | #endif |
55 | | #ifdef MOZ_WIDGET_GTK |
56 | | # include <gtk/gtk.h> |
57 | | #endif |
58 | | #ifdef MOZ_GECKO_PROFILER |
59 | | #include "ChildProfilerController.h" |
60 | | #endif |
61 | | |
62 | | namespace mozilla { |
63 | | namespace gfx { |
64 | | |
65 | | using namespace ipc; |
66 | | using namespace layers; |
67 | | |
68 | | static GPUParent* sGPUParent; |
69 | | |
70 | | GPUParent::GPUParent() |
71 | | : mLaunchTime(TimeStamp::Now()) |
72 | 0 | { |
73 | 0 | sGPUParent = this; |
74 | 0 | } |
75 | | |
76 | | GPUParent::~GPUParent() |
77 | 0 | { |
78 | 0 | sGPUParent = nullptr; |
79 | 0 | } |
80 | | |
81 | | /* static */ GPUParent* |
82 | | GPUParent::GetSingleton() |
83 | 0 | { |
84 | 0 | return sGPUParent; |
85 | 0 | } |
86 | | |
87 | | bool |
88 | | GPUParent::Init(base::ProcessId aParentPid, |
89 | | const char* aParentBuildID, |
90 | | MessageLoop* aIOLoop, |
91 | | IPC::Channel* aChannel) |
92 | 0 | { |
93 | 0 | // Initialize the thread manager before starting IPC. Otherwise, messages |
94 | 0 | // may be posted to the main thread and we won't be able to process them. |
95 | 0 | if (NS_WARN_IF(NS_FAILED(nsThreadManager::get().Init()))) { |
96 | 0 | return false; |
97 | 0 | } |
98 | 0 | |
99 | 0 | // Now it's safe to start IPC. |
100 | 0 | if (NS_WARN_IF(!Open(aChannel, aParentPid, aIOLoop))) { |
101 | 0 | return false; |
102 | 0 | } |
103 | 0 | |
104 | 0 | nsDebugImpl::SetMultiprocessMode("GPU"); |
105 | 0 |
|
106 | 0 | // This must be checked before any IPDL message, which may hit sentinel |
107 | 0 | // errors due to parent and content processes having different |
108 | 0 | // versions. |
109 | 0 | MessageChannel* channel = GetIPCChannel(); |
110 | 0 | if (channel && !channel->SendBuildIDsMatchMessage(aParentBuildID)) { |
111 | 0 | // We need to quit this process if the buildID doesn't match the parent's. |
112 | 0 | // This can occur when an update occurred in the background. |
113 | 0 | ProcessChild::QuickExit(); |
114 | 0 | } |
115 | 0 |
|
116 | 0 | // Init crash reporter support. |
117 | 0 | CrashReporterClient::InitSingleton(this); |
118 | 0 |
|
119 | 0 | // Ensure gfxPrefs are initialized. |
120 | 0 | gfxPrefs::GetSingleton(); |
121 | 0 | gfxConfig::Init(); |
122 | 0 | gfxVars::Initialize(); |
123 | 0 | gfxPlatform::InitNullMetadata(); |
124 | 0 | // Ensure our Factory is initialised, mainly for gfx logging to work. |
125 | 0 | gfxPlatform::InitMoz2DLogging(); |
126 | 0 | mlg::InitializeMemoryReporters(); |
127 | | #if defined(XP_WIN) |
128 | | DeviceManagerDx::Init(); |
129 | | #endif |
130 | |
|
131 | 0 | if (NS_FAILED(NS_InitMinimalXPCOM())) { |
132 | 0 | return false; |
133 | 0 | } |
134 | 0 | |
135 | 0 | CompositorThreadHolder::Start(); |
136 | 0 | // TODO: Bug 1406327, Start VRListenerThreadHolder when loading VR content. |
137 | 0 | VRListenerThreadHolder::Start(); |
138 | 0 | APZThreadUtils::SetControllerThread(MessageLoop::current()); |
139 | 0 | apz::InitializeGlobalState(); |
140 | 0 | LayerTreeOwnerTracker::Initialize(); |
141 | 0 | mozilla::ipc::SetThisProcessName("GPU Process"); |
142 | | #ifdef XP_WIN |
143 | | wmf::MFStartup(); |
144 | | #endif |
145 | | return true; |
146 | 0 | } |
147 | | |
148 | | void |
149 | | GPUParent::NotifyDeviceReset() |
150 | 0 | { |
151 | 0 | if (!NS_IsMainThread()) { |
152 | 0 | NS_DispatchToMainThread( |
153 | 0 | NS_NewRunnableFunction("gfx::GPUParent::NotifyDeviceReset", []() -> void { |
154 | 0 | GPUParent::GetSingleton()->NotifyDeviceReset(); |
155 | 0 | })); |
156 | 0 | return; |
157 | 0 | } |
158 | 0 |
|
159 | 0 | // Reset and reinitialize the compositor devices |
160 | | #ifdef XP_WIN |
161 | | if (!DeviceManagerDx::Get()->MaybeResetAndReacquireDevices()) { |
162 | | // If the device doesn't need to be reset then the device |
163 | | // has already been reset by a previous NotifyDeviceReset message. |
164 | | return; |
165 | | } |
166 | | #endif |
167 | | |
168 | 0 | // Notify the main process that there's been a device reset |
169 | 0 | // and that they should reset their compositors and repaint |
170 | 0 | GPUDeviceData data; |
171 | 0 | RecvGetDeviceStatus(&data); |
172 | 0 | Unused << SendNotifyDeviceReset(data); |
173 | 0 | } |
174 | | |
175 | | PAPZInputBridgeParent* |
176 | | GPUParent::AllocPAPZInputBridgeParent(const LayersId& aLayersId) |
177 | 0 | { |
178 | 0 | APZInputBridgeParent* parent = new APZInputBridgeParent(aLayersId); |
179 | 0 | parent->AddRef(); |
180 | 0 | return parent; |
181 | 0 | } |
182 | | |
183 | | bool |
184 | | GPUParent::DeallocPAPZInputBridgeParent(PAPZInputBridgeParent* aActor) |
185 | 0 | { |
186 | 0 | APZInputBridgeParent* parent = static_cast<APZInputBridgeParent*>(aActor); |
187 | 0 | parent->Release(); |
188 | 0 | return true; |
189 | 0 | } |
190 | | |
191 | | mozilla::ipc::IPCResult |
192 | | GPUParent::RecvInit(nsTArray<GfxPrefSetting>&& prefs, |
193 | | nsTArray<GfxVarUpdate>&& vars, |
194 | | const DevicePrefs& devicePrefs, |
195 | | nsTArray<LayerTreeIdMapping>&& aMappings) |
196 | 0 | { |
197 | 0 | const nsTArray<gfxPrefs::Pref*>& globalPrefs = gfxPrefs::all(); |
198 | 0 | for (auto& setting : prefs) { |
199 | 0 | gfxPrefs::Pref* pref = globalPrefs[setting.index()]; |
200 | 0 | pref->SetCachedValue(setting.value()); |
201 | 0 | } |
202 | 0 | for (const auto& var : vars) { |
203 | 0 | gfxVars::ApplyUpdate(var); |
204 | 0 | } |
205 | 0 |
|
206 | 0 | // Inherit device preferences. |
207 | 0 | gfxConfig::Inherit(Feature::HW_COMPOSITING, devicePrefs.hwCompositing()); |
208 | 0 | gfxConfig::Inherit(Feature::D3D11_COMPOSITING, devicePrefs.d3d11Compositing()); |
209 | 0 | gfxConfig::Inherit(Feature::OPENGL_COMPOSITING, devicePrefs.oglCompositing()); |
210 | 0 | gfxConfig::Inherit(Feature::ADVANCED_LAYERS, devicePrefs.advancedLayers()); |
211 | 0 | gfxConfig::Inherit(Feature::DIRECT2D, devicePrefs.useD2D1()); |
212 | 0 |
|
213 | 0 | { // Let the crash reporter know if we've got WR enabled or not. For other |
214 | 0 | // processes this happens in gfxPlatform::InitWebRenderConfig. |
215 | 0 | ScopedGfxFeatureReporter reporter("WR", gfxPlatform::WebRenderPrefEnabled()); |
216 | 0 | if (gfxVars::UseWebRender()) { |
217 | 0 | reporter.SetSuccessful(); |
218 | 0 | } |
219 | 0 | } |
220 | 0 |
|
221 | 0 | for (const LayerTreeIdMapping& map : aMappings) { |
222 | 0 | LayerTreeOwnerTracker::Get()->Map(map.layersId(), map.ownerId()); |
223 | 0 | } |
224 | 0 |
|
225 | | #if defined(XP_WIN) |
226 | | if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) { |
227 | | DeviceManagerDx::Get()->CreateCompositorDevices(); |
228 | | } |
229 | | if (gfxVars::UseWebRender()) { |
230 | | DeviceManagerDx::Get()->CreateDirectCompositionDevice(); |
231 | | // Ensure to initialize GfxInfo |
232 | | nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo(); |
233 | | Unused << gfxInfo; |
234 | | |
235 | | Factory::EnsureDWriteFactory(); |
236 | | } |
237 | | #endif |
238 | |
|
239 | 0 | #if defined(MOZ_WIDGET_GTK) |
240 | 0 | char* display_name = PR_GetEnv("DISPLAY"); |
241 | 0 | if (display_name) { |
242 | 0 | int argc = 3; |
243 | 0 | char option_name[] = "--display"; |
244 | 0 | char* argv[] = { |
245 | 0 | // argv0 is unused because g_set_prgname() was called in |
246 | 0 | // XRE_InitChildProcess(). |
247 | 0 | nullptr, |
248 | 0 | option_name, |
249 | 0 | display_name, |
250 | 0 | nullptr |
251 | 0 | }; |
252 | 0 | char** argvp = argv; |
253 | 0 | gtk_init(&argc, &argvp); |
254 | 0 | } else { |
255 | 0 | gtk_init(nullptr, nullptr); |
256 | 0 | } |
257 | 0 |
|
258 | 0 | // Ensure we have an FT library for font instantiation. |
259 | 0 | // This would normally be set by gfxPlatform::Init(). |
260 | 0 | // Since we bypass that, we must do it here instead. |
261 | 0 | if (gfxVars::UseWebRender()) { |
262 | 0 | FT_Library library = Factory::NewFTLibrary(); |
263 | 0 | MOZ_ASSERT(library); |
264 | 0 | Factory::SetFTLibrary(library); |
265 | 0 | } |
266 | 0 | #endif |
267 | 0 |
|
268 | 0 | // Make sure to do this *after* we update gfxVars above. |
269 | 0 | if (gfxVars::UseWebRender()) { |
270 | 0 | wr::RenderThread::Start(); |
271 | 0 | } |
272 | 0 |
|
273 | 0 | VRManager::ManagerInit(); |
274 | 0 | // Send a message to the UI process that we're done. |
275 | 0 | GPUDeviceData data; |
276 | 0 | RecvGetDeviceStatus(&data); |
277 | 0 | Unused << SendInitComplete(data); |
278 | 0 |
|
279 | 0 | Telemetry::AccumulateTimeDelta(Telemetry::GPU_PROCESS_INITIALIZATION_TIME_MS, mLaunchTime); |
280 | 0 | return IPC_OK(); |
281 | 0 | } |
282 | | |
283 | | mozilla::ipc::IPCResult |
284 | | GPUParent::RecvInitCompositorManager(Endpoint<PCompositorManagerParent>&& aEndpoint) |
285 | 0 | { |
286 | 0 | CompositorManagerParent::Create(std::move(aEndpoint)); |
287 | 0 | return IPC_OK(); |
288 | 0 | } |
289 | | |
290 | | mozilla::ipc::IPCResult |
291 | | GPUParent::RecvInitVsyncBridge(Endpoint<PVsyncBridgeParent>&& aVsyncEndpoint) |
292 | 0 | { |
293 | 0 | mVsyncBridge = VsyncBridgeParent::Start(std::move(aVsyncEndpoint)); |
294 | 0 | return IPC_OK(); |
295 | 0 | } |
296 | | |
297 | | mozilla::ipc::IPCResult |
298 | | GPUParent::RecvInitImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) |
299 | 0 | { |
300 | 0 | ImageBridgeParent::CreateForGPUProcess(std::move(aEndpoint)); |
301 | 0 | return IPC_OK(); |
302 | 0 | } |
303 | | |
304 | | mozilla::ipc::IPCResult |
305 | | GPUParent::RecvInitVRManager(Endpoint<PVRManagerParent>&& aEndpoint) |
306 | 0 | { |
307 | 0 | VRManagerParent::CreateForGPUProcess(std::move(aEndpoint)); |
308 | 0 | return IPC_OK(); |
309 | 0 | } |
310 | | |
311 | | mozilla::ipc::IPCResult |
312 | | GPUParent::RecvInitVR(Endpoint<PVRGPUChild>&& aEndpoint) |
313 | 0 | { |
314 | 0 | gfx::VRGPUChild::InitForGPUProcess(std::move(aEndpoint)); |
315 | 0 | return IPC_OK(); |
316 | 0 | } |
317 | | |
318 | | mozilla::ipc::IPCResult |
319 | | GPUParent::RecvInitUiCompositorController(const LayersId& aRootLayerTreeId, Endpoint<PUiCompositorControllerParent>&& aEndpoint) |
320 | 0 | { |
321 | 0 | UiCompositorControllerParent::Start(aRootLayerTreeId, std::move(aEndpoint)); |
322 | 0 | return IPC_OK(); |
323 | 0 | } |
324 | | |
325 | | mozilla::ipc::IPCResult |
326 | | GPUParent::RecvInitProfiler(Endpoint<PProfilerChild>&& aEndpoint) |
327 | 0 | { |
328 | 0 | #ifdef MOZ_GECKO_PROFILER |
329 | 0 | mProfilerController = ChildProfilerController::Create(std::move(aEndpoint)); |
330 | 0 | #endif |
331 | 0 | return IPC_OK(); |
332 | 0 | } |
333 | | |
334 | | mozilla::ipc::IPCResult |
335 | | GPUParent::RecvUpdatePref(const GfxPrefSetting& setting) |
336 | 0 | { |
337 | 0 | gfxPrefs::Pref* pref = gfxPrefs::all()[setting.index()]; |
338 | 0 | pref->SetCachedValue(setting.value()); |
339 | 0 | return IPC_OK(); |
340 | 0 | } |
341 | | |
342 | | mozilla::ipc::IPCResult |
343 | | GPUParent::RecvUpdateVar(const GfxVarUpdate& aUpdate) |
344 | 0 | { |
345 | 0 | gfxVars::ApplyUpdate(aUpdate); |
346 | 0 | return IPC_OK(); |
347 | 0 | } |
348 | | |
349 | | static void |
350 | | CopyFeatureChange(Feature aFeature, FeatureChange* aOut) |
351 | 0 | { |
352 | 0 | FeatureState& feature = gfxConfig::GetFeature(aFeature); |
353 | 0 | if (feature.DisabledByDefault() || feature.IsEnabled()) { |
354 | 0 | // No change: |
355 | 0 | // - Disabled-by-default means the parent process told us not to use this feature. |
356 | 0 | // - Enabled means we were told to use this feature, and we didn't discover anything |
357 | 0 | // that would prevent us from doing so. |
358 | 0 | *aOut = null_t(); |
359 | 0 | return; |
360 | 0 | } |
361 | 0 | |
362 | 0 | MOZ_ASSERT(!feature.IsEnabled()); |
363 | 0 |
|
364 | 0 | nsCString message; |
365 | 0 | message.AssignASCII(feature.GetFailureMessage()); |
366 | 0 |
|
367 | 0 | *aOut = FeatureFailure(feature.GetValue(), message, feature.GetFailureId()); |
368 | 0 | } |
369 | | |
370 | | mozilla::ipc::IPCResult |
371 | | GPUParent::RecvGetDeviceStatus(GPUDeviceData* aOut) |
372 | 0 | { |
373 | 0 | CopyFeatureChange(Feature::D3D11_COMPOSITING, &aOut->d3d11Compositing()); |
374 | 0 | CopyFeatureChange(Feature::OPENGL_COMPOSITING, &aOut->oglCompositing()); |
375 | 0 | CopyFeatureChange(Feature::ADVANCED_LAYERS, &aOut->advancedLayers()); |
376 | 0 |
|
377 | | #if defined(XP_WIN) |
378 | | if (DeviceManagerDx* dm = DeviceManagerDx::Get()) { |
379 | | D3D11DeviceStatus deviceStatus; |
380 | | dm->ExportDeviceInfo(&deviceStatus); |
381 | | aOut->gpuDevice() = deviceStatus; |
382 | | } |
383 | | #else |
384 | | aOut->gpuDevice() = null_t(); |
385 | 0 | #endif |
386 | 0 |
|
387 | 0 | return IPC_OK(); |
388 | 0 | } |
389 | | |
390 | | mozilla::ipc::IPCResult |
391 | | GPUParent::RecvSimulateDeviceReset(GPUDeviceData* aOut) |
392 | 0 | { |
393 | | #if defined(XP_WIN) |
394 | | DeviceManagerDx::Get()->ForceDeviceReset(ForcedDeviceResetReason::COMPOSITOR_UPDATED); |
395 | | DeviceManagerDx::Get()->MaybeResetAndReacquireDevices(); |
396 | | if (gfxVars::UseWebRender()) { |
397 | | wr::RenderThread::Get()->SimulateDeviceReset(); |
398 | | } |
399 | | #endif |
400 | | RecvGetDeviceStatus(aOut); |
401 | 0 | return IPC_OK(); |
402 | 0 | } |
403 | | |
404 | | mozilla::ipc::IPCResult |
405 | | GPUParent::RecvNewContentCompositorManager(Endpoint<PCompositorManagerParent>&& aEndpoint) |
406 | 0 | { |
407 | 0 | CompositorManagerParent::Create(std::move(aEndpoint)); |
408 | 0 | return IPC_OK(); |
409 | 0 | } |
410 | | |
411 | | mozilla::ipc::IPCResult |
412 | | GPUParent::RecvNewContentImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) |
413 | 0 | { |
414 | 0 | if (!ImageBridgeParent::CreateForContent(std::move(aEndpoint))) { |
415 | 0 | return IPC_FAIL_NO_REASON(this); |
416 | 0 | } |
417 | 0 | return IPC_OK(); |
418 | 0 | } |
419 | | |
420 | | mozilla::ipc::IPCResult |
421 | | GPUParent::RecvNewContentVRManager(Endpoint<PVRManagerParent>&& aEndpoint) |
422 | 0 | { |
423 | 0 | if (!VRManagerParent::CreateForContent(std::move(aEndpoint))) { |
424 | 0 | return IPC_FAIL_NO_REASON(this); |
425 | 0 | } |
426 | 0 | return IPC_OK(); |
427 | 0 | } |
428 | | |
429 | | mozilla::ipc::IPCResult |
430 | | GPUParent::RecvNewContentVideoDecoderManager(Endpoint<PVideoDecoderManagerParent>&& aEndpoint) |
431 | 0 | { |
432 | 0 | if (!dom::VideoDecoderManagerParent::CreateForContent(std::move(aEndpoint))) { |
433 | 0 | return IPC_FAIL_NO_REASON(this); |
434 | 0 | } |
435 | 0 | return IPC_OK(); |
436 | 0 | } |
437 | | |
438 | | mozilla::ipc::IPCResult |
439 | | GPUParent::RecvAddLayerTreeIdMapping(const LayerTreeIdMapping& aMapping) |
440 | 0 | { |
441 | 0 | LayerTreeOwnerTracker::Get()->Map(aMapping.layersId(), aMapping.ownerId()); |
442 | 0 | return IPC_OK(); |
443 | 0 | } |
444 | | |
445 | | mozilla::ipc::IPCResult |
446 | | GPUParent::RecvRemoveLayerTreeIdMapping(const LayerTreeIdMapping& aMapping) |
447 | 0 | { |
448 | 0 | LayerTreeOwnerTracker::Get()->Unmap(aMapping.layersId(), aMapping.ownerId()); |
449 | 0 | CompositorBridgeParent::DeallocateLayerTreeId(aMapping.layersId()); |
450 | 0 | return IPC_OK(); |
451 | 0 | } |
452 | | |
453 | | mozilla::ipc::IPCResult |
454 | | GPUParent::RecvNotifyGpuObservers(const nsCString& aTopic) |
455 | 0 | { |
456 | 0 | nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService(); |
457 | 0 | MOZ_ASSERT(obsSvc); |
458 | 0 | if (obsSvc) { |
459 | 0 | obsSvc->NotifyObservers(nullptr, aTopic.get(), nullptr); |
460 | 0 | } |
461 | 0 | return IPC_OK(); |
462 | 0 | } |
463 | | |
464 | | /* static */ void |
465 | | GPUParent::GetGPUProcessName(nsACString& aStr) |
466 | 0 | { |
467 | 0 | auto processType = XRE_GetProcessType(); |
468 | 0 | unsigned pid = 0; |
469 | 0 | if (processType == GeckoProcessType_GPU) { |
470 | 0 | pid = getpid(); |
471 | 0 | } else { |
472 | 0 | MOZ_DIAGNOSTIC_ASSERT(processType == GeckoProcessType_Default); |
473 | 0 | pid = GPUProcessManager::Get()->GPUProcessPid(); |
474 | 0 | } |
475 | 0 |
|
476 | 0 | nsPrintfCString processName("GPU (pid %u)", pid); |
477 | 0 | aStr.Assign(processName); |
478 | 0 | } |
479 | | |
480 | | mozilla::ipc::IPCResult |
481 | | GPUParent::RecvRequestMemoryReport(const uint32_t& aGeneration, |
482 | | const bool& aAnonymize, |
483 | | const bool& aMinimizeMemoryUsage, |
484 | | const MaybeFileDesc& aDMDFile) |
485 | 0 | { |
486 | 0 | nsAutoCString processName; |
487 | 0 | GetGPUProcessName(processName); |
488 | 0 |
|
489 | 0 | mozilla::dom::MemoryReportRequestClient::Start( |
490 | 0 | aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName); |
491 | 0 | return IPC_OK(); |
492 | 0 | } |
493 | | |
494 | | mozilla::ipc::IPCResult |
495 | | GPUParent::RecvShutdownVR() |
496 | 0 | { |
497 | 0 | if (gfxPrefs::VRProcessEnabled()) { |
498 | 0 | VRGPUChild::ShutDown(); |
499 | 0 | } |
500 | 0 | return IPC_OK(); |
501 | 0 | } |
502 | | |
503 | | void |
504 | | GPUParent::ActorDestroy(ActorDestroyReason aWhy) |
505 | 0 | { |
506 | 0 | if (AbnormalShutdown == aWhy) { |
507 | 0 | NS_WARNING("Shutting down GPU process early due to a crash!"); |
508 | 0 | ProcessChild::QuickExit(); |
509 | 0 | } |
510 | 0 |
|
511 | | #ifdef XP_WIN |
512 | | wmf::MFShutdown(); |
513 | | #endif |
514 | |
|
515 | 0 | #ifndef NS_FREE_PERMANENT_DATA |
516 | 0 | // No point in going through XPCOM shutdown because we don't keep persistent |
517 | 0 | // state. |
518 | 0 | ProcessChild::QuickExit(); |
519 | 0 | #endif |
520 | 0 |
|
521 | 0 | #ifdef MOZ_GECKO_PROFILER |
522 | 0 | if (mProfilerController) { |
523 | 0 | mProfilerController->Shutdown(); |
524 | 0 | mProfilerController = nullptr; |
525 | 0 | } |
526 | 0 | #endif |
527 | 0 |
|
528 | 0 | if (mVsyncBridge) { |
529 | 0 | mVsyncBridge->Shutdown(); |
530 | 0 | mVsyncBridge = nullptr; |
531 | 0 | } |
532 | 0 | dom::VideoDecoderManagerParent::ShutdownVideoBridge(); |
533 | 0 | CompositorThreadHolder::Shutdown(); |
534 | 0 | VRListenerThreadHolder::Shutdown(); |
535 | 0 | // There is a case that RenderThread exists when gfxVars::UseWebRender() is false. |
536 | 0 | // This could happen when WebRender was fallbacked to compositor. |
537 | 0 | if (wr::RenderThread::Get()) { |
538 | 0 | wr::RenderThread::ShutDown(); |
539 | 0 | } |
540 | 0 |
|
541 | 0 | // Shut down the default GL context provider. |
542 | 0 | gl::GLContextProvider::Shutdown(); |
543 | 0 |
|
544 | | #if defined(XP_WIN) |
545 | | // The above shutdown calls operate on the available context providers on |
546 | | // most platforms. Windows is a "special snowflake", though, and has three |
547 | | // context providers available, so we have to shut all of them down. |
548 | | // We should only support the default GL provider on Windows; then, this |
549 | | // could go away. Unfortunately, we currently support WGL (the default) for |
550 | | // WebGL on Optimus. |
551 | | gl::GLContextProviderEGL::Shutdown(); |
552 | | #endif |
553 | |
|
554 | 0 | Factory::ShutDown(); |
555 | | #if defined(XP_WIN) |
556 | | DeviceManagerDx::Shutdown(); |
557 | | #endif |
558 | | LayerTreeOwnerTracker::Shutdown(); |
559 | 0 | gfxVars::Shutdown(); |
560 | 0 | gfxConfig::Shutdown(); |
561 | 0 | gfxPrefs::DestroySingleton(); |
562 | 0 | CrashReporterClient::DestroySingleton(); |
563 | 0 | XRE_ShutdownChildProcess(); |
564 | 0 | } |
565 | | |
566 | | } // namespace gfx |
567 | | } // namespace mozilla |