Bug 771795 - Stop over-invalidating SVG. r=heycam.

This commit is contained in:
Jonathan Watt 2012-07-08 08:29:57 +02:00
parent cda7a1ab86
commit 5047eaf363
7 changed files with 71 additions and 30 deletions

View File

@ -271,6 +271,15 @@ nsSVGDisplayContainerFrame::UpdateBounds()
nsSVGEffects::UpdateEffects(this);
}
// We only invalidate if we are dirty, if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be invalidated
// when it gets that initial reflow), and if our parent is not dirty (since
// if it is, then it will invalidate its entire new area, which will include
// our new area).
bool invalidate = (mState & NS_FRAME_IS_DIRTY) &&
!(GetParent()->GetStateBits() &
(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY));
FinishAndStoreOverflow(overflowRects, mRect.Size());
// Remove state bits after FinishAndStoreOverflow so that it doesn't
@ -278,10 +287,7 @@ nsSVGDisplayContainerFrame::UpdateBounds()
mState &= ~(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY |
NS_FRAME_HAS_DIRTY_CHILDREN);
if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
// We only invalidate if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be
// invalidated when it gets that initial reflow):
if (invalidate) {
// XXXSDL Let FinishAndStoreOverflow do this.
nsSVGUtils::InvalidateBounds(this, true);
}

View File

@ -381,6 +381,15 @@ nsSVGForeignObjectFrame::UpdateBounds()
nsSVGEffects::UpdateEffects(this);
}
// We only invalidate if we are dirty, if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be invalidated
// when it gets that initial reflow), and if our parent is not dirty (since
// if it is, then it will invalidate its entire new area, which will include
// our new area).
bool invalidate = (mState & NS_FRAME_IS_DIRTY) &&
!(GetParent()->GetStateBits() &
(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY));
// TODO: once we support |overflow:visible| on foreignObject, then we will
// need to take account of our descendants here.
nsRect overflow = nsRect(nsPoint(0,0), mRect.Size());
@ -391,10 +400,7 @@ nsSVGForeignObjectFrame::UpdateBounds()
mState &= ~(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY |
NS_FRAME_HAS_DIRTY_CHILDREN);
if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
// We only invalidate if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be
// invalidated when it gets that initial reflow):
if (invalidate) {
// XXXSDL Let FinishAndStoreOverflow do this.
nsSVGUtils::InvalidateBounds(this, true);
}

View File

@ -490,6 +490,15 @@ nsSVGGlyphFrame::UpdateBounds()
mCoveredRegion = nsSVGUtils::TransformFrameRectToOuterSVG(
mRect, GetCanvasTM(FOR_OUTERSVG_TM), PresContext());
// We only invalidate if we are dirty, if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be invalidated
// when it gets that initial reflow), and if our parent is not dirty (since
// if it is, then it will invalidate its entire new area, which will include
// our new area).
bool invalidate = (mState & NS_FRAME_IS_DIRTY) &&
!(GetParent()->GetStateBits() &
(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY));
nsRect overflow = nsRect(nsPoint(0,0), mRect.Size());
nsOverflowAreas overflowAreas(overflow, overflow);
FinishAndStoreOverflow(overflowAreas, mRect.Size());
@ -497,10 +506,7 @@ nsSVGGlyphFrame::UpdateBounds()
mState &= ~(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY |
NS_FRAME_HAS_DIRTY_CHILDREN);
if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
// We only invalidate if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be
// invalidated when it gets that initial reflow):
if (invalidate) {
// XXXSDL Let FinishAndStoreOverflow do this.
nsSVGUtils::InvalidateBounds(this, true);
}

View File

@ -496,6 +496,15 @@ nsSVGImageFrame::UpdateBounds()
nsSVGEffects::UpdateEffects(this);
}
// We only invalidate if we are dirty, if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be invalidated
// when it gets that initial reflow), and if our parent is not dirty (since
// if it is, then it will invalidate its entire new area, which will include
// our new area).
bool invalidate = (mState & NS_FRAME_IS_DIRTY) &&
!(GetParent()->GetStateBits() &
(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY));
nsRect overflow = nsRect(nsPoint(0,0), mRect.Size());
nsOverflowAreas overflowAreas(overflow, overflow);
FinishAndStoreOverflow(overflowAreas, mRect.Size());
@ -503,10 +512,7 @@ nsSVGImageFrame::UpdateBounds()
mState &= ~(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY |
NS_FRAME_HAS_DIRTY_CHILDREN);
if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
// We only invalidate if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be
// invalidated when it gets that initial reflow):
if (invalidate) {
// XXXSDL Let FinishAndStoreOverflow do this.
nsSVGUtils::InvalidateBounds(this, true);
}

View File

@ -239,6 +239,15 @@ nsSVGPathGeometryFrame::UpdateBounds()
nsSVGEffects::UpdateEffects(this);
}
// We only invalidate if we are dirty, if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be invalidated
// when it gets that initial reflow), and if our parent is not dirty (since
// if it is, then it will invalidate its entire new area, which will include
// our new area).
bool invalidate = (mState & NS_FRAME_IS_DIRTY) &&
!(GetParent()->GetStateBits() &
(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY));
nsRect overflow = nsRect(nsPoint(0,0), mRect.Size());
nsOverflowAreas overflowAreas(overflow, overflow);
FinishAndStoreOverflow(overflowAreas, mRect.Size());
@ -246,12 +255,8 @@ nsSVGPathGeometryFrame::UpdateBounds()
mState &= ~(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY |
NS_FRAME_HAS_DIRTY_CHILDREN);
// XXXSDL get rid of this in favor of the invalidate call in
// FinishAndStoreOverflow?
if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
// We only invalidate if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be
// invalidated when it gets that initial reflow):
if (invalidate) {
// XXXSDL Let FinishAndStoreOverflow do this.
nsSVGUtils::InvalidateBounds(this, true);
}
}

View File

@ -184,6 +184,15 @@ nsSVGSwitchFrame::UpdateBounds()
nsSVGEffects::UpdateEffects(this);
}
// We only invalidate if we are dirty, if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be invalidated
// when it gets that initial reflow), and if our parent is not dirty (since
// if it is, then it will invalidate its entire new area, which will include
// our new area).
bool invalidate = (mState & NS_FRAME_IS_DIRTY) &&
!(GetParent()->GetStateBits() &
(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY));
FinishAndStoreOverflow(overflowRects, mRect.Size());
// Remove state bits after FinishAndStoreOverflow so that it doesn't
@ -191,10 +200,7 @@ nsSVGSwitchFrame::UpdateBounds()
mState &= ~(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY |
NS_FRAME_HAS_DIRTY_CHILDREN);
if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
// We only invalidate if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be
// invalidated when it gets that initial reflow):
if (invalidate) {
// XXXSDL Let FinishAndStoreOverflow do this.
nsSVGUtils::InvalidateBounds(this, true);
}

View File

@ -231,14 +231,20 @@ nsSVGTextFrame::UpdateBounds()
UpdateGlyphPositioning(false);
// We only invalidate if we are dirty, if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be invalidated
// when it gets that initial reflow), and if our parent is not dirty (since
// if it is, then it will invalidate its entire new area, which will include
// our new area).
bool invalidate = (mState & NS_FRAME_IS_DIRTY) &&
!(GetParent()->GetStateBits() &
(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY));
// With glyph positions updated, our descendants can invalidate their new
// areas correctly:
nsSVGTextFrameBase::UpdateBounds();
if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
// We only invalidate if our outer-<svg> has already had its
// initial reflow (since if it hasn't, its entire area will be
// invalidated when it gets that initial reflow):
if (invalidate) {
// XXXSDL Let FinishAndStoreOverflow do this.
nsSVGUtils::InvalidateBounds(this, true);
}