Commit 451966ed authored by fs's avatar fs Committed by Commit bot

Refactor SMIL animation value updates

Push updating of the animation value into SVGElement. This resembles the
Web Animations code-path to some degree and maybe we can make them even
more similar eventually. This is the first CL in a series that will
remove knowledge of <use>/shadow trees from the SMIL animation code.

BUG=640676

Review-Url: https://codereview.chromium.org/2272033002
Cr-Commit-Position: refs/heads/master@{#414366}
parent 0044de6d
...@@ -190,20 +190,18 @@ void SVGAnimateElement::resetAnimatedType() ...@@ -190,20 +190,18 @@ void SVGAnimateElement::resetAnimatedType()
addReferenceTo(element); addReferenceTo(element);
if (!m_animatedProperty) if (!m_animatedProperty)
m_animatedProperty = m_animator.startAnimValAnimation(animatedElements); m_animatedProperty = m_animator.startAnimValAnimation();
else else
m_animatedProperty = m_animator.resetAnimValToBaseVal(animatedElements); m_animatedProperty = m_animator.resetAnimValToBaseVal();
return; return;
} }
DCHECK_EQ(shouldApply, ApplyCSSAnimation);
// CSS properties animation code-path. // CSS properties animation code-path.
String baseValue; String baseValue;
DCHECK(isTargetAttributeCSSProperty(targetElement, attributeName));
if (shouldApply == ApplyCSSAnimation) { computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue);
ASSERT(SVGAnimationElement::isTargetAttributeCSSProperty(targetElement, attributeName));
computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue);
}
m_animatedProperty = m_animator.constructFromString(baseValue); m_animatedProperty = m_animator.constructFromString(baseValue);
} }
...@@ -282,8 +280,7 @@ void SVGAnimateElement::clearAnimatedType() ...@@ -282,8 +280,7 @@ void SVGAnimateElement::clearAnimatedType()
// SVG DOM animVal animation code-path. // SVG DOM animVal animation code-path.
if (m_animatedProperty) { if (m_animatedProperty) {
SVGElementInstances animatedElements = findElementInstances(targetElement); m_animator.stopAnimValAnimation();
m_animator.stopAnimValAnimation(animatedElements);
notifyTargetAndInstancesAboutAnimValChange(targetElement, attributeName()); notifyTargetAndInstancesAboutAnimValChange(targetElement, attributeName());
} }
......
...@@ -32,7 +32,8 @@ ...@@ -32,7 +32,8 @@
namespace blink { namespace blink {
class SVGAnimatedTypeAnimator; // The size of SVGElementInstances is 1 unless there is a <use> instance of the element.
using SVGElementInstances = HeapVector<Member<SVGElement>, 1u>;
class CORE_EXPORT SVGAnimateElement : public SVGAnimationElement { class CORE_EXPORT SVGAnimateElement : public SVGAnimationElement {
DEFINE_WRAPPERTYPEINFO(); DEFINE_WRAPPERTYPEINFO();
......
...@@ -161,55 +161,32 @@ void SVGAnimatedTypeAnimator::calculateFromAndByValues(Member<SVGPropertyBase>& ...@@ -161,55 +161,32 @@ void SVGAnimatedTypeAnimator::calculateFromAndByValues(Member<SVGPropertyBase>&
to->add(from, m_contextElement); to->add(from, m_contextElement);
} }
namespace { SVGPropertyBase* SVGAnimatedTypeAnimator::resetAnimation()
void setAnimatedValueOnAllTargetProperties(const SVGElementInstances& list, const QualifiedName& attributeName, SVGPropertyBase* value)
{ {
for (SVGElement* elementInstance : list) { DCHECK(isAnimatingSVGDom());
if (SVGAnimatedPropertyBase* animatedProperty = elementInstance->propertyFromAttribute(attributeName)) DCHECK(m_contextElement);
animatedProperty->setAnimatedValue(value);
}
}
} // namespace
SVGPropertyBase* SVGAnimatedTypeAnimator::resetAnimation(const SVGElementInstances& list)
{
ASSERT(isAnimatingSVGDom());
SVGPropertyBase* animatedValue = m_animatedProperty->createAnimatedValue(); SVGPropertyBase* animatedValue = m_animatedProperty->createAnimatedValue();
ASSERT(animatedValue->type() == m_type); DCHECK_EQ(animatedValue->type(), m_type);
setAnimatedValueOnAllTargetProperties(list, m_animatedProperty->attributeName(), animatedValue); m_contextElement->setAnimatedAttribute(m_animatedProperty->attributeName(), animatedValue);
return animatedValue; return animatedValue;
} }
SVGPropertyBase* SVGAnimatedTypeAnimator::startAnimValAnimation(const SVGElementInstances& list) SVGPropertyBase* SVGAnimatedTypeAnimator::startAnimValAnimation()
{ {
ASSERT(isAnimatingSVGDom()); return resetAnimation();
SVGElement::InstanceUpdateBlocker blocker(m_contextElement);
return resetAnimation(list);
} }
void SVGAnimatedTypeAnimator::stopAnimValAnimation(const SVGElementInstances& list) void SVGAnimatedTypeAnimator::stopAnimValAnimation()
{ {
if (!isAnimatingSVGDom()) if (!isAnimatingSVGDom())
return; return;
DCHECK(m_contextElement);
ASSERT(m_contextElement); m_contextElement->clearAnimatedAttribute(m_animatedProperty->attributeName());
SVGElement::InstanceUpdateBlocker blocker(m_contextElement);
for (SVGElement* elementInstance : list) {
if (SVGAnimatedPropertyBase* animatedProperty = elementInstance->propertyFromAttribute(m_animatedProperty->attributeName()))
animatedProperty->animationEnded();
}
} }
SVGPropertyBase* SVGAnimatedTypeAnimator::resetAnimValToBaseVal(const SVGElementInstances& list) SVGPropertyBase* SVGAnimatedTypeAnimator::resetAnimValToBaseVal()
{ {
SVGElement::InstanceUpdateBlocker blocker(m_contextElement); return resetAnimation();
return resetAnimation(list);
} }
class ParsePropertyFromString { class ParsePropertyFromString {
......
...@@ -23,8 +23,6 @@ ...@@ -23,8 +23,6 @@
#include "core/svg/properties/SVGPropertyInfo.h" #include "core/svg/properties/SVGPropertyInfo.h"
#include "platform/heap/Handle.h" #include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
#include "wtf/text/WTFString.h" #include "wtf/text/WTFString.h"
namespace blink { namespace blink {
...@@ -34,9 +32,6 @@ class SVGPropertyBase; ...@@ -34,9 +32,6 @@ class SVGPropertyBase;
class SVGElement; class SVGElement;
class SVGAnimationElement; class SVGAnimationElement;
// The size of SVGElementInstances is 1 unless there is a <use> instance of the element.
using SVGElementInstances = HeapVector<Member<SVGElement>, 1u>;
class SVGAnimatedTypeAnimator final { class SVGAnimatedTypeAnimator final {
DISALLOW_NEW(); DISALLOW_NEW();
public: public:
...@@ -47,9 +42,9 @@ public: ...@@ -47,9 +42,9 @@ public:
SVGPropertyBase* constructFromString(const String&); SVGPropertyBase* constructFromString(const String&);
SVGPropertyBase* startAnimValAnimation(const SVGElementInstances&); SVGPropertyBase* startAnimValAnimation();
void stopAnimValAnimation(const SVGElementInstances&); void stopAnimValAnimation();
SVGPropertyBase* resetAnimValToBaseVal(const SVGElementInstances&); SVGPropertyBase* resetAnimValToBaseVal();
void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGPropertyBase*, SVGPropertyBase*, SVGPropertyBase*, SVGPropertyBase*); void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGPropertyBase*, SVGPropertyBase*, SVGPropertyBase*, SVGPropertyBase*);
float calculateDistance(const String& fromString, const String& toString); float calculateDistance(const String& fromString, const String& toString);
...@@ -68,7 +63,7 @@ public: ...@@ -68,7 +63,7 @@ public:
private: private:
friend class ParsePropertyFromString; friend class ParsePropertyFromString;
SVGPropertyBase* createPropertyForAnimation(const String&); SVGPropertyBase* createPropertyForAnimation(const String&);
SVGPropertyBase* resetAnimation(const SVGElementInstances&); SVGPropertyBase* resetAnimation();
Member<SVGAnimationElement> m_animationElement; Member<SVGAnimationElement> m_animationElement;
Member<SVGElement> m_contextElement; Member<SVGElement> m_contextElement;
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#define SVGAnimationElement_h #define SVGAnimationElement_h
#include "core/CoreExport.h" #include "core/CoreExport.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/animation/SVGSMILElement.h" #include "core/svg/animation/SVGSMILElement.h"
#include "ui/gfx/geometry/cubic_bezier.h" #include "ui/gfx/geometry/cubic_bezier.h"
#include "wtf/Functional.h" #include "wtf/Functional.h"
......
...@@ -237,6 +237,16 @@ void SVGElement::applyActiveWebAnimations() ...@@ -237,6 +237,16 @@ void SVGElement::applyActiveWebAnimations()
svgRareData()->setWebAnimatedAttributesDirty(false); svgRareData()->setWebAnimatedAttributesDirty(false);
} }
template<typename T>
static void updateInstancesAnimatedAttributeNoInvalidate(SVGElement* element, const QualifiedName& attribute, T callback)
{
SVGElement::InstanceUpdateBlocker blocker(element);
for (SVGElement* instance : SVGAnimateElement::findElementInstances(element)) {
if (SVGAnimatedPropertyBase* animatedProperty = instance->propertyFromAttribute(attribute))
callback(*animatedProperty);
}
}
template<typename T> template<typename T>
static void updateInstancesAnimatedAttribute(SVGElement* element, const QualifiedName& attribute, T callback) static void updateInstancesAnimatedAttribute(SVGElement* element, const QualifiedName& attribute, T callback)
{ {
...@@ -270,6 +280,20 @@ void SVGElement::clearWebAnimatedAttributes() ...@@ -270,6 +280,20 @@ void SVGElement::clearWebAnimatedAttributes()
svgRareData()->webAnimatedAttributes().clear(); svgRareData()->webAnimatedAttributes().clear();
} }
void SVGElement::setAnimatedAttribute(const QualifiedName& attribute, SVGPropertyBase* value)
{
updateInstancesAnimatedAttributeNoInvalidate(this, attribute, [&value](SVGAnimatedPropertyBase& animatedProperty) {
animatedProperty.setAnimatedValue(value);
});
}
void SVGElement::clearAnimatedAttribute(const QualifiedName& attribute)
{
updateInstancesAnimatedAttributeNoInvalidate(this, attribute, [](SVGAnimatedPropertyBase& animatedProperty) {
animatedProperty.animationEnded();
});
}
AffineTransform SVGElement::localCoordinateSpaceTransform(CTMScope) const AffineTransform SVGElement::localCoordinateSpaceTransform(CTMScope) const
{ {
// To be overriden by SVGGraphicsElement (or as special case SVGTextElement and SVGPatternElement) // To be overriden by SVGGraphicsElement (or as special case SVGTextElement and SVGPatternElement)
......
...@@ -89,6 +89,9 @@ public: ...@@ -89,6 +89,9 @@ public:
void setWebAnimatedAttribute(const QualifiedName& attribute, SVGPropertyBase*); void setWebAnimatedAttribute(const QualifiedName& attribute, SVGPropertyBase*);
void clearWebAnimatedAttributes(); void clearWebAnimatedAttributes();
void setAnimatedAttribute(const QualifiedName&, SVGPropertyBase*);
void clearAnimatedAttribute(const QualifiedName&);
SVGSVGElement* ownerSVGElement() const; SVGSVGElement* ownerSVGElement() const;
SVGElement* viewportElement() const; SVGElement* viewportElement() const;
......
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