#ifndef CC_ANIMATION_ELEMENT_ANIMATIONS_H_
#define CC_ANIMATION_ELEMENT_ANIMATIONS_H_
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "cc/animation/animation_export.h"
#include "cc/animation/filter_animation_curve.h"
#include "cc/animation/scroll_offset_animation_curve.h"
#include "cc/paint/element_id.h"
#include "cc/paint/paint_worklet_input.h"
#include "cc/trees/property_animation_state.h"
#include "cc/trees/target_property.h"
#include "ui/gfx/animation/keyframe/animation_curve.h"
#include "ui/gfx/animation/keyframe/target_property.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/transform.h"
namespace gfx {
class TransformOperations;
}
namespace cc {
class AnimationHost;
class FilterOperations;
class KeyframeEffect;
class KeyframeModel;
enum class ElementListType;
class CC_ANIMATION_EXPORT ElementAnimations
: public gfx::FloatAnimationCurve::Target,
public gfx::ColorAnimationCurve::Target,
public gfx::TransformAnimationCurve::Target,
public ScrollOffsetAnimationCurve::Target,
public FilterAnimationCurve::Target,
public base::RefCounted<ElementAnimations> {
public:
static scoped_refptr<ElementAnimations> Create(AnimationHost* host,
ElementId element_id);
ElementAnimations(const ElementAnimations&) = delete;
ElementAnimations& operator=(const ElementAnimations&) = delete;
bool AnimationHostIs(AnimationHost* host) const {
return animation_host_ == host;
}
void ClearAnimationHost() { animation_host_ = nullptr; }
ElementId element_id() const { return element_id_; }
void ClearAffectedElementTypes(const PropertyToElementIdMap& element_id_map);
void RemoveKeyframeEffects();
void AddKeyframeEffect(KeyframeEffect* keyframe_effect);
void RemoveKeyframeEffect(KeyframeEffect* keyframe_effect);
bool IsEmpty() const;
void PushPropertiesTo(
scoped_refptr<ElementAnimations> element_animations_impl) const;
bool HasTickingKeyframeEffect() const;
bool HasAnyKeyframeModel() const;
bool HasAnyAnimationTargetingProperty(TargetProperty::Type property,
ElementId element_id) const;
bool IsPotentiallyAnimatingProperty(TargetProperty::Type target_property,
ElementListType list_type) const;
bool IsCurrentlyAnimatingProperty(TargetProperty::Type target_property,
ElementListType list_type) const;
bool AnimationsPreserveAxisAlignment() const;
float MaximumScale(ElementId element_id, ElementListType list_type) const;
bool ScrollOffsetAnimationWasInterrupted() const;
void SetNeedsPushProperties();
void InitClientAnimationState();
void UpdateClientAnimationState();
void AttachToCurve(gfx::AnimationCurve* c);
void OnFloatAnimated(const float& value,
int target_property_id,
gfx::KeyframeModel* keyframe_model) override;
void OnFilterAnimated(const FilterOperations& filter,
int target_property_id,
gfx::KeyframeModel* keyframe_model) override;
void OnColorAnimated(const SkColor& color,
int target_property_id,
gfx::KeyframeModel* keyframe_model) override;
void OnTransformAnimated(const gfx::TransformOperations& operations,
int target_property_id,
gfx::KeyframeModel* keyframe_model) override;
void OnScrollOffsetAnimated(const gfx::PointF& scroll_offset,
int target_property_id,
gfx::KeyframeModel* keyframe_model) override;
std::optional<gfx::PointF> ScrollOffsetForAnimation() const;
PropertyToElementIdMap GetPropertyToElementIdMap() const;
unsigned int CountKeyframesForTesting() const;
KeyframeEffect* FirstKeyframeEffectForTesting() const;
bool HasKeyframeEffectForTesting(const KeyframeEffect* keyframe) const;
private:
friend class base::RefCounted<ElementAnimations>;
ElementAnimations(AnimationHost* host, ElementId element_id);
~ElementAnimations() override;
void InitAffectedElementTypes();
void OnFilterAnimated(ElementListType list_type,
const FilterOperations& filters,
gfx::KeyframeModel* keyframe_model);
void OnBackdropFilterAnimated(ElementListType list_type,
const FilterOperations& backdrop_filters,
gfx::KeyframeModel* keyframe_model);
void OnOpacityAnimated(ElementListType list_type,
float opacity,
gfx::KeyframeModel* keyframe_model);
void OnCustomPropertyAnimated(PaintWorkletInput::PropertyValue property_value,
KeyframeModel* keyframe_model,
int target_property_id);
void OnTransformAnimated(ElementListType list_type,
const gfx::Transform& transform,
gfx::KeyframeModel* keyframe_model);
void OnScrollOffsetAnimated(ElementListType list_type,
const gfx::PointF& scroll_offset,
gfx::KeyframeModel* keyframe_model);
static gfx::TargetProperties GetPropertiesMaskForAnimationState();
void UpdateMaximumScale(ElementId element_id,
ElementListType list_type,
float* cached_scale);
void UpdateKeyframeEffectsTickingState() const;
void RemoveKeyframeEffectsFromTicking() const;
bool KeyframeModelAffectsActiveElements(
gfx::KeyframeModel* keyframe_model) const;
bool KeyframeModelAffectsPendingElements(
gfx::KeyframeModel* keyframe_model) const;
base::ObserverList<KeyframeEffect>::Unchecked keyframe_effects_list_;
raw_ptr<AnimationHost> animation_host_;
ElementId element_id_;
mutable bool needs_push_properties_;
PropertyAnimationState active_state_;
PropertyAnimationState pending_state_;
float transform_property_active_maximum_scale_;
float transform_property_pending_maximum_scale_;
float scale_property_active_maximum_scale_;
float scale_property_pending_maximum_scale_;
};
}
#endif