firefox/mozilla-1581748.patch

575 lines
23 KiB
Diff
Raw Normal View History

2019-09-17 11:22:34 +00:00
diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1581748 firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp
--- firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1581748 2019-09-17 13:19:47.190908284 +0200
+++ firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp 2019-09-17 13:19:47.196908262 +0200
@@ -32,7 +32,7 @@ extern mozilla::LazyLogModule gWidgetWay
# define LOGWAYLAND(args)
#endif /* MOZ_LOGGING */
-// Maximal compositin timeout it miliseconds
+// Maximal compositing timeout it miliseconds
#define COMPOSITING_TIMEOUT 200
namespace mozilla {
@@ -513,13 +513,15 @@ WindowSurfaceWayland::WindowSurfaceWayla
mDelayedCommitHandle(nullptr),
mLastCommitTime(0),
mDrawToWaylandBufferDirectly(true),
+ mCanSwitchWaylandBuffer(true),
mBufferPendingCommit(false),
mBufferCommitAllowed(false),
- mWholeWindowBufferDamage(false),
mBufferNeedsClear(false),
mIsMainThread(NS_IsMainThread()),
mNeedScaleFactorUpdate(true) {
for (int i = 0; i < BACK_BUFFER_NUM; i++) mBackupBuffer[i] = nullptr;
2019-09-17 12:10:11 +00:00
+ mRenderingCacheMode = CACHE_ALL;
2019-09-17 11:22:34 +00:00
+
}
WindowSurfaceWayland::~WindowSurfaceWayland() {
@@ -591,8 +593,6 @@ WindowBackBuffer* WindowSurfaceWayland::
// There's no buffer created yet, create a new one.
if (!mWaylandBuffer) {
- MOZ_ASSERT(aCanSwitchBuffer && mWholeWindowBufferDamage,
- "Created new buffer for partial drawing!");
LOGWAYLAND((" Created new buffer [%d x %d]\n", mBufferScreenRect.width,
mBufferScreenRect.height));
@@ -682,9 +682,8 @@ WindowBackBuffer* WindowSurfaceWayland::
return mWaylandBuffer;
}
-already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::LockWaylandBuffer(
- bool aCanSwitchBuffer) {
- WindowBackBuffer* buffer = GetWaylandBufferToDraw(aCanSwitchBuffer);
+already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::LockWaylandBuffer() {
+ WindowBackBuffer* buffer = GetWaylandBufferToDraw(mCanSwitchWaylandBuffer);
LOGWAYLAND(("WindowSurfaceWayland::LockWaylandBuffer [%p] Got buffer %p\n",
(void*)this, (void*)buffer));
@@ -698,7 +697,9 @@ already_AddRefed<gfx::DrawTarget> Window
return nullptr;
}
- if (mBufferNeedsClear && mWholeWindowBufferDamage) {
+ mCanSwitchWaylandBuffer = false;
+
+ if (mBufferNeedsClear) {
buffer->Clear();
mBufferNeedsClear = false;
}
@@ -728,40 +729,30 @@ already_AddRefed<gfx::DrawTarget> Window
WindowBackBuffer::GetSurfaceFormat());
}
-static bool IsWindowFullScreenUpdate(LayoutDeviceIntRect& screenRect,
- const LayoutDeviceIntRegion& aRegion) {
- if (aRegion.GetNumRects() > 1) return false;
-
- IntRect rect = aRegion.RectIter().Get().ToUnknownRect();
- return (rect.x == 0 && rect.y == 0 && screenRect.width == rect.width &&
- screenRect.height == rect.height);
+static bool IsWindowFullScreenUpdate(
+ LayoutDeviceIntRect& aScreenRect,
+ const LayoutDeviceIntRegion& aUpdatedRegion) {
+ if (aUpdatedRegion.GetNumRects() > 1) return false;
+
+ IntRect rect = aUpdatedRegion.RectIter().Get().ToUnknownRect();
+ return (rect.x == 0 && rect.y == 0 && aScreenRect.width == rect.width &&
+ aScreenRect.height == rect.height);
}
-static bool IsPopupFullScreenUpdate(LayoutDeviceIntRect& screenRect,
- const LayoutDeviceIntRegion& aRegion) {
+static bool IsPopupFullScreenUpdate(
+ LayoutDeviceIntRect& aScreenRect,
+ const LayoutDeviceIntRegion& aUpdatedRegion) {
// We know that popups can be drawn from two parts; a panel and an arrow.
// Assume we redraw whole popups when we have two rects and bounding
// box is equal to window borders.
- if (aRegion.GetNumRects() > 2) return false;
+ if (aUpdatedRegion.GetNumRects() > 2) return false;
- IntRect lockSize = aRegion.GetBounds().ToUnknownRect();
+ gfx::IntRect lockSize = aUpdatedRegion.GetBounds().ToUnknownRect();
return (lockSize.x == 0 && lockSize.y == 0 &&
- screenRect.width == lockSize.width &&
- screenRect.height == lockSize.height);
+ aScreenRect.width == lockSize.width &&
+ aScreenRect.height == lockSize.height);
}
-/*
- There are some situations which can happen here:
-
- A) Lock() is called to whole surface. In that case we don't need
- to clip/buffer the drawing and we can return wl_buffer directly
- for drawing.
- - mWaylandBuffer is available - that's an ideal situation.
- - mWaylandBuffer is locked by compositor - go B)
-
- B) Lock() is requested for part(s) of screen. We need to provide temporary
- surface to draw into and copy result (clipped) to target wl_surface.
- */
already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::Lock(
const LayoutDeviceIntRegion& aRegion) {
MOZ_ASSERT(mIsMainThread == NS_IsMainThread());
@@ -777,22 +768,31 @@ already_AddRefed<gfx::DrawTarget> Window
LayoutDeviceIntRect lockedScreenRect = mWindow->GetBounds();
gfx::IntRect lockSize = aRegion.GetBounds().ToUnknownRect();
- // Are we asked for entire nsWindow to draw?
bool isTransparentPopup =
mWindow->IsWaylandPopup() &&
(eTransparencyTransparent == mWindow->GetTransparencyMode());
- // We have request to lock whole buffer/window.
- mWholeWindowBufferDamage =
- isTransparentPopup ? IsPopupFullScreenUpdate(lockedScreenRect, aRegion)
- : IsWindowFullScreenUpdate(lockedScreenRect, aRegion);
-
- // Clear buffer when we (re)draw new transparent popup window,
- // otherwise leave it as-is, mBufferNeedsClear can be set from previous
- // (already pending) commits which are cached now.
- if (mWholeWindowBufferDamage) {
+ bool windowRedraw = isTransparentPopup
+ ? IsPopupFullScreenUpdate(lockedScreenRect, aRegion)
+ : IsWindowFullScreenUpdate(lockedScreenRect, aRegion);
+ if (windowRedraw) {
+ // Clear buffer when we (re)draw new transparent popup window,
+ // otherwise leave it as-is, mBufferNeedsClear can be set from previous
+ // (already pending) commits which are cached now.
mBufferNeedsClear =
mWindow->WaylandSurfaceNeedsClear() || isTransparentPopup;
+
+ // Store info that we can switch WaylandBuffer when we flush
+ // mImageSurface / mDelayedImageCommits. Don't clear it - it's cleared
+ // at LockWaylandBuffer() when we actualy switch the buffer.
+ mCanSwitchWaylandBuffer = windowRedraw;
+
+ // We do full buffer repaint so clear our cached drawings.
+ mDelayedImageCommits.Clear();
+ mWaylandBufferDamage.SetEmpty();
+
+ // Also do scale factor update for whole window updates just to be sure.
+ mNeedScaleFactorUpdate = true;
}
LOGWAYLAND(
@@ -808,7 +808,7 @@ already_AddRefed<gfx::DrawTarget> Window
LOGWAYLAND((" IsWindowFullScreenUpdate = %d\n",
IsWindowFullScreenUpdate(lockedScreenRect, aRegion)));
LOGWAYLAND((" mBufferNeedsClear = %d\n", mBufferNeedsClear));
- LOGWAYLAND((" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
+ LOGWAYLAND((" windowRedraw = %d\n", windowRedraw));
#if MOZ_LOGGING
if (!(mBufferScreenRect == lockedScreenRect)) {
@@ -822,8 +822,9 @@ already_AddRefed<gfx::DrawTarget> Window
// We can't commit them any more as they're for former window size, so
// scratch them.
mDelayedImageCommits.Clear();
+ mWaylandBufferDamage.SetEmpty();
- if (!mWholeWindowBufferDamage) {
+ if (!windowRedraw) {
NS_WARNING("Partial screen update when window is resized!");
// This should not happen. Screen size changed but we got only
// partal screen update instead of whole screen. Discard this painting
@@ -833,52 +834,56 @@ already_AddRefed<gfx::DrawTarget> Window
mBufferScreenRect = lockedScreenRect;
}
- if (mWholeWindowBufferDamage) {
- // We can lock/commit entire buffer direcly.
- mDrawToWaylandBufferDirectly = true;
-
- // If there's any pending image commit scratch them as we're going
- // to redraw the whole sceen anyway.
- mDelayedImageCommits.Clear();
+ mDrawToWaylandBufferDirectly =
+ (windowRedraw || mRenderingCacheMode != CACHE_ALL);
- RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
- /* aCanSwitchBuffer */ mWholeWindowBufferDamage);
+ if (mDrawToWaylandBufferDirectly) {
+ LOGWAYLAND((" Direct drawing\n"));
+ RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer();
if (dt) {
+ if (!windowRedraw) {
+ DrawDelayedImageCommits(dt, mWaylandBufferDamage);
+ }
return dt.forget();
}
}
- // We do indirect drawing due to:
- //
- // 1) We don't have any front buffer available. Try indirect drawing
- // to mImageSurface which is mirrored to front buffer at commit.
- // 2) Only part of the screen is locked. We can't lock entire screen for
- // such drawing as it produces visible artifacts.
+ // Any caching is disabled and we don't have any back buffer available.
+ if (mRenderingCacheMode == CACHE_NONE) {
+ return nullptr;
+ }
+
+ // We do indirect drawing because there isn't any front buffer available.
+ // Do indirect drawing to mImageSurface which is commited to wayland
+ // wl_buffer by DrawDelayedImageCommits() later.
mDrawToWaylandBufferDirectly = false;
LOGWAYLAND((" Indirect drawing.\n"));
return LockImageSurface(gfx::IntSize(lockSize.XMost(), lockSize.YMost()));
}
+bool WindowImageSurface::OverlapsSurface(
+ class WindowImageSurface& aBottomSurface) {
+ return mUpdateRegion.Contains(aBottomSurface.mUpdateRegion);
+}
+
void WindowImageSurface::Draw(gfx::SourceSurface* aSurface,
gfx::DrawTarget* aDest,
const LayoutDeviceIntRegion& aRegion) {
- uint32_t numRects = aRegion.GetNumRects();
- if (numRects != 1) {
- AutoTArray<IntRect, 32> rects;
- rects.SetCapacity(numRects);
- for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
- rects.AppendElement(iter.Get().ToUnknownRect());
- }
- aDest->PushDeviceSpaceClipRects(rects.Elements(), rects.Length());
- }
-
+#ifdef MOZ_LOGGING
gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
- gfx::Rect rect(bounds);
- aDest->DrawSurface(aSurface, rect, rect);
+ LOGWAYLAND(("WindowImageSurface::Draw\n"));
+ LOGWAYLAND((" rects num %d\n", aRegion.GetNumRects()));
+ LOGWAYLAND((" bounds [ %d, %d] -> [%d x %d]\n", bounds.x, bounds.y,
+ bounds.width, bounds.height));
+#endif
- if (numRects != 1) {
- aDest->PopClip();
+ for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
+ mozilla::LayoutDeviceIntRect r = iter.Get();
+ gfx::Rect rect(r.ToUnknownRect());
+ LOGWAYLAND((" draw rect [%f,%f] -> [%f x %f]\n", rect.x, rect.y,
+ rect.width, rect.height));
+ aDest->DrawSurface(aSurface, rect, rect);
}
}
@@ -896,6 +901,18 @@ WindowImageSurface::WindowImageSurface(
mImageSurface->Format());
}
+void WindowSurfaceWayland::DrawDelayedImageCommits(
+ gfx::DrawTarget* aDrawTarget, LayoutDeviceIntRegion& aWaylandBufferDamage) {
+ LOGWAYLAND(
+ ("WindowSurfaceWayland::DrawDelayedImageCommits [%p]\n", (void*)this));
+ MOZ_ASSERT(mDelayedImageCommits.Length() > 0, "Nothing to draw?");
+
+ for (unsigned int i = 0; i < mDelayedImageCommits.Length(); i++) {
+ mDelayedImageCommits[i].Draw(aDrawTarget, aWaylandBufferDamage);
+ }
+ mDelayedImageCommits.Clear();
+}
+
void WindowSurfaceWayland::CacheImageSurface(
const LayoutDeviceIntRegion& aRegion) {
#ifdef MOZ_LOGGING
@@ -906,8 +923,26 @@ void WindowSurfaceWayland::CacheImageSur
bounds.width, bounds.height));
#endif
- mDelayedImageCommits.AppendElement(
- WindowImageSurface(mImageSurface, aRegion));
+ WindowImageSurface surf = WindowImageSurface(mImageSurface, aRegion);
+
+ if (mDelayedImageCommits.Length()) {
+ int lastSurf = mDelayedImageCommits.Length() - 1;
+ if (surf.OverlapsSurface(mDelayedImageCommits[lastSurf])) {
+#ifdef MOZ_LOGGING
+ {
+ gfx::IntRect size = mDelayedImageCommits[lastSurf]
+ .GetUpdateRegion()
+ ->GetBounds()
+ .ToUnknownRect();
+ LOGWAYLAND((" removing [ %d, %d] -> [%d x %d]\n", size.x, size.y,
+ size.width, size.height));
+ }
+#endif
+ mDelayedImageCommits.RemoveElementAt(lastSurf);
+ }
+ }
+
+ mDelayedImageCommits.AppendElement(surf);
// mImageSurface is owned by mDelayedImageCommits
mImageSurface = nullptr;
@@ -915,17 +950,6 @@ void WindowSurfaceWayland::CacheImageSur
(" There's %d cached images\n", int(mDelayedImageCommits.Length())));
}
-void WindowSurfaceWayland::DrawDelayedImageCommits(
- gfx::DrawTarget* aDrawTarget, LayoutDeviceIntRegion& aWaylandBufferDamage) {
- LOGWAYLAND(
- ("WindowSurfaceWayland::DrawDelayedImageCommits [%p]\n", (void*)this));
-
- for (unsigned int i = 0; i < mDelayedImageCommits.Length(); i++) {
- mDelayedImageCommits[i].Draw(aDrawTarget, aWaylandBufferDamage);
- }
- mDelayedImageCommits.Clear();
-}
-
bool WindowSurfaceWayland::CommitImageCacheToWaylandBuffer() {
if (!mDelayedImageCommits.Length()) {
return false;
@@ -933,8 +957,7 @@ bool WindowSurfaceWayland::CommitImageCa
MOZ_ASSERT(!mDrawToWaylandBufferDirectly);
- RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
- /* aCanSwitchBuffer */ mWholeWindowBufferDamage);
+ RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer();
if (!dt) {
return false;
}
@@ -942,7 +965,6 @@ bool WindowSurfaceWayland::CommitImageCa
LOGWAYLAND((" Flushing %ld cached WindowImageSurfaces to Wayland buffer\n",
long(mDelayedImageCommits.Length())));
- // Draw any delayed image commits first
DrawDelayedImageCommits(dt, mWaylandBufferDamage);
UnlockWaylandBuffer();
@@ -967,7 +989,7 @@ void WindowSurfaceWayland::CommitWayland
LOGWAYLAND(("WindowSurfaceWayland::CommitWaylandBuffer [%p]\n", (void*)this));
LOGWAYLAND(
(" mDrawToWaylandBufferDirectly = %d\n", mDrawToWaylandBufferDirectly));
- LOGWAYLAND((" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
+ LOGWAYLAND((" mCanSwitchWaylandBuffer = %d\n", mCanSwitchWaylandBuffer));
LOGWAYLAND((" mDelayedCommitHandle = %p\n", mDelayedCommitHandle));
LOGWAYLAND((" mFrameCallback = %p\n", mFrameCallback));
LOGWAYLAND((" mLastCommittedSurface = %p\n", mLastCommittedSurface));
@@ -1030,20 +1052,11 @@ void WindowSurfaceWayland::CommitWayland
mLastCommittedSurface = nullptr;
}
- if (mWholeWindowBufferDamage) {
- LOGWAYLAND((" send whole screen damage\n"));
- wl_surface_damage(waylandSurface, 0, 0, mBufferScreenRect.width,
- mBufferScreenRect.height);
- mWholeWindowBufferDamage = false;
- mNeedScaleFactorUpdate = true;
- } else {
- for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done();
- iter.Next()) {
- mozilla::LayoutDeviceIntRect r = iter.Get();
- LOGWAYLAND((" wl_surface_damage_buffer [%d, %d] -> [%d, %d]\n", r.x,
- r.y, r.width, r.height));
- wl_surface_damage_buffer(waylandSurface, r.x, r.y, r.width, r.height);
- }
+ for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done(); iter.Next()) {
+ mozilla::LayoutDeviceIntRect r = iter.Get();
+ LOGWAYLAND((" wl_surface_damage_buffer [%d, %d] -> [%d, %d]\n", r.x, r.y,
+ r.width, r.height));
+ wl_surface_damage_buffer(waylandSurface, r.x, r.y, r.width, r.height);
}
// Clear all back buffer damage as we're committing
@@ -1062,9 +1075,9 @@ void WindowSurfaceWayland::CommitWayland
mLastCommittedSurface = waylandSurface;
mLastCommitTime = g_get_monotonic_time() / 1000;
- // Ask wl_display to start events synchronization. We're going wait
+ // Ask wl_display to start events synchronization. We're going to wait
// until all events are processed before next WindowSurfaceWayland::Lock()
- // as we need freed wl_buffer there.
+ // as we hope for free wl_buffer there.
mWaylandDisplay->SyncBegin();
// There's no pending commit, all changes are sent to compositor.
@@ -1074,9 +1087,6 @@ void WindowSurfaceWayland::CommitWayland
void WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) {
MOZ_ASSERT(mIsMainThread == NS_IsMainThread());
- // Flush all waiting events explicitly as we need
- // mWaylandDisplay->FlushEventQueue();
-
#ifdef MOZ_LOGGING
{
gfx::IntRect lockSize = aInvalidRegion.GetBounds().ToUnknownRect();
@@ -1087,17 +1097,12 @@ void WindowSurfaceWayland::Commit(const
mBufferScreenRect.width, mBufferScreenRect.height));
LOGWAYLAND((" mDrawToWaylandBufferDirectly = %d\n",
mDrawToWaylandBufferDirectly));
- LOGWAYLAND(
- (" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
}
#endif
if (mDrawToWaylandBufferDirectly) {
MOZ_ASSERT(mWaylandBuffer->IsLocked());
- // If we're not at fullscreen damage add drawing area from aInvalidRegion
- if (!mWholeWindowBufferDamage) {
- mWaylandBufferDamage.OrWith(aInvalidRegion);
- }
+ mWaylandBufferDamage.OrWith(aInvalidRegion);
UnlockWaylandBuffer();
mBufferPendingCommit = true;
} else {
diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.h.mozilla-1581748 firefox-69.0/widget/gtk/WindowSurfaceWayland.h
--- firefox-69.0/widget/gtk/WindowSurfaceWayland.h.mozilla-1581748 2019-09-17 13:19:47.191908280 +0200
+++ firefox-69.0/widget/gtk/WindowSurfaceWayland.h 2019-09-17 13:19:47.197908258 +0200
@@ -161,6 +161,10 @@ class WindowImageSurface {
WindowImageSurface(gfxImageSurface* aImageSurface,
const LayoutDeviceIntRegion& aUpdateRegion);
+ bool OverlapsSurface(class WindowImageSurface& aBottomSurface);
+
+ const LayoutDeviceIntRegion* GetUpdateRegion() { return &mUpdateRegion; };
+
private:
RefPtr<gfx::SourceSurface> mSurface;
RefPtr<gfxImageSurface> mImageSurface;
@@ -174,20 +178,59 @@ class WindowSurfaceWayland : public Wind
explicit WindowSurfaceWayland(nsWindow* aWindow);
~WindowSurfaceWayland();
+ // Lock() / Commit() are called by gecko when Firefox
+ // wants to display something. Lock() returns a DrawTarget
+ // where gecko paints. When gecko is done it calls Commit()
+ // and we try to send the DrawTarget (backed by wl_buffer)
+ // to wayland compositor.
+ //
+ // If we fail (wayland compositor is busy,
+ // wl_surface is not created yet) we queue the painting
+ // and we send it to wayland compositor in FrameCallbackHandler()/
+ // DelayedCommitHandler/CommitWaylandBuffer().
already_AddRefed<gfx::DrawTarget> Lock(
const LayoutDeviceIntRegion& aRegion) override;
void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final;
+
+ // It's called from wayland compositor when there's the right
+ // time to send wl_buffer to display. It's no-op if there's no
+ // queued commits.
void FrameCallbackHandler();
+
+ // When a new window is created we may not have a valid wl_surface
+ // for drawing (Gtk haven't created it yet). All commits are queued
+ // and DelayedCommitHandler() is called by timer when wl_surface is ready
+ // for drawing.
void DelayedCommitHandler();
+
+ // Try to commit all queued drawings to Wayland compositor. This is usually
+ // called from other routines but can be used to explicitly flush
+ // all drawings as we do when wl_buffer is released
+ // (see WindowBackBufferShm::Detach() for instance).
void CommitWaylandBuffer();
nsWaylandDisplay* GetWaylandDisplay() { return mWaylandDisplay; };
+ // Image cache mode can be set by widget.wayland_cache_mode
+ typedef enum {
+ // Cache and clip all drawings, default. It's slowest
+ // but also without any rendered artifacts.
+ CACHE_ALL = 0,
+ // Cache drawing only when back buffer is missing. May produce
+ // some rendering artifacts and flickering when partial screen update
+ // is rendered.
+ CACHE_MISSING = 1,
+ // Don't cache anything, draw only when back buffer is available.
+ // Suitable for fullscreen content only like fullscreen video playback and
+ // may work well with dmabuf backend.
+ CACHE_NONE = 2
+ } RenderingCacheMode;
+
private:
WindowBackBuffer* CreateWaylandBuffer(int aWidth, int aHeight);
WindowBackBuffer* GetWaylandBufferToDraw(bool aCanSwitchBuffer);
- already_AddRefed<gfx::DrawTarget> LockWaylandBuffer(bool aCanSwitchBuffer);
+ already_AddRefed<gfx::DrawTarget> LockWaylandBuffer();
void UnlockWaylandBuffer();
already_AddRefed<gfx::DrawTarget> LockImageSurface(
@@ -206,23 +249,71 @@ class WindowSurfaceWayland : public Wind
// mBufferScreenRect is window size when our wayland buffer was allocated.
LayoutDeviceIntRect mBufferScreenRect;
nsWaylandDisplay* mWaylandDisplay;
+
+ // Actual buffer (backed by wl_buffer) where all drawings go into.
+ // Drawn areas are stored at mWaylandBufferDamage and if there's
+ // any uncommited drawings which needs to be send to wayland compositor
+ // the mBufferPendingCommit is set.
WindowBackBuffer* mWaylandBuffer;
- LayoutDeviceIntRegion mWaylandBufferDamage;
WindowBackBuffer* mBackupBuffer[BACK_BUFFER_NUM];
+ LayoutDeviceIntRegion mWaylandBufferDamage;
+
+ // After every commit to wayland compositor a frame callback is requested.
+ // Any next commit to wayland compositor will happen when frame callback
+ // comes from wayland compositor back as it's the best time to do the commit.
wl_callback* mFrameCallback;
wl_surface* mLastCommittedSurface;
+
+ // Registered reference to pending DelayedCommitHandler() call.
WindowSurfaceWayland** mDelayedCommitHandle;
+
+ // Cached drawings. If we can't get WaylandBuffer (wl_buffer) at
+ // WindowSurfaceWayland::Lock() we direct gecko rendering to
+ // mImageSurface.
+ // If we can't get WaylandBuffer at WindowSurfaceWayland::Commit()
+ // time, mImageSurface is moved to mDelayedImageCommits which
+ // holds all cached drawings.
+ // mDelayedImageCommits can be drawn by FrameCallbackHandler(),
+ // DelayedCommitHandler() or when WaylandBuffer is detached.
RefPtr<gfxImageSurface> mImageSurface;
AutoTArray<WindowImageSurface, 30> mDelayedImageCommits;
+
int64_t mLastCommitTime;
+
+ // Indicates that we don't have any cached drawings at mDelayedImageCommits
+ // and WindowSurfaceWayland::Lock() returned WaylandBuffer to gecko
+ // to draw into.
bool mDrawToWaylandBufferDirectly;
+
+ // Set when our cached drawings (mDelayedImageCommits) contains
+ // full screen damage. That means we can safely switch WaylandBuffer
+ // at LockWaylandBuffer().
+ bool mCanSwitchWaylandBuffer;
+
+ // Set when actual WaylandBuffer contains drawings which are not send to
+ // wayland compositor yet.
bool mBufferPendingCommit;
+
+ // We can't send WaylandBuffer (wl_buffer) to compositor when gecko
+ // is rendering into it (i.e. between WindowSurfaceWayland::Lock() /
+ // WindowSurfaceWayland::Commit()).
+ // Thus we use mBufferCommitAllowed to disable commit by callbacks
+ // (FrameCallbackHandler(), DelayedCommitHandler())
bool mBufferCommitAllowed;
- bool mWholeWindowBufferDamage;
+
+ // We need to clear WaylandBuffer when entire transparent window is repainted.
+ // This typically apply to popup windows.
bool mBufferNeedsClear;
+
bool mIsMainThread;
+
+ // When new WaylandBuffer (wl_buffer) is send to wayland compositor
+ // (buffer switch or resize) we also need to set its scale factor.
bool mNeedScaleFactorUpdate;
+ // Image caching strategy, see RenderingCacheMode for details.
+ RenderingCacheMode mRenderingCacheMode;
+
static bool UseDMABufBackend();
static bool mUseDMABufInitialized;
static bool mUseDMABuf;