author | Jeff Muizelaar <jmuizelaar@mozilla.com> |
Wed, 18 Apr 2018 18:54:26 -0400 | |
changeset 414432 | 98b307b376401db95e4b3db071adec6ee16130f5 |
parent 414431 | c8b6fba2ae947808a8965b2e1254487dbe1b7d48 |
child 414433 | 1dfbb10696ab6ca83903852ae15cf6fac6155f10 |
push id | 33868 |
push user | nerli@mozilla.com |
push date | Thu, 19 Apr 2018 09:53:51 +0000 |
treeherder | mozilla-central@8ed49dd81059 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mstange |
bugs | 1454510 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- 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, @@ -627,17 +626,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()) { @@ -911,25 +910,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) { @@ -1054,17 +1055,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() {