Bug 1508378 - Fix round error when damage rect size/position is odd number and scale factor is used, r=lsalzman
authorMartin Stransky <stransky@redhat.com>
Wed, 10 Apr 2019 14:17:28 +0000
changeset 469000 38b3fac27d90d56e3fa2ff7e57640045dabfea10
parent 468999 6e87244c4b89ce588c5259cea63b04f35cd85bc4
child 469001 8389653f29718f2c9a8d548606d760eff2e5b893
push id82904
push userapavel@mozilla.com
push dateThu, 11 Apr 2019 11:21:59 +0000
treeherderautoland@38b3fac27d90 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman
bugs1508378
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1508378 - Fix round error when damage rect size/position is odd number and scale factor is used, r=lsalzman We have rendering artifacts when sceen scale is set and damage size/position is odd number. It's caused by round error so update the size/position accordingly. Differential Revision: https://phabricator.services.mozilla.com/D26903
widget/gtk/WindowSurfaceWayland.cpp
widget/gtk/WindowSurfaceWayland.h
--- a/widget/gtk/WindowSurfaceWayland.cpp
+++ b/widget/gtk/WindowSurfaceWayland.cpp
@@ -624,16 +624,33 @@ static void WaylandBufferDelayCommitHand
   } else {
     // Referenced WindowSurfaceWayland is already deleted.
     // Do nothing but just release the mDelayedCommitHandle allocated at
     // WindowSurfaceWayland::CommitWaylandBuffer().
     free(aSurface);
   }
 }
 
+void WindowSurfaceWayland::CalcRectScale(LayoutDeviceIntRect& aRect, int aScale) {
+  if (aRect.x & 0x1) {
+    aRect.width += 1;
+  }
+  aRect.x = aRect.x / aScale;
+
+  if (aRect.y & 0x1) {
+    aRect.height += 1;
+  }
+  aRect.y = aRect.y / aScale;
+
+  aRect.width = (aRect.width & 0x1) ? aRect.width / aScale + 1 :
+                                      aRect.width / aScale;
+  aRect.height = (aRect.height & 0x1) ? aRect.height / aScale + 1 :
+                                        aRect.height / aScale;
+}
+
 void WindowSurfaceWayland::CommitWaylandBuffer() {
   MOZ_ASSERT(mPendingCommit, "Committing empty surface!");
 
   if (mWaitToFullScreenUpdate) {
     return;
   }
 
   wl_surface* waylandSurface = mWindow->GetWaylandSurface();
@@ -679,21 +696,23 @@ 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();
          iter.Next()) {
-      const mozilla::LayoutDeviceIntRect& r = iter.Get();
+      mozilla::LayoutDeviceIntRect r = iter.Get();
       // We need to remove the scale factor because the wl_surface_damage
       // also multiplies by current  scale factor.
-      wl_surface_damage(waylandSurface, r.x / scaleFactor, r.y / scaleFactor,
-                        r.width / scaleFactor, r.height / scaleFactor);
+      if (scaleFactor > 1) {
+        CalcRectScale(r, scaleFactor);
+      }
+      wl_surface_damage(waylandSurface, r.x, r.y, r.width, r.height);
     }
   }
 
   // Clear all back buffer damage as we're committing
   // all requested regions.
   mWaylandBufferDamage.SetEmpty();
 
   mFrameCallback = wl_surface_frame(waylandSurface);
--- a/widget/gtk/WindowSurfaceWayland.h
+++ b/widget/gtk/WindowSurfaceWayland.h
@@ -96,16 +96,17 @@ class WindowSurfaceWayland : public Wind
   WindowBackBuffer* GetWaylandBufferToDraw(int aWidth, int aHeight);
 
   already_AddRefed<gfx::DrawTarget> LockWaylandBuffer(int aWidth, int aHeight,
                                                       bool aClearBuffer);
   already_AddRefed<gfx::DrawTarget> LockImageSurface(
       const gfx::IntSize& aLockSize);
   bool CommitImageSurfaceToWaylandBuffer(const LayoutDeviceIntRegion& aRegion);
   void CommitWaylandBuffer();
+  void CalcRectScale(LayoutDeviceIntRect& aRect, int scale);
 
   // TODO: Do we need to hold a reference to nsWindow object?
   nsWindow* mWindow;
   nsWaylandDisplay* mWaylandDisplay;
   WindowBackBuffer* mWaylandBuffer;
   LayoutDeviceIntRegion mWaylandBufferDamage;
   WindowBackBuffer* mBackupBuffer[BACK_BUFFER_NUM];
   RefPtr<gfxImageSurface> mImageSurface;