Bug 1205087 - Cache the AnimatedGeometryRoot on DisplayItem. r=roc

This commit is contained in:
Kartikaya Gupta 2015-10-05 17:09:34 -04:00
parent 9489abdaa4
commit 99f5fcc021
7 changed files with 57 additions and 15 deletions

View File

@ -1061,7 +1061,7 @@ public:
MOZ_ASSERT_IF(isAtRoot, mContainerReferenceFrame == mBuilder->RootReferenceFrame());
mContainerAnimatedGeometryRoot = isAtRoot
? mContainerReferenceFrame
: nsLayoutUtils::GetAnimatedGeometryRootFor(aContainerItem, aBuilder);
: aContainerItem->AnimatedGeometryRoot();
MOZ_ASSERT(!mBuilder->IsPaintingToWindow() ||
nsLayoutUtils::IsAncestorFrameCrossDoc(mBuilder->RootReferenceFrame(),
mContainerAnimatedGeometryRoot));
@ -3716,8 +3716,7 @@ ContainerState::ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
// Try using the actual active scrolled root of the backmost item, as that
// should result in the least invalidation when scrolling.
*aAnimatedGeometryRoot =
nsLayoutUtils::GetAnimatedGeometryRootFor(item, mBuilder);
*aAnimatedGeometryRoot = item->AnimatedGeometryRoot();
return true;
}
return false;
@ -3892,8 +3891,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
bool forceInactive;
const nsIFrame* animatedGeometryRoot;
const nsIFrame* animatedGeometryRootForScrollMetadata = nullptr;
const nsIFrame* realAnimatedGeometryRootOfItem =
nsLayoutUtils::GetAnimatedGeometryRootFor(item, mBuilder);
const nsIFrame* realAnimatedGeometryRootOfItem = item->AnimatedGeometryRoot();
if (mFlattenToSingleLayer) {
forceInactive = true;
animatedGeometryRoot = lastAnimatedGeometryRoot;

View File

@ -1996,11 +1996,17 @@ void nsDisplayList::Sort(nsDisplayListBuilder* aBuilder,
nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: mFrame(aFrame)
, mClip(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder))
, mAnimatedGeometryRoot(nullptr)
#ifdef MOZ_DUMP_PAINTING
, mPainted(false)
#endif
{
mReferenceFrame = aBuilder->FindReferenceFrameFor(aFrame, &mToReferenceFrame);
// This can return the wrong result if the item override ShouldFixToViewport(),
// the item needs to set it again in its constructor.
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootForInit(this, aBuilder);
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(),
mAnimatedGeometryRoot), "Bad");
NS_ASSERTION(aBuilder->GetDirtyRect().width >= 0 ||
!aBuilder->IsForPainting(), "dirty rect not set");
// The dirty rect is for mCurrentFrame, so we have to use
@ -2141,6 +2147,9 @@ nsDisplayBackgroundImage::nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilde
mBounds = GetBoundsInternal(aBuilder);
mDestArea = GetDestAreaInternal(aBuilder);
if (ShouldFixToViewport(aBuilder)) {
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootFor(this, aBuilder);
}
}
nsRect
@ -3786,8 +3795,7 @@ RequiredLayerStateForChildren(nsDisplayListBuilder* aBuilder,
LayerState result = LAYER_INACTIVE;
for (nsDisplayItem* i = aList.GetBottom(); i; i = i->GetAbove()) {
if (result == LAYER_INACTIVE &&
nsLayoutUtils::GetAnimatedGeometryRootFor(i, aBuilder) !=
aExpectedAnimatedGeometryRootForChildren) {
i->AnimatedGeometryRoot() != aExpectedAnimatedGeometryRootForChildren) {
result = LAYER_ACTIVE;
}
@ -4061,8 +4069,7 @@ nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
if (NeedsActiveLayer(aBuilder))
return LAYER_ACTIVE;
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList,
nsLayoutUtils::GetAnimatedGeometryRootFor(this, aBuilder));
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList, AnimatedGeometryRoot());
}
bool
@ -4794,6 +4801,7 @@ nsDisplayTransform::SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder)
mReferenceFrame =
aBuilder->FindReferenceFrameFor(outerFrame);
mToReferenceFrame = mFrame->GetOffsetToCrossDoc(mReferenceFrame);
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootForFrame(aBuilder, outerFrame);
mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame;
}

View File

@ -1231,6 +1231,7 @@ public:
: mFrame(aFrame)
, mClip(nullptr)
, mReferenceFrame(nullptr)
, mAnimatedGeometryRoot(nullptr)
#ifdef MOZ_DUMP_PAINTING
, mPainted(false)
#endif
@ -1692,6 +1693,11 @@ public:
*/
virtual const nsIFrame* ReferenceFrameForChildren() const { return mReferenceFrame; }
nsIFrame* AnimatedGeometryRoot() const {
MOZ_ASSERT(mAnimatedGeometryRoot, "Must have cached AGR before accessing it!");
return mAnimatedGeometryRoot;
}
/**
* Checks if this display item (or any children) contains content that might
* be rendered with component alpha (e.g. subpixel antialiasing). Returns the
@ -1751,6 +1757,7 @@ protected:
const DisplayItemClip* mClip;
// Result of FindReferenceFrameFor(mFrame), if mFrame is non-null
const nsIFrame* mReferenceFrame;
nsIFrame* mAnimatedGeometryRoot;
// Result of ToReferenceFrame(mFrame), if mFrame is non-null
nsPoint mToReferenceFrame;
// This is the rectangle that needs to be painted.

View File

@ -162,9 +162,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
}
bool snap;
nsRect rect = aItem->GetBounds(aBuilder, &snap);
nsRect layerRect = rect -
nsLayoutUtils::GetAnimatedGeometryRootFor(aItem, aBuilder)->
GetOffsetToCrossDoc(aItem->ReferenceFrame());
nsRect layerRect = rect - aItem->AnimatedGeometryRoot()->GetOffsetToCrossDoc(aItem->ReferenceFrame());
nscolor color;
nsRect vis = aItem->GetVisibleRect();
nsRect component = aItem->GetComponentAlphaBounds(aBuilder);
@ -179,7 +177,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
aStream << nsPrintfCString("<a href=\"javascript:ViewImage('%s')\">", string.BeginReading());
}
#endif
aStream << nsPrintfCString("%s p=0x%p f=0x%p(%s) %sbounds(%d,%d,%d,%d) layerBounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) %s",
aStream << nsPrintfCString("%s p=0x%p f=0x%p(%s) %sbounds(%d,%d,%d,%d) layerBounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) %s ref=0x%p agr=0x%p",
aItem->Name(), aItem, (void*)f, NS_ConvertUTF16toUTF8(contentData).get(),
(aItem->ZIndex() ? nsPrintfCString("z=%d ", aItem->ZIndex()).get() : ""),
rect.x, rect.y, rect.width, rect.height,
@ -187,7 +185,8 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
vis.x, vis.y, vis.width, vis.height,
component.x, component.y, component.width, component.height,
clip.ToString().get(),
aItem->IsUniform(aBuilder, &color) ? " uniform" : "");
aItem->IsUniform(aBuilder, &color) ? " uniform" : "",
aItem->ReferenceFrame(), aItem->AnimatedGeometryRoot());
nsRegionRectIterator iter(opaque);
for (const nsRect* r = iter.Next(); r; r = iter.Next()) {

View File

@ -1961,6 +1961,25 @@ nsLayoutUtils::GetAnimatedGeometryRootFor(nsDisplayItem* aItem,
return GetAnimatedGeometryRootForFrame(aBuilder, f);
}
nsIFrame*
nsLayoutUtils::GetAnimatedGeometryRootForInit(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder)
{
nsIFrame* f = aItem->Frame();
if (aItem->ShouldFixToViewport(aBuilder)) {
// Make its active scrolled root be the active scrolled root of
// the enclosing viewport, since it shouldn't be scrolled by scrolled
// frames in its document. InvalidateFixedBackgroundFramesFromList in
// nsGfxScrollFrame will not repaint this item when scrolling occurs.
nsIFrame* viewportFrame =
nsLayoutUtils::GetClosestFrameOfType(f, nsGkAtoms::viewportFrame, aBuilder->RootReferenceFrame());
if (viewportFrame) {
return GetAnimatedGeometryRootForFrame(aBuilder, viewportFrame);
}
}
return GetAnimatedGeometryRootForFrame(aBuilder, f);
}
// static
nsIScrollableFrame*
nsLayoutUtils::GetNearestScrollableFrameForDirection(nsIFrame* aFrame,

View File

@ -563,6 +563,13 @@ public:
static nsIFrame* GetAnimatedGeometryRootFor(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder,
uint32_t aFlags = 0);
/**
* Version of GetAnimatedGeometryRootFor that can be called in nsDisplayItem
* constructor, and only from there. Not valid for transform items, but they
* set their AGR in their constructor.
*/
static nsIFrame* GetAnimatedGeometryRootForInit(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder);
/**
* Finds the nearest ancestor frame to aFrame that is considered to have (or

View File

@ -239,7 +239,11 @@ public:
nsDisplayCanvasBackgroundImage(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
uint32_t aLayer, const nsStyleBackground* aBg)
: nsDisplayBackgroundImage(aBuilder, aFrame, aLayer, aBg)
{}
{
if (ShouldFixToViewport(aBuilder)) {
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootFor(this, aBuilder);
}
}
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override;