Bug 1396776 - Part 1. Change the type of mCancasTM from AutoPtr<gfxMatrix> to Maybe<gfxMatrix>.
With this chnage, we do not need to allocate/deacllote memory for mCanvasTM when
GetCanvasTM/ NotifySVGChanged(nsSVGDisplayableFrame::TRANSFORM_CHANGED) was
called.
MozReview-Commit-ID: 45xOMQh5nwo
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -3207,17 +3207,17 @@ SVGTextFrame::AttributeChanged(int32_t a
// return nsChangeHint_UpdateOverflow for "transform" attribute changes
// and cause DoApplyRenderingChangeToTree to make the SchedulePaint call.
if (!(mState & NS_FRAME_FIRST_REFLOW) &&
mCanvasTM && mCanvasTM->IsSingular()) {
// We won't have calculated the glyph positions correctly.
NotifyGlyphMetricsChange();
}
- mCanvasTM = nullptr;
+ mCanvasTM.reset();
} else if (IsGlyphPositioningAttribute(aAttribute) ||
aAttribute == nsGkAtoms::textLength ||
aAttribute == nsGkAtoms::lengthAdjust) {
NotifyGlyphMetricsChange();
}
return NS_OK;
}
@@ -3484,17 +3484,17 @@ SVGTextFrame::NotifySVGChanged(uint32_t
}
}
// If the scale at which we computed our mFontSizeScaleFactor has changed by
// at least a factor of two, reflow the text. This avoids reflowing text
// at every tick of a transform animation, but ensures our glyph metrics
// do not get too far out of sync with the final font size on the screen.
if (needNewCanvasTM && mLastContextScale != 0.0f) {
- mCanvasTM = nullptr;
+ mCanvasTM.reset();
// If we are a non-display frame, then we don't want to call
// GetCanvasTM(), since the context scale does not use it.
gfxMatrix newTM =
(mState & NS_FRAME_IS_NONDISPLAY) ? gfxMatrix() :
GetCanvasTM();
// Compare the old and new context scales.
float scale = GetContextScale(newTM);
float change = scale / mLastContextScale;
@@ -3924,17 +3924,17 @@ SVGTextFrame::GetCanvasTM()
NS_ASSERTION(!(GetStateBits() & NS_FRAME_IS_NONDISPLAY),
"should not call GetCanvasTM() when we are non-display");
nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(GetParent());
dom::SVGTextContentElement *content = static_cast<dom::SVGTextContentElement*>(GetContent());
gfxMatrix tm = content->PrependLocalTransformsTo(parent->GetCanvasTM());
- mCanvasTM = new gfxMatrix(tm);
+ mCanvasTM = Some(tm);
}
return *mCanvasTM;
}
//----------------------------------------------------------------------
// SVGTextFrame SVG DOM methods
/**
--- a/layout/svg/SVGTextFrame.h
+++ b/layout/svg/SVGTextFrame.h
@@ -531,17 +531,17 @@ private:
/**
* The MutationObserver we have registered for the <text> element subtree.
*/
RefPtr<MutationObserver> mMutationObserver;
/**
* Cached canvasTM value.
*/
- nsAutoPtr<gfxMatrix> mCanvasTM;
+ Maybe<gfxMatrix> mCanvasTM;
/**
* The number of characters in the DOM after the final nsTextFrame. For
* example, with
*
* <text>abcd<tspan display="none">ef</tspan></text>
*
* mTrailingUndisplayedCharacters would be 2.
--- a/layout/svg/nsSVGAFrame.cpp
+++ b/layout/svg/nsSVGAFrame.cpp
@@ -46,17 +46,17 @@ public:
#endif
// nsSVGDisplayableFrame interface:
virtual void NotifySVGChanged(uint32_t aFlags) override;
// nsSVGContainerFrame methods:
virtual gfxMatrix GetCanvasTM() override;
private:
- nsAutoPtr<gfxMatrix> mCanvasTM;
+ Maybe<gfxMatrix> mCanvasTM;
};
//----------------------------------------------------------------------
// Implementation
nsIFrame*
NS_NewSVGAFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
{
@@ -119,17 +119,17 @@ nsSVGAFrame::AttributeChanged(int32_t
void
nsSVGAFrame::NotifySVGChanged(uint32_t aFlags)
{
MOZ_ASSERT(aFlags & (TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED),
"Invalidation logic may need adjusting");
if (aFlags & TRANSFORM_CHANGED) {
// make sure our cached transform matrix gets (lazily) updated
- mCanvasTM = nullptr;
+ mCanvasTM.reset();
}
nsSVGDisplayContainerFrame::NotifySVGChanged(aFlags);
}
//----------------------------------------------------------------------
// nsSVGContainerFrame methods:
@@ -139,13 +139,13 @@ nsSVGAFrame::GetCanvasTM()
if (!mCanvasTM) {
NS_ASSERTION(GetParent(), "null parent");
nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(GetParent());
dom::SVGAElement *content = static_cast<dom::SVGAElement*>(GetContent());
gfxMatrix tm = content->PrependLocalTransformsTo(parent->GetCanvasTM());
- mCanvasTM = new gfxMatrix(tm);
+ mCanvasTM = Some(tm);
}
return *mCanvasTM;
}
--- a/layout/svg/nsSVGGFrame.cpp
+++ b/layout/svg/nsSVGGFrame.cpp
@@ -47,34 +47,34 @@ nsSVGGFrame::Init(nsIContent* aCon
void
nsSVGGFrame::NotifySVGChanged(uint32_t aFlags)
{
MOZ_ASSERT(aFlags & (TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED),
"Invalidation logic may need adjusting");
if (aFlags & TRANSFORM_CHANGED) {
// make sure our cached transform matrix gets (lazily) updated
- mCanvasTM = nullptr;
+ mCanvasTM.reset();
}
nsSVGDisplayContainerFrame::NotifySVGChanged(aFlags);
}
gfxMatrix
nsSVGGFrame::GetCanvasTM()
{
if (!mCanvasTM) {
NS_ASSERTION(GetParent(), "null parent");
nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(GetParent());
SVGGraphicsElement *content = static_cast<SVGGraphicsElement*>(GetContent());
gfxMatrix tm = content->PrependLocalTransformsTo(parent->GetCanvasTM());
- mCanvasTM = new gfxMatrix(tm);
+ mCanvasTM = Some(tm);
}
return *mCanvasTM;
}
nsresult
nsSVGGFrame::AttributeChanged(int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType)
--- a/layout/svg/nsSVGGFrame.h
+++ b/layout/svg/nsSVGGFrame.h
@@ -45,12 +45,12 @@ public:
int32_t aModType) override;
// nsSVGDisplayableFrame interface:
virtual void NotifySVGChanged(uint32_t aFlags) override;
// nsSVGContainerFrame methods:
virtual gfxMatrix GetCanvasTM() override;
- nsAutoPtr<gfxMatrix> mCanvasTM;
+ Maybe<gfxMatrix> mCanvasTM;
};
#endif
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -691,17 +691,17 @@ nsSVGOuterSVGFrame::AttributeChanged(int
{
if (aNameSpaceID == kNameSpaceID_None &&
!(GetStateBits() & (NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_NONDISPLAY))) {
if (aAttribute == nsGkAtoms::viewBox ||
aAttribute == nsGkAtoms::preserveAspectRatio ||
aAttribute == nsGkAtoms::transform) {
// make sure our cached transform matrix gets (lazily) updated
- mCanvasTM = nullptr;
+ mCanvasTM.reset();
nsSVGUtils::NotifyChildrenOfSVGChange(PrincipalChildList().FirstChild(),
aAttribute == nsGkAtoms::viewBox ?
TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED : TRANSFORM_CHANGED);
if (aAttribute != nsGkAtoms::transform) {
static_cast<SVGSVGElement*>(GetContent())->ChildrenOnlyTransformChanged();
}
@@ -844,17 +844,17 @@ nsSVGOuterSVGFrame::NotifyViewportOrTran
if (aFlags & FULL_ZOOM_CHANGED) {
// Convert FULL_ZOOM_CHANGED to TRANSFORM_CHANGED:
aFlags = (aFlags & ~FULL_ZOOM_CHANGED) | TRANSFORM_CHANGED;
}
if (aFlags & TRANSFORM_CHANGED) {
// Make sure our canvas transform matrix gets (lazily) recalculated:
- mCanvasTM = nullptr;
+ mCanvasTM.reset();
if (haveNonFulLZoomTransformChange &&
!(mState & NS_FRAME_IS_NONDISPLAY)) {
uint32_t flags = (mState & NS_FRAME_IN_REFLOW) ?
SVGSVGElement::eDuringReflow : 0;
content->ChildrenOnlyTransformChanged(flags);
}
}
@@ -903,17 +903,17 @@ nsSVGOuterSVGFrame::GetCanvasTM()
SVGSVGElement *content = static_cast<SVGSVGElement*>(GetContent());
float devPxPerCSSPx =
1.0f / PresContext()->AppUnitsToFloatCSSPixels(
PresContext()->AppUnitsPerDevPixel());
gfxMatrix tm = content->PrependLocalTransformsTo(
gfxMatrix::Scaling(devPxPerCSSPx, devPxPerCSSPx));
- mCanvasTM = new gfxMatrix(tm);
+ mCanvasTM = Some(tm);
}
return *mCanvasTM;
}
//----------------------------------------------------------------------
// Implementation helpers
bool
--- a/layout/svg/nsSVGOuterSVGFrame.h
+++ b/layout/svg/nsSVGOuterSVGFrame.h
@@ -182,17 +182,17 @@ protected:
// This is temporary until display list based invalidation is implemented for
// SVG.
// A hash-set containing our nsSVGForeignObjectFrame descendants. Note we use
// a hash-set to avoid the O(N^2) behavior we'd get tearing down an SVG frame
// subtree if we were to use a list (see bug 381285 comment 20).
nsAutoPtr<nsTHashtable<nsPtrHashKey<nsSVGForeignObjectFrame> > > mForeignObjectHash;
- nsAutoPtr<gfxMatrix> mCanvasTM;
+ Maybe<gfxMatrix> mCanvasTM;
nsRegion mInvalidRegion;
float mFullZoom;
bool mViewportInitialized;
bool mIsRootContent;
};
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -95,18 +95,18 @@ nsSVGPatternFrame::Init(nsIContent*
// If our GetCanvasTM is getting called, we
// need to return *our current* transformation
// matrix, which depends on our units parameters
// and X, Y, Width, and Height
gfxMatrix
nsSVGPatternFrame::GetCanvasTM()
{
- if (mCTM) {
- return *mCTM;
+ if (mCanvasTM) {
+ return *mCanvasTM;
}
// Do we know our rendering parent?
if (mSource) {
// Yes, use it!
return mSource->GetCanvasTM();
}
@@ -276,21 +276,17 @@ nsSVGPatternFrame::PaintPattern(const Dr
// Construct the CTM that we will provide to our children when we
// render them into the tile.
gfxMatrix ctm = ConstructCTM(viewBox, patternContentUnits, patternUnits,
callerBBox, aContextMatrix, aSource);
if (ctm.IsSingular()) {
return nullptr;
}
- if (patternWithChildren->mCTM) {
- *patternWithChildren->mCTM = ctm;
- } else {
- patternWithChildren->mCTM = new gfxMatrix(ctm);
- }
+ patternWithChildren->mCanvasTM = Some(ctm);
// Get the bounding box of the pattern. This will be used to determine
// the size of the surface, and will also be used to define the bounding
// box for the pattern tile.
gfxRect bbox = GetPatternRect(patternUnits, callerBBox, aContextMatrix, aSource);
if (bbox.Width() <= 0.0 || bbox.Height() <= 0.0) {
return nullptr;
}
@@ -338,17 +334,17 @@ nsSVGPatternFrame::PaintPattern(const Dr
if (resultOverflows ||
patternWidth != surfaceSize.width ||
patternHeight != surfaceSize.height) {
// scale drawing to pattern surface size
gfxMatrix tempTM =
gfxMatrix(surfaceSize.width / patternWidth, 0.0,
0.0, surfaceSize.height / patternHeight,
0.0, 0.0);
- patternWithChildren->mCTM->PreMultiply(tempTM);
+ patternWithChildren->mCanvasTM->PreMultiply(tempTM);
// and rescale pattern to compensate
patternMatrix->PreScale(patternWidth / surfaceSize.width,
patternHeight / surfaceSize.height);
}
RefPtr<DrawTarget> dt =
aDrawTarget->CreateSimilarDrawTarget(surfaceSize, SurfaceFormat::B8G8R8A8);
@@ -380,17 +376,17 @@ nsSVGPatternFrame::PaintPattern(const Dr
AutoSetRestorePaintServerState paintServer(patternWithChildren);
for (nsIFrame* kid = firstKid; kid;
kid = kid->GetNextSibling()) {
// The CTM of each frame referencing us can be different
nsSVGDisplayableFrame* SVGFrame = do_QueryFrame(kid);
if (SVGFrame) {
SVGFrame->NotifySVGChanged(nsSVGDisplayableFrame::TRANSFORM_CHANGED);
}
- gfxMatrix tm = *(patternWithChildren->mCTM);
+ gfxMatrix tm = *(patternWithChildren->mCanvasTM);
if (kid->GetContent()->IsSVGElement()) {
tm = static_cast<nsSVGElement*>(kid->GetContent())->
PrependLocalTransformsTo(tm, eUserSpaceToParent);
}
nsSVGUtils::PaintFrameWithEffects(kid, *ctx, tm, aImgParams);
}
}
--- a/layout/svg/nsSVGPatternFrame.h
+++ b/layout/svg/nsSVGPatternFrame.h
@@ -131,17 +131,17 @@ protected:
const Matrix &callerCTM,
nsIFrame *aTarget);
private:
// this is a *temporary* reference to the frame of the element currently
// referencing our pattern. This must be temporary because different
// referencing frames will all reference this one frame
mozilla::SVGGeometryFrame* mSource;
- nsAutoPtr<gfxMatrix> mCTM;
+ Maybe<gfxMatrix> mCanvasTM;
protected:
// This flag is used to detect loops in xlink:href processing
bool mLoopFlag;
bool mNoHRefURI;
};
#endif
--- a/layout/svg/nsSVGUseFrame.cpp
+++ b/layout/svg/nsSVGUseFrame.cpp
@@ -51,17 +51,17 @@ nsSVGUseFrame::AttributeChanged(int32_t
nsIAtom* aAttribute,
int32_t aModType)
{
SVGUseElement *useElement = static_cast<SVGUseElement*>(GetContent());
if (aNameSpaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::x || aAttribute == nsGkAtoms::y) {
// make sure our cached transform matrix gets (lazily) updated
- mCanvasTM = nullptr;
+ mCanvasTM.reset();
nsLayoutUtils::PostRestyleEvent(
useElement, nsRestyleHint(0),
nsChangeHint_InvalidateRenderingObservers);
nsSVGUtils::ScheduleReflowSVG(this);
nsSVGUtils::NotifyChildrenOfSVGChange(this, TRANSFORM_CHANGED);
} else if (aAttribute == nsGkAtoms::width ||
aAttribute == nsGkAtoms::height) {
bool invalidate = false;
--- a/layout/svg/nsSVGViewportFrame.cpp
+++ b/layout/svg/nsSVGViewportFrame.cpp
@@ -122,17 +122,17 @@ nsSVGViewportFrame::NotifySVGChanged(uin
if (!aFlags) {
return; // No notification flags left
}
}
}
if (aFlags & TRANSFORM_CHANGED) {
// make sure our cached transform matrix gets (lazily) updated
- mCanvasTM = nullptr;
+ mCanvasTM.reset();
}
nsSVGDisplayContainerFrame::NotifySVGChanged(aFlags);
}
SVGBBox
nsSVGViewportFrame::GetBBoxContribution(const Matrix &aToBBoxUserspace,
uint32_t aFlags)
@@ -186,35 +186,35 @@ nsSVGViewportFrame::AttributeChanged(int
aAttribute == nsGkAtoms::height) {
nsLayoutUtils::PostRestyleEvent(
mContent->AsElement(), nsRestyleHint(0),
nsChangeHint_InvalidateRenderingObservers);
nsSVGUtils::ScheduleReflowSVG(this);
if (content->HasViewBoxOrSyntheticViewBox()) {
// make sure our cached transform matrix gets (lazily) updated
- mCanvasTM = nullptr;
+ mCanvasTM.reset();
content->ChildrenOnlyTransformChanged();
nsSVGUtils::NotifyChildrenOfSVGChange(this, TRANSFORM_CHANGED);
} else {
uint32_t flags = COORD_CONTEXT_CHANGED;
if (mCanvasTM && mCanvasTM->IsSingular()) {
- mCanvasTM = nullptr;
+ mCanvasTM.reset();
flags |= TRANSFORM_CHANGED;
}
nsSVGUtils::NotifyChildrenOfSVGChange(this, flags);
}
} else if (aAttribute == nsGkAtoms::transform ||
aAttribute == nsGkAtoms::preserveAspectRatio ||
aAttribute == nsGkAtoms::viewBox ||
aAttribute == nsGkAtoms::x ||
aAttribute == nsGkAtoms::y) {
// make sure our cached transform matrix gets (lazily) updated
- mCanvasTM = nullptr;
+ mCanvasTM.reset();
nsSVGUtils::NotifyChildrenOfSVGChange(
this, aAttribute == nsGkAtoms::viewBox ?
TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED : TRANSFORM_CHANGED);
// We don't invalidate for transform changes (the layers code does that).
// Also note that SVGTransformableElement::GetAttributeChangeHint will
// return nsChangeHint_UpdateOverflow for "transform" attribute changes
@@ -283,17 +283,17 @@ nsSVGViewportFrame::GetCanvasTM()
if (!mCanvasTM) {
NS_ASSERTION(GetParent(), "null parent");
nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(GetParent());
SVGViewportElement *content = static_cast<SVGViewportElement*>(GetContent());
gfxMatrix tm = content->PrependLocalTransformsTo(parent->GetCanvasTM());
- mCanvasTM = new gfxMatrix(tm);
+ mCanvasTM = Some(tm);
}
return *mCanvasTM;
}
bool
nsSVGViewportFrame::HasChildrenOnlyTransform(gfx::Matrix *aTransform) const
{
SVGViewportElement *content = static_cast<SVGViewportElement*>(GetContent());
--- a/layout/svg/nsSVGViewportFrame.h
+++ b/layout/svg/nsSVGViewportFrame.h
@@ -47,13 +47,13 @@ public:
virtual bool HasChildrenOnlyTransform(Matrix *aTransform) const override;
// nsISVGSVGFrame interface:
virtual void NotifyViewportOrTransformChanged(uint32_t aFlags) override;
protected:
- nsAutoPtr<gfxMatrix> mCanvasTM;
+ Maybe<gfxMatrix> mCanvasTM;
};
#endif // __NS_SVGVIEWPORTFRAME_H__