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 8056ad42af
commit 14342d950c
6 changed files with 56 additions and 26 deletions

View File

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

View File

@ -46,7 +46,14 @@ class nsISVGSVGFrame
public: public:
NS_DECL_QUERYFRAME_TARGET(nsISVGSVGFrame) 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__ #endif // __NS_ISVGSVGFRAME_H__

View File

@ -236,9 +236,14 @@ nsSVGInnerSVGFrame::GetFrameForPoint(const nsPoint &aPoint)
// nsISVGSVGFrame methods: // nsISVGSVGFrame methods:
void 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(); virtual gfxMatrix GetCanvasTM();
// nsISVGSVGFrame interface: // nsISVGSVGFrame interface:
virtual void NotifyViewportChange(); virtual void NotifyViewportOrTransformChanged(PRUint32 aFlags);
protected: protected:

View File

@ -415,12 +415,18 @@ nsSVGOuterSVGFrame::Reflow(nsPresContext* aPresContext,
nsSVGSVGElement *svgElem = static_cast<nsSVGSVGElement*>(mContent); nsSVGSVGElement *svgElem = static_cast<nsSVGSVGElement*>(mContent);
if (newViewportSize != svgElem->GetViewportSize() || PRUint32 changeBits = 0;
mFullZoom != PresContext()->GetFullZoom()) { if (newViewportSize != svgElem->GetViewportSize()) {
changeBits |= COORD_CONTEXT_CHANGED;
svgElem->SetViewportSize(newViewportSize); svgElem->SetViewportSize(newViewportSize);
mViewportInitialized = true; }
if (mFullZoom != PresContext()->GetFullZoom()) {
changeBits |= TRANSFORM_CHANGED;
mFullZoom = PresContext()->GetFullZoom(); mFullZoom = PresContext()->GetFullZoom();
NotifyViewportChange(); }
mViewportInitialized = true;
if (changeBits) {
NotifyViewportOrTransformChanged(changeBits);
} }
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
@ -705,30 +711,41 @@ nsSVGOuterSVGFrame::GetType() const
// nsISVGSVGFrame methods: // nsISVGSVGFrame methods:
void 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) { if (!mViewportInitialized) {
return; 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 (aFlags & COORD_CONTEXT_CHANGED) {
#if 1 if (content->HasViewBox() || content->ShouldSynthesizeViewBox()) {
{ // Percentage lengths on children resolve against the viewBox rect so we
#else // don't need to notify them of the viewport change, but the viewBox
// XXX this caused reftest failures (bug 413960) // transform will have changed, so we need to notify them of that instead.
if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::viewBox)) { aFlags = TRANSFORM_CHANGED;
#endif }
// make sure canvas transform matrix gets (lazily) recalculated: else if (mCanvasTM && mCanvasTM->IsSingular()) {
mCanvasTM = nsnull; // 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
flags |= TRANSFORM_CHANGED; // mCanvasTM for this width/height change even though we don't have a
// viewBox.
aFlags |= TRANSFORM_CHANGED;
}
} }
// inform children if (aFlags & TRANSFORM_CHANGED) {
nsSVGUtils::NotifyChildrenOfSVGChange(this, flags); // Make sure our canvas transform matrix gets (lazily) recalculated:
mCanvasTM = nsnull;
}
nsSVGUtils::NotifyChildrenOfSVGChange(this, aFlags);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

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