4f64ca4eade092e82548c743df5d1b7aaeac8a74
[WebKit-https.git] / Source / WebCore / animation / KeyframeEffect.h
1 /*
2  * Copyright (C) 2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include "AnimationEffect.h"
29 #include "CSSPropertyBlendingClient.h"
30 #include "CompositeOperation.h"
31 #include "CompositeOperationOrAuto.h"
32 #include "EffectTiming.h"
33 #include "Element.h"
34 #include "IterationCompositeOperation.h"
35 #include "KeyframeEffectOptions.h"
36 #include "KeyframeList.h"
37 #include "RenderStyle.h"
38 #include "StyleProperties.h"
39 #include <wtf/Ref.h>
40
41 namespace WebCore {
42
43 class Element;
44 class FilterOperations;
45
46 class KeyframeEffect : public AnimationEffect
47     , public CSSPropertyBlendingClient {
48 public:
49     static ExceptionOr<Ref<KeyframeEffect>> create(JSC::ExecState&, Element*, JSC::Strong<JSC::JSObject>&&, Optional<Variant<double, KeyframeEffectOptions>>&&);
50     static ExceptionOr<Ref<KeyframeEffect>> create(JSC::ExecState&, Ref<KeyframeEffect>&&);
51     static Ref<KeyframeEffect> create(const Element&);
52     ~KeyframeEffect() { }
53
54     bool isKeyframeEffect() const final { return true; }
55
56     struct BasePropertyIndexedKeyframe {
57         Variant<std::nullptr_t, Vector<Optional<double>>, double> offset = Vector<Optional<double>>();
58         Variant<Vector<String>, String> easing = Vector<String>();
59         Variant<Vector<CompositeOperationOrAuto>, CompositeOperationOrAuto> composite = Vector<CompositeOperationOrAuto>();
60     };
61
62     struct BaseKeyframe {
63         Optional<double> offset;
64         String easing { "linear" };
65         CompositeOperationOrAuto composite { CompositeOperationOrAuto::Auto };
66     };
67
68     struct PropertyAndValues {
69         CSSPropertyID property;
70         Vector<String> values;
71     };
72
73     struct KeyframeLikeObject {
74         BasePropertyIndexedKeyframe baseProperties;
75         Vector<PropertyAndValues> propertiesAndValues;
76     };
77
78     struct ParsedKeyframe {
79         Optional<double> offset;
80         double computedOffset;
81         CompositeOperationOrAuto composite { CompositeOperationOrAuto::Auto };
82         String easing;
83         RefPtr<TimingFunction> timingFunction;
84         Ref<MutableStyleProperties> style;
85         HashMap<CSSPropertyID, String> unparsedStyle;
86
87         ParsedKeyframe()
88             : style(MutableStyleProperties::create())
89         {
90         }
91     };
92
93     struct BaseComputedKeyframe {
94         Optional<double> offset;
95         double computedOffset;
96         String easing { "linear" };
97         CompositeOperationOrAuto composite { CompositeOperationOrAuto::Auto };
98     };
99
100     Element* target() const { return m_target.get(); }
101     void setTarget(RefPtr<Element>&&);
102
103     Vector<JSC::Strong<JSC::JSObject>> getKeyframes(JSC::ExecState&);
104     ExceptionOr<void> setKeyframes(JSC::ExecState&, JSC::Strong<JSC::JSObject>&&);
105
106     IterationCompositeOperation iterationComposite() const { return m_iterationCompositeOperation; }
107     void setIterationComposite(IterationCompositeOperation iterationCompositeOperation) { m_iterationCompositeOperation = iterationCompositeOperation; }
108     CompositeOperation composite() const { return m_compositeOperation; }
109     void setComposite(CompositeOperation compositeOperation) { m_compositeOperation = compositeOperation; }
110
111     void getAnimatedStyle(std::unique_ptr<RenderStyle>& animatedStyle);
112     void apply(RenderStyle&) override;
113     void invalidate() override;
114     void animationDidSeek() final;
115     void animationSuspensionStateDidChange(bool) final;
116     void applyPendingAcceleratedActions();
117     bool isRunningAccelerated() const { return m_lastRecordedAcceleratedAction != AcceleratedAction::Stop; }
118     bool hasPendingAcceleratedAction() const { return !m_pendingAcceleratedActions.isEmpty() && isRunningAccelerated(); }
119
120     RenderElement* renderer() const override;
121     const RenderStyle& currentStyle() const override;
122     bool isAccelerated() const override { return m_shouldRunAccelerated; }
123     bool filterFunctionListsMatch() const override { return m_filterFunctionListsMatch; }
124     bool transformFunctionListsMatch() const override { return m_transformFunctionListsMatch; }
125 #if ENABLE(FILTERS_LEVEL_2)
126     bool backdropFilterFunctionListsMatch() const override { return m_backdropFilterFunctionListsMatch; }
127 #endif
128     bool colorFilterFunctionListsMatch() const override { return m_colorFilterFunctionListsMatch; }
129
130     void computeDeclarativeAnimationBlendingKeyframes(const RenderStyle* oldStyle, const RenderStyle& newStyle);
131     bool hasBlendingKeyframes() const { return m_blendingKeyframes.size(); }
132     const HashSet<CSSPropertyID>& animatedProperties() const { return m_blendingKeyframes.properties(); }
133
134     bool computeExtentOfTransformAnimation(LayoutRect&) const;
135     bool computeTransformedExtentViaTransformList(const FloatRect&, const RenderStyle&, LayoutRect&) const;
136     bool computeTransformedExtentViaMatrix(const FloatRect&, const RenderStyle&, LayoutRect&) const;
137     bool forceLayoutIfNeeded();
138
139 private:
140     KeyframeEffect(Element*);
141
142     enum class AcceleratedAction { Play, Pause, Seek, Stop };
143
144     void copyPropertiesFromSource(Ref<KeyframeEffect>&&);
145     ExceptionOr<void> processKeyframes(JSC::ExecState&, JSC::Strong<JSC::JSObject>&&);
146     void addPendingAcceleratedAction(AcceleratedAction);
147     void updateAcceleratedAnimationState();
148     void setAnimatedPropertiesInStyle(RenderStyle&, double);
149     TimingFunction* timingFunctionForKeyframeAtIndex(size_t);
150     Ref<const Animation> backingAnimationForCompositedRenderer() const;
151     void computedNeedsForcedLayout();
152     void computeStackingContextImpact();
153     void updateBlendingKeyframes(RenderStyle&);
154     void computeCSSAnimationBlendingKeyframes();
155     void computeCSSTransitionBlendingKeyframes(const RenderStyle* oldStyle, const RenderStyle& newStyle);
156     void computeShouldRunAccelerated();
157     void setBlendingKeyframes(KeyframeList&);
158     void checkForMatchingTransformFunctionLists();
159     void checkForMatchingFilterFunctionLists();
160 #if ENABLE(FILTERS_LEVEL_2)
161     void checkForMatchingBackdropFilterFunctionLists();
162 #endif
163     void checkForMatchingColorFilterFunctionLists();
164
165     bool checkForMatchingFilterFunctionLists(CSSPropertyID, const std::function<const FilterOperations& (const RenderStyle&)>&) const;
166
167     AcceleratedAction m_lastRecordedAcceleratedAction { AcceleratedAction::Stop };
168     bool m_shouldRunAccelerated { false };
169     bool m_needsForcedLayout { false };
170     bool m_triggersStackingContext { false };
171     bool m_transformFunctionListsMatch { false };
172     bool m_filterFunctionListsMatch { false };
173 #if ENABLE(FILTERS_LEVEL_2)
174     bool m_backdropFilterFunctionListsMatch { false };
175 #endif
176     bool m_colorFilterFunctionListsMatch { false };
177
178     RefPtr<Element> m_target;
179     KeyframeList m_blendingKeyframes;
180     Vector<ParsedKeyframe> m_parsedKeyframes;
181     IterationCompositeOperation m_iterationCompositeOperation { IterationCompositeOperation::Replace };
182     CompositeOperation m_compositeOperation { CompositeOperation::Replace };
183
184     Vector<AcceleratedAction> m_pendingAcceleratedActions;
185 };
186
187 } // namespace WebCore
188
189 SPECIALIZE_TYPE_TRAITS_ANIMATION_EFFECT(KeyframeEffect, isKeyframeEffect());