blob: b475715eb30c61b1ca5a181ce8b68c22da8dfefe [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CSSAnimationUpdate_h
#define CSSAnimationUpdate_h
#include "core/animation/AnimationStack.h"
#include "core/animation/InertEffect.h"
#include "core/animation/Interpolation.h"
#include "core/animation/KeyframeEffectModel.h"
#include "core/animation/css/CSSAnimatableValueFactory.h"
#include "core/css/CSSKeyframesRule.h"
#include "core/css/CSSPropertyEquality.h"
#include "core/layout/LayoutObject.h"
#include "wtf/Allocator.h"
#include "wtf/HashMap.h"
#include "wtf/Vector.h"
#include "wtf/text/AtomicString.h"
namespace blink {
class Animation;
// This class stores the CSS Animations/Transitions information we use during a style recalc.
// This includes updates to animations/transitions as well as the Interpolations to be applied.
class CSSAnimationUpdate final {
DISALLOW_NEW();
WTF_MAKE_NONCOPYABLE(CSSAnimationUpdate);
public:
class NewAnimation {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
NewAnimation(AtomicString name, size_t nameIndex, const InertEffect& effect, Timing timing, StyleRuleKeyframes* styleRule)
: name(name)
, nameIndex(nameIndex)
, effect(effect)
, timing(timing)
, styleRule(styleRule)
, styleRuleVersion(this->styleRule->version())
{
}
DEFINE_INLINE_TRACE()
{
visitor->trace(effect);
visitor->trace(styleRule);
}
AtomicString name;
size_t nameIndex;
Member<const InertEffect> effect;
Timing timing;
Member<StyleRuleKeyframes> styleRule;
unsigned styleRuleVersion;
};
class UpdatedAnimation {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
UpdatedAnimation(size_t index, Animation* animation, const InertEffect& effect, Timing specifiedTiming, StyleRuleKeyframes* styleRule)
: index(index)
, animation(animation)
, effect(&effect)
, specifiedTiming(specifiedTiming)
, styleRule(styleRule)
, styleRuleVersion(this->styleRule->version())
{
}
DEFINE_INLINE_TRACE()
{
visitor->trace(animation);
visitor->trace(effect);
visitor->trace(styleRule);
}
size_t index;
Member<Animation> animation;
Member<const InertEffect> effect;
Timing specifiedTiming;
Member<StyleRuleKeyframes> styleRule;
unsigned styleRuleVersion;
};
CSSAnimationUpdate()
{
}
~CSSAnimationUpdate()
{
}
void copy(const CSSAnimationUpdate& update)
{
ASSERT(isEmpty());
m_newAnimations = update.newAnimations();
m_animationsWithUpdates = update.animationsWithUpdates();
m_newTransitions = update.newTransitions();
m_activeInterpolationsForAnimations = update.activeInterpolationsForAnimations();
m_activeInterpolationsForTransitions = update.activeInterpolationsForTransitions();
m_cancelledAnimationIndices = update.cancelledAnimationIndices();
m_animationIndicesWithPauseToggled = update.animationIndicesWithPauseToggled();
m_cancelledTransitions = update.cancelledTransitions();
m_finishedTransitions = update.finishedTransitions();
m_updatedCompositorKeyframes = update.updatedCompositorKeyframes();
}
void clear()
{
m_newAnimations.clear();
m_animationsWithUpdates.clear();
m_newTransitions.clear();
m_activeInterpolationsForAnimations.clear();
m_activeInterpolationsForTransitions.clear();
m_cancelledAnimationIndices.clear();
m_animationIndicesWithPauseToggled.clear();
m_cancelledTransitions.clear();
m_finishedTransitions.clear();
m_updatedCompositorKeyframes.clear();
}
void startAnimation(const AtomicString& animationName, size_t nameIndex, const InertEffect& effect, const Timing& timing, StyleRuleKeyframes* styleRule)
{
m_newAnimations.append(NewAnimation(animationName, nameIndex, effect, timing, styleRule));
}
// Returns whether animation has been suppressed and should be filtered during style application.
bool isSuppressedAnimation(const Animation* animation) const { return m_suppressedAnimations.contains(animation); }
void cancelAnimation(size_t index, const Animation& animation)
{
m_cancelledAnimationIndices.append(index);
m_suppressedAnimations.add(&animation);
}
void toggleAnimationIndexPaused(size_t index)
{
m_animationIndicesWithPauseToggled.append(index);
}
void updateAnimation(size_t index, Animation* animation, const InertEffect& effect, const Timing& specifiedTiming,
StyleRuleKeyframes* styleRule)
{
m_animationsWithUpdates.append(UpdatedAnimation(index, animation, effect, specifiedTiming, styleRule));
m_suppressedAnimations.add(animation);
}
void updateCompositorKeyframes(Animation* animation)
{
m_updatedCompositorKeyframes.append(animation);
}
void startTransition(CSSPropertyID id, const AnimatableValue* from, const AnimatableValue* to, PassRefPtr<AnimatableValue> reversingAdjustedStartValue, double reversingShorteningFactor, const InertEffect& effect)
{
NewTransition newTransition;
newTransition.id = id;
newTransition.from = from;
newTransition.to = to;
newTransition.reversingAdjustedStartValue = reversingAdjustedStartValue;
newTransition.reversingShorteningFactor = reversingShorteningFactor;
newTransition.effect = &effect;
m_newTransitions.set(id, newTransition);
}
bool isCancelledTransition(CSSPropertyID id) const { return m_cancelledTransitions.contains(id); }
void cancelTransition(CSSPropertyID id) { m_cancelledTransitions.add(id); }
void finishTransition(CSSPropertyID id) { m_finishedTransitions.add(id); }
const HeapVector<NewAnimation>& newAnimations() const { return m_newAnimations; }
const Vector<size_t>& cancelledAnimationIndices() const { return m_cancelledAnimationIndices; }
const HeapHashSet<Member<const Animation>>& suppressedAnimations() const { return m_suppressedAnimations; }
const Vector<size_t>& animationIndicesWithPauseToggled() const { return m_animationIndicesWithPauseToggled; }
const HeapVector<UpdatedAnimation>& animationsWithUpdates() const { return m_animationsWithUpdates; }
const HeapVector<Member<Animation>>& updatedCompositorKeyframes() const { return m_updatedCompositorKeyframes; }
struct NewTransition {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
DEFINE_INLINE_TRACE()
{
visitor->trace(effect);
}
CSSPropertyID id;
const AnimatableValue* from;
const AnimatableValue* to;
RefPtr<AnimatableValue> reversingAdjustedStartValue;
double reversingShorteningFactor;
Member<const InertEffect> effect;
};
using NewTransitionMap = HeapHashMap<CSSPropertyID, NewTransition>;
const NewTransitionMap& newTransitions() const { return m_newTransitions; }
const HashSet<CSSPropertyID>& cancelledTransitions() const { return m_cancelledTransitions; }
const HashSet<CSSPropertyID>& finishedTransitions() const { return m_finishedTransitions; }
void adoptActiveInterpolationsForAnimations(ActiveInterpolationsMap& newMap) { newMap.swap(m_activeInterpolationsForAnimations); }
void adoptActiveInterpolationsForTransitions(ActiveInterpolationsMap& newMap) { newMap.swap(m_activeInterpolationsForTransitions); }
const ActiveInterpolationsMap& activeInterpolationsForAnimations() const { return m_activeInterpolationsForAnimations; }
const ActiveInterpolationsMap& activeInterpolationsForTransitions() const { return m_activeInterpolationsForTransitions; }
ActiveInterpolationsMap& activeInterpolationsForAnimations() { return m_activeInterpolationsForAnimations; }
bool isEmpty() const
{
return m_newAnimations.isEmpty()
&& m_cancelledAnimationIndices.isEmpty()
&& m_suppressedAnimations.isEmpty()
&& m_animationIndicesWithPauseToggled.isEmpty()
&& m_animationsWithUpdates.isEmpty()
&& m_newTransitions.isEmpty()
&& m_cancelledTransitions.isEmpty()
&& m_finishedTransitions.isEmpty()
&& m_activeInterpolationsForAnimations.isEmpty()
&& m_activeInterpolationsForTransitions.isEmpty()
&& m_updatedCompositorKeyframes.isEmpty();
}
DEFINE_INLINE_TRACE()
{
visitor->trace(m_newTransitions);
visitor->trace(m_newAnimations);
visitor->trace(m_suppressedAnimations);
visitor->trace(m_animationsWithUpdates);
visitor->trace(m_updatedCompositorKeyframes);
}
private:
// Order is significant since it defines the order in which new animations
// will be started. Note that there may be multiple animations present
// with the same name, due to the way in which we split up animations with
// incomplete keyframes.
HeapVector<NewAnimation> m_newAnimations;
Vector<size_t> m_cancelledAnimationIndices;
HeapHashSet<Member<const Animation>> m_suppressedAnimations;
Vector<size_t> m_animationIndicesWithPauseToggled;
HeapVector<UpdatedAnimation> m_animationsWithUpdates;
HeapVector<Member<Animation>> m_updatedCompositorKeyframes;
NewTransitionMap m_newTransitions;
HashSet<CSSPropertyID> m_cancelledTransitions;
HashSet<CSSPropertyID> m_finishedTransitions;
ActiveInterpolationsMap m_activeInterpolationsForAnimations;
ActiveInterpolationsMap m_activeInterpolationsForTransitions;
friend class PendingAnimationUpdate;
};
} // namespace blink
WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::CSSAnimationUpdate::NewAnimation);
WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::CSSAnimationUpdate::UpdatedAnimation);
#endif