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()
addReferenceTo(element);
if (!m_animatedProperty)
m_animatedProperty = m_animator.startAnimValAnimation(animatedElements);
m_animatedProperty = m_animator.startAnimValAnimation();
else
m_animatedProperty = m_animator.resetAnimValToBaseVal(animatedElements);
m_animatedProperty = m_animator.resetAnimValToBaseVal();
return;
}
DCHECK_EQ(shouldApply, ApplyCSSAnimation);
// CSS properties animation code-path.
String baseValue;
if (shouldApply == ApplyCSSAnimation) {
ASSERT(SVGAnimationElement::isTargetAttributeCSSProperty(targetElement, attributeName));
computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue);
}
DCHECK(isTargetAttributeCSSProperty(targetElement, attributeName));
computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue);
m_animatedProperty = m_animator.constructFromString(baseValue);
}
......@@ -282,8 +280,7 @@ void SVGAnimateElement::clearAnimatedType()
// SVG DOM animVal animation code-path.
if (m_animatedProperty) {
SVGElementInstances animatedElements = findElementInstances(targetElement);
m_animator.stopAnimValAnimation(animatedElements);
m_animator.stopAnimValAnimation();
notifyTargetAndInstancesAboutAnimValChange(targetElement, attributeName());
}
......
......@@ -32,7 +32,8 @@
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 {
DEFINE_WRAPPERTYPEINFO();
......
......@@ -161,55 +161,32 @@ void SVGAnimatedTypeAnimator::calculateFromAndByValues(Member<SVGPropertyBase>&
to->add(from, m_contextElement);
}
namespace {
void setAnimatedValueOnAllTargetProperties(const SVGElementInstances& list, const QualifiedName& attributeName, SVGPropertyBase* value)
SVGPropertyBase* SVGAnimatedTypeAnimator::resetAnimation()
{
for (SVGElement* elementInstance : list) {
if (SVGAnimatedPropertyBase* animatedProperty = elementInstance->propertyFromAttribute(attributeName))
animatedProperty->setAnimatedValue(value);
}
}
} // namespace
SVGPropertyBase* SVGAnimatedTypeAnimator::resetAnimation(const SVGElementInstances& list)
{
ASSERT(isAnimatingSVGDom());
DCHECK(isAnimatingSVGDom());
DCHECK(m_contextElement);
SVGPropertyBase* animatedValue = m_animatedProperty->createAnimatedValue();
ASSERT(animatedValue->type() == m_type);
setAnimatedValueOnAllTargetProperties(list, m_animatedProperty->attributeName(), animatedValue);
DCHECK_EQ(animatedValue->type(), m_type);
m_contextElement->setAnimatedAttribute(m_animatedProperty->attributeName(), animatedValue);
return animatedValue;
}
SVGPropertyBase* SVGAnimatedTypeAnimator::startAnimValAnimation(const SVGElementInstances& list)
SVGPropertyBase* SVGAnimatedTypeAnimator::startAnimValAnimation()
{
ASSERT(isAnimatingSVGDom());
SVGElement::InstanceUpdateBlocker blocker(m_contextElement);
return resetAnimation(list);
return resetAnimation();
}
void SVGAnimatedTypeAnimator::stopAnimValAnimation(const SVGElementInstances& list)
void SVGAnimatedTypeAnimator::stopAnimValAnimation()
{
if (!isAnimatingSVGDom())
return;
ASSERT(m_contextElement);
SVGElement::InstanceUpdateBlocker blocker(m_contextElement);
for (SVGElement* elementInstance : list) {
if (SVGAnimatedPropertyBase* animatedProperty = elementInstance->propertyFromAttribute(m_animatedProperty->attributeName()))
animatedProperty->animationEnded();
}
DCHECK(m_contextElement);
m_contextElement->clearAnimatedAttribute(m_animatedProperty->attributeName());
}
SVGPropertyBase* SVGAnimatedTypeAnimator::resetAnimValToBaseVal(const SVGElementInstances& list)
SVGPropertyBase* SVGAnimatedTypeAnimator::resetAnimValToBaseVal()
{
SVGElement::InstanceUpdateBlocker blocker(m_contextElement);
return resetAnimation(list);
return resetAnimation();
}
class ParsePropertyFromString {
......
......@@ -23,8 +23,6 @@
#include "core/svg/properties/SVGPropertyInfo.h"
#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
#include "wtf/text/WTFString.h"
namespace blink {
......@@ -34,9 +32,6 @@ class SVGPropertyBase;
class SVGElement;
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 {
DISALLOW_NEW();
public:
......@@ -47,9 +42,9 @@ public:
SVGPropertyBase* constructFromString(const String&);
SVGPropertyBase* startAnimValAnimation(const SVGElementInstances&);
void stopAnimValAnimation(const SVGElementInstances&);
SVGPropertyBase* resetAnimValToBaseVal(const SVGElementInstances&);
SVGPropertyBase* startAnimValAnimation();
void stopAnimValAnimation();
SVGPropertyBase* resetAnimValToBaseVal();
void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGPropertyBase*, SVGPropertyBase*, SVGPropertyBase*, SVGPropertyBase*);
float calculateDistance(const String& fromString, const String& toString);
......@@ -68,7 +63,7 @@ public:
private:
friend class ParsePropertyFromString;
SVGPropertyBase* createPropertyForAnimation(const String&);
SVGPropertyBase* resetAnimation(const SVGElementInstances&);
SVGPropertyBase* resetAnimation();
Member<SVGAnimationElement> m_animationElement;
Member<SVGElement> m_contextElement;
......
......@@ -26,7 +26,6 @@
#define SVGAnimationElement_h
#include "core/CoreExport.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/animation/SVGSMILElement.h"
#include "ui/gfx/geometry/cubic_bezier.h"
#include "wtf/Functional.h"
......
......@@ -237,6 +237,16 @@ void SVGElement::applyActiveWebAnimations()
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>
static void updateInstancesAnimatedAttribute(SVGElement* element, const QualifiedName& attribute, T callback)
{
......@@ -270,6 +280,20 @@ void SVGElement::clearWebAnimatedAttributes()
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
{
// To be overriden by SVGGraphicsElement (or as special case SVGTextElement and SVGPatternElement)
......
......@@ -89,6 +89,9 @@ public:
void setWebAnimatedAttribute(const QualifiedName& attribute, SVGPropertyBase*);
void clearWebAnimatedAttributes();
void setAnimatedAttribute(const QualifiedName&, SVGPropertyBase*);
void clearAnimatedAttribute(const QualifiedName&);
SVGSVGElement* ownerSVGElement() 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