Bug 413960, part 2 - Stop sending out unnecessary COORD_CONTEXT_CHANGED/TRANSFORM_CHANGED notifications from nsSVGOuterSVGFrame. r=longsonr.

--HG--
extra : rebase_source : fa0e8a232559e19b9a151a34a8f235154327409b
This commit is contained in:
Jonathan Watt 2012-05-03 17:05:53 +01:00
parent e5b7d2725a
commit 2977682c89
6 changed files with 56 additions and 26 deletions

View File

@ -1107,7 +1107,8 @@ nsSVGSVGElement::InvalidateTransformNotifyFrame()
nsISVGSVGFrame* svgframe = do_QueryFrame(frame);
// might fail this check if we've failed conditional processing
if (svgframe) {
svgframe->NotifyViewportChange();
svgframe->NotifyViewportOrTransformChanged(
nsISVGChildFrame::TRANSFORM_CHANGED);
}
}
}

View File

@ -46,7 +46,14 @@ class nsISVGSVGFrame
public:
NS_DECL_QUERYFRAME_TARGET(nsISVGSVGFrame)
virtual void NotifyViewportChange()=0;
/**
* Called when non-attribute changes have caused the element's width/height
* or its for-children transform to change, and to get the element to notify
* its children appropriately. aFlags must be set to
* nsISVGChildFrame::COORD_CONTEXT_CHANGED and/or
* nsISVGChildFrame::TRANSFORM_CHANGED.
*/
virtual void NotifyViewportOrTransformChanged(PRUint32 aFlags)=0;
};
#endif // __NS_ISVGSVGFRAME_H__

View File

@ -236,9 +236,14 @@ nsSVGInnerSVGFrame::GetFrameForPoint(const nsPoint &aPoint)
// nsISVGSVGFrame methods:
void
nsSVGInnerSVGFrame::NotifyViewportChange()
nsSVGInnerSVGFrame::NotifyViewportOrTransformChanged(PRUint32 aFlags)
{
NS_ERROR("Inner SVG frames should not get Viewport changes.");
// The dimensions of inner-<svg> frames are purely defined by their "width"
// and "height" attributes, and transform changes can only occur as a result
// of changes to their "width", "height", "viewBox" or "preserveAspectRatio"
// attributes. Changes to all of these attributes are handled in
// AttributeChanged(), so we should never be called.
NS_ERROR("Not called for nsSVGInnerSVGFrame");
}
//----------------------------------------------------------------------

View File

@ -91,7 +91,7 @@ public:
virtual gfxMatrix GetCanvasTM();
// nsISVGSVGFrame interface:
virtual void NotifyViewportChange();
virtual void NotifyViewportOrTransformChanged(PRUint32 aFlags);
protected:

View File

@ -415,12 +415,18 @@ nsSVGOuterSVGFrame::Reflow(nsPresContext* aPresContext,
nsSVGSVGElement *svgElem = static_cast<nsSVGSVGElement*>(mContent);
if (newViewportSize != svgElem->GetViewportSize() ||
mFullZoom != PresContext()->GetFullZoom()) {
PRUint32 changeBits = 0;
if (newViewportSize != svgElem->GetViewportSize()) {
changeBits |= COORD_CONTEXT_CHANGED;
svgElem->SetViewportSize(newViewportSize);
mViewportInitialized = true;
}
if (mFullZoom != PresContext()->GetFullZoom()) {
changeBits |= TRANSFORM_CHANGED;
mFullZoom = PresContext()->GetFullZoom();
NotifyViewportChange();
}
mViewportInitialized = true;
if (changeBits) {
NotifyViewportOrTransformChanged(changeBits);
}
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
@ -705,30 +711,41 @@ nsSVGOuterSVGFrame::GetType() const
// nsISVGSVGFrame methods:
void
nsSVGOuterSVGFrame::NotifyViewportChange()
nsSVGOuterSVGFrame::NotifyViewportOrTransformChanged(PRUint32 aFlags)
{
// no point in doing anything when were not init'ed yet:
NS_ABORT_IF_FALSE(aFlags &&
!(aFlags & ~(COORD_CONTEXT_CHANGED | TRANSFORM_CHANGED)),
"Unexpected aFlags value");
// No point in doing anything when were not init'ed yet:
if (!mViewportInitialized) {
return;
}
PRUint32 flags = COORD_CONTEXT_CHANGED;
nsSVGSVGElement *content = static_cast<nsSVGSVGElement*>(mContent);
// viewport changes only affect our transform if we have a viewBox attribute
#if 1
{
#else
// XXX this caused reftest failures (bug 413960)
if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::viewBox)) {
#endif
// make sure canvas transform matrix gets (lazily) recalculated:
mCanvasTM = nsnull;
flags |= TRANSFORM_CHANGED;
if (aFlags & COORD_CONTEXT_CHANGED) {
if (content->HasViewBox() || content->ShouldSynthesizeViewBox()) {
// Percentage lengths on children resolve against the viewBox rect so we
// don't need to notify them of the viewport change, but the viewBox
// transform will have changed, so we need to notify them of that instead.
aFlags = TRANSFORM_CHANGED;
}
else if (mCanvasTM && mCanvasTM->IsSingular()) {
// A width/height of zero will result in us having a singular mCanvasTM
// even when we don't have a viewBox. So we also want to recompute our
// mCanvasTM for this width/height change even though we don't have a
// viewBox.
aFlags |= TRANSFORM_CHANGED;
}
}
// inform children
nsSVGUtils::NotifyChildrenOfSVGChange(this, flags);
if (aFlags & TRANSFORM_CHANGED) {
// Make sure our canvas transform matrix gets (lazily) recalculated:
mCanvasTM = nsnull;
}
nsSVGUtils::NotifyChildrenOfSVGChange(this, aFlags);
}
//----------------------------------------------------------------------

View File

@ -114,7 +114,7 @@ public:
PRInt32 aModType);
// nsISVGSVGFrame interface:
virtual void NotifyViewportChange();
virtual void NotifyViewportOrTransformChanged(PRUint32 aFlags);
// nsSVGContainerFrame methods:
virtual gfxMatrix GetCanvasTM();