diff --git a/gfx/layers/wr/WebRenderCommandBuilder.cpp b/gfx/layers/wr/WebRenderCommandBuilder.cpp index fd8c26f02adb..bf96f669afe1 100644 --- a/gfx/layers/wr/WebRenderCommandBuilder.cpp +++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp @@ -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 mKey; std::vector> mExternalSurfaces; std::vector> 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; }*/ @@ -413,7 +417,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, @@ -444,7 +448,7 @@ struct DIGroup { 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); @@ -473,7 +477,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 @@ -505,7 +509,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, @@ -535,7 +539,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, @@ -554,11 +558,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 = @@ -567,7 +571,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 { @@ -577,14 +581,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 geometry( aItem->AllocateGeometry(aBuilder)); nsRect clippedBounds = clip.ApplyNonRoundedIntersection( @@ -595,7 +599,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 { @@ -607,7 +611,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)); @@ -617,7 +621,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); } @@ -1164,6 +1168,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; @@ -1221,8 +1227,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); @@ -1267,7 +1274,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. @@ -1375,6 +1382,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,