From 0d2b959f9fc5c85fb7c90ed068d9602cd285f47c Mon Sep 17 00:00:00 2001 From: Ethan Lin Date: Mon, 6 Nov 2017 16:51:16 +0800 Subject: [PATCH] Bug 1410583 - Make sure we paint the whole item for blob image. r=jrmuizel MozReview-Commit-ID: 84LiyRA2WFC --HG-- extra : rebase_source : 769128dff81e4610decf2fbe53196a94e7857773 --- gfx/layers/wr/WebRenderCommandBuilder.cpp | 27 +++++++++++++---------- layout/painting/nsDisplayList.cpp | 11 +++++++-- layout/painting/nsDisplayList.h | 3 ++- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/gfx/layers/wr/WebRenderCommandBuilder.cpp b/gfx/layers/wr/WebRenderCommandBuilder.cpp index d77581021bd8..aed64c29dd2d 100644 --- a/gfx/layers/wr/WebRenderCommandBuilder.cpp +++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp @@ -459,24 +459,27 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem, bool snap; nsRect itemBounds = aItem->GetBounds(aDisplayListBuilder, &snap); - nsRect clippedBounds = itemBounds; - const DisplayItemClip& clip = aItem->GetClip(); // Blob images will only draw the visible area of the blob so we don't need to clip // them here and can just rely on the webrender clipping. - if (clip.HasClip() && !gfxPrefs::WebRenderBlobImages()) { - clippedBounds = itemBounds.Intersect(clip.GetClipRect()); + bool useClipBounds = true; + nsRect paintBounds = itemBounds; + if (gfxPrefs::WebRenderBlobImages()) { + paintBounds = itemBounds; + useClipBounds = false; + } else { + paintBounds = aItem->GetClippedBounds(aDisplayListBuilder); } // nsDisplayItem::Paint() may refer the variables that come from ComputeVisibility(). // So we should call RecomputeVisibility() before painting. e.g.: nsDisplayBoxShadowInner // uses mVisibleRegion in Paint() and mVisibleRegion is computed in // nsDisplayBoxShadowInner::ComputeVisibility(). - nsRegion visibleRegion(clippedBounds); - aItem->RecomputeVisibility(aDisplayListBuilder, &visibleRegion); + nsRegion visibleRegion(itemBounds); + aItem->RecomputeVisibility(aDisplayListBuilder, &visibleRegion, useClipBounds); const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel(); - LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits(clippedBounds, appUnitsPerDevPixel); + LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits(paintBounds, appUnitsPerDevPixel); gfx::Size scale = aSc.GetInheritedScale(); // XXX not sure if paintSize should be in layer or layoutdevice pixels, it @@ -502,7 +505,7 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem, nsRegion invalidRegion; if (aItem->IsInvalid(invalid)) { - invalidRegion.OrWith(clippedBounds); + invalidRegion.OrWith(paintBounds); } else { nsPoint shift = itemBounds.TopLeft() - geometry->mBounds.TopLeft(); geometry->MoveBy(shift); @@ -511,9 +514,9 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem, nsRect lastBounds = fallbackData->GetBounds(); lastBounds.MoveBy(shift); - if (!lastBounds.IsEqualInterior(clippedBounds)) { + if (!lastBounds.IsEqualInterior(paintBounds)) { invalidRegion.OrWith(lastBounds); - invalidRegion.OrWith(clippedBounds); + invalidRegion.OrWith(paintBounds); } } needPaint = !invalidRegion.IsEmpty(); @@ -524,7 +527,7 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem, gfx::SurfaceFormat::A8 : gfx::SurfaceFormat::B8G8R8A8; if (gfxPrefs::WebRenderBlobImages()) { bool snapped; - bool isOpaque = aItem->GetOpaqueRegion(aDisplayListBuilder, &snapped).Contains(clippedBounds); + bool isOpaque = aItem->GetOpaqueRegion(aDisplayListBuilder, &snapped).Contains(paintBounds); RefPtr recorder = MakeAndAddRef([&] (MemStream &aStream, std::vector> &aUnscaledFonts) { size_t count = aUnscaledFonts.size(); @@ -585,7 +588,7 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem, // Update current bounds to fallback data fallbackData->SetGeometry(Move(geometry)); - fallbackData->SetBounds(clippedBounds); + fallbackData->SetBounds(paintBounds); MOZ_ASSERT(fallbackData->GetKey()); diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 9573661586a4..0b7e558cc4ab 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -2929,7 +2929,8 @@ nsDisplayItem::ComputeVisibility(nsDisplayListBuilder* aBuilder, bool nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder, - nsRegion* aVisibleRegion) { + nsRegion* aVisibleRegion, + bool aUseClipBounds) { if (mForceNotVisible && !GetSameCoordinateSystemChildren()) { // mForceNotVisible wants to ensure that this display item doesn't render // anything itself. If this item has contents, then we obviously want to @@ -2937,7 +2938,13 @@ nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder, NS_ASSERTION(mVisibleRect.IsEmpty(), "invisible items without children should have empty vis rect"); } else { - nsRect bounds = GetClippedBounds(aBuilder); + nsRect bounds; + if (aUseClipBounds) { + bounds = GetClippedBounds(aBuilder); + } else { + bool snap; + bounds = GetBounds(aBuilder, &snap); + } nsRegion itemVisible; itemVisible.And(*aVisibleRegion, bounds); diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index bb2b5c85b8d0..c89575e8f72a 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -2505,7 +2505,8 @@ public: * -- Subtracts bounds from aVisibleRegion if the item is opaque */ bool RecomputeVisibility(nsDisplayListBuilder* aBuilder, - nsRegion* aVisibleRegion); + nsRegion* aVisibleRegion, + bool aUseClipBounds = true); /** * Returns the result of aBuilder->ToReferenceFrame(GetUnderlyingFrame())