Index: third_party/WebKit/Source/core/animation/KeyframeEffect.cpp |
diff --git a/third_party/WebKit/Source/core/animation/KeyframeEffect.cpp b/third_party/WebKit/Source/core/animation/KeyframeEffect.cpp |
index 85ce7b94362af5dc3a1ce0dbb4a375af1c607e26..1c07f6ab1bcfc3c786609c6e08f02750cd4c0721 100644 |
--- a/third_party/WebKit/Source/core/animation/KeyframeEffect.cpp |
+++ b/third_party/WebKit/Source/core/animation/KeyframeEffect.cpp |
@@ -32,21 +32,13 @@ |
#include "bindings/core/v8/Dictionary.h" |
#include "bindings/core/v8/ExceptionState.h" |
-#include "core/animation/Animation.h" |
#include "core/animation/AnimationEffectTiming.h" |
-#include "core/animation/AnimationTimeline.h" |
-#include "core/animation/CompositorAnimations.h" |
-#include "core/animation/ElementAnimations.h" |
-#include "core/animation/Interpolation.h" |
-#include "core/animation/KeyframeEffectModel.h" |
+#include "core/animation/EffectInput.h" |
#include "core/animation/KeyframeEffectOptions.h" |
#include "core/animation/KeyframeEffectReadOnly.h" |
-#include "core/animation/PropertyHandle.h" |
+#include "core/animation/TimingInput.h" |
#include "core/dom/Element.h" |
-#include "core/dom/NodeComputedStyle.h" |
#include "core/frame/UseCounter.h" |
-#include "core/paint/PaintLayer.h" |
-#include "core/svg/SVGElement.h" |
namespace blink { |
@@ -122,275 +114,8 @@ KeyframeEffect::KeyframeEffect(Element* target, |
KeyframeEffect::~KeyframeEffect() {} |
-void KeyframeEffect::attach(Animation* animation) { |
- if (m_target) { |
- m_target->ensureElementAnimations().animations().add(animation); |
- m_target->setNeedsAnimationStyleRecalc(); |
- if (RuntimeEnabledFeatures::webAnimationsSVGEnabled() && |
- m_target->isSVGElement()) |
- toSVGElement(m_target)->setWebAnimationsPending(); |
- } |
- AnimationEffectReadOnly::attach(animation); |
-} |
- |
-void KeyframeEffect::detach() { |
- if (m_target) |
- m_target->elementAnimations()->animations().remove(animation()); |
- if (m_sampledEffect) |
- clearEffects(); |
- AnimationEffectReadOnly::detach(); |
-} |
- |
-void KeyframeEffect::specifiedTimingChanged() { |
- if (animation()) { |
- // FIXME: Needs to consider groups when added. |
- DCHECK_EQ(animation()->effect(), this); |
- animation()->setCompositorPending(true); |
- } |
-} |
- |
-static AnimationStack& ensureAnimationStack(Element* element) { |
- return element->ensureElementAnimations().animationStack(); |
-} |
- |
-bool KeyframeEffect::hasMultipleTransformProperties() const { |
- if (!m_target->computedStyle()) |
- return false; |
- |
- unsigned transformPropertyCount = 0; |
- if (m_target->computedStyle()->hasTransformOperations()) |
- transformPropertyCount++; |
- if (m_target->computedStyle()->rotate()) |
- transformPropertyCount++; |
- if (m_target->computedStyle()->scale()) |
- transformPropertyCount++; |
- if (m_target->computedStyle()->translate()) |
- transformPropertyCount++; |
- return transformPropertyCount > 1; |
-} |
- |
-// Returns true if transform, translate, rotate or scale is composited |
-// and a motion path or other transform properties |
-// has been introduced on the element |
-bool KeyframeEffect::hasIncompatibleStyle() { |
- if (!m_target->computedStyle()) |
- return false; |
- |
- bool affectsTransform = |
- animation()->affects(*m_target, CSSPropertyTransform) || |
- animation()->affects(*m_target, CSSPropertyScale) || |
- animation()->affects(*m_target, CSSPropertyRotate) || |
- animation()->affects(*m_target, CSSPropertyTranslate); |
- |
- if (animation()->hasActiveAnimationsOnCompositor()) { |
- if (m_target->computedStyle()->hasOffset() && affectsTransform) |
- return true; |
- return hasMultipleTransformProperties(); |
- } |
- |
- return false; |
-} |
- |
-void KeyframeEffect::applyEffects() { |
- DCHECK(isInEffect()); |
- DCHECK(animation()); |
- if (!m_target || !m_model) |
- return; |
- |
- if (hasIncompatibleStyle()) |
- animation()->cancelAnimationOnCompositor(); |
- |
- double iteration = currentIteration(); |
- DCHECK_GE(iteration, 0); |
- bool changed = false; |
- if (m_sampledEffect) { |
- changed = m_model->sample(clampTo<int>(iteration, 0), progress(), |
- iterationDuration(), |
- m_sampledEffect->mutableInterpolations()); |
- } else { |
- Vector<RefPtr<Interpolation>> interpolations; |
- m_model->sample(clampTo<int>(iteration, 0), progress(), iterationDuration(), |
- interpolations); |
- if (!interpolations.isEmpty()) { |
- SampledEffect* sampledEffect = SampledEffect::create(this); |
- sampledEffect->mutableInterpolations().swap(interpolations); |
- m_sampledEffect = sampledEffect; |
- ensureAnimationStack(m_target).add(sampledEffect); |
- changed = true; |
- } else { |
- return; |
- } |
- } |
- |
- if (changed) { |
- m_target->setNeedsAnimationStyleRecalc(); |
- if (RuntimeEnabledFeatures::webAnimationsSVGEnabled() && |
- m_target->isSVGElement()) |
- toSVGElement(*m_target).setWebAnimationsPending(); |
- } |
-} |
- |
-void KeyframeEffect::clearEffects() { |
- DCHECK(animation()); |
- DCHECK(m_sampledEffect); |
- |
- m_sampledEffect->clear(); |
- m_sampledEffect = nullptr; |
- restartAnimationOnCompositor(); |
- m_target->setNeedsAnimationStyleRecalc(); |
- if (RuntimeEnabledFeatures::webAnimationsSVGEnabled() && |
- m_target->isSVGElement()) |
- toSVGElement(*m_target).clearWebAnimatedAttributes(); |
- invalidate(); |
-} |
- |
-void KeyframeEffect::updateChildrenAndEffects() const { |
- if (!m_model) |
- return; |
- DCHECK(animation()); |
- if (isInEffect() && !animation()->effectSuppressed()) |
- const_cast<KeyframeEffect*>(this)->applyEffects(); |
- else if (m_sampledEffect) |
- const_cast<KeyframeEffect*>(this)->clearEffects(); |
-} |
- |
-double KeyframeEffect::calculateTimeToEffectChange( |
- bool forwards, |
- double localTime, |
- double timeToNextIteration) const { |
- const double startTime = specifiedTiming().startDelay; |
- const double endTimeMinusEndDelay = startTime + activeDurationInternal(); |
- const double endTime = endTimeMinusEndDelay + specifiedTiming().endDelay; |
- const double afterTime = std::min(endTimeMinusEndDelay, endTime); |
- |
- switch (getPhase()) { |
- case PhaseNone: |
- return std::numeric_limits<double>::infinity(); |
- case PhaseBefore: |
- DCHECK_GE(startTime, localTime); |
- return forwards ? startTime - localTime |
- : std::numeric_limits<double>::infinity(); |
- case PhaseActive: |
- if (forwards) { |
- // Need service to apply fill / fire events. |
- const double timeToEnd = afterTime - localTime; |
- if (requiresIterationEvents()) { |
- return std::min(timeToEnd, timeToNextIteration); |
- } |
- return timeToEnd; |
- } |
- return 0; |
- case PhaseAfter: |
- DCHECK_GE(localTime, afterTime); |
- // If this KeyframeEffect is still in effect then it will need to update |
- // when its parent goes out of effect. We have no way of knowing when |
- // that will be, however, so the parent will need to supply it. |
- return forwards ? std::numeric_limits<double>::infinity() |
- : localTime - afterTime; |
- default: |
- NOTREACHED(); |
- return std::numeric_limits<double>::infinity(); |
- } |
-} |
- |
-void KeyframeEffect::notifySampledEffectRemovedFromAnimationStack() { |
- m_sampledEffect = nullptr; |
-} |
- |
-bool KeyframeEffect::isCandidateForAnimationOnCompositor( |
- double animationPlaybackRate) const { |
- // Do not put transforms on compositor if more than one of them are defined |
- // in computed style because they need to be explicitly ordered |
- if (!model() || !m_target || |
- (m_target->computedStyle() && m_target->computedStyle()->hasOffset()) || |
- hasMultipleTransformProperties()) |
- return false; |
- |
- return CompositorAnimations::isCandidateForAnimationOnCompositor( |
- specifiedTiming(), *m_target, animation(), *model(), |
- animationPlaybackRate); |
-} |
- |
-bool KeyframeEffect::maybeStartAnimationOnCompositor( |
- int group, |
- double startTime, |
- double currentTime, |
- double animationPlaybackRate) { |
- DCHECK(!hasActiveAnimationsOnCompositor()); |
- if (!isCandidateForAnimationOnCompositor(animationPlaybackRate)) |
- return false; |
- if (!CompositorAnimations::canStartAnimationOnCompositor(*m_target)) |
- return false; |
- CompositorAnimations::startAnimationOnCompositor( |
- *m_target, group, startTime, currentTime, specifiedTiming(), *animation(), |
- *model(), m_compositorAnimationIds, animationPlaybackRate); |
- DCHECK(!m_compositorAnimationIds.isEmpty()); |
- return true; |
-} |
- |
-bool KeyframeEffect::hasActiveAnimationsOnCompositor() const { |
- return !m_compositorAnimationIds.isEmpty(); |
-} |
- |
-bool KeyframeEffect::hasActiveAnimationsOnCompositor( |
- CSSPropertyID property) const { |
- return hasActiveAnimationsOnCompositor() && affects(PropertyHandle(property)); |
-} |
- |
-bool KeyframeEffect::affects(PropertyHandle property) const { |
- return m_model && m_model->affects(property); |
-} |
- |
-bool KeyframeEffect::cancelAnimationOnCompositor() { |
- // FIXME: cancelAnimationOnCompositor is called from withins style recalc. |
- // This queries compositingState, which is not necessarily up to date. |
- // https://code.google.com/p/chromium/issues/detail?id=339847 |
- DisableCompositingQueryAsserts disabler; |
- if (!hasActiveAnimationsOnCompositor()) |
- return false; |
- if (!m_target || !m_target->layoutObject()) |
- return false; |
- DCHECK(animation()); |
- for (const auto& compositorAnimationId : m_compositorAnimationIds) |
- CompositorAnimations::cancelAnimationOnCompositor(*m_target, *animation(), |
- compositorAnimationId); |
- m_compositorAnimationIds.clear(); |
- return true; |
-} |
- |
-void KeyframeEffect::restartAnimationOnCompositor() { |
- if (cancelAnimationOnCompositor()) |
- animation()->setCompositorPending(true); |
-} |
- |
-void KeyframeEffect::cancelIncompatibleAnimationsOnCompositor() { |
- if (m_target && animation() && model()) |
- CompositorAnimations::cancelIncompatibleAnimationsOnCompositor( |
- *m_target, *animation(), *model()); |
-} |
- |
-void KeyframeEffect::pauseAnimationForTestingOnCompositor(double pauseTime) { |
- DCHECK(hasActiveAnimationsOnCompositor()); |
- if (!m_target || !m_target->layoutObject()) |
- return; |
- DCHECK(animation()); |
- for (const auto& compositorAnimationId : m_compositorAnimationIds) |
- CompositorAnimations::pauseAnimationForTestingOnCompositor( |
- *m_target, *animation(), compositorAnimationId, pauseTime); |
-} |
- |
-void KeyframeEffect::attachCompositedLayers() { |
- DCHECK(m_target); |
- DCHECK(animation()); |
- CompositorAnimations::attachCompositedLayers(*m_target, *animation()); |
-} |
- |
AnimationEffectTiming* KeyframeEffect::timing() { |
return AnimationEffectTiming::create(this); |
} |
-DEFINE_TRACE(KeyframeEffect) { |
- KeyframeEffectReadOnly::trace(visitor); |
-} |
- |
} // namespace blink |