commit ece8a53a9215ad108c3ad2711091cfd01e8a8fb9
parent 9bb68e9509ebbd91f0b46e7173f33dad42a9bff1
Author: Andrew Osmond <aosmond@gmail.com>
Date: Tue, 4 Nov 2025 16:05:01 +0000
Bug 1997848 - Fallback from acceleration for compositor session creation errors. r=gfx-reviewers,lsalzman
Simulating device resets for parent process compositing is problematic
because we need to dispatch to handle device resets, but the compositor
session creation never lets go of the main thread to allow those events
to be processed.
In reality most platforms have a GPU process now, and if we disable the
GPU process, we use Software WebRender, for which a simulated device
reset is unlikely to help anyways. The only exception is on Linux, but
it is not that common to fail to create a compositor, so it is probably
okay to fall back to Software WebRender right away.
Similarly, killing the GPU process is also a problem for the same
reason. We need to clean up inline, and there are some reentrancy
concerns. Once we investigate those, we can land a later patch to
re-enable this for the compositor session path.
Differential Revision: https://phabricator.services.mozilla.com/D271214
Diffstat:
2 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/gfx/ipc/GPUProcessManager.cpp b/gfx/ipc/GPUProcessManager.cpp
@@ -106,7 +106,6 @@ GPUProcessManager::GPUProcessManager()
mAppInForeground(true),
mProcess(nullptr),
mProcessToken(0),
- mProcessStable(true),
mGPUChild(nullptr) {
MOZ_COUNT_CTOR(GPUProcessManager);
@@ -714,24 +713,9 @@ bool GPUProcessManager::FallbackFromAcceleration(wr::WebRenderError aError,
}
}
-bool GPUProcessManager::DisableWebRenderConfig(wr::WebRenderError aError,
+void GPUProcessManager::DisableWebRenderConfig(wr::WebRenderError aError,
const nsCString& aMsg) {
- // If we have a stable compositor process, this may just be due to an OOM or
- // bad driver state. In that case, we should consider restarting the GPU
- // process, or simulating a device reset to teardown the compositors to
- // hopefully alleviate the situation.
- if (IsProcessStable(TimeStamp::Now()) || (kIsAndroid && !mAppInForeground)) {
- if (mProcess) {
- mProcess->KillProcess(/* aGenerateMinidump */ false);
- } else {
- SimulateDeviceReset();
- }
-
- mLastError = Some(aError);
- mLastErrorMsg = Some(aMsg);
- return false;
- }
-
+ // Clear out any cached errors from a remote device reset.
mLastError.reset();
mLastErrorMsg.reset();
@@ -755,20 +739,17 @@ bool GPUProcessManager::DisableWebRenderConfig(wr::WebRenderError aError,
mUnstableProcessAttempts = 1;
mGPUChild->EnsureGPUReady(/* aForceSync */ true);
}
-
- return true;
}
void GPUProcessManager::DisableWebRender(wr::WebRenderError aError,
const nsCString& aMsg) {
- if (DisableWebRenderConfig(aError, aMsg)) {
- if (mProcess) {
- DestroyRemoteCompositorSessions();
- } else {
- DestroyInProcessCompositorSessions();
- }
- NotifyListenersOnCompositeDeviceReset();
+ DisableWebRenderConfig(aError, aMsg);
+ if (mProcess) {
+ DestroyRemoteCompositorSessions();
+ } else {
+ DestroyInProcessCompositorSessions();
}
+ NotifyListenersOnCompositeDeviceReset();
}
void GPUProcessManager::NotifyWebRenderError(wr::WebRenderError aError) {
@@ -797,7 +778,18 @@ void GPUProcessManager::NotifyWebRenderError(wr::WebRenderError aError) {
}
#endif
- DisableWebRender(aError, nsCString());
+ // If we have a stable GPU process, this may just be due to an OOM or bad
+ // driver state. In that case, we should consider restarting the GPU process
+ // to hopefully alleviate the situation.
+ if (mProcess && (IsProcessStable(TimeStamp::Now()) ||
+ (kIsAndroid && !mAppInForeground))) {
+ mProcess->KillProcess(/* aGenerateMinidump */ false);
+ mLastError = Some(aError);
+ mLastErrorMsg = Some(""_ns);
+ return;
+ }
+
+ DisableWebRender(aError, ""_ns);
}
/* static */
@@ -897,10 +889,19 @@ void GPUProcessManager::OnRemoteProcessDeviceReset(
gfxCriticalNote << "Detect DeviceReset " << aReason << " " << aPlace
<< " in GPU process";
- if (OnDeviceReset(/* aTrackThreshold */ true) &&
- !DisableWebRenderConfig(wr::WebRenderError::EXCESSIVE_RESETS,
- nsCString())) {
- return;
+ if (OnDeviceReset(/* aTrackThreshold */ true)) {
+ // If we have a stable GPU process, this may just be due to an OOM or bad
+ // driver state. In that case, we should consider restarting the GPU process
+ // to hopefully alleviate the situation.
+ if (mProcess && (IsProcessStable(TimeStamp::Now()) ||
+ (kIsAndroid && !mAppInForeground))) {
+ mProcess->KillProcess(/* aGenerateMinidump */ false);
+ mLastError = Some(wr::WebRenderError::EXCESSIVE_RESETS);
+ mLastErrorMsg = Some(""_ns);
+ return;
+ }
+
+ DisableWebRenderConfig(wr::WebRenderError::EXCESSIVE_RESETS, ""_ns);
}
DestroyRemoteCompositorSessions();
diff --git a/gfx/ipc/GPUProcessManager.h b/gfx/ipc/GPUProcessManager.h
@@ -284,8 +284,7 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
// acceleration.
bool OnDeviceReset(bool aTrackThreshold);
- // Returns true if WebRender was enabled and is now disabled.
- bool DisableWebRenderConfig(wr::WebRenderError aError, const nsCString& aMsg);
+ void DisableWebRenderConfig(wr::WebRenderError aError, const nsCString& aMsg);
void FallbackToSoftware(const char* aMessage);
@@ -407,7 +406,7 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
// Fields that are associated with the current GPU process.
GPUProcessHost* mProcess;
uint64_t mProcessToken;
- bool mProcessStable;
+ bool mProcessStable = false;
bool mProcessStableOnce = false;
Maybe<wr::WebRenderError> mLastError;
Maybe<nsCString> mLastErrorMsg;