зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1494062 - Part 2. Ensure blob image dirty rects are not clipped too small by containers. r=jrmuizel
If an item in a blob image gets a new parent container which clips it to a smaller area than it was previously, we need to ensure the dirty rect does not take into account the new clip when determining the old intersection area. Instead now all old rects for an image are clipped to the image bounds, rather than the image bounds clipped to the aggregate of the ancestor containers. Differential Revision: https://phabricator.services.mozilla.com/D16855
This commit is contained in:
Родитель
dbc1b3ebee
Коммит
42e20bac8f
|
@ -324,6 +324,9 @@ struct DIGroup {
|
|||
// The current bounds of the blob image, relative to
|
||||
// the top-left of the mLayerBounds.
|
||||
IntRect mImageBounds;
|
||||
// mImageBounds clipped to the container/parent of the
|
||||
// current item being processed.
|
||||
IntRect mClippedImageBounds;
|
||||
Maybe<wr::BlobImageKey> mKey;
|
||||
std::vector<RefPtr<SourceSurface>> mExternalSurfaces;
|
||||
std::vector<RefPtr<ScaledFont>> mFonts;
|
||||
|
@ -391,8 +394,9 @@ struct DIGroup {
|
|||
LayoutDeviceIntPoint offset = RoundedToInt(bounds.TopLeft());
|
||||
GP("\n");
|
||||
GP("CGC offset %d %d\n", offset.x, offset.y);
|
||||
GP("imageRect %d %d %d %d\n", mImageBounds.x, mImageBounds.y,
|
||||
mImageBounds.width, mImageBounds.height);
|
||||
GP("clippedImageRect %d %d %d %d\n", mClippedImageBounds.x,
|
||||
mClippedImageBounds.y, mClippedImageBounds.width,
|
||||
mClippedImageBounds.height);
|
||||
/*if (aItem->IsReused() && aData->mGeometry) {
|
||||
return;
|
||||
}*/
|
||||
|
@ -412,7 +416,7 @@ struct DIGroup {
|
|||
|
||||
IntRect transformedRect = ToDeviceSpace(
|
||||
clippedBounds, aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft());
|
||||
aData->mRect = transformedRect.Intersect(mImageBounds);
|
||||
aData->mRect = transformedRect.Intersect(mClippedImageBounds);
|
||||
GP("CGC %s %d %d %d %d\n", aItem->Name(), clippedBounds.x,
|
||||
clippedBounds.y, clippedBounds.width, clippedBounds.height);
|
||||
GP("%d %d, %f %f\n", mLayerBounds.TopLeft().x, mLayerBounds.TopLeft().y,
|
||||
|
@ -442,7 +446,7 @@ struct DIGroup {
|
|||
// no transform
|
||||
IntRect transformedRect = ToDeviceSpace(
|
||||
clippedBounds, aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft());
|
||||
aData->mRect = transformedRect.Intersect(mImageBounds);
|
||||
aData->mRect = transformedRect.Intersect(mClippedImageBounds);
|
||||
InvalidateRect(aData->mRect);
|
||||
GP("new rect: %d %d %d %d\n", aData->mRect.x, aData->mRect.y,
|
||||
aData->mRect.width, aData->mRect.height);
|
||||
|
@ -471,7 +475,7 @@ struct DIGroup {
|
|||
IntRect transformedRect =
|
||||
ToDeviceSpace(clippedBounds, aMatrix, appUnitsPerDevPixel,
|
||||
mLayerBounds.TopLeft());
|
||||
aData->mRect = transformedRect.Intersect(mImageBounds);
|
||||
aData->mRect = transformedRect.Intersect(mClippedImageBounds);
|
||||
InvalidateRect(aData->mRect);
|
||||
|
||||
// CGC invariant broken
|
||||
|
@ -503,7 +507,7 @@ struct DIGroup {
|
|||
ToDeviceSpace(clippedBounds, aMatrix, appUnitsPerDevPixel,
|
||||
mLayerBounds.TopLeft());
|
||||
InvalidateRect(aData->mRect.Intersect(mImageBounds));
|
||||
aData->mRect = transformedRect.Intersect(mImageBounds);
|
||||
aData->mRect = transformedRect.Intersect(mClippedImageBounds);
|
||||
InvalidateRect(aData->mRect);
|
||||
|
||||
GP("ClipChange: %s %d %d %d %d\n", aItem->Name(), aData->mRect.x,
|
||||
|
@ -533,7 +537,7 @@ struct DIGroup {
|
|||
ToDeviceSpace(clippedBounds, aMatrix, appUnitsPerDevPixel,
|
||||
mLayerBounds.TopLeft());
|
||||
InvalidateRect(aData->mRect.Intersect(mImageBounds));
|
||||
aData->mRect = transformedRect.Intersect(mImageBounds);
|
||||
aData->mRect = transformedRect.Intersect(mClippedImageBounds);
|
||||
InvalidateRect(aData->mRect);
|
||||
|
||||
GP("TransformChange: %s %d %d %d %d\n", aItem->Name(), aData->mRect.x,
|
||||
|
@ -552,11 +556,11 @@ struct DIGroup {
|
|||
ToDeviceSpace(clippedBounds, aMatrix, appUnitsPerDevPixel,
|
||||
mLayerBounds.TopLeft());
|
||||
InvalidateRect(aData->mRect.Intersect(mImageBounds));
|
||||
aData->mRect = transformedRect.Intersect(mImageBounds);
|
||||
aData->mRect = transformedRect.Intersect(mClippedImageBounds);
|
||||
InvalidateRect(aData->mRect);
|
||||
GP("UpdateContainerLayerPropertiesAndDetectChange change\n");
|
||||
} else if (!aData->mImageRect.IsEqualEdges(mImageBounds)) {
|
||||
// Make sure we update mRect for mImageBounds changes
|
||||
} else if (!aData->mImageRect.IsEqualEdges(mClippedImageBounds)) {
|
||||
// Make sure we update mRect for mClippedImageBounds changes
|
||||
nsRect clippedBounds = clip.ApplyNonRoundedIntersection(
|
||||
geometry->ComputeInvalidationRegion());
|
||||
IntRect transformedRect =
|
||||
|
@ -565,7 +569,7 @@ struct DIGroup {
|
|||
// The invalid rect should contain the old rect and the new rect
|
||||
// but may not because the parent may have been removed.
|
||||
InvalidateRect(aData->mRect);
|
||||
aData->mRect = transformedRect.Intersect(mImageBounds);
|
||||
aData->mRect = transformedRect.Intersect(mClippedImageBounds);
|
||||
InvalidateRect(aData->mRect);
|
||||
GP("ContainerLayer image rect bounds change\n");
|
||||
} else {
|
||||
|
@ -575,14 +579,14 @@ struct DIGroup {
|
|||
IntRect transformedRect =
|
||||
ToDeviceSpace(clippedBounds, aMatrix, appUnitsPerDevPixel,
|
||||
mLayerBounds.TopLeft());
|
||||
auto rect = transformedRect.Intersect(mImageBounds);
|
||||
auto rect = transformedRect.Intersect(mClippedImageBounds);
|
||||
GP("Layer NoChange: %s %d %d %d %d\n", aItem->Name(),
|
||||
aData->mRect.x, aData->mRect.y, aData->mRect.XMost(),
|
||||
aData->mRect.YMost());
|
||||
MOZ_RELEASE_ASSERT(rect.IsEqualEdges(aData->mRect));
|
||||
}
|
||||
} else if (!aData->mImageRect.IsEqualEdges(mImageBounds)) {
|
||||
// Make sure we update mRect for mImageBounds changes
|
||||
} else if (!aData->mImageRect.IsEqualEdges(mClippedImageBounds)) {
|
||||
// Make sure we update mRect for mClippedImageBounds changes
|
||||
UniquePtr<nsDisplayItemGeometry> geometry(
|
||||
aItem->AllocateGeometry(aBuilder));
|
||||
nsRect clippedBounds = clip.ApplyNonRoundedIntersection(
|
||||
|
@ -593,7 +597,7 @@ struct DIGroup {
|
|||
// The invalid rect should contain the old rect and the new rect
|
||||
// but may not because the parent may have been removed.
|
||||
InvalidateRect(aData->mRect);
|
||||
aData->mRect = transformedRect.Intersect(mImageBounds);
|
||||
aData->mRect = transformedRect.Intersect(mClippedImageBounds);
|
||||
InvalidateRect(aData->mRect);
|
||||
GP("image rect bounds change\n");
|
||||
} else {
|
||||
|
@ -605,7 +609,7 @@ struct DIGroup {
|
|||
IntRect transformedRect =
|
||||
ToDeviceSpace(clippedBounds, aMatrix, appUnitsPerDevPixel,
|
||||
mLayerBounds.TopLeft());
|
||||
auto rect = transformedRect.Intersect(mImageBounds);
|
||||
auto rect = transformedRect.Intersect(mClippedImageBounds);
|
||||
GP("NoChange: %s %d %d %d %d\n", aItem->Name(), aData->mRect.x,
|
||||
aData->mRect.y, aData->mRect.XMost(), aData->mRect.YMost());
|
||||
MOZ_RELEASE_ASSERT(rect.IsEqualEdges(aData->mRect));
|
||||
|
@ -615,7 +619,7 @@ struct DIGroup {
|
|||
aData->mClip = clip;
|
||||
aData->mMatrix = aMatrix;
|
||||
aData->mGroupOffset = mLayerBounds.TopLeft();
|
||||
aData->mImageRect = mImageBounds;
|
||||
aData->mImageRect = mClippedImageBounds;
|
||||
GP("post mInvalidRect: %d %d %d %d\n", mInvalidRect.x, mInvalidRect.y,
|
||||
mInvalidRect.width, mInvalidRect.height);
|
||||
}
|
||||
|
@ -1162,6 +1166,8 @@ void Grouper::ConstructGroups(nsDisplayListBuilder* aDisplayListBuilder,
|
|||
currentGroup->mAppUnitsPerDevPixel;
|
||||
groupData->mFollowingGroup.mLayerBounds = currentGroup->mLayerBounds;
|
||||
groupData->mFollowingGroup.mImageBounds = currentGroup->mImageBounds;
|
||||
groupData->mFollowingGroup.mClippedImageBounds =
|
||||
currentGroup->mClippedImageBounds;
|
||||
groupData->mFollowingGroup.mScale = currentGroup->mScale;
|
||||
groupData->mFollowingGroup.mResidualOffset =
|
||||
currentGroup->mResidualOffset;
|
||||
|
@ -1219,8 +1225,9 @@ void Grouper::ConstructItemInsideInactive(
|
|||
|
||||
// Temporarily restrict the image bounds to the bounds of the container so
|
||||
// that clipped children within the container know about the clip.
|
||||
IntRect oldImageBounds = aGroup->mImageBounds;
|
||||
aGroup->mImageBounds = aGroup->mImageBounds.Intersect(data->mRect);
|
||||
IntRect oldClippedImageBounds = aGroup->mClippedImageBounds;
|
||||
aGroup->mClippedImageBounds =
|
||||
aGroup->mClippedImageBounds.Intersect(data->mRect);
|
||||
|
||||
if (aItem->GetType() == DisplayItemType::TYPE_FILTER) {
|
||||
gfx::Size scale(1, 1);
|
||||
|
@ -1265,7 +1272,7 @@ void Grouper::ConstructItemInsideInactive(
|
|||
}
|
||||
|
||||
GP("Including %s of %d\n", aItem->Name(), aGroup->mDisplayItems.Count());
|
||||
aGroup->mImageBounds = oldImageBounds;
|
||||
aGroup->mClippedImageBounds = oldClippedImageBounds;
|
||||
}
|
||||
|
||||
/* This is just a copy of nsRect::ScaleToOutsidePixels with an offset added in.
|
||||
|
@ -1373,6 +1380,7 @@ void WebRenderCommandBuilder::DoGroupingForDisplayList(
|
|||
group.mAppUnitsPerDevPixel, residualOffset));
|
||||
group.mImageBounds =
|
||||
IntRect(0, 0, group.mLayerBounds.width, group.mLayerBounds.height);
|
||||
group.mClippedImageBounds = group.mImageBounds;
|
||||
group.mPaintRect =
|
||||
LayerIntRect::FromUnknownRect(
|
||||
ScaleToOutsidePixelsOffset(aWrappingItem->GetPaintRect(), scale.width,
|
||||
|
|
Загрузка…
Ссылка в новой задаче