mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 07:15:46 +00:00
Bug 1477693
- Part 3: Refactor FrameLayerBuilder invalidation functions to better handle different coordinate spaces r=mattwoodrow
MozReview-Commit-ID: 1NDcg88a1Ge --HG-- extra : rebase_source : 97208a584e907473793fd9f4a528bc6166683ebf
This commit is contained in:
parent
222e57e271
commit
82395c69d1
@ -332,6 +332,7 @@ DisplayItemData::EndUpdate()
|
||||
mIsInvalid = false;
|
||||
mUsed = false;
|
||||
mReusedItem = false;
|
||||
mOldTransform = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -2174,21 +2175,15 @@ AppendToString(nsACString& s, const nsIntRegion& r,
|
||||
* apply the inverse of that transform before calling InvalidateRegion.
|
||||
*/
|
||||
static void
|
||||
InvalidatePostTransformRegion(PaintedLayer* aLayer, const nsIntRegion& aRegion,
|
||||
const nsIntPoint& aTranslation,
|
||||
TransformClipNode* aTransform)
|
||||
InvalidatePostTransformRegion(PaintedLayer* aLayer,
|
||||
const nsIntRegion& aRegion,
|
||||
const nsIntPoint& aTranslation)
|
||||
{
|
||||
// Convert the region from the coordinates of the container layer
|
||||
// (relative to the snapped top-left of the display list reference frame)
|
||||
// to the PaintedLayer's own coordinates
|
||||
nsIntRegion rgn = aRegion;
|
||||
|
||||
if (aTransform) {
|
||||
PaintedDisplayItemLayerUserData* data =
|
||||
GetPaintedDisplayItemLayerUserData(aLayer);
|
||||
rgn = aTransform->TransformRegion(rgn, data->mAppUnitsPerDevPixel);
|
||||
}
|
||||
|
||||
rgn.MoveBy(-aTranslation);
|
||||
aLayer->InvalidateRegion(rgn);
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
@ -2201,19 +2196,26 @@ InvalidatePostTransformRegion(PaintedLayer* aLayer, const nsIntRegion& aRegion,
|
||||
}
|
||||
|
||||
static void
|
||||
InvalidatePostTransformRect(PaintedLayer* aLayer,
|
||||
const nsRect& aRect,
|
||||
const DisplayItemClip& aClip,
|
||||
const nsIntPoint& aTranslation,
|
||||
TransformClipNode* aTransform)
|
||||
InvalidatePreTransformRect(PaintedLayer* aLayer,
|
||||
const nsRect& aRect,
|
||||
const DisplayItemClip& aClip,
|
||||
const nsIntPoint& aTranslation,
|
||||
TransformClipNode* aTransform)
|
||||
{
|
||||
PaintedDisplayItemLayerUserData* data =
|
||||
static_cast<PaintedDisplayItemLayerUserData*>(aLayer->GetUserData(&gPaintedDisplayItemLayerUserData));
|
||||
|
||||
nsRect rect = aClip.ApplyNonRoundedIntersection(aRect);
|
||||
|
||||
nsIntRect pixelRect = rect.ScaleToOutsidePixels(data->mXScale, data->mYScale, data->mAppUnitsPerDevPixel);
|
||||
InvalidatePostTransformRegion(aLayer, pixelRect, aTranslation, aTransform);
|
||||
nsIntRect pixelRect = rect.ScaleToOutsidePixels(data->mXScale, data->mYScale,
|
||||
data->mAppUnitsPerDevPixel);
|
||||
|
||||
if (aTransform) {
|
||||
pixelRect =
|
||||
aTransform->TransformRect(pixelRect, data->mAppUnitsPerDevPixel);
|
||||
}
|
||||
|
||||
InvalidatePostTransformRegion(aLayer, pixelRect, aTranslation);
|
||||
}
|
||||
|
||||
|
||||
@ -2349,11 +2351,11 @@ FrameLayerBuilder::WillEndTransaction()
|
||||
printf_stderr("Invalidating unused display item (%i) belonging to frame %p from layer %p\n", did->mDisplayItemKey, did->mFrameList[0], t);
|
||||
}
|
||||
#endif
|
||||
InvalidatePostTransformRect(t,
|
||||
did->mGeometry->ComputeInvalidationRegion(),
|
||||
did->mClip,
|
||||
GetLastPaintOffset(t),
|
||||
did->mTransform);
|
||||
InvalidatePreTransformRect(t,
|
||||
did->mGeometry->ComputeInvalidationRegion(),
|
||||
did->mClip,
|
||||
GetLastPaintOffset(t),
|
||||
did->mTransform);
|
||||
}
|
||||
|
||||
did->ClearAnimationCompositorState();
|
||||
@ -3846,13 +3848,6 @@ PaintedLayerData::Accumulate(ContainerState* aState,
|
||||
currentData,
|
||||
aItem->GetDisplayItemDataLayerManager());
|
||||
|
||||
if (currentData) {
|
||||
currentData->mTransform = nullptr;
|
||||
}
|
||||
if (oldData) {
|
||||
oldData->mTransform = nullptr;
|
||||
}
|
||||
|
||||
mAssignedDisplayItems.emplace_back(aItem, aLayerState, oldData,
|
||||
aContentRect, aType, hasOpacity,
|
||||
aTransform);
|
||||
@ -5191,11 +5186,11 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
|
||||
printf_stderr("Display item type %s(%p) changed layers %p to %p!\n", aItem->Name(), aItem->Frame(), t, aNewLayer);
|
||||
}
|
||||
#endif
|
||||
InvalidatePostTransformRect(t,
|
||||
aData->mGeometry->ComputeInvalidationRegion(),
|
||||
aData->mClip,
|
||||
mLayerBuilder->GetLastPaintOffset(t),
|
||||
aData->mTransform);
|
||||
InvalidatePreTransformRect(t,
|
||||
aData->mGeometry->ComputeInvalidationRegion(),
|
||||
aData->mClip,
|
||||
mLayerBuilder->GetLastPaintOffset(t),
|
||||
aData->mTransform);
|
||||
}
|
||||
// Clear the old geometry so that invalidation thinks the item has been
|
||||
// added this paint.
|
||||
@ -5203,6 +5198,22 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
|
||||
}
|
||||
}
|
||||
|
||||
static nsRect
|
||||
GetInvalidationRect(nsDisplayItemGeometry* aGeometry,
|
||||
const DisplayItemClip& aClip,
|
||||
TransformClipNode* aTransform,
|
||||
const int32_t aA2D)
|
||||
{
|
||||
const nsRect& rect = aGeometry->ComputeInvalidationRegion();
|
||||
const nsRect clipped = aClip.ApplyNonRoundedIntersection(rect);
|
||||
|
||||
if (aTransform) {
|
||||
return aTransform->TransformRect(clipped, aA2D);
|
||||
}
|
||||
|
||||
return clipped;
|
||||
}
|
||||
|
||||
void
|
||||
FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
|
||||
{
|
||||
@ -5236,16 +5247,25 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
|
||||
}
|
||||
|
||||
const DisplayItemClip& clip = item->GetClip();
|
||||
const int32_t appUnitsPerDevPixel = layerData->mAppUnitsPerDevPixel;
|
||||
|
||||
// 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;
|
||||
nsRegion combined;
|
||||
nsIntRegion invalidPixels;
|
||||
|
||||
if (!aData->mGeometry) {
|
||||
// This item is being added for the first time, invalidate its entire area.
|
||||
geometry = item->AllocateGeometry(mDisplayListBuilder);
|
||||
combined = clip.ApplyNonRoundedIntersection(geometry->ComputeInvalidationRegion());
|
||||
|
||||
const nsRect bounds = GetInvalidationRect(geometry, clip,
|
||||
aData->mTransform,
|
||||
appUnitsPerDevPixel);
|
||||
|
||||
invalidPixels = bounds.ScaleToOutsidePixels(layerData->mXScale,
|
||||
layerData->mYScale,
|
||||
appUnitsPerDevPixel);
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
|
||||
printf_stderr("Display item type %s(%p) added to layer %p!\n", item->Name(), item->Frame(), aData->mLayer.get());
|
||||
@ -5254,21 +5274,38 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
|
||||
} else if (aData->mIsInvalid || (item->IsInvalid(invalid) && invalid.IsEmpty())) {
|
||||
// Layout marked item/frame as needing repainting (without an explicit rect), invalidate the entire old and new areas.
|
||||
geometry = item->AllocateGeometry(mDisplayListBuilder);
|
||||
combined = aData->mClip.ApplyNonRoundedIntersection(aData->mGeometry->ComputeInvalidationRegion());
|
||||
combined.MoveBy(shift);
|
||||
combined.Or(combined, clip.ApplyNonRoundedIntersection(geometry->ComputeInvalidationRegion()));
|
||||
|
||||
nsRect oldArea = GetInvalidationRect(aData->mGeometry, aData->mClip,
|
||||
aData->mOldTransform,
|
||||
appUnitsPerDevPixel);
|
||||
oldArea.MoveBy(shift);
|
||||
|
||||
nsRect newArea = GetInvalidationRect(geometry, clip,
|
||||
aData->mTransform,
|
||||
appUnitsPerDevPixel);
|
||||
|
||||
nsRegion combined;
|
||||
combined.Or(oldArea, newArea);
|
||||
invalidPixels = combined.ScaleToOutsidePixels(layerData->mXScale,
|
||||
layerData->mYScale,
|
||||
appUnitsPerDevPixel);
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
|
||||
printf_stderr("Display item type %s(%p) (in layer %p) belongs to an invalidated frame!\n", item->Name(), item->Frame(), aData->mLayer.get());
|
||||
printf_stderr("Display item type %s(%p) (in layer %p) belongs to an invalidated frame!\n",
|
||||
item->Name(), item->Frame(), aData->mLayer.get());
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// Let the display item check for geometry changes and decide what needs to be
|
||||
// repainted.
|
||||
const nsRegion& changedFrameInvalidations =
|
||||
aData->GetChangedFrameInvalidations();
|
||||
|
||||
const nsRegion& changedFrameInvalidations = aData->GetChangedFrameInvalidations();
|
||||
aData->mGeometry->MoveBy(shift);
|
||||
item->ComputeInvalidationRegion(mDisplayListBuilder, aData->mGeometry, &combined);
|
||||
|
||||
nsRegion combined;
|
||||
item->ComputeInvalidationRegion(mDisplayListBuilder, aData->mGeometry,
|
||||
&combined);
|
||||
|
||||
// Only allocate a new geometry object if something actually changed, otherwise the existing
|
||||
// one should be fine. We always reallocate for inactive layers, since these types don't
|
||||
@ -5278,6 +5315,7 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
|
||||
item->NeedsGeometryUpdates()) {
|
||||
geometry = item->AllocateGeometry(mDisplayListBuilder);
|
||||
}
|
||||
|
||||
aData->mClip.AddOffsetAndComputeDifference(shift, aData->mGeometry->ComputeInvalidationRegion(),
|
||||
clip, geometry ? geometry->ComputeInvalidationRegion() :
|
||||
aData->mGeometry->ComputeInvalidationRegion(),
|
||||
@ -5292,19 +5330,29 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
|
||||
if (clip.ComputeRegionInClips(&aData->mClip, shift, &clipRegion)) {
|
||||
combined.And(combined, clipRegion);
|
||||
}
|
||||
|
||||
invalidPixels = combined.ScaleToOutsidePixels(layerData->mXScale,
|
||||
layerData->mYScale,
|
||||
appUnitsPerDevPixel);
|
||||
|
||||
if (aData->mTransform) {
|
||||
invalidPixels =
|
||||
aData->mTransform->TransformRegion(invalidPixels, appUnitsPerDevPixel);
|
||||
}
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
|
||||
if (!combined.IsEmpty()) {
|
||||
printf_stderr("Display item type %s(%p) (in layer %p) changed geometry!\n", item->Name(), item->Frame(), aData->mLayer.get());
|
||||
printf_stderr("Display item type %s(%p) (in layer %p) changed geometry!\n",
|
||||
item->Name(), item->Frame(), aData->mLayer.get());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (!combined.IsEmpty()) {
|
||||
InvalidatePostTransformRegion(paintedLayer,
|
||||
combined.ScaleToOutsidePixels(layerData->mXScale, layerData->mYScale, layerData->mAppUnitsPerDevPixel),
|
||||
layerData->mTranslation,
|
||||
aData->mTransform);
|
||||
|
||||
if (!invalidPixels.IsEmpty()) {
|
||||
InvalidatePostTransformRegion(paintedLayer, invalidPixels,
|
||||
layerData->mTranslation);
|
||||
}
|
||||
|
||||
aData->EndUpdate(geometry);
|
||||
@ -5361,6 +5409,7 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
||||
data->mOptLayer = aLayer;
|
||||
}
|
||||
|
||||
data->mOldTransform = data->mTransform;
|
||||
data->mTransform = aItem.mTransform;
|
||||
}
|
||||
|
||||
@ -5415,6 +5464,7 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
||||
tempManager);
|
||||
data = layerBuilder->StoreDataForFrame(aItem.mItem, tmpLayer,
|
||||
LAYER_ACTIVE, data);
|
||||
data->mOldTransform = data->mTransform;
|
||||
data->mTransform = aItem.mTransform;
|
||||
}
|
||||
|
||||
@ -5455,9 +5505,14 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
||||
invalid.And(invalid, intClip);
|
||||
}
|
||||
|
||||
if (data && data->mTransform) {
|
||||
invalid =
|
||||
data->mTransform->TransformRegion(invalid,
|
||||
paintedData->mAppUnitsPerDevPixel);
|
||||
}
|
||||
|
||||
InvalidatePostTransformRegion(layer, invalid,
|
||||
GetTranslationForPaintedLayer(layer),
|
||||
data ? data->mTransform.get() : nullptr);
|
||||
GetTranslationForPaintedLayer(layer));
|
||||
}
|
||||
}
|
||||
aItem.mInactiveLayerManager = tempManager;
|
||||
|
@ -121,6 +121,7 @@ public:
|
||||
}
|
||||
|
||||
RefPtr<TransformClipNode> mTransform;
|
||||
RefPtr<TransformClipNode> mOldTransform;
|
||||
|
||||
private:
|
||||
DisplayItemData(LayerManagerData* aParent,
|
||||
|
Loading…
Reference in New Issue
Block a user