changeset: 468935:3b964face103 tag: tip user: Martin Stransky date: Wed Apr 10 15:14:32 2019 +0200 summary: Bug 1508378 - Fix round error when damage rect size/position is odd number and scale factor is used, r=lsalzman diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp --- 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); diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h --- 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 LockWaylandBuffer(int aWidth, int aHeight, bool aClearBuffer); already_AddRefed 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 mImageSurface;