Bug 1992856 - Disable remote canvas as the final fallback step before disabling the GPU process. a=RyanVM

Given that we would otherwise disable remote canvas when we disable the
GPU process, it is not meaningfully worse for users to just disable
remote canvas keeping the GPU process as the final step. It is still
preferable to losing the GPU process sandbox. This includes D2D canvas,
accelerated canvas and WebGPU, as well as WebGL on Android.

Original Revision: https://phabricator.services.mozilla.com/D267667

Differential Revision: https://phabricator.services.mozilla.com/D267862
This commit is contained in:
Andrew Osmond
2025-10-09 12:12:25 +00:00
committed by rvandermeulen@mozilla.com
parent 14de960c73
commit 1d31c84e92
3 changed files with 72 additions and 14 deletions

View File

@@ -3355,7 +3355,8 @@ static void AcceleratedCanvas2DPrefChangeCallback(const char*, void*) {
feature.UserForceEnable("Force-enabled by pref");
}
if (kIsAndroid && !gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {
if (!StaticPrefs::gfx_canvas_accelerated_allow_in_parent_AtStartup() &&
!gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {
feature.Disable(FeatureStatus::Blocked, "Disabled by GPU Process disabled",
"FEATURE_FAILURE_DISABLED_BY_GPU_PROCESS_DISABLED"_ns);
} else if (!gfxConfig::IsEnabled(Feature::WEBRENDER)) {
@@ -3947,6 +3948,10 @@ bool gfxPlatform::FallbackFromAcceleration(FeatureStatus aStatus,
swglFallbackAllowed && !gfxVars::UseSoftwareWebRender()) {
// Fallback from WebRender to Software WebRender.
gfxCriticalNote << "Fallback WR to SW-WR";
DisableAcceleratedCanvasForFallback(
FeatureStatus::UnavailableNoHwCompositing,
"Disabled by fallback to Software WebRender",
"FEATURE_FAILURE_DISABLED_BY_FALLBACK_SOFTWARE_WEBRENDER"_ns);
gfxVars::SetUseSoftwareWebRender(true);
return true;
}
@@ -3958,10 +3963,34 @@ bool gfxPlatform::FallbackFromAcceleration(FeatureStatus aStatus,
// otherwise get stuck with WebRender. As such, force a switch to Software
// WebRender in this case.
gfxCriticalNoteOnce << "Fallback WR to SW-WR, forced";
DisableAcceleratedCanvasForFallback(
FeatureStatus::UnavailableNoHwCompositing,
"Disabled by fallback to Software WebRender",
"FEATURE_FAILURE_DISABLED_BY_FALLBACK_SOFTWARE_WEBRENDER"_ns);
gfxVars::SetUseSoftwareWebRender(true);
return true;
}
if ((gfxVars::RemoteCanvasEnabled() &&
!StaticPrefs::dom_webgpu_allow_in_parent_AtStartup()) ||
(gfxVars::UseAcceleratedCanvas2D() &&
!StaticPrefs::gfx_canvas_accelerated_allow_in_parent_AtStartup()) ||
(gfxVars::AllowWebGPU() &&
!StaticPrefs::gfx_canvas_remote_allow_in_parent_AtStartup()) ||
(kIsAndroid && gfxVars::AllowWebglOop())) {
// Because content has a lot of control over inputs to remote canvas, we
// try to disable it as part of our final fallback step before disabling
// the GPU process. We don't actually support remote canvas in the parent
// process anyways, so this is not meaningfully worse from just
// switching directly to the parent process.
gfxCriticalNoteOnce << "Fallback SW-WR, disable remote canvas";
DisableAllCanvasForFallback(
FeatureStatus::UnavailableNoGpuProcess,
"Disabled by fallback to GPU Process disabled",
"FEATURE_FAILURE_DISABLED_BY_FALLBACK_GPU_PROCESS_DISABLED"_ns);
return true;
}
if (aCrashAfterFinalFallback) {
MOZ_CRASH("Fallback configurations exhausted");
}
@@ -3972,33 +4001,46 @@ bool gfxPlatform::FallbackFromAcceleration(FeatureStatus aStatus,
}
/* static */
void gfxPlatform::DisableGPUProcess() {
void gfxPlatform::DisableAcceleratedCanvasForFallback(
FeatureStatus aStatus, const char* aMessage, const nsACString& aFailureId) {
if (gfxVars::UseAcceleratedCanvas2D() &&
!StaticPrefs::gfx_canvas_accelerated_allow_in_parent_AtStartup()) {
gfxConfig::Disable(Feature::ACCELERATED_CANVAS2D, aStatus, aMessage,
aFailureId);
gfxVars::SetUseAcceleratedCanvas2D(false);
}
}
/* static */
void gfxPlatform::DisableAllCanvasForFallback(FeatureStatus aStatus,
const char* aMessage,
const nsACString& aFailureId) {
DisableAcceleratedCanvasForFallback(aStatus, aMessage, aFailureId);
if (gfxVars::AllowWebGPU() &&
!StaticPrefs::dom_webgpu_allow_in_parent_AtStartup()) {
gfxConfig::Disable(Feature::WEBGPU, FeatureStatus::UnavailableNoGpuProcess,
"Disabled by GPU process disabled",
"FEATURE_WEBGPU_DISABLED_BY_GPU_PROCESS_DISABLED"_ns);
gfxConfig::Disable(Feature::WEBGPU, aStatus, aMessage, aFailureId);
gfxVars::SetAllowWebGPU(false);
}
if (gfxVars::RemoteCanvasEnabled() &&
!StaticPrefs::gfx_canvas_remote_allow_in_parent_AtStartup()) {
gfxConfig::Disable(
Feature::REMOTE_CANVAS, FeatureStatus::UnavailableNoGpuProcess,
"Disabled by GPU process disabled",
"FEATURE_REMOTE_CANVAS_DISABLED_BY_GPU_PROCESS_DISABLED"_ns);
gfxConfig::Disable(Feature::REMOTE_CANVAS, aStatus, aMessage, aFailureId);
gfxVars::SetRemoteCanvasEnabled(false);
}
if (kIsAndroid) {
// On android, enable out-of-process WebGL only when GPU process exists.
gfxVars::SetAllowWebglOop(false);
// On android, enable accelerated canvas only when GPU process exists.
gfxVars::SetUseAcceleratedCanvas2D(false);
gfxConfig::Disable(Feature::ACCELERATED_CANVAS2D, FeatureStatus::Blocked,
"Disabled by GPU Process disabled",
"FEATURE_FAILURE_DISABLED_BY_GPU_PROCESS_DISABLED"_ns);
}
}
/* static */
void gfxPlatform::DisableGPUProcess() {
DisableAllCanvasForFallback(
FeatureStatus::UnavailableNoGpuProcess,
"Disabled by fallback to GPU Process disabled",
"FEATURE_FAILURE_DISABLED_BY_FALLBACK_GPU_PROCESS_DISABLED"_ns);
#if defined(XP_WIN)
CompositeProcessD3D11FencesHolderMap::Init();

View File

@@ -730,6 +730,13 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
*/
static bool PerfWarnings();
static void DisableAcceleratedCanvasForFallback(
mozilla::gfx::FeatureStatus aStatus, const char* aMessage,
const nsACString& aFailureId);
static void DisableAllCanvasForFallback(mozilla::gfx::FeatureStatus aStatus,
const char* aMessage,
const nsACString& aFailureId);
static void DisableGPUProcess();
void NotifyCompositorCreated(mozilla::layers::LayersBackend aBackend);

View File

@@ -6521,6 +6521,15 @@
#endif
mirror: always
- name: gfx.canvas.accelerated.allow-in-parent
type: bool
#if defined(XP_WIN) || defined(ANDROID)
value: false
#else
value: true
#endif
mirror: once
# Whether to attempt to enable Accelerated Canvas2D regardless of blocklisting.
- name: gfx.canvas.accelerated.force-enabled
type: bool