Bug 876157 - Avoid expensive nsSVGGradientFrame::GetGradientTransform calls when gradients paint only a single color. r=roc

This commit is contained in:
Jonathan Watt 2013-05-27 08:31:39 +01:00
parent 89eacf7637
commit ddccab29b8

View File

@ -174,18 +174,9 @@ nsSVGGradientFrame::GetGradientTransform(nsIFrame *aSource,
gfxMatrix bboxMatrix; gfxMatrix bboxMatrix;
uint16_t gradientUnits = GetGradientUnits(); uint16_t gradientUnits = GetGradientUnits();
if (gradientUnits == SVG_UNIT_TYPE_USERSPACEONUSE) { if (gradientUnits != SVG_UNIT_TYPE_USERSPACEONUSE) {
// If this gradient is applied to text, our caller NS_ASSERTION(gradientUnits == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX,
// will be the glyph, which is not a container, so we "Unknown gradientUnits type");
// need to get the parent
if (aSource->GetContent()->IsNodeOfType(nsINode::eTEXT))
mSource = aSource->GetParent();
else
mSource = aSource;
} else {
NS_ASSERTION(
gradientUnits == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX,
"Unknown gradientUnits type");
// objectBoundingBox is the default anyway // objectBoundingBox is the default anyway
gfxRect bbox = gfxRect bbox =
@ -242,11 +233,16 @@ nsSVGGradientFrame::GetPaintServerPattern(nsIFrame *aSource,
float aGraphicOpacity, float aGraphicOpacity,
const gfxRect *aOverrideBounds) const gfxRect *aOverrideBounds)
{ {
// Get the transform list (if there is one) uint16_t gradientUnits = GetGradientUnits();
gfxMatrix patternMatrix = GetGradientTransform(aSource, aOverrideBounds); MOZ_ASSERT(gradientUnits == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX ||
gradientUnits == SVG_UNIT_TYPE_USERSPACEONUSE);
if (patternMatrix.IsSingular()) if (gradientUnits == SVG_UNIT_TYPE_USERSPACEONUSE) {
return nullptr; // Set mSource for this consumer.
// If this gradient is applied to text, our caller will be the glyph, which
// is not an element, so we need to get the parent
mSource = aSource->GetContent()->IsNodeOfType(nsINode::eTEXT) ?
aSource->GetParent() : aSource;
}
uint32_t nStops = GetStopCount(); uint32_t nStops = GetStopCount();
@ -272,6 +268,15 @@ nsSVGGradientFrame::GetPaintServerPattern(nsIFrame *aSource,
return pattern.forget(); return pattern.forget();
} }
// Get the transform list (if there is one). We do this after the returns
// above since this call can be expensive when "gradientUnits" is set to
// "objectBoundingBox" (since that requiring a GetBBox() call).
gfxMatrix patternMatrix = GetGradientTransform(aSource, aOverrideBounds);
if (patternMatrix.IsSingular()) {
return nullptr;
}
// revert the vector effect transform so that the gradient appears unchanged // revert the vector effect transform so that the gradient appears unchanged
if (aFillOrStroke == &nsStyleSVG::mStroke) { if (aFillOrStroke == &nsStyleSVG::mStroke) {
patternMatrix.Multiply(nsSVGUtils::GetStrokeTransform(aSource).Invert()); patternMatrix.Multiply(nsSVGUtils::GetStrokeTransform(aSource).Invert());