зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1498499 - [Wayland] Implement triple buffering at Wayland, r=jhorak
Differential Revision: https://phabricator.services.mozilla.com/D8849 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
8dbaa4117c
Коммит
0365dbffd5
|
@ -563,7 +563,6 @@ WindowSurfaceWayland::WindowSurfaceWayland(nsWindow *aWindow)
|
||||||
: mWindow(aWindow)
|
: mWindow(aWindow)
|
||||||
, mWaylandDisplay(WaylandDisplayGet(aWindow->GetWaylandDisplay()))
|
, mWaylandDisplay(WaylandDisplayGet(aWindow->GetWaylandDisplay()))
|
||||||
, mWaylandBuffer(nullptr)
|
, mWaylandBuffer(nullptr)
|
||||||
, mBackupBuffer(nullptr)
|
|
||||||
, mFrameCallback(nullptr)
|
, mFrameCallback(nullptr)
|
||||||
, mLastCommittedSurface(nullptr)
|
, mLastCommittedSurface(nullptr)
|
||||||
, mDisplayThreadMessageLoop(MessageLoop::current())
|
, mDisplayThreadMessageLoop(MessageLoop::current())
|
||||||
|
@ -574,6 +573,8 @@ WindowSurfaceWayland::WindowSurfaceWayland(nsWindow *aWindow)
|
||||||
, mIsMainThread(NS_IsMainThread())
|
, mIsMainThread(NS_IsMainThread())
|
||||||
, mNeedScaleFactorUpdate(true)
|
, mNeedScaleFactorUpdate(true)
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < BACK_BUFFER_NUM; i++)
|
||||||
|
mBackupBuffer[i] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowSurfaceWayland::~WindowSurfaceWayland()
|
WindowSurfaceWayland::~WindowSurfaceWayland()
|
||||||
|
@ -594,7 +595,12 @@ WindowSurfaceWayland::~WindowSurfaceWayland()
|
||||||
}
|
}
|
||||||
|
|
||||||
delete mWaylandBuffer;
|
delete mWaylandBuffer;
|
||||||
delete mBackupBuffer;
|
|
||||||
|
for (int i = 0; i < BACK_BUFFER_NUM; i++) {
|
||||||
|
if (mBackupBuffer[i]) {
|
||||||
|
delete mBackupBuffer[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!mIsMainThread) {
|
if (!mIsMainThread) {
|
||||||
// We can be destroyed from main thread even though we was created/used
|
// 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) {
|
if (!mWaylandBuffer) {
|
||||||
mWaylandBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight);
|
mWaylandBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight);
|
||||||
mBackupBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight);
|
|
||||||
return mWaylandBuffer;
|
return mWaylandBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,24 +633,38 @@ WindowSurfaceWayland::GetWaylandBufferToDraw(int aWidth, int aHeight)
|
||||||
return mWaylandBuffer;
|
return mWaylandBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Front buffer is used by compositor, draw to back buffer
|
MOZ_ASSERT(!mPendingCommit,
|
||||||
if (mBackupBuffer->IsAttached()) {
|
"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");
|
NS_WARNING("No drawing buffer available");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(!mPendingCommit,
|
WindowBackBuffer *lastWaylandBuffer = mWaylandBuffer;
|
||||||
"Uncommitted buffer switch, screen artifacts ahead.");
|
mWaylandBuffer = mBackupBuffer[availableBuffer];
|
||||||
|
mBackupBuffer[availableBuffer] = lastWaylandBuffer;
|
||||||
|
|
||||||
WindowBackBuffer *tmp = mWaylandBuffer;
|
if (lastWaylandBuffer->IsMatchingSize(aWidth, aHeight)) {
|
||||||
mWaylandBuffer = mBackupBuffer;
|
|
||||||
mBackupBuffer = tmp;
|
|
||||||
|
|
||||||
if (mBackupBuffer->IsMatchingSize(aWidth, aHeight)) {
|
|
||||||
// Former front buffer has the same size as a requested one.
|
// Former front buffer has the same size as a requested one.
|
||||||
// Gecko may expect a content already drawn on screen so copy
|
// Gecko may expect a content already drawn on screen so copy
|
||||||
// existing data to the new buffer.
|
// existing data to the new buffer.
|
||||||
mWaylandBuffer->SetImageDataFromBuffer(mBackupBuffer);
|
mWaylandBuffer->SetImageDataFromBuffer(lastWaylandBuffer);
|
||||||
// When buffer switches we need to damage whole screen
|
// When buffer switches we need to damage whole screen
|
||||||
// (https://bugzilla.redhat.com/show_bug.cgi?id=1418260)
|
// (https://bugzilla.redhat.com/show_bug.cgi?id=1418260)
|
||||||
mWaylandBufferFullScreenDamage = true;
|
mWaylandBufferFullScreenDamage = true;
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include <prthread.h>
|
#include <prthread.h>
|
||||||
#include "mozilla/gfx/Types.h"
|
#include "mozilla/gfx/Types.h"
|
||||||
|
|
||||||
|
#define BACK_BUFFER_NUM 2
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace widget {
|
namespace widget {
|
||||||
|
|
||||||
|
@ -126,7 +128,7 @@ private:
|
||||||
nsWaylandDisplay* mWaylandDisplay;
|
nsWaylandDisplay* mWaylandDisplay;
|
||||||
WindowBackBuffer* mWaylandBuffer;
|
WindowBackBuffer* mWaylandBuffer;
|
||||||
LayoutDeviceIntRegion mWaylandBufferDamage;
|
LayoutDeviceIntRegion mWaylandBufferDamage;
|
||||||
WindowBackBuffer* mBackupBuffer;
|
WindowBackBuffer* mBackupBuffer[BACK_BUFFER_NUM];
|
||||||
RefPtr<gfxImageSurface> mImageSurface;
|
RefPtr<gfxImageSurface> mImageSurface;
|
||||||
wl_callback* mFrameCallback;
|
wl_callback* mFrameCallback;
|
||||||
wl_surface* mLastCommittedSurface;
|
wl_surface* mLastCommittedSurface;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче