--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -90,17 +90,17 @@ struct BlobItemData
bool mEmpty;
// properties that are used to emulate layer tree invalidation
Matrix mMatrix; // updated to track the current transform to device space
Matrix4x4Flagged mTransform; // only used with nsDisplayTransform items to detect transform changes
float mOpacity; // only used with nsDisplayOpacity items to detect change to opacity
IntRect mImageRect;
- IntPoint mGroupOffset;
+ LayerIntPoint mGroupOffset;
BlobItemData(DIGroup* aGroup, nsDisplayItem *aItem)
: mGroup(aGroup)
{
mInvalid = false;
mEmpty = false;
mDisplayItemKey = aItem->GetPerFrameKey();
AddFrame(aItem->Frame());
@@ -282,17 +282,17 @@ struct DIGroup
nsTHashtable<nsPtrHashKey<BlobItemData>> mDisplayItems;
nsPoint mAnimatedGeometryRootOrigin;
nsPoint mLastAnimatedGeometryRootOrigin;
IntRect mInvalidRect;
nsRect mGroupBounds;
int32_t mAppUnitsPerDevPixel;
gfx::Size mScale;
- IntPoint mGroupOffset;
+ LayerIntRect mLayerBounds;
Maybe<wr::ImageKey> mKey;
DIGroup() : mAppUnitsPerDevPixel(0) {}
void InvalidateRect(const IntRect& aRect)
{
// Empty rects get dropped
mInvalidRect = mInvalidRect.Union(aRect);
@@ -311,19 +311,19 @@ struct DIGroup
BlobItemData* data = iter.Get()->GetKey();
GP("Deleting %p-%d\n", data->mFrame, data->mDisplayItemKey);
iter.Remove();
delete data;
}
}
static IntRect
- ToDeviceSpace(nsRect aBounds, Matrix& aMatrix, int32_t aAppUnitsPerDevPixel, IntPoint aOffset)
+ ToDeviceSpace(nsRect aBounds, Matrix& aMatrix, int32_t aAppUnitsPerDevPixel, LayerIntPoint aOffset)
{
- return RoundedOut(aMatrix.TransformBounds(ToRect(nsLayoutUtils::RectToGfxRect(aBounds, aAppUnitsPerDevPixel)))) - aOffset;
+ return RoundedOut(aMatrix.TransformBounds(ToRect(nsLayoutUtils::RectToGfxRect(aBounds, aAppUnitsPerDevPixel)))) - aOffset.ToUnknownPoint();
}
void ComputeGeometryChange(nsDisplayItem* aItem, BlobItemData* aData, Matrix& aMatrix, nsDisplayListBuilder* aBuilder)
{
// If the frame is marked as invalidated, and didn't specify a rect to invalidate then we want to
// invalidate both the old and new bounds, otherwise we only want to invalidate the changed areas.
// If we do get an invalid rect, then we want to add this on top of the change areas.
nsRect invalid;
@@ -335,43 +335,42 @@ struct DIGroup
if (shift.x != 0 || shift.y != 0)
GP("shift %d %d\n", shift.x, shift.y);
int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
MOZ_RELEASE_ASSERT(mAppUnitsPerDevPixel == appUnitsPerDevPixel);
LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits(mGroupBounds, appUnitsPerDevPixel);
LayoutDeviceIntPoint offset = RoundedToInt(bounds.TopLeft());
GP("\n");
GP("CGC offset %d %d\n", offset.x, offset.y);
- IntSize size = mGroupBounds.Size().ScaleToNearestPixels(mScale.width, mScale.height, appUnitsPerDevPixel);
- //MOZ_RELEASE_ASSERT(mGroupOffset.x == offset.x && mGroupOffset.y == offset.y);
+ LayerIntSize size = mLayerBounds.Size();
IntRect imageRect(0, 0, size.width, size.height);
GP("imageSize: %d %d\n", size.width, size.height);
/*if (aItem->IsReused() && aData->mGeometry) {
return;
}*/
GP("pre mInvalidRect: %s %p-%d - inv: %d %d %d %d\n", aItem->Name(), aItem->Frame(), aItem->GetPerFrameKey(),
mInvalidRect.x, mInvalidRect.y, mInvalidRect.width, mInvalidRect.height);
if (!aData->mGeometry) {
// This item is being added for the first time, invalidate its entire area.
UniquePtr<nsDisplayItemGeometry> geometry(aItem->AllocateGeometry(aBuilder));
combined = clip.ApplyNonRoundedIntersection(geometry->ComputeInvalidationRegion());
aData->mGeometry = Move(geometry);
nsRect bounds = combined.GetBounds();
- IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mGroupOffset);
+ IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft());
aData->mRect = transformedRect.Intersect(imageRect);
GP("CGC %s %d %d %d %d\n", aItem->Name(), bounds.x, bounds.y, bounds.width, bounds.height);
- GP("%d %d, %f %f\n", mGroupOffset.x, mGroupOffset.y, aMatrix._11, aMatrix._22);
+ GP("%d %d, %f %f\n", mLayerBounds.TopLeft().x, mLayerBounds.TopLeft().y, aMatrix._11, aMatrix._22);
GP("mRect %d %d %d %d\n", aData->mRect.x, aData->mRect.y, aData->mRect.width, aData->mRect.height);
InvalidateRect(aData->mRect);
aData->mInvalid = true;
} else if (/*aData->mIsInvalid || XXX: handle image load invalidation */ (aItem->IsInvalid(invalid) && invalid.IsEmpty())) {
MOZ_RELEASE_ASSERT(imageRect.IsEqualEdges(aData->mImageRect));
- MOZ_RELEASE_ASSERT(mGroupOffset == aData->mGroupOffset);
+ MOZ_RELEASE_ASSERT(mLayerBounds.TopLeft() == aData->mGroupOffset);
UniquePtr<nsDisplayItemGeometry> geometry(aItem->AllocateGeometry(aBuilder));
/* Instead of doing this dance, let's just invalidate the old rect and the
* new rect.
combined = aData->mClip.ApplyNonRoundedIntersection(aData->mGeometry->ComputeInvalidationRegion());
combined.MoveBy(shift);
combined.Or(combined, clip.ApplyNonRoundedIntersection(geometry->ComputeInvalidationRegion()));
aData->mGeometry = Move(geometry);
*/
@@ -383,67 +382,67 @@ struct DIGroup
GP("old rect: %d %d %d %d\n",
aData->mRect.x,
aData->mRect.y,
aData->mRect.width,
aData->mRect.height);
InvalidateRect(aData->mRect.Intersect(imageRect));
// We want to snap to outside pixels. When should we multiply by the matrix?
// XXX: TransformBounds is expensive. We should avoid doing it if we have no transform
- IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mGroupOffset);
+ IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft());
aData->mRect = transformedRect.Intersect(imageRect);
InvalidateRect(aData->mRect);
GP("new rect: %d %d %d %d\n",
aData->mRect.x,
aData->mRect.y,
aData->mRect.width,
aData->mRect.height);
aData->mInvalid = true;
} else {
MOZ_RELEASE_ASSERT(imageRect.IsEqualEdges(aData->mImageRect));
- MOZ_RELEASE_ASSERT(mGroupOffset == aData->mGroupOffset);
+ MOZ_RELEASE_ASSERT(mLayerBounds.TopLeft() == aData->mGroupOffset);
GP("else invalidate: %s\n", aItem->Name());
aData->mGeometry->MoveBy(shift);
// this includes situations like reflow changing the position
aItem->ComputeInvalidationRegion(aBuilder, aData->mGeometry.get(), &combined);
if (!combined.IsEmpty()) {
// There might be no point in doing this elaborate tracking here to get
// smaller areas
InvalidateRect(aData->mRect.Intersect(imageRect)); // invalidate the old area -- in theory combined should take care of this
UniquePtr<nsDisplayItemGeometry> geometry(aItem->AllocateGeometry(aBuilder));
aData->mClip.AddOffsetAndComputeDifference(shift, aData->mGeometry->ComputeInvalidationRegion(), clip,
geometry ? geometry->ComputeInvalidationRegion() :
aData->mGeometry->ComputeInvalidationRegion(),
&combined);
- IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mGroupOffset);
+ IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft());
IntRect invalidRect = transformedRect.Intersect(imageRect);
GP("combined not empty: mRect %d %d %d %d\n", invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height);
// invalidate the invalidated area.
InvalidateRect(invalidRect);
aData->mGeometry = Move(geometry);
combined = clip.ApplyNonRoundedIntersection(aData->mGeometry->ComputeInvalidationRegion());
- transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mGroupOffset);
+ transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft());
aData->mRect = transformedRect.Intersect(imageRect);
aData->mInvalid = true;
} else {
if (aData->mClip != clip) {
UniquePtr<nsDisplayItemGeometry> geometry(aItem->AllocateGeometry(aBuilder));
if (!IsContainerLayerItem(aItem)) {
// the bounds of layer items can change on us without ComputeInvalidationRegion
// returning any change. Other items shouldn't have any hidden
// geometry change.
MOZ_RELEASE_ASSERT(geometry->mBounds.IsEqualEdges(aData->mGeometry->mBounds));
} else {
aData->mGeometry = Move(geometry);
}
combined = clip.ApplyNonRoundedIntersection(aData->mGeometry->ComputeInvalidationRegion());
- IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mGroupOffset);
+ IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft());
InvalidateRect(aData->mRect.Intersect(imageRect));
aData->mRect = transformedRect.Intersect(imageRect);
InvalidateRect(aData->mRect);
GP("ClipChange: %s %d %d %d %d\n", aItem->Name(),
aData->mRect.x, aData->mRect.y, aData->mRect.XMost(), aData->mRect.YMost());
} else if (!aMatrix.ExactlyEquals(aData->mMatrix)) {
@@ -457,59 +456,59 @@ struct DIGroup
if (!IsContainerLayerItem(aItem)) {
// the bounds of layer items can change on us
// other items shouldn't
MOZ_RELEASE_ASSERT(geometry->mBounds.IsEqualEdges(aData->mGeometry->mBounds));
} else {
aData->mGeometry = Move(geometry);
}
combined = clip.ApplyNonRoundedIntersection(aData->mGeometry->ComputeInvalidationRegion());
- IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mGroupOffset);
+ IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft());
InvalidateRect(aData->mRect.Intersect(imageRect));
aData->mRect = transformedRect.Intersect(imageRect);
InvalidateRect(aData->mRect);
GP("TransformChange: %s %d %d %d %d\n", aItem->Name(),
aData->mRect.x, aData->mRect.y, aData->mRect.XMost(), aData->mRect.YMost());
} else if (IsContainerLayerItem(aItem)) {
UniquePtr<nsDisplayItemGeometry> geometry(aItem->AllocateGeometry(aBuilder));
// we need to catch bounds changes of containers so that we continue to have the correct bounds rects in the recording
if (!geometry->mBounds.IsEqualEdges(aData->mGeometry->mBounds) ||
UpdateContainerLayerPropertiesAndDetectChange(aItem, aData)) {
combined = clip.ApplyNonRoundedIntersection(geometry->ComputeInvalidationRegion());
aData->mGeometry = Move(geometry);
- IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mGroupOffset);
+ IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft());
InvalidateRect(aData->mRect.Intersect(imageRect));
aData->mRect = transformedRect.Intersect(imageRect);
InvalidateRect(aData->mRect);
GP("UpdateContainerLayerPropertiesAndDetectChange change\n");
} else {
// XXX: this code can eventually be deleted/made debug only
combined = clip.ApplyNonRoundedIntersection(geometry->ComputeInvalidationRegion());
- IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mGroupOffset);
+ IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft());
auto rect = transformedRect.Intersect(imageRect);
MOZ_RELEASE_ASSERT(rect.IsEqualEdges(aData->mRect));
GP("Layer NoChange: %s %d %d %d %d\n", aItem->Name(),
aData->mRect.x, aData->mRect.y, aData->mRect.XMost(), aData->mRect.YMost());
}
} else {
// XXX: this code can eventually be deleted/made debug only
UniquePtr<nsDisplayItemGeometry> geometry(aItem->AllocateGeometry(aBuilder));
combined = clip.ApplyNonRoundedIntersection(geometry->ComputeInvalidationRegion());
- IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mGroupOffset);
+ IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft());
auto rect = transformedRect.Intersect(imageRect);
MOZ_RELEASE_ASSERT(rect.IsEqualEdges(aData->mRect));
GP("NoChange: %s %d %d %d %d\n", aItem->Name(),
aData->mRect.x, aData->mRect.y, aData->mRect.XMost(), aData->mRect.YMost());
}
}
}
aData->mClip = clip;
aData->mMatrix = aMatrix;
- aData->mGroupOffset = mGroupOffset;
+ aData->mGroupOffset = mLayerBounds.TopLeft();
aData->mImageRect = imageRect;
GP("post mInvalidRect: %d %d %d %d\n", mInvalidRect.x, mInvalidRect.y, mInvalidRect.width, mInvalidRect.height);
}
void EndGroup(WebRenderLayerManager* aWrManager,
wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
Grouper* aGrouper,
@@ -636,17 +635,17 @@ struct DIGroup
mKey.value());
}
void PaintItemRange(Grouper* aGrouper,
nsDisplayItem* aStartItem,
nsDisplayItem* aEndItem,
gfxContext* aContext,
gfx::DrawEventRecorderMemory* aRecorder) {
- IntSize size = mGroupBounds.Size().ScaleToNearestPixels(mScale.width, mScale.height, aGrouper->mAppUnitsPerDevPixel);
+ LayerIntSize size = mLayerBounds.Size();
for (nsDisplayItem* item = aStartItem; item != aEndItem; item = item->GetAbove()) {
IntRect bounds = ItemBounds(item);
auto bottomRight = bounds.BottomRight();
GP("Trying %s %p-%d %d %d %d %d\n", item->Name(), item->Frame(), item->GetPerFrameKey(), bounds.x, bounds.y, bounds.XMost(), bounds.YMost());
GP("paint check invalid %d %d - %d %d\n", bottomRight.x, bottomRight.y, size.width, size.height);
// skip empty items
if (bounds.IsEmpty()) {
@@ -920,25 +919,27 @@ Grouper::ConstructGroups(WebRenderComman
groupData->mFollowingGroup.mAppUnitsPerDevPixel != currentGroup->mAppUnitsPerDevPixel) {
if (groupData->mFollowingGroup.mAppUnitsPerDevPixel != currentGroup->mAppUnitsPerDevPixel) {
GP("app unit change following: %d %d\n", groupData->mFollowingGroup.mAppUnitsPerDevPixel, currentGroup->mAppUnitsPerDevPixel);
}
// The group changed size
GP("Inner group size change\n");
groupData->mFollowingGroup.ClearItems();
if (groupData->mFollowingGroup.mKey) {
- IntSize size = currentGroup->mGroupBounds.Size().ScaleToNearestPixels(currentGroup->mScale.width, currentGroup->mScale.height, mAppUnitsPerDevPixel);
- groupData->mFollowingGroup.mInvalidRect = IntRect(IntPoint(0, 0), size);
+ LayerIntRect layerBounds = LayerIntRect::FromUnknownRect(currentGroup->mGroupBounds.ScaleToOutsidePixels(currentGroup->mScale.width,
+ currentGroup->mScale.height,
+ mAppUnitsPerDevPixel));
+ groupData->mFollowingGroup.mInvalidRect = IntRect(IntPoint(0, 0), layerBounds.Size().ToUnknownSize());
aCommandBuilder->mManager->AddImageKeyForDiscard(groupData->mFollowingGroup.mKey.value());
groupData->mFollowingGroup.mKey = Nothing();
}
}
groupData->mFollowingGroup.mGroupBounds = currentGroup->mGroupBounds;
groupData->mFollowingGroup.mAppUnitsPerDevPixel = currentGroup->mAppUnitsPerDevPixel;
- groupData->mFollowingGroup.mGroupOffset = currentGroup->mGroupOffset;
+ groupData->mFollowingGroup.mLayerBounds = currentGroup->mLayerBounds;
groupData->mFollowingGroup.mScale = currentGroup->mScale;
currentGroup = &groupData->mFollowingGroup;
startOfCurrentGroup = item->GetAbove();
} else { // inactive item
if (item->GetType() == DisplayItemType::TYPE_TRANSFORM) {
@@ -1063,17 +1064,17 @@ WebRenderCommandBuilder::DoGroupingForDi
group.mKey = Nothing();
}
}
g.mAppUnitsPerDevPixel = appUnitsPerDevPixel;
g.mTransform = Matrix::Scaling(scale.width, scale.height);
group.mAppUnitsPerDevPixel = appUnitsPerDevPixel;
group.mGroupBounds = groupBounds;
group.mScale = scale;
- group.mGroupOffset = group.mGroupBounds.TopLeft().ScaleToNearestPixels(scale.width, scale.height, g.mAppUnitsPerDevPixel);
+ group.mLayerBounds = LayerIntRect::FromUnknownRect(group.mGroupBounds.ScaleToOutsidePixels(scale.width, scale.height, group.mAppUnitsPerDevPixel));
group.mAnimatedGeometryRootOrigin = group.mGroupBounds.TopLeft();
g.ConstructGroups(this, aBuilder, aResources, &group, aList, aSc);
mScrollingHelper.EndList(aSc);
}
void
WebRenderCommandBuilder::Destroy()
{