Bug 735898. Part 1: Cache bounds (union of all child item bounds) in nsDisplayWrapList. r=mattwoodrow

This commit is contained in:
Robert O'Callahan 2012-04-11 16:48:47 +12:00
parent 04eb195d7e
commit 84a03695da
2 changed files with 26 additions and 17 deletions

View File

@ -1569,12 +1569,14 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList)
: nsDisplayItem(aBuilder, aFrame) {
mList.AppendToTop(aList);
mBounds = mList.GetBounds(aBuilder);
}
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayItem* aItem)
: nsDisplayItem(aBuilder, aFrame) {
mList.AppendToTop(aItem);
mBounds = mList.GetBounds(aBuilder);
}
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
@ -1595,7 +1597,7 @@ nsDisplayWrapList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
nsRect
nsDisplayWrapList::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return mList.GetBounds(aBuilder);
return mBounds;
}
bool
@ -1615,6 +1617,7 @@ nsDisplayWrapList::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
*aSnap = false;
nsRegion result;
if (mList.IsOpaque()) {
// Everything within GetBounds that's visible is opaque.
result = GetBounds(aBuilder, aSnap);
}
return result;
@ -1834,7 +1837,7 @@ bool nsDisplayOpacity::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* a
// aItem->GetUnderlyingFrame() returns non-null because it's nsDisplayOpacity
if (aItem->GetUnderlyingFrame()->GetContent() != mFrame->GetContent())
return false;
mList.AppendToBottom(&static_cast<nsDisplayOpacity*>(aItem)->mList);
MergeFrom(static_cast<nsDisplayOpacity*>(aItem));
return true;
}
@ -2002,7 +2005,7 @@ nsDisplayScrollLayer::TryMerge(nsDisplayListBuilder* aBuilder,
props.Set(nsIFrame::ScrollLayerCount(),
reinterpret_cast<void*>(GetScrollLayerCount() - 1));
mList.AppendToBottom(&other->mList);
MergeFrom(other);
// XXX - This ensures that the frame associated with a scroll layer after
// merging is the first, rather than the last. This tends to change less,
// ensuring we're more likely to retain the associated gfx layer.
@ -2141,13 +2144,13 @@ bool nsDisplayClip::ComputeVisibility(nsDisplayListBuilder* aBuilder,
}
bool nsDisplayClip::TryMerge(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem) {
nsDisplayItem* aItem) {
if (aItem->GetType() != TYPE_CLIP)
return false;
nsDisplayClip* other = static_cast<nsDisplayClip*>(aItem);
if (!other->mClip.IsEqualInterior(mClip))
return false;
mList.AppendToBottom(&other->mList);
MergeFrom(other);
return true;
}
@ -2242,7 +2245,7 @@ bool nsDisplayClipRoundedRect::TryMerge(nsDisplayListBuilder* aBuilder, nsDispla
if (!mClip.IsEqualInterior(other->mClip) ||
memcmp(mRadii, other->mRadii, sizeof(mRadii)) != 0)
return false;
mList.AppendToBottom(&other->mList);
MergeFrom(other);
return true;
}
@ -2903,8 +2906,7 @@ nsDisplayTransform::TryMerge(nsDisplayListBuilder *aBuilder,
/* Now, move everything over to this frame and signal that
* we merged things!
*/
mStoredList.GetList()->
AppendToBottom(&static_cast<nsDisplayTransform *>(aItem)->mStoredList);
mStoredList.MergeFrom(&static_cast<nsDisplayTransform*>(aItem)->mStoredList);
return true;
}
@ -2992,7 +2994,7 @@ bool nsDisplayTransform::UntransformRect(const nsRect &aUntransformedBounds,
nsDisplaySVGEffects::nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList)
: nsDisplayWrapList(aBuilder, aFrame, aList), mEffectsFrame(aFrame),
mBounds(aFrame->GetVisualOverflowRectRelativeToSelf())
mEffectsBounds(aFrame->GetVisualOverflowRectRelativeToSelf())
{
MOZ_COUNT_CTOR(nsDisplaySVGEffects);
}
@ -3059,9 +3061,9 @@ bool nsDisplaySVGEffects::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem
if (aItem->GetUnderlyingFrame()->GetContent() != mFrame->GetContent())
return false;
nsDisplaySVGEffects* other = static_cast<nsDisplaySVGEffects*>(aItem);
mList.AppendToBottom(&other->mList);
mBounds.UnionRect(mBounds,
other->mBounds + other->mEffectsFrame->GetOffsetTo(mEffectsFrame));
MergeFrom(other);
mEffectsBounds.UnionRect(mEffectsBounds,
other->mEffectsBounds + other->mEffectsFrame->GetOffsetTo(mEffectsFrame));
return true;
}

View File

@ -1701,8 +1701,8 @@ public:
nsIFrame* aFrame);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion);
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion);
virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) {
NS_WARNING("This list should already have been flattened!!!");
return false;
@ -1737,8 +1737,15 @@ public:
protected:
nsDisplayWrapList() {}
void MergeFrom(nsDisplayWrapList* aOther)
{
mList.AppendToBottom(&aOther->mList);
mBounds.UnionRect(mBounds, aOther->mBounds);
}
nsDisplayList mList;
nsRect mBounds;
};
/**
@ -2065,7 +2072,7 @@ public:
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return mBounds + aBuilder->ToReferenceFrame(mEffectsFrame);
return mEffectsBounds + aBuilder->ToReferenceFrame(mEffectsFrame);
}
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
@ -2083,7 +2090,7 @@ public:
private:
nsIFrame* mEffectsFrame;
// relative to mEffectsFrame
nsRect mBounds;
nsRect mEffectsBounds;
};
/* A display item that applies a transformation to all of its descendant