From 0365dbffd5e9fe5e89aba28c1aa7df0311626a3d Mon Sep 17 00:00:00 2001 From: Martin Stransky Date: Thu, 18 Oct 2018 14:30:21 +0000 Subject: [PATCH] Bug 1498499 - [Wayland] Implement triple buffering at Wayland, r=jhorak Differential Revision: https://phabricator.services.mozilla.com/D8849 --HG-- extra : moz-landing-system : lando --- widget/gtk/WindowSurfaceWayland.cpp | 45 ++++++++++++++++++++--------- widget/gtk/WindowSurfaceWayland.h | 4 ++- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp index 6f17eb3e37b4..f788c2b6b651 100644 --- a/widget/gtk/WindowSurfaceWayland.cpp +++ b/widget/gtk/WindowSurfaceWayland.cpp @@ -563,7 +563,6 @@ WindowSurfaceWayland::WindowSurfaceWayland(nsWindow *aWindow) : mWindow(aWindow) , mWaylandDisplay(WaylandDisplayGet(aWindow->GetWaylandDisplay())) , mWaylandBuffer(nullptr) - , mBackupBuffer(nullptr) , mFrameCallback(nullptr) , mLastCommittedSurface(nullptr) , mDisplayThreadMessageLoop(MessageLoop::current()) @@ -574,6 +573,8 @@ WindowSurfaceWayland::WindowSurfaceWayland(nsWindow *aWindow) , mIsMainThread(NS_IsMainThread()) , mNeedScaleFactorUpdate(true) { + for (int i = 0; i < BACK_BUFFER_NUM; i++) + mBackupBuffer[i] = nullptr; } WindowSurfaceWayland::~WindowSurfaceWayland() @@ -594,7 +595,12 @@ WindowSurfaceWayland::~WindowSurfaceWayland() } delete mWaylandBuffer; - delete mBackupBuffer; + + for (int i = 0; i < BACK_BUFFER_NUM; i++) { + if (mBackupBuffer[i]) { + delete mBackupBuffer[i]; + } + } if (!mIsMainThread) { // We can be destroyed from main thread even though we was created/used @@ -614,7 +620,6 @@ WindowSurfaceWayland::GetWaylandBufferToDraw(int aWidth, int aHeight) { if (!mWaylandBuffer) { mWaylandBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); - mBackupBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); return mWaylandBuffer; } @@ -628,24 +633,38 @@ WindowSurfaceWayland::GetWaylandBufferToDraw(int aWidth, int aHeight) return mWaylandBuffer; } - // Front buffer is used by compositor, draw to back buffer - if (mBackupBuffer->IsAttached()) { + MOZ_ASSERT(!mPendingCommit, + "Uncommitted buffer switch, screen artifacts ahead."); + + // Front buffer is used by compositor, select a back buffer + int availableBuffer; + for (availableBuffer = 0; availableBuffer < BACK_BUFFER_NUM; + availableBuffer++) { + if (!mBackupBuffer[availableBuffer]) { + mBackupBuffer[availableBuffer] = + new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); + break; + } + + if (!mBackupBuffer[availableBuffer]->IsAttached()) { + break; + } + } + + if (MOZ_UNLIKELY(availableBuffer == BACK_BUFFER_NUM)) { NS_WARNING("No drawing buffer available"); return nullptr; } - MOZ_ASSERT(!mPendingCommit, - "Uncommitted buffer switch, screen artifacts ahead."); + WindowBackBuffer *lastWaylandBuffer = mWaylandBuffer; + mWaylandBuffer = mBackupBuffer[availableBuffer]; + mBackupBuffer[availableBuffer] = lastWaylandBuffer; - WindowBackBuffer *tmp = mWaylandBuffer; - mWaylandBuffer = mBackupBuffer; - mBackupBuffer = tmp; - - if (mBackupBuffer->IsMatchingSize(aWidth, aHeight)) { + if (lastWaylandBuffer->IsMatchingSize(aWidth, aHeight)) { // Former front buffer has the same size as a requested one. // Gecko may expect a content already drawn on screen so copy // existing data to the new buffer. - mWaylandBuffer->SetImageDataFromBuffer(mBackupBuffer); + mWaylandBuffer->SetImageDataFromBuffer(lastWaylandBuffer); // When buffer switches we need to damage whole screen // (https://bugzilla.redhat.com/show_bug.cgi?id=1418260) mWaylandBufferFullScreenDamage = true; diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h index 1a9306c45ba0..5b8935bddc41 100644 --- a/widget/gtk/WindowSurfaceWayland.h +++ b/widget/gtk/WindowSurfaceWayland.h @@ -10,6 +10,8 @@ #include #include "mozilla/gfx/Types.h" +#define BACK_BUFFER_NUM 2 + namespace mozilla { namespace widget { @@ -126,7 +128,7 @@ private: nsWaylandDisplay* mWaylandDisplay; WindowBackBuffer* mWaylandBuffer; LayoutDeviceIntRegion mWaylandBufferDamage; - WindowBackBuffer* mBackupBuffer; + WindowBackBuffer* mBackupBuffer[BACK_BUFFER_NUM]; RefPtr mImageSurface; wl_callback* mFrameCallback; wl_surface* mLastCommittedSurface;