mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1882779 [Linux] Lock WindowSurfaceProvider between StartRemoteDrawingInRegion() and EndRemoteDrawingInRegion() calls r=emilio
It makes sure underlying native surface (XWindow/wl_surface) stays allocated until compositor thread finishes rendering and returns drawing target to us. Differential Revision: https://phabricator.services.mozilla.com/D204073
This commit is contained in:
parent
1445faddbf
commit
3ed1a9c810
@ -11,6 +11,7 @@
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "nsWindow.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
|
||||
#ifdef MOZ_WAYLAND
|
||||
# include "mozilla/StaticPrefs_widget.h"
|
||||
@ -129,13 +130,13 @@ RefPtr<WindowSurface> WindowSurfaceProvider::CreateWindowSurface() {
|
||||
// 2. XPutImage
|
||||
# ifdef MOZ_HAVE_SHMIMAGE
|
||||
if (!mIsShaped && nsShmImage::UseShm()) {
|
||||
LOG(("Drawing to Window 0x%lx will use MIT-SHM\n", mXWindow));
|
||||
LOG(("Drawing to Window 0x%lx will use MIT-SHM\n", (Window)mXWindow));
|
||||
return MakeRefPtr<WindowSurfaceX11SHM>(DefaultXDisplay(), mXWindow,
|
||||
mXVisual, mXDepth);
|
||||
}
|
||||
# endif // MOZ_HAVE_SHMIMAGE
|
||||
|
||||
LOG(("Drawing to Window 0x%lx will use XPutImage\n", mXWindow));
|
||||
LOG(("Drawing to Window 0x%lx will use XPutImage\n", (Window)mXWindow));
|
||||
return MakeRefPtr<WindowSurfaceX11Image>(DefaultXDisplay(), mXWindow,
|
||||
mXVisual, mXDepth, mIsShaped);
|
||||
}
|
||||
@ -143,6 +144,11 @@ RefPtr<WindowSurface> WindowSurfaceProvider::CreateWindowSurface() {
|
||||
MOZ_RELEASE_ASSERT(false);
|
||||
}
|
||||
|
||||
// We need to ignore thread safety checks here. We need to hold mMutex
|
||||
// between StartRemoteDrawingInRegion()/EndRemoteDrawingInRegion() calls
|
||||
// which confuses it.
|
||||
MOZ_PUSH_IGNORE_THREAD_SAFETY
|
||||
|
||||
already_AddRefed<gfx::DrawTarget>
|
||||
WindowSurfaceProvider::StartRemoteDrawingInRegion(
|
||||
const LayoutDeviceIntRegion& aInvalidRegion,
|
||||
@ -151,7 +157,13 @@ WindowSurfaceProvider::StartRemoteDrawingInRegion(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
// We return a reference to mWindowSurface inside draw target so we need to
|
||||
// hold the mutex untill EndRemoteDrawingInRegion() call where draw target
|
||||
// is returned.
|
||||
// If we return null dt, EndRemoteDrawingInRegion() won't be called to
|
||||
// release mutex.
|
||||
mMutex.Lock();
|
||||
auto unlockMutex = MakeScopeExit([&] { mMutex.Unlock(); });
|
||||
|
||||
if (!mWindowSurfaceValid) {
|
||||
mWindowSurface = nullptr;
|
||||
@ -178,12 +190,20 @@ WindowSurfaceProvider::StartRemoteDrawingInRegion(
|
||||
dt = mWindowSurface->Lock(aInvalidRegion);
|
||||
}
|
||||
#endif
|
||||
if (dt) {
|
||||
// We have valid dt, mutex will be released in EndRemoteDrawingInRegion().
|
||||
unlockMutex.release();
|
||||
}
|
||||
|
||||
return dt.forget();
|
||||
}
|
||||
|
||||
void WindowSurfaceProvider::EndRemoteDrawingInRegion(
|
||||
gfx::DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
// Unlock mutex from StartRemoteDrawingInRegion().
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
auto unlockMutex = MakeScopeExit([&] { mMutex.Unlock(); });
|
||||
|
||||
// Commit to mWindowSurface only if we have a valid one.
|
||||
if (!mWindowSurface || !mWindowSurfaceValid) {
|
||||
return;
|
||||
@ -218,5 +238,7 @@ void WindowSurfaceProvider::EndRemoteDrawingInRegion(
|
||||
mWindowSurface->Commit(aInvalidRegion);
|
||||
}
|
||||
|
||||
MOZ_POP_THREAD_SAFETY
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
Loading…
Reference in New Issue
Block a user