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/. */
9 # include "WMFDecoderModule.h"
11 #include "GLContextProvider.h"
12 #include "GPUParent.h"
13 #include "GPUProcessHost.h"
14 #include "GPUProcessManager.h"
15 #include "gfxGradientCache.h"
16 #include "GfxInfoBase.h"
17 #include "VRGPUChild.h"
18 #include "VRManager.h"
19 #include "VRManagerParent.h"
20 #include "VsyncBridgeParent.h"
22 #include "gfxConfig.h"
23 #include "gfxCrashReporterUtils.h"
24 #include "gfxPlatform.h"
25 #include "mozilla/Assertions.h"
26 #include "mozilla/Components.h"
27 #include "mozilla/FOGIPC.h"
28 #include "mozilla/HangDetails.h"
29 #include "mozilla/PerfStats.h"
30 #include "mozilla/Preferences.h"
31 #include "mozilla/ProcessPriorityManager.h"
32 #include "mozilla/RemoteDecoderManagerChild.h"
33 #include "mozilla/RemoteDecoderManagerParent.h"
34 #include "mozilla/ScopeExit.h"
35 #include "mozilla/StaticPrefs_dom.h"
36 #include "mozilla/StaticPrefs_media.h"
37 #include "mozilla/Telemetry.h"
38 #include "mozilla/TimeStamp.h"
39 #include "mozilla/dom/MemoryReportRequest.h"
40 #include "mozilla/gfx/2D.h"
41 #include "mozilla/gfx/CanvasRenderThread.h"
42 #include "mozilla/gfx/gfxVars.h"
43 #include "mozilla/glean/GleanMetrics.h"
44 #include "mozilla/image/ImageMemoryReporter.h"
45 #include "mozilla/ipc/CrashReporterClient.h"
46 #include "mozilla/ipc/ProcessChild.h"
47 #include "mozilla/ipc/ProcessUtils.h"
48 #include "mozilla/layers/APZInputBridgeParent.h"
49 #include "mozilla/layers/APZPublicUtils.h" // for apz::InitializeGlobalState
50 #include "mozilla/layers/APZThreadUtils.h"
51 #include "mozilla/layers/CompositorBridgeParent.h"
52 #include "mozilla/layers/CompositorManagerParent.h"
53 #include "mozilla/layers/CompositorThread.h"
54 #include "mozilla/layers/ImageBridgeParent.h"
55 #include "mozilla/layers/LayerTreeOwnerTracker.h"
56 #include "mozilla/layers/RemoteTextureMap.h"
57 #include "mozilla/layers/UiCompositorControllerParent.h"
58 #include "mozilla/layers/VideoBridgeParent.h"
59 #include "mozilla/webrender/RenderThread.h"
60 #include "mozilla/webrender/WebRenderAPI.h"
61 #include "nsDebugImpl.h"
62 #include "nsIGfxInfo.h"
63 #include "nsIXULRuntime.h"
64 #include "nsThreadManager.h"
67 #include "skia/include/core/SkGraphics.h"
73 # include "gfxDWriteFonts.h"
74 # include "gfxWindowsPlatform.h"
75 # include "mozilla/WindowsVersion.h"
76 # include "mozilla/gfx/DeviceManagerDx.h"
77 # include "mozilla/layers/GpuProcessD3D11TextureMap.h"
78 # include "mozilla/layers/GpuProcessD3D11QueryMap.h"
79 # include "mozilla/layers/TextureD3D11.h"
80 # include "mozilla/widget/WinCompositorWindowThread.h"
81 # include "MediaCodecsSupport.h"
82 # include "WMFDecoderModule.h"
89 # include "skia/include/ports/SkTypeface_cairo.h"
92 # include "mozilla/layers/AndroidHardwareBuffer.h"
93 # include "skia/include/ports/SkTypeface_cairo.h"
95 #include "ChildProfilerController.h"
96 #include "nsAppRunner.h"
98 #if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
99 # include "mozilla/SandboxTestingChild.h"
102 namespace mozilla::gfx
{
105 using namespace layers
;
107 static GPUParent
* sGPUParent
;
109 static void ReportHardwareMediaCodecSupportIfNeeded() {
110 // We only need to report the result once.
111 static bool sReported
= false;
116 NS_GetCurrentThread()->Dispatch(NS_NewRunnableFunction(
117 "GPUParent:ReportHardwareMediaCodecSupportIfNeeded", []() {
118 // Only report telemetry when hardware decoding is available.
119 if (!gfx::gfxVars::IsInitialized() ||
120 !gfx::gfxVars::CanUseHardwareVideoDecoding()) {
125 // TODO : we can remove this after HEVC is enabled by default.
126 // HEVC is not enabled. We need to force to enable it in order to know
127 // its support as well, and it would be turn off later.
128 if (StaticPrefs::media_wmf_hevc_enabled() != 1) {
129 WMFDecoderModule::Init(WMFDecoderModule::Config::ForceEnableHEVC
);
131 const auto support
= PDMFactory::Supported(true /* force refresh */);
132 if (support
.contains(
133 mozilla::media::MediaCodecsSupport::H264HardwareDecode
)) {
134 Telemetry::ScalarSet(
135 Telemetry::ScalarID::MEDIA_DEVICE_HARDWARE_DECODING_SUPPORT
,
138 if (support
.contains(
139 mozilla::media::MediaCodecsSupport::VP8HardwareDecode
)) {
140 Telemetry::ScalarSet(
141 Telemetry::ScalarID::MEDIA_DEVICE_HARDWARE_DECODING_SUPPORT
,
144 if (support
.contains(
145 mozilla::media::MediaCodecsSupport::VP9HardwareDecode
)) {
146 Telemetry::ScalarSet(
147 Telemetry::ScalarID::MEDIA_DEVICE_HARDWARE_DECODING_SUPPORT
,
150 if (support
.contains(
151 mozilla::media::MediaCodecsSupport::AV1HardwareDecode
)) {
152 Telemetry::ScalarSet(
153 Telemetry::ScalarID::MEDIA_DEVICE_HARDWARE_DECODING_SUPPORT
,
156 if (support
.contains(
157 mozilla::media::MediaCodecsSupport::HEVCHardwareDecode
)) {
158 Telemetry::ScalarSet(
159 Telemetry::ScalarID::MEDIA_DEVICE_HARDWARE_DECODING_SUPPORT
,
162 if (StaticPrefs::media_wmf_hevc_enabled() != 1) {
163 WMFDecoderModule::Init();
167 // TODO : in the future, when we have GPU procss on MacOS, then we can report
168 // HEVC usage as well.
171 GPUParent::GPUParent() : mLaunchTime(TimeStamp::Now()) { sGPUParent
= this; }
173 GPUParent::~GPUParent() { sGPUParent
= nullptr; }
176 GPUParent
* GPUParent::GetSingleton() {
177 MOZ_DIAGNOSTIC_ASSERT(sGPUParent
);
181 /* static */ bool GPUParent::MaybeFlushMemory() {
182 #if defined(XP_WIN) && !defined(HAVE_64BIT_BUILD)
183 MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
184 if (!XRE_IsGPUProcess()) {
189 stat
.dwLength
= sizeof(stat
);
190 if (!GlobalMemoryStatusEx(&stat
)) {
194 // We only care about virtual process memory space in the GPU process because
195 // the UI process is already watching total memory usage.
196 static const size_t kLowVirtualMemoryThreshold
= 384 * 1024 * 1024;
197 bool lowMemory
= stat
.ullAvailVirtual
< kLowVirtualMemoryThreshold
;
199 // We suppress more than one low memory notification until we exit the
200 // condition. The UI process goes through more effort, reporting on-going
201 // memory pressure, but rather than try to manage a shared state, we just
202 // send one notification here to try to resolve it.
203 static bool sLowMemory
= false;
204 if (lowMemory
&& !sLowMemory
) {
205 NS_DispatchToMainThread(
206 NS_NewRunnableFunction("gfx::GPUParent::FlushMemory", []() -> void {
207 Unused
<< GPUParent::GetSingleton()->SendFlushMemory(
211 sLowMemory
= lowMemory
;
218 bool GPUParent::Init(mozilla::ipc::UntypedEndpoint
&& aEndpoint
,
219 const char* aParentBuildID
) {
220 // Initialize the thread manager before starting IPC. Otherwise, messages
221 // may be posted to the main thread and we won't be able to process them.
222 if (NS_WARN_IF(NS_FAILED(nsThreadManager::get().Init()))) {
226 // Now it's safe to start IPC.
227 if (NS_WARN_IF(!aEndpoint
.Bind(this))) {
231 nsDebugImpl::SetMultiprocessMode("GPU");
233 // This must be checked before any IPDL message, which may hit sentinel
234 // errors due to parent and content processes having different
236 MessageChannel
* channel
= GetIPCChannel();
237 if (channel
&& !channel
->SendBuildIDsMatchMessage(aParentBuildID
)) {
238 // We need to quit this process if the buildID doesn't match the parent's.
239 // This can occur when an update occurred in the background.
240 ProcessChild::QuickExit();
243 if (NS_FAILED(NS_InitMinimalXPCOM())) {
247 // Ensure the observer service exists.
248 ProcessPriorityManager::Init();
250 // Init crash reporter support.
251 CrashReporterClient::InitSingleton(this);
254 gfxVars::Initialize();
255 gfxPlatform::InitNullMetadata();
256 // Ensure our Factory is initialised, mainly for gfx logging to work.
257 gfxPlatform::InitMoz2DLogging();
259 gfxWindowsPlatform::InitMemoryReportersForGPUProcess();
260 DeviceManagerDx::Init();
261 GpuProcessD3D11TextureMap::Init();
262 GpuProcessD3D11QueryMap::Init();
265 CompositorThreadHolder::Start();
266 RemoteTextureMap::Init();
267 APZThreadUtils::SetControllerThread(NS_GetCurrentThread());
268 apz::InitializeGlobalState();
269 LayerTreeOwnerTracker::Initialize();
270 CompositorBridgeParent::InitializeStatics();
271 mozilla::ipc::SetThisProcessName("GPU Process");
276 void GPUParent::NotifyDeviceReset() {
277 if (!NS_IsMainThread()) {
278 NS_DispatchToMainThread(NS_NewRunnableFunction(
279 "gfx::GPUParent::NotifyDeviceReset",
280 []() -> void { GPUParent::GetSingleton()->NotifyDeviceReset(); }));
284 // Reset and reinitialize the compositor devices
286 if (!DeviceManagerDx::Get()->MaybeResetAndReacquireDevices()) {
287 // If the device doesn't need to be reset then the device
288 // has already been reset by a previous NotifyDeviceReset message.
293 // Notify the main process that there's been a device reset
294 // and that they should reset their compositors and repaint
296 RecvGetDeviceStatus(&data
);
297 Unused
<< SendNotifyDeviceReset(data
);
300 void GPUParent::NotifyOverlayInfo(layers::OverlayInfo aInfo
) {
301 if (!NS_IsMainThread()) {
302 NS_DispatchToMainThread(NS_NewRunnableFunction(
303 "gfx::GPUParent::NotifyOverlayInfo", [aInfo
]() -> void {
304 GPUParent::GetSingleton()->NotifyOverlayInfo(aInfo
);
308 Unused
<< SendNotifyOverlayInfo(aInfo
);
311 void GPUParent::NotifySwapChainInfo(layers::SwapChainInfo aInfo
) {
312 if (!NS_IsMainThread()) {
313 NS_DispatchToMainThread(NS_NewRunnableFunction(
314 "gfx::GPUParent::NotifySwapChainInfo", [aInfo
]() -> void {
315 GPUParent::GetSingleton()->NotifySwapChainInfo(aInfo
);
319 Unused
<< SendNotifySwapChainInfo(aInfo
);
322 void GPUParent::NotifyDisableRemoteCanvas() {
323 if (!NS_IsMainThread()) {
324 NS_DispatchToMainThread(NS_NewRunnableFunction(
325 "gfx::GPUParent::NotifyDisableRemoteCanvas", []() -> void {
326 GPUParent::GetSingleton()->NotifyDisableRemoteCanvas();
330 Unused
<< SendNotifyDisableRemoteCanvas();
333 mozilla::ipc::IPCResult
GPUParent::RecvInit(
334 nsTArray
<GfxVarUpdate
>&& vars
, const DevicePrefs
& devicePrefs
,
335 nsTArray
<LayerTreeIdMapping
>&& aMappings
,
336 nsTArray
<GfxInfoFeatureStatus
>&& aFeatures
, uint32_t aWrNamespace
) {
337 for (const auto& var
: vars
) {
338 gfxVars::ApplyUpdate(var
);
341 // Inherit device preferences.
342 gfxConfig::Inherit(Feature::HW_COMPOSITING
, devicePrefs
.hwCompositing());
343 gfxConfig::Inherit(Feature::D3D11_COMPOSITING
,
344 devicePrefs
.d3d11Compositing());
345 gfxConfig::Inherit(Feature::OPENGL_COMPOSITING
, devicePrefs
.oglCompositing());
346 gfxConfig::Inherit(Feature::DIRECT2D
, devicePrefs
.useD2D1());
347 gfxConfig::Inherit(Feature::D3D11_HW_ANGLE
, devicePrefs
.d3d11HwAngle());
349 { // Let the crash reporter know if we've got WR enabled or not. For other
350 // processes this happens in gfxPlatform::InitWebRenderConfig.
351 ScopedGfxFeatureReporter
reporter("WR",
352 gfxPlatform::WebRenderPrefEnabled());
353 reporter
.SetSuccessful();
356 for (const LayerTreeIdMapping
& map
: aMappings
) {
357 LayerTreeOwnerTracker::Get()->Map(map
.layersId(), map
.ownerId());
360 widget::GfxInfoBase::SetFeatureStatus(std::move(aFeatures
));
362 // We bypass gfxPlatform::Init, so we must initialize any relevant libraries
363 // here that would normally be initialized there.
366 bool useRemoteCanvas
=
367 gfxVars::RemoteCanvasEnabled() || gfxVars::UseAcceleratedCanvas2D();
368 if (useRemoteCanvas
) {
369 gfxGradientCache::Init();
373 if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING
)) {
374 if (DeviceManagerDx::Get()->CreateCompositorDevices() && useRemoteCanvas
) {
375 if (DeviceManagerDx::Get()->CreateCanvasDevice()) {
376 gfxDWriteFont::InitDWriteSupport();
378 gfxWarning() << "Failed to create canvas device.";
382 DeviceManagerDx::Get()->CreateDirectCompositionDevice();
383 // Ensure to initialize GfxInfo
384 nsCOMPtr
<nsIGfxInfo
> gfxInfo
= components::GfxInfo::Service();
387 Factory::EnsureDWriteFactory();
390 #if defined(MOZ_WIDGET_GTK)
391 char* display_name
= PR_GetEnv("MOZ_GDK_DISPLAY");
393 bool waylandEnabled
= false;
395 waylandEnabled
= IsWaylandEnabled();
397 if (!waylandEnabled
) {
398 display_name
= PR_GetEnv("DISPLAY");
403 char option_name
[] = "--display";
404 char* argv
[] = {// argv0 is unused because g_set_prgname() was called in
405 // XRE_InitChildProcess().
406 nullptr, option_name
, display_name
, nullptr};
408 gtk_init(&argc
, &argvp
);
410 gtk_init(nullptr, nullptr);
413 // Ensure we have an FT library for font instantiation.
414 // This would normally be set by gfxPlatform::Init().
415 // Since we bypass that, we must do it here instead.
416 FT_Library library
= Factory::NewFTLibrary();
418 Factory::SetFTLibrary(library
);
420 // true to match gfxPlatform::FontHintingEnabled(). We must hardcode
421 // this value because we do not have a gfxPlatform instance.
424 // Ensure that GfxInfo::Init is called on the main thread.
425 nsCOMPtr
<nsIGfxInfo
> gfxInfo
= components::GfxInfo::Service();
430 // Ensure we have an FT library for font instantiation.
431 // This would normally be set by gfxPlatform::Init().
432 // Since we bypass that, we must do it here instead.
433 FT_Library library
= Factory::NewFTLibrary();
435 Factory::SetFTLibrary(library
);
437 // false to match gfxAndroidPlatform::FontHintingEnabled(). We must
438 // hardcode this value because we do not have a gfxPlatform instance.
439 SkInitCairoFT(false);
441 if (gfxVars::UseAHardwareBufferSharedSurfaceWebglOop()) {
442 layers::AndroidHardwareBufferApi::Init();
443 layers::AndroidHardwareBufferManager::Init();
448 // Make sure to do this *after* we update gfxVars above.
449 wr::RenderThread::Start(aWrNamespace
);
450 gfx::CanvasRenderThread::Start();
451 image::ImageMemoryReporter::InitForWebRender();
453 VRManager::ManagerInit();
454 // Send a message to the UI process that we're done.
456 RecvGetDeviceStatus(&data
);
457 Unused
<< SendInitComplete(data
);
459 // Dispatch a task to run when idle that will determine which codecs are
460 // usable. The primary goal is to determine if the media feature pack is
462 MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThreadQueue(
463 NS_NewRunnableFunction(
464 "GPUParent::Supported",
466 auto supported
= PDMFactory::Supported();
467 Unused
<< GPUParent::GetSingleton()->SendUpdateMediaCodecsSupported(
469 ReportHardwareMediaCodecSupportIfNeeded();
471 2000 /* 2 seconds timeout */, EventQueuePriority::Idle
));
473 Telemetry::AccumulateTimeDelta(Telemetry::GPU_PROCESS_INITIALIZATION_TIME_MS
,
478 #if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
479 mozilla::ipc::IPCResult
GPUParent::RecvInitSandboxTesting(
480 Endpoint
<PSandboxTestingChild
>&& aEndpoint
) {
481 if (!SandboxTestingChild::Initialize(std::move(aEndpoint
))) {
483 this, "InitSandboxTesting failed to initialise the child process.");
489 mozilla::ipc::IPCResult
GPUParent::RecvInitCompositorManager(
490 Endpoint
<PCompositorManagerParent
>&& aEndpoint
, uint32_t aNamespace
) {
491 CompositorManagerParent::Create(std::move(aEndpoint
), ContentParentId(),
492 aNamespace
, /* aIsRoot */ true);
496 mozilla::ipc::IPCResult
GPUParent::RecvInitVsyncBridge(
497 Endpoint
<PVsyncBridgeParent
>&& aVsyncEndpoint
) {
498 mVsyncBridge
= VsyncBridgeParent::Start(std::move(aVsyncEndpoint
));
502 mozilla::ipc::IPCResult
GPUParent::RecvInitImageBridge(
503 Endpoint
<PImageBridgeParent
>&& aEndpoint
) {
504 ImageBridgeParent::CreateForGPUProcess(std::move(aEndpoint
));
508 mozilla::ipc::IPCResult
GPUParent::RecvInitVideoBridge(
509 Endpoint
<PVideoBridgeParent
>&& aEndpoint
,
510 const layers::VideoBridgeSource
& aSource
) {
511 // For GPU decoding, the video bridge would be opened in
512 // `VideoBridgeChild::StartupForGPUProcess`.
513 MOZ_ASSERT(aSource
== layers::VideoBridgeSource::RddProcess
||
514 aSource
== layers::VideoBridgeSource::MFMediaEngineCDMProcess
);
515 VideoBridgeParent::Open(std::move(aEndpoint
), aSource
);
519 mozilla::ipc::IPCResult
GPUParent::RecvInitVRManager(
520 Endpoint
<PVRManagerParent
>&& aEndpoint
) {
521 VRManagerParent::CreateForGPUProcess(std::move(aEndpoint
));
525 mozilla::ipc::IPCResult
GPUParent::RecvInitVR(
526 Endpoint
<PVRGPUChild
>&& aEndpoint
) {
527 gfx::VRGPUChild::InitForGPUProcess(std::move(aEndpoint
));
531 mozilla::ipc::IPCResult
GPUParent::RecvInitUiCompositorController(
532 const LayersId
& aRootLayerTreeId
,
533 Endpoint
<PUiCompositorControllerParent
>&& aEndpoint
) {
534 UiCompositorControllerParent::Start(aRootLayerTreeId
, std::move(aEndpoint
));
538 mozilla::ipc::IPCResult
GPUParent::RecvInitAPZInputBridge(
539 const LayersId
& aRootLayerTreeId
,
540 Endpoint
<PAPZInputBridgeParent
>&& aEndpoint
) {
541 APZInputBridgeParent::Create(aRootLayerTreeId
, std::move(aEndpoint
));
545 mozilla::ipc::IPCResult
GPUParent::RecvInitProfiler(
546 Endpoint
<PProfilerChild
>&& aEndpoint
) {
547 mProfilerController
= ChildProfilerController::Create(std::move(aEndpoint
));
551 mozilla::ipc::IPCResult
GPUParent::RecvUpdateVar(const GfxVarUpdate
& aUpdate
) {
553 auto scopeExit
= MakeScopeExit(
554 [couldUseHWDecoder
= gfx::gfxVars::CanUseHardwareVideoDecoding()] {
555 if (couldUseHWDecoder
!= gfx::gfxVars::CanUseHardwareVideoDecoding()) {
556 // The capabilities of the system may have changed, force a refresh by
557 // re-initializing the WMF PDM.
558 WMFDecoderModule::Init();
559 Unused
<< GPUParent::GetSingleton()->SendUpdateMediaCodecsSupported(
560 PDMFactory::Supported(true /* force refresh */));
561 ReportHardwareMediaCodecSupportIfNeeded();
565 gfxVars::ApplyUpdate(aUpdate
);
569 mozilla::ipc::IPCResult
GPUParent::RecvPreferenceUpdate(const Pref
& aPref
) {
570 Preferences::SetPreference(aPref
);
574 mozilla::ipc::IPCResult
GPUParent::RecvScreenInformationChanged() {
576 DeviceManagerDx::Get()->PostUpdateMonitorInfo();
581 mozilla::ipc::IPCResult
GPUParent::RecvNotifyBatteryInfo(
582 const BatteryInformation
& aBatteryInfo
) {
583 wr::RenderThread::Get()->SetBatteryInfo(aBatteryInfo
);
587 static void CopyFeatureChange(Feature aFeature
, Maybe
<FeatureFailure
>* aOut
) {
588 FeatureState
& feature
= gfxConfig::GetFeature(aFeature
);
589 if (feature
.DisabledByDefault() || feature
.IsEnabled()) {
591 // - Disabled-by-default means the parent process told us not to use this
593 // - Enabled means we were told to use this feature, and we didn't
595 // that would prevent us from doing so.
600 MOZ_ASSERT(!feature
.IsEnabled());
603 message
.AssignASCII(feature
.GetFailureMessage());
606 Some(FeatureFailure(feature
.GetValue(), message
, feature
.GetFailureId()));
609 mozilla::ipc::IPCResult
GPUParent::RecvGetDeviceStatus(GPUDeviceData
* aOut
) {
610 CopyFeatureChange(Feature::D3D11_COMPOSITING
, &aOut
->d3d11Compositing());
611 CopyFeatureChange(Feature::OPENGL_COMPOSITING
, &aOut
->oglCompositing());
614 if (DeviceManagerDx
* dm
= DeviceManagerDx::Get()) {
615 D3D11DeviceStatus deviceStatus
;
616 dm
->ExportDeviceInfo(&deviceStatus
);
617 aOut
->gpuDevice() = Some(deviceStatus
);
620 aOut
->gpuDevice() = Nothing();
626 mozilla::ipc::IPCResult
GPUParent::RecvSimulateDeviceReset() {
628 DeviceManagerDx::Get()->ForceDeviceReset(
629 ForcedDeviceResetReason::COMPOSITOR_UPDATED
);
631 wr::RenderThread::Get()->SimulateDeviceReset();
635 mozilla::ipc::IPCResult
GPUParent::RecvNewContentCompositorManager(
636 Endpoint
<PCompositorManagerParent
>&& aEndpoint
,
637 const ContentParentId
& aChildId
, uint32_t aNamespace
) {
638 CompositorManagerParent::Create(std::move(aEndpoint
), aChildId
, aNamespace
,
639 /* aIsRoot */ false);
643 mozilla::ipc::IPCResult
GPUParent::RecvNewContentImageBridge(
644 Endpoint
<PImageBridgeParent
>&& aEndpoint
, const ContentParentId
& aChildId
) {
645 if (!ImageBridgeParent::CreateForContent(std::move(aEndpoint
), aChildId
)) {
646 return IPC_FAIL_NO_REASON(this);
651 mozilla::ipc::IPCResult
GPUParent::RecvNewContentVRManager(
652 Endpoint
<PVRManagerParent
>&& aEndpoint
, const ContentParentId
& aChildId
) {
653 if (!VRManagerParent::CreateForContent(std::move(aEndpoint
), aChildId
)) {
654 return IPC_FAIL_NO_REASON(this);
659 mozilla::ipc::IPCResult
GPUParent::RecvNewContentRemoteDecoderManager(
660 Endpoint
<PRemoteDecoderManagerParent
>&& aEndpoint
,
661 const ContentParentId
& aChildId
) {
662 if (!RemoteDecoderManagerParent::CreateForContent(std::move(aEndpoint
),
664 return IPC_FAIL_NO_REASON(this);
669 mozilla::ipc::IPCResult
GPUParent::RecvAddLayerTreeIdMapping(
670 const LayerTreeIdMapping
& aMapping
) {
671 LayerTreeOwnerTracker::Get()->Map(aMapping
.layersId(), aMapping
.ownerId());
675 mozilla::ipc::IPCResult
GPUParent::RecvRemoveLayerTreeIdMapping(
676 const LayerTreeIdMapping
& aMapping
) {
677 LayerTreeOwnerTracker::Get()->Unmap(aMapping
.layersId(), aMapping
.ownerId());
678 CompositorBridgeParent::DeallocateLayerTreeId(aMapping
.layersId());
682 mozilla::ipc::IPCResult
GPUParent::RecvNotifyGpuObservers(
683 const nsCString
& aTopic
) {
684 nsCOMPtr
<nsIObserverService
> obsSvc
= mozilla::services::GetObserverService();
687 obsSvc
->NotifyObservers(nullptr, aTopic
.get(), nullptr);
693 void GPUParent::GetGPUProcessName(nsACString
& aStr
) {
694 auto processType
= XRE_GetProcessType();
696 if (processType
== GeckoProcessType_GPU
) {
699 MOZ_DIAGNOSTIC_ASSERT(processType
== GeckoProcessType_Default
);
700 pid
= GPUProcessManager::Get()->GPUProcessPid();
703 nsPrintfCString
processName("GPU (pid %u)", pid
);
704 aStr
.Assign(processName
);
707 mozilla::ipc::IPCResult
GPUParent::RecvRequestMemoryReport(
708 const uint32_t& aGeneration
, const bool& aAnonymize
,
709 const bool& aMinimizeMemoryUsage
, const Maybe
<FileDescriptor
>& aDMDFile
,
710 const RequestMemoryReportResolver
& aResolver
) {
711 nsAutoCString processName
;
712 GetGPUProcessName(processName
);
714 mozilla::dom::MemoryReportRequestClient::Start(
715 aGeneration
, aAnonymize
, aMinimizeMemoryUsage
, aDMDFile
, processName
,
716 [&](const MemoryReport
& aReport
) {
717 Unused
<< GetSingleton()->SendAddMemoryReport(aReport
);
723 mozilla::ipc::IPCResult
GPUParent::RecvShutdownVR() {
724 if (StaticPrefs::dom_vr_process_enabled_AtStartup()) {
725 VRGPUChild::Shutdown();
730 mozilla::ipc::IPCResult
GPUParent::RecvUpdatePerfStatsCollectionMask(
731 const uint64_t& aMask
) {
732 PerfStats::SetCollectionMask(static_cast<PerfStats::MetricMask
>(aMask
));
736 mozilla::ipc::IPCResult
GPUParent::RecvCollectPerfStatsJSON(
737 CollectPerfStatsJSONResolver
&& aResolver
) {
738 aResolver(PerfStats::CollectLocalPerfStatsJSON());
742 mozilla::ipc::IPCResult
GPUParent::RecvFlushFOGData(
743 FlushFOGDataResolver
&& aResolver
) {
744 glean::FlushFOGData(std::move(aResolver
));
748 mozilla::ipc::IPCResult
GPUParent::RecvTestTriggerMetrics(
749 TestTriggerMetricsResolver
&& aResolve
) {
750 mozilla::glean::test_only_ipc::a_counter
.Add(nsIXULRuntime::PROCESS_TYPE_GPU
);
755 mozilla::ipc::IPCResult
GPUParent::RecvCrashProcess() {
756 MOZ_CRASH("Deliberate GPU process crash");
760 void GPUParent::ActorDestroy(ActorDestroyReason aWhy
) {
761 if (AbnormalShutdown
== aWhy
) {
762 NS_WARNING("Shutting down GPU process early due to a crash!");
763 ProcessChild::QuickExit();
766 // Send the last bits of Glean data over to the main process.
768 [](ByteBuf
&& aBuf
) { glean::SendFOGData(std::move(aBuf
)); });
770 #ifndef NS_FREE_PERMANENT_DATA
771 // No point in going through XPCOM shutdown because we don't keep persistent
773 ProcessChild::QuickExit();
776 // Wait until all RemoteDecoderManagerParent have closed.
777 mShutdownBlockers
.WaitUntilClear(10 * 1000 /* 10s timeout*/)
778 ->Then(GetCurrentSerialEventTarget(), __func__
, [self
= RefPtr
{this}]() {
779 if (self
->mProfilerController
) {
780 self
->mProfilerController
->Shutdown();
781 self
->mProfilerController
= nullptr;
784 if (self
->mVsyncBridge
) {
785 self
->mVsyncBridge
->Shutdown();
786 self
->mVsyncBridge
= nullptr;
788 VideoBridgeParent::Shutdown();
789 // This could be running on either the Compositor thread, the Renderer
790 // thread, or the dedicated CanvasRender thread, so we need to shutdown
791 // before the former two.
792 CanvasRenderThread::Shutdown();
793 CompositorThreadHolder::Shutdown();
794 RemoteTextureMap::Shutdown();
795 // There is a case that RenderThread exists when gfxVars::UseWebRender()
796 // is false. This could happen when WebRender was fallbacked to
798 if (wr::RenderThread::Get()) {
799 wr::RenderThread::ShutDown();
802 if (widget::WinCompositorWindowThread::Get()) {
803 widget::WinCompositorWindowThread::ShutDown();
807 image::ImageMemoryReporter::ShutdownForWebRender();
809 // Shut down the default GL context provider.
810 gl::GLContextProvider::Shutdown();
813 // The above shutdown calls operate on the available context providers
814 // on most platforms. Windows is a "special snowflake", though, and has
815 // three context providers available, so we have to shut all of them
816 // down. We should only support the default GL provider on Windows;
817 // then, this could go away. Unfortunately, we currently support WGL
818 // (the default) for WebGL on Optimus.
819 gl::GLContextProviderEGL::Shutdown();
824 // We bypass gfxPlatform shutdown, so we must shutdown any libraries here
825 // that would normally be handled by it.
826 #ifdef NS_FREE_PERMANENT_DATA
827 SkGraphics::PurgeFontCache();
828 cairo_debug_reset_static_data();
832 GpuProcessD3D11QueryMap::Shutdown();
833 GpuProcessD3D11TextureMap::Shutdown();
834 DeviceManagerDx::Shutdown();
836 LayerTreeOwnerTracker::Shutdown();
838 gfxConfig::Shutdown();
839 CrashReporterClient::DestroySingleton();
840 XRE_ShutdownChildProcess();
844 } // namespace mozilla::gfx