Blob Blame History Raw
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;
+  mRenderingCacheMode = CACHE_ALL;
+
 }
 
 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;