From 8ca63c894da60359d3030faf749481834906da59 Mon Sep 17 00:00:00 2001 From: sotaro Date: Wed, 17 Nov 2021 01:18:05 +0000 Subject: [PATCH] Bug 1740675 - Cleanup device handling around RenderThread r=nical,gfx-reviewers RenderCompositorANGLE::ShutdownEGLLibraryIfNecessary() is not necessary since Bug 1656034 fix. Device reset handling could be more platform independent. Differential Revision: https://phabricator.services.mozilla.com/D130960 --- .../RenderCompositorANGLE.cpp | 65 ++++--------------- .../RenderCompositorANGLE.h | 10 +-- .../RenderCompositorEGL.cpp | 21 +++--- gfx/webrender_bindings/RenderCompositorEGL.h | 7 +- gfx/webrender_bindings/RenderThread.cpp | 2 + gfx/webrender_bindings/RendererOGL.cpp | 1 - 6 files changed, 35 insertions(+), 71 deletions(-) diff --git a/gfx/webrender_bindings/RenderCompositorANGLE.cpp b/gfx/webrender_bindings/RenderCompositorANGLE.cpp index 8306bbd4cfd0..38ea3a3567b7 100644 --- a/gfx/webrender_bindings/RenderCompositorANGLE.cpp +++ b/gfx/webrender_bindings/RenderCompositorANGLE.cpp @@ -47,7 +47,7 @@ extern LazyLogModule gRenderThreadLog; /* static */ UniquePtr RenderCompositorANGLE::Create( const RefPtr& aWidget, nsACString& aError) { - const auto& gl = RenderThread::Get()->SingletonGL(aError); + RefPtr gl = RenderThread::Get()->SingletonGL(aError); if (!gl) { if (aError.IsEmpty()) { aError.Assign("RcANGLE(no shared GL)"_ns); @@ -58,7 +58,7 @@ UniquePtr RenderCompositorANGLE::Create( } UniquePtr compositor = - MakeUnique(aWidget); + MakeUnique(aWidget, std::move(gl)); if (!compositor->Initialize(aError)) { return nullptr; } @@ -66,8 +66,10 @@ UniquePtr RenderCompositorANGLE::Create( } RenderCompositorANGLE::RenderCompositorANGLE( - const RefPtr& aWidget) + const RefPtr& aWidget, + RefPtr&& aGL) : RenderCompositor(aWidget), + mGL(aGL), mEGLConfig(nullptr), mEGLSurface(nullptr), mUseTripleBuffering(false), @@ -76,6 +78,7 @@ RenderCompositorANGLE::RenderCompositorANGLE( mUsePartialPresent(false), mFullRender(false), mDisablingNativeCompositor(false) { + MOZ_ASSERT(mGL); LOG("RenderCompositorANGLE::RenderCompositorANGLE()"); } @@ -87,16 +90,7 @@ RenderCompositorANGLE::~RenderCompositorANGLE() { } ID3D11Device* RenderCompositorANGLE::GetDeviceOfEGLDisplay(nsACString& aError) { - const auto& gl = RenderThread::Get()->SingletonGL(aError); - if (!gl) { - if (aError.IsEmpty()) { - aError.Assign("RcANGLE(no shared GL in get device)"_ns); - } else { - aError.Append("(GetDevice)"_ns); - } - return nullptr; - } - const auto& gle = gl::GLContextEGL::Cast(gl); + const auto& gle = gl::GLContextEGL::Cast(mGL); const auto& egl = gle->mEgl; MOZ_ASSERT(egl); if (!egl || @@ -119,27 +113,6 @@ ID3D11Device* RenderCompositorANGLE::GetDeviceOfEGLDisplay(nsACString& aError) { return device; } -bool RenderCompositorANGLE::ShutdownEGLLibraryIfNecessary(nsACString& aError) { - const auto& displayDevice = GetDeviceOfEGLDisplay(aError); - RefPtr device = - gfx::DeviceManagerDx::Get()->GetCompositorDevice(); - - // When DeviceReset is handled by GPUProcessManager/GPUParent, - // CompositorDevice is updated to a new device. EGLDisplay also needs to be - // updated, since EGLDisplay uses DeviceManagerDx::mCompositorDevice on ANGLE - // WebRender use case. EGLDisplay could be updated when Renderer count becomes - // 0. It is ensured by GPUProcessManager during handling DeviceReset. - // GPUChild::RecvNotifyDeviceReset() destroys all CompositorSessions before - // re-creating them. - - if ((!displayDevice || device.get() != displayDevice) && - RenderThread::Get()->RendererCount() == 0) { - // Shutdown GLLibraryEGL for updating EGLDisplay. - RenderThread::Get()->ClearSingletonGL(); - } - return true; -} - bool RenderCompositorANGLE::Initialize(nsACString& aError) { // TODO(aosmond): This causes us to lose WebRender because it is unable to // distinguish why we failed and retry once the reset is complete. This does @@ -150,27 +123,12 @@ bool RenderCompositorANGLE::Initialize(nsACString& aError) { return false; } - // Update device if necessary. - if (!ShutdownEGLLibraryIfNecessary(aError)) { - aError.Append("(Shutdown EGL)"_ns); - return false; - } - const auto gl = RenderThread::Get()->SingletonGL(aError); - if (!gl) { - if (aError.IsEmpty()) { - aError.Assign("RcANGLE(no shared GL post maybe shutdown)"_ns); - } else { - aError.Append("(Initialize)"_ns); - } - return false; - } - // Force enable alpha channel to make sure ANGLE use correct framebuffer // formart - const auto& gle = gl::GLContextEGL::Cast(gl); + const auto& gle = gl::GLContextEGL::Cast(mGL); const auto& egl = gle->mEgl; if (!gl::CreateConfig(*egl, &mEGLConfig, /* bpp */ 32, - /* enableDepthBuffer */ false, gl->IsGLES())) { + /* enableDepthBuffer */ false, mGL->IsGLES())) { aError.Assign("RcANGLE(create EGLConfig failed)"_ns); return false; } @@ -192,7 +150,7 @@ bool RenderCompositorANGLE::Initialize(nsACString& aError) { if (gfx::gfxVars::UseWebRenderDCompWin()) { HWND compositorHwnd = GetCompositorHwnd(); if (compositorHwnd) { - mDCLayerTree = DCLayerTree::Create(gl, mEGLConfig, mDevice, mCtx, + mDCLayerTree = DCLayerTree::Create(mGL, mEGLConfig, mDevice, mCtx, compositorHwnd, aError); if (!mDCLayerTree) { return false; @@ -703,8 +661,7 @@ bool RenderCompositorANGLE::CreateEGLSurface() { const auto buffer = reinterpret_cast(backBuf.get()); - const auto gl = RenderThread::Get()->SingletonGL(); - const auto& gle = gl::GLContextEGL::Cast(gl); + const auto& gle = gl::GLContextEGL::Cast(mGL); const auto& egl = gle->mEgl; const EGLSurface surface = egl->fCreatePbufferFromClientBuffer( LOCAL_EGL_D3D_TEXTURE_ANGLE, buffer, mEGLConfig, pbuffer_attribs); diff --git a/gfx/webrender_bindings/RenderCompositorANGLE.h b/gfx/webrender_bindings/RenderCompositorANGLE.h index 190b4e9258b7..cb1203e3fe4b 100644 --- a/gfx/webrender_bindings/RenderCompositorANGLE.h +++ b/gfx/webrender_bindings/RenderCompositorANGLE.h @@ -36,7 +36,8 @@ class RenderCompositorANGLE : public RenderCompositor { const RefPtr& aWidget, nsACString& aError); explicit RenderCompositorANGLE( - const RefPtr& aWidget); + const RefPtr& aWidget, + RefPtr&& aGL); virtual ~RenderCompositorANGLE(); bool Initialize(nsACString& aError); @@ -49,9 +50,7 @@ class RenderCompositorANGLE : public RenderCompositor { bool Resume() override; void Update() override; - gl::GLContext* gl() const override { - return RenderThread::Get()->SingletonGL(); - } + gl::GLContext* gl() const override { return mGL; } bool MakeCurrent() override; @@ -124,11 +123,12 @@ class RenderCompositorANGLE : public RenderCompositor { void CreateSwapChainForDCompIfPossible(IDXGIFactory2* aDXGIFactory2); RefPtr CreateSwapChainForDComp(bool aUseTripleBuffering, bool aUseAlpha); - bool ShutdownEGLLibraryIfNecessary(nsACString& aError); RefPtr GetD3D11Query(); void ReleaseNativeCompositorResources(); HWND GetCompositorHwnd(); + RefPtr mGL; + EGLConfig mEGLConfig; EGLSurface mEGLSurface; diff --git a/gfx/webrender_bindings/RenderCompositorEGL.cpp b/gfx/webrender_bindings/RenderCompositorEGL.cpp index 8600ca948c81..6bf48111cddb 100644 --- a/gfx/webrender_bindings/RenderCompositorEGL.cpp +++ b/gfx/webrender_bindings/RenderCompositorEGL.cpp @@ -41,11 +41,16 @@ UniquePtr RenderCompositorEGL::Create( if ((kIsWayland || kIsX11) && !gfx::gfxVars::UseEGL()) { return nullptr; } - if (!RenderThread::Get()->SingletonGL()) { - gfxCriticalNote << "Failed to get shared GL context"; + RefPtr gl = RenderThread::Get()->SingletonGL(aError); + if (!gl) { + if (aError.IsEmpty()) { + aError.Assign("RcANGLE(no shared GL)"_ns); + } else { + aError.Append("(Create)"_ns); + } return nullptr; } - return MakeUnique(aWidget); + return MakeUnique(aWidget, std::move(gl)); } EGLSurface RenderCompositorEGL::CreateEGLSurface() { @@ -59,8 +64,10 @@ EGLSurface RenderCompositorEGL::CreateEGLSurface() { } RenderCompositorEGL::RenderCompositorEGL( - const RefPtr& aWidget) - : RenderCompositor(aWidget), mEGLSurface(EGL_NO_SURFACE) { + const RefPtr& aWidget, + RefPtr&& aGL) + : RenderCompositor(aWidget), mGL(aGL), mEGLSurface(EGL_NO_SURFACE) { + MOZ_ASSERT(mGL); LOG("RenderCompositorEGL::RenderCompositorEGL()"); } @@ -204,10 +211,6 @@ bool RenderCompositorEGL::Resume() { bool RenderCompositorEGL::IsPaused() { return mEGLSurface == EGL_NO_SURFACE; } -gl::GLContext* RenderCompositorEGL::gl() const { - return RenderThread::Get()->SingletonGL(); -} - bool RenderCompositorEGL::MakeCurrent() { const auto& gle = gl::GLContextEGL::Cast(gl()); diff --git a/gfx/webrender_bindings/RenderCompositorEGL.h b/gfx/webrender_bindings/RenderCompositorEGL.h index 842743400d77..c523501c5c07 100644 --- a/gfx/webrender_bindings/RenderCompositorEGL.h +++ b/gfx/webrender_bindings/RenderCompositorEGL.h @@ -19,7 +19,8 @@ class RenderCompositorEGL : public RenderCompositor { static UniquePtr Create( const RefPtr& aWidget, nsACString& aError); - explicit RenderCompositorEGL(const RefPtr& aWidget); + explicit RenderCompositorEGL(const RefPtr& aWidget, + RefPtr&& aGL); virtual ~RenderCompositorEGL(); bool BeginFrame() override; @@ -28,7 +29,7 @@ class RenderCompositorEGL : public RenderCompositor { bool Resume() override; bool IsPaused() override; - gl::GLContext* gl() const override; + gl::GLContext* gl() const override { return mGL; } bool MakeCurrent() override; @@ -52,6 +53,8 @@ class RenderCompositorEGL : public RenderCompositor { void DestroyEGLSurface(); + RefPtr mGL; + EGLSurface mEGLSurface; #ifdef MOZ_WIDGET_ANDROID // On android we must track our own surface size. diff --git a/gfx/webrender_bindings/RenderThread.cpp b/gfx/webrender_bindings/RenderThread.cpp index 03f665525c30..c63a4d3c9b4b 100644 --- a/gfx/webrender_bindings/RenderThread.cpp +++ b/gfx/webrender_bindings/RenderThread.cpp @@ -262,6 +262,7 @@ void RenderThread::RemoveRenderer(wr::WindowId aWindowId) { mRenderers.erase(aWindowId); if (mRenderers.empty()) { + ClearSingletonGL(); mHandlingDeviceReset = false; mHandlingWebRenderError = false; } @@ -864,6 +865,7 @@ void RenderThread::HandleDeviceReset(const char* aWhere, GLenum aReason) { // All RenderCompositors will be destroyed by the GPUProcessManager in // either OnRemoteProcessDeviceReset via the GPUChild, or // OnInProcessDeviceReset here directly. + // On Windows, device will be re-created before sessions re-creation. gfxCriticalNote << "GFX: RenderThread detected a device reset in " << aWhere; if (XRE_IsGPUProcess()) { diff --git a/gfx/webrender_bindings/RendererOGL.cpp b/gfx/webrender_bindings/RendererOGL.cpp index c6069e73fe54..0d7af692626c 100644 --- a/gfx/webrender_bindings/RendererOGL.cpp +++ b/gfx/webrender_bindings/RendererOGL.cpp @@ -157,7 +157,6 @@ RenderedFrameId RendererOGL::UpdateAndRender( // XXX This could cause oom in webrender since pending_texture_updates is // not handled. It needs to be addressed. return RenderedFrameId(); - ; } // XXX set clear color if MOZ_WIDGET_ANDROID is defined.