Commit 80641183 authored by pdr@chromium.org's avatar pdr@chromium.org

Lazily allocate svg shape transforms, shrink RenderSVGShape by 44B

This patch switches to lazily allocating transforms in RenderSVGShape
because local transforms are relatively rare.

BUG=429551

Review URL: https://codereview.chromium.org/701433002

git-svn-id: svn://svn.chromium.org/blink/trunk@185118 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 444b4466
......@@ -110,6 +110,19 @@ bool RenderSVGShape::strokeContains(const FloatPoint& point, bool requiresStroke
return shapeDependentStrokeContains(point);
}
void RenderSVGShape::updateLocalTransform()
{
SVGGraphicsElement* graphicsElement = toSVGGraphicsElement(element());
if (graphicsElement->hasAnimatedLocalTransform()) {
if (m_localTransform)
m_localTransform->setTransform(graphicsElement->calculateAnimatedLocalTransform());
else
m_localTransform = adoptPtr(new AffineTransform(graphicsElement->calculateAnimatedLocalTransform()));
} else {
m_localTransform = 0;
}
}
void RenderSVGShape::layout()
{
bool updateCachedBoundariesInParents = false;
......@@ -123,7 +136,7 @@ void RenderSVGShape::layout()
}
if (m_needsTransformUpdate) {
m_localTransform = toSVGGraphicsElement(element())->calculateAnimatedLocalTransform();
updateLocalTransform();
m_needsTransformUpdate = false;
updateCachedBoundariesInParents = true;
}
......@@ -175,7 +188,7 @@ bool RenderSVGShape::nodeAtFloatPoint(const HitTestRequest& request, HitTestResu
return false;
FloatPoint localPoint;
if (!SVGRenderSupport::transformToUserSpaceAndCheckClipping(this, m_localTransform, pointInParent, localPoint))
if (!SVGRenderSupport::transformToUserSpaceAndCheckClipping(this, localToParentTransform(), pointInParent, localPoint))
return false;
PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_GEOMETRY_HITTESTING, request, style()->pointerEvents());
......
......@@ -70,7 +70,7 @@ public:
bool hasNonScalingStroke() const { return style()->svgStyle().vectorEffect() == VE_NON_SCALING_STROKE; }
Path* nonScalingStrokePath(const Path*, const AffineTransform&) const;
AffineTransform nonScalingStrokeTransform() const;
virtual AffineTransform localTransform() const override final { return m_localTransform; }
virtual AffineTransform localTransform() const override final { return m_localTransform ? *m_localTransform : RenderSVGModelObject::localTransform(); }
virtual const Vector<MarkerPosition>* markerPositions() const { return 0; }
......@@ -98,7 +98,7 @@ private:
bool fillContains(const FloatPoint&, bool requiresFill = true, const WindRule fillRule = RULE_NONZERO);
bool strokeContains(const FloatPoint&, bool requiresStroke = true);
virtual const AffineTransform& localToParentTransform() const override final { return m_localTransform; }
virtual const AffineTransform& localToParentTransform() const override final { return m_localTransform ? *m_localTransform : RenderSVGModelObject::localToParentTransform(); }
virtual bool isOfType(RenderObjectType type) const override { return type == RenderObjectSVGShape || RenderSVGModelObject::isOfType(type); }
virtual const char* renderName() const override { return "RenderSVGShape"; }
......@@ -113,10 +113,11 @@ private:
FloatRect calculateObjectBoundingBox() const;
FloatRect calculateStrokeBoundingBox() const;
void updatePaintInvalidationBoundingBox();
void updateLocalTransform();
private:
FloatRect m_paintInvalidationBoundingBox;
AffineTransform m_localTransform;
OwnPtr<AffineTransform> m_localTransform;
OwnPtr<Path> m_path;
bool m_needsBoundariesUpdate : 1;
......
......@@ -122,6 +122,14 @@ PassRefPtr<SVGMatrixTearOff> SVGGraphicsElement::getScreenCTMFromJavascript()
return SVGMatrixTearOff::create(getScreenCTM());
}
bool SVGGraphicsElement::hasAnimatedLocalTransform() const
{
RenderStyle* style = renderer() ? renderer()->style() : 0;
// Each of these is used in SVGGraphicsElement::calculateAnimatedLocalTransform to create an animated local transform.
return (style && style->hasTransform()) || !m_transform->currentValue()->isEmpty() || hasSVGRareData();
}
AffineTransform SVGGraphicsElement::calculateAnimatedLocalTransform() const
{
AffineTransform matrix;
......
......@@ -51,6 +51,7 @@ public:
SVGElement* farthestViewportElement() const;
virtual AffineTransform localCoordinateSpaceTransform(SVGElement::CTMScope) const override { return calculateAnimatedLocalTransform(); }
bool hasAnimatedLocalTransform() const;
AffineTransform calculateAnimatedLocalTransform() const;
virtual AffineTransform* animateMotionTransform() override;
......
......@@ -51,6 +51,8 @@ public:
void setMatrix(double a, double b, double c, double d, double e, double f);
void setTransform(const AffineTransform& other) { setMatrix(other.m_transform); }
void map(double x, double y, double& x2, double& y2) const;
// Rounds the mapped point to the nearest integer value.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment