From a00e96e1d39ee7f0954d6a692c2494bca27e8a16 Mon Sep 17 00:00:00 2001 From: Chris Martin Date: Wed, 29 Sep 2021 15:00:19 +0000 Subject: [PATCH] Bug 1718414 - Stop canvas from initializing D3D in locked-down content process when GPU process fails r=sotaro,bobowen Before Win32k Lockdown, Canvas would ensure that it would get the fastest possible implementation by initializing devices in content process before allocating persistent buffers for its backing. However, with Win32k Lockdown it's no longer possible, as initializing Direct3D and Direct2D make Win32k calls that crash the locked-down content process. This issue is generally solved by Remote Canvas; however, Remote Canvas is disabled if the GPU process is disabled. If that happens, the current behavior is to attempt to initialize hardware acceleration again, causing a crash when Win32k Lockdown is in effect. This patch changes the behavior so that the devices will not initialize if they are in a locked-down content process, even if Remote Canvas is disabled. The effect is that Canvas will fall back to using Skia for everything. Differential Revision: https://phabricator.services.mozilla.com/D126761 --- gfx/layers/wr/WebRenderLayerManager.cpp | 13 +++++++++++-- gfx/thebes/gfxWindowsPlatform.cpp | 2 ++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index 54b4baf1de9e..1d41912188a9 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -27,6 +27,7 @@ #ifdef XP_WIN # include "gfxDWriteFonts.h" +# include "mozilla/WindowsProcessMitigations.h" #endif namespace mozilla { @@ -737,10 +738,18 @@ void WebRenderLayerManager::ScheduleComposite() { already_AddRefed WebRenderLayerManager::CreatePersistentBufferProvider( const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat) { - // Ensure devices initialization for canvas 2d if not remote. The devices are - // lazily initialized with WebRender to reduce memory usage. if (!gfxPlatform::UseRemoteCanvas()) { +#ifdef XP_WIN + // Any kind of hardware acceleration is incompatible with Win32k Lockdown + // We don't initialize devices here so that PersistentBufferProviderShared + // will fall back to using a piece of shared memory as a backing for the + // canvas + if (!IsWin32kLockedDown()) { + gfxPlatform::GetPlatform()->EnsureDevicesInitialized(); + } +#else gfxPlatform::GetPlatform()->EnsureDevicesInitialized(); +#endif } RefPtr provider = diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index a9cefe10d5e9..eed1ff38b717 100644 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -1227,6 +1227,8 @@ void gfxWindowsPlatform::RecordStartupTelemetry() { // Supports lazy device initialization on Windows, so that WebRender can avoid // initializing GPU state and allocating swap chains for most non-GPU processes. void gfxWindowsPlatform::EnsureDevicesInitialized() { + MOZ_DIAGNOSTIC_ASSERT(!IsWin32kLockedDown()); + if (!mInitializedDevices) { mInitializedDevices = true; InitializeDevices();