Blob Blame History Raw
changeset:   465236:be9a6c98a4a7
tag:         tip
user:        Martin Stransky <stransky@redhat.com>
date:        Mon Mar 18 10:42:48 2019 +0100
summary:     tearing


diff --git a/widget/gtk/nsAppShell.cpp b/widget/gtk/nsAppShell.cpp
--- a/widget/gtk/nsAppShell.cpp
+++ b/widget/gtk/nsAppShell.cpp
@@ -35,16 +35,17 @@ using mozilla::widget::ScreenHelperGTK;
 using mozilla::widget::ScreenManager;
 
 #define NOTIFY_TOKEN 0xFA
 
 LazyLogModule gWidgetLog("Widget");
 LazyLogModule gWidgetFocusLog("WidgetFocus");
 LazyLogModule gWidgetDragLog("WidgetDrag");
 LazyLogModule gWidgetDrawLog("WidgetDraw");
+LazyLogModule gWidgetWaylandLog("WidgetWayland");
 
 static GPollFunc sPollFunc;
 
 // Wrapper function to disable hang monitoring while waiting in poll().
 static gint PollWrapper(GPollFD* ufds, guint nfsd, gint timeout_) {
   mozilla::BackgroundHangMonitor().NotifyWait();
   gint result;
   {

diff -up firefox-66.0/widget/gtk/WindowSurfaceWayland.cpp.old firefox-66.0/widget/gtk/WindowSurfaceWayland.cpp
--- firefox-66.0/widget/gtk/WindowSurfaceWayland.cpp.old	2019-03-20 15:48:52.265966904 +0100
+++ firefox-66.0/widget/gtk/WindowSurfaceWayland.cpp	2019-03-20 14:48:21.082035284 +0100
@@ -20,6 +20,18 @@
 #include <fcntl.h>
 #include <errno.h>
 
+#undef LOG
+#ifdef MOZ_LOGGING
+#  include "mozilla/Logging.h"
+#  include "nsTArray.h"
+#  include "Units.h"
+extern mozilla::LazyLogModule gWidgetWaylandLog;
+#  define LOGWAYLAND(args) \
+    MOZ_LOG(gWidgetWaylandLog, mozilla::LogLevel::Debug, args)
+#else
+#  define LOGWAYLAND(args)
+#endif /* MOZ_LOGGING */
+
 namespace mozilla {
 namespace widget {
 
@@ -241,7 +253,7 @@ WaylandShmPool::~WaylandShmPool() {
 
 static void buffer_release(void* data, wl_buffer* buffer) {
   auto surface = reinterpret_cast<WindowBackBuffer*>(data);
-  surface->Detach();
+  surface->Detach(buffer);
 }
 
 static const struct wl_buffer_listener buffer_listener = {buffer_release};
@@ -261,9 +273,16 @@ void WindowBackBuffer::Create(int aWidth
 
   mWidth = aWidth;
   mHeight = aHeight;
+
+  LOGWAYLAND((
+      "%s [%p] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, (void*)this,
+      (void*)mWaylandBuffer,
+      mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1));
 }
 
 void WindowBackBuffer::Release() {
+  LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this));
+
   wl_buffer_destroy(mWaylandBuffer);
   mWidth = mHeight = 0;
 }
@@ -288,6 +307,9 @@ WindowBackBuffer::~WindowBackBuffer() {
 bool WindowBackBuffer::Resize(int aWidth, int aHeight) {
   if (aWidth == mWidth && aHeight == mHeight) return true;
 
+  LOGWAYLAND(
+      ("%s [%p] %d %d\n", __PRETTY_FUNCTION__, (void*)this, aWidth, aHeight));
+
   Release();
   Create(aWidth, aHeight);
 
@@ -295,13 +317,26 @@ bool WindowBackBuffer::Resize(int aWidth
 }
 
 void WindowBackBuffer::Attach(wl_surface* aSurface) {
+  LOGWAYLAND((
+      "%s [%p] wl_surface %p ID %d wl_buffer %p ID %d\n", __PRETTY_FUNCTION__,
+      (void*)this, (void*)aSurface,
+      aSurface ? wl_proxy_get_id((struct wl_proxy*)aSurface) : -1,
+      (void*)mWaylandBuffer,
+      mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1));
+
   wl_surface_attach(aSurface, mWaylandBuffer, 0, 0);
   wl_surface_commit(aSurface);
   wl_display_flush(mWaylandDisplay->GetDisplay());
   mAttached = true;
 }
 
-void WindowBackBuffer::Detach() { mAttached = false; }
+void WindowBackBuffer::Detach(wl_buffer* aBuffer) {
+  LOGWAYLAND(("%s [%p] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, (void*)this,
+              (void*)aBuffer,
+              aBuffer ? wl_proxy_get_id((struct wl_proxy*)aBuffer) : -1));
+
+  mAttached = false;
+}
 
 bool WindowBackBuffer::SetImageDataFromBuffer(
     class WindowBackBuffer* aSourceBuffer) {
@@ -316,6 +351,11 @@ bool WindowBackBuffer::SetImageDataFromB
 }
 
 already_AddRefed<gfx::DrawTarget> WindowBackBuffer::Lock() {
+  LOGWAYLAND((
+      "%s [%p] [%d x %d] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__,
+      (void*)this, mWidth, mHeight, (void*)mWaylandBuffer,
+      mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1));
+
   gfx::IntSize lockSize(mWidth, mHeight);
   return gfxPlatform::CreateDrawTargetForData(
       static_cast<unsigned char*>(mShmPool.GetImageData()), lockSize,
@@ -345,7 +385,8 @@ WindowSurfaceWayland::WindowSurfaceWayla
       mPendingCommit(false),
       mWaylandBufferFullScreenDamage(false),
       mIsMainThread(NS_IsMainThread()),
-      mNeedScaleFactorUpdate(true) {
+      mNeedScaleFactorUpdate(true),
+      mWaitToFullScreenUpdate(true) {
   for (int i = 0; i < BACK_BUFFER_NUM; i++) mBackupBuffer[i] = nullptr;
 }
 
@@ -387,7 +428,11 @@ WindowSurfaceWayland::~WindowSurfaceWayl
 WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw(int aWidth,
                                                                int aHeight) {
   if (!mWaylandBuffer) {
+    LOGWAYLAND(("%s [%p] Create [%d x %d]\n", __PRETTY_FUNCTION__, (void*)this,
+                aWidth, aHeight));
+
     mWaylandBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight);
+    mWaitToFullScreenUpdate = true;
     return mWaylandBuffer;
   }
 
@@ -396,8 +441,11 @@ WindowBackBuffer* WindowSurfaceWayland::
       mWaylandBuffer->Resize(aWidth, aHeight);
       // There's a chance that scale factor has been changed
       // when buffer size changed
-      mNeedScaleFactorUpdate = true;
+      mWaitToFullScreenUpdate = true;
     }
+    LOGWAYLAND(("%s [%p] Reuse buffer [%d x %d]\n", __PRETTY_FUNCTION__,
+                (void*)this, aWidth, aHeight));
+
     return mWaylandBuffer;
   }
 
@@ -420,6 +468,8 @@ WindowBackBuffer* WindowSurfaceWayland::
   }
 
   if (MOZ_UNLIKELY(availableBuffer == BACK_BUFFER_NUM)) {
+    LOGWAYLAND(("%s [%p] No drawing buffer available!\n", __PRETTY_FUNCTION__,
+                (void*)this));
     NS_WARNING("No drawing buffer available");
     return nullptr;
   }
@@ -429,6 +479,8 @@ WindowBackBuffer* WindowSurfaceWayland::
   mBackupBuffer[availableBuffer] = lastWaylandBuffer;
 
   if (lastWaylandBuffer->IsMatchingSize(aWidth, aHeight)) {
+    LOGWAYLAND(("%s [%p] Copy from old buffer [%d x %d]\n", __PRETTY_FUNCTION__,
+                (void*)this, 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.
@@ -437,9 +489,12 @@ WindowBackBuffer* WindowSurfaceWayland::
     // (https://bugzilla.redhat.com/show_bug.cgi?id=1418260)
     mWaylandBufferFullScreenDamage = true;
   } else {
+    LOGWAYLAND(("%s [%p] Resize to [%d x %d]\n", __PRETTY_FUNCTION__,
+                (void*)this, aWidth, aHeight));
     // Former buffer has different size from the new request. Only resize
     // the new buffer and leave gecko to render new whole content.
     mWaylandBuffer->Resize(aWidth, aHeight);
+    mWaitToFullScreenUpdate = true;
   }
 
   return mWaylandBuffer;
@@ -499,6 +554,10 @@ already_AddRefed<gfx::DrawTarget> Window
   gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
   gfx::IntSize lockSize(bounds.XMost(), bounds.YMost());
 
+  LOGWAYLAND(("%s [%p] lockSize [%d x %d] screenSize [%d x %d]\n",
+              __PRETTY_FUNCTION__, (void*)this, lockSize.width, lockSize.height,
+              screenRect.width, lockSize.height));
+
   // Are we asked for entire nsWindow to draw?
   mDrawToWaylandBufferDirectly =
       (aRegion.GetNumRects() == 1 && bounds.x == 0 && bounds.y == 0 &&
@@ -510,6 +569,13 @@ already_AddRefed<gfx::DrawTarget> Window
         LockWaylandBuffer(screenRect.width, screenRect.height,
                           mWindow->WaylandSurfaceNeedsClear());
     if (dt) {
+      // When we have a request to update whole screen at once
+      // (surface was created, resized or changed somehow)
+      // we also need update scale factor of the screen.
+      if (mWaitToFullScreenUpdate) {
+        mWaitToFullScreenUpdate = false;
+        mNeedScaleFactorUpdate = true;
+      }
       return dt.forget();
     }
 
@@ -576,6 +642,10 @@ static void WaylandBufferDelayCommitHand
 void WindowSurfaceWayland::CommitWaylandBuffer() {
   MOZ_ASSERT(mPendingCommit, "Committing empty surface!");
 
+  if (mWaitToFullScreenUpdate) {
+    return;
+  }
+
   wl_surface* waylandSurface = mWindow->GetWaylandSurface();
   if (!waylandSurface) {
     // Target window is not created yet - delay the commit. This can happen only
@@ -619,6 +689,7 @@ void WindowSurfaceWayland::CommitWayland
     LayoutDeviceIntRect rect = mWindow->GetBounds();
     wl_surface_damage(waylandSurface, 0, 0, rect.width, rect.height);
     mWaylandBufferFullScreenDamage = false;
+    mNeedScaleFactorUpdate = true;
   } else {
     gint scaleFactor = mWindow->GdkScaleFactor();
     for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done();
@@ -653,6 +724,18 @@ void WindowSurfaceWayland::CommitWayland
 void WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) {
   MOZ_ASSERT(mIsMainThread == NS_IsMainThread());
 
+#ifdef DEBUG
+  {
+    LayoutDeviceIntRect screenRect = mWindow->GetBounds();
+    gfx::IntRect bounds = aInvalidRegion.GetBounds().ToUnknownRect();
+    gfx::IntSize lockSize(bounds.XMost(), bounds.YMost());
+
+    LOGWAYLAND(("%s [%p] lockSize [%d x %d] screenSize [%d x %d]\n",
+                __PRETTY_FUNCTION__, (void*)this, lockSize.width,
+                lockSize.height, screenRect.width, lockSize.height));
+  }
+#endif
+
   // We have new content at mImageSurface - copy data to mWaylandBuffer first.
   if (!mDrawToWaylandBufferDirectly) {
     CommitImageSurfaceToWaylandBuffer(aInvalidRegion);
diff -up firefox-66.0/widget/gtk/WindowSurfaceWayland.h.old firefox-66.0/widget/gtk/WindowSurfaceWayland.h
--- firefox-66.0/widget/gtk/WindowSurfaceWayland.h.old	2019-03-20 15:48:56.218949138 +0100
+++ firefox-66.0/widget/gtk/WindowSurfaceWayland.h	2019-03-20 14:48:21.082035284 +0100
@@ -46,7 +46,7 @@ class WindowBackBuffer {
   already_AddRefed<gfx::DrawTarget> Lock();
 
   void Attach(wl_surface* aSurface);
-  void Detach();
+  void Detach(wl_buffer* aBuffer);
   bool IsAttached() { return mAttached; }
 
   void Clear();
@@ -118,6 +118,7 @@ class WindowSurfaceWayland : public Wind
   bool mWaylandBufferFullScreenDamage;
   bool mIsMainThread;
   bool mNeedScaleFactorUpdate;
+  bool mWaitToFullScreenUpdate;
 };
 
 }  // namespace widget