From 6ded94d38cf94a5da8d6a73dfbfca2acb0d719cc Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Tue, 11 Sep 2018 11:55:16 +0200 Subject: Bug 1467363 - Protect access to mTransparentSurface with a lock. --- widget/windows/WinCompositorWidget.cpp | 8 ++++++++ widget/windows/WinCompositorWidget.h | 4 ++++ widget/windows/nsWindowGfx.cpp | 2 ++ 3 files changed, 14 insertions(+) (limited to 'widget/windows') diff --git a/widget/windows/WinCompositorWidget.cpp b/widget/windows/WinCompositorWidget.cpp index f660bd019..99ce67573 100644 --- a/widget/windows/WinCompositorWidget.cpp +++ b/widget/windows/WinCompositorWidget.cpp @@ -22,6 +22,7 @@ using namespace mozilla::gfx; WinCompositorWidget::WinCompositorWidget(const CompositorWidgetInitData& aInitData) : mWidgetKey(aInitData.widgetKey()), mWnd(reinterpret_cast(aInitData.hWnd())), + mTransparentSurfaceLock("mTransparentSurfaceLock"), mTransparencyMode(static_cast(aInitData.transparencyMode())), mMemoryDC(nullptr), mCompositeDC(nullptr), @@ -39,6 +40,7 @@ WinCompositorWidget::WinCompositorWidget(const CompositorWidgetInitData& aInitDa void WinCompositorWidget::OnDestroyWindow() { + MutexAutoLock lock(mTransparentSurfaceLock); mTransparentSurface = nullptr; mMemoryDC = nullptr; } @@ -75,6 +77,8 @@ WinCompositorWidget::GetClientSize() already_AddRefed WinCompositorWidget::StartRemoteDrawing() { + MutexAutoLock lock(mTransparentSurfaceLock); + MOZ_ASSERT(!mCompositeDC); RefPtr surf; @@ -229,6 +233,7 @@ WinCompositorWidget::LeavePresentLock() RefPtr WinCompositorWidget::EnsureTransparentSurface() { + mTransparentSurfaceLock.AssertCurrentThreadOwns(); MOZ_ASSERT(mTransparencyMode == eTransparencyTransparent); IntSize size = GetClientSize().ToUnknownSize(); @@ -245,6 +250,7 @@ WinCompositorWidget::EnsureTransparentSurface() void WinCompositorWidget::CreateTransparentSurface(const gfx::IntSize& aSize) { + mTransparentSurfaceLock.AssertCurrentThreadOwns(); MOZ_ASSERT(!mTransparentSurface && !mMemoryDC); RefPtr surface = new gfxWindowsSurface(aSize, SurfaceFormat::A8R8G8B8_UINT32); mTransparentSurface = surface; @@ -254,6 +260,7 @@ WinCompositorWidget::CreateTransparentSurface(const gfx::IntSize& aSize) void WinCompositorWidget::UpdateTransparency(nsTransparencyMode aMode) { + MutexAutoLock lock(mTransparentSurfaceLock); if (mTransparencyMode == aMode) { return; } @@ -270,6 +277,7 @@ WinCompositorWidget::UpdateTransparency(nsTransparencyMode aMode) void WinCompositorWidget::ClearTransparentWindow() { + MutexAutoLock lock(mTransparentSurfaceLock); if (!mTransparentSurface) { return; } diff --git a/widget/windows/WinCompositorWidget.h b/widget/windows/WinCompositorWidget.h index 9661cab45..1689a8641 100644 --- a/widget/windows/WinCompositorWidget.h +++ b/widget/windows/WinCompositorWidget.h @@ -10,6 +10,7 @@ #include "gfxASurface.h" #include "mozilla/gfx/CriticalSection.h" #include "mozilla/gfx/Point.h" +#include "mozilla/Mutex.h" #include "nsIWidget.h" class nsWindow; @@ -83,6 +84,8 @@ public: return mWnd; } + mozilla::Mutex& GetTransparentSurfaceLock() { return mTransparentSurfaceLock; } + private: HDC GetWindowSurface(); void FreeWindowSurface(HDC dc); @@ -95,6 +98,7 @@ private: gfx::CriticalSection mPresentLock; // Transparency handling. + mozilla::Mutex mTransparentSurfaceLock; nsTransparencyMode mTransparencyMode; RefPtr mTransparentSurface; HDC mMemoryDC; diff --git a/widget/windows/nsWindowGfx.cpp b/widget/windows/nsWindowGfx.cpp index a88631f89..9b303a0f2 100644 --- a/widget/windows/nsWindowGfx.cpp +++ b/widget/windows/nsWindowGfx.cpp @@ -320,6 +320,8 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel) #if defined(MOZ_XUL) // don't support transparency for non-GDI rendering, for now if (eTransparencyTransparent == mTransparencyMode) { + // This mutex needs to be held when EnsureTransparentSurface is called. + MutexAutoLock lock(mBasicLayersSurface->GetTransparentSurfaceLock()); targetSurface = mBasicLayersSurface->EnsureTransparentSurface(); } #endif -- cgit v1.2.3