| 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
|
|
|