1 /*
2  * Copyright (C) 2013 Google 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 are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ELEMENT_ANIMATIONS_H_
32 #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ELEMENT_ANIMATIONS_H_
33 
34 #include "base/macros.h"
35 #include "base/memory/scoped_refptr.h"
36 #include "third_party/blink/renderer/core/animation/css/css_animations.h"
37 #include "third_party/blink/renderer/core/animation/effect_stack.h"
38 #include "third_party/blink/renderer/core/animation/worklet_animation_base.h"
39 #include "third_party/blink/renderer/core/css/properties/css_bitset.h"
40 #include "third_party/blink/renderer/platform/wtf/hash_counted_set.h"
41 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
42 
43 namespace blink {
44 
45 class CSSAnimations;
46 
47 using AnimationCountedSet = HeapHashCountedSet<WeakMember<Animation>>;
48 using WorkletAnimationSet = HeapHashSet<WeakMember<WorkletAnimationBase>>;
49 
50 class CORE_EXPORT ElementAnimations final
51     : public GarbageCollected<ElementAnimations> {
52  public:
53   ElementAnimations();
54   ~ElementAnimations();
55 
56   // Animations that are currently active for this element, their effects will
57   // be applied during a style recalc. CSS Transitions are included in this
58   // stack.
GetEffectStack()59   EffectStack& GetEffectStack() { return effect_stack_; }
GetEffectStack()60   const EffectStack& GetEffectStack() const { return effect_stack_; }
61   // Tracks the state of active CSS Animations and Transitions. The individual
62   // animations will also be part of the animation stack, but the mapping
63   // between animation name and animation is kept here.
CssAnimations()64   CSSAnimations& CssAnimations() { return css_animations_; }
CssAnimations()65   const CSSAnimations& CssAnimations() const { return css_animations_; }
66 
67   // Animations which have effects targeting this element.
Animations()68   AnimationCountedSet& Animations() { return animations_; }
69   // Worklet Animations which have effects targeting this element.
GetWorkletAnimations()70   WorkletAnimationSet& GetWorkletAnimations() { return worklet_animations_; }
71 
IsEmpty()72   bool IsEmpty() const {
73     return effect_stack_.IsEmpty() && css_animations_.IsEmpty() &&
74            animations_.IsEmpty();
75   }
76 
77   void RestartAnimationOnCompositor();
78 
79   void UpdateAnimationFlags(ComputedStyle&);
SetAnimationStyleChange(bool animation_style_change)80   void SetAnimationStyleChange(bool animation_style_change) {
81     animation_style_change_ = animation_style_change;
82   }
IsAnimationStyleChange()83   bool IsAnimationStyleChange() const { return animation_style_change_; }
84 
85   const ComputedStyle* BaseComputedStyle() const;
86   const CSSBitset* BaseImportantSet() const;
87   void UpdateBaseComputedStyle(const ComputedStyle*,
88                                std::unique_ptr<CSSBitset> base_important_set);
89   void ClearBaseComputedStyle();
90 
91   bool UpdateBoxSizeAndCheckTransformAxisAlignment(const FloatSize& box_size);
92 
93   void Trace(Visitor*) const;
94 
95  private:
96   EffectStack effect_stack_;
97   CSSAnimations css_animations_;
98   AnimationCountedSet animations_;
99   WorkletAnimationSet worklet_animations_;
100 
101   // When an Element is being animated, its entire style will be dirtied every
102   // frame by the running animation - even if the animation is only changing a
103   // few properties. To avoid the expensive cost of recomputing the entire
104   // style, we store a cached value of the 'base' computed style (e.g. with no
105   // change from the running animations) and use that during style recalc,
106   // applying only the animation changes on top of it.
107   bool animation_style_change_;
108   scoped_refptr<ComputedStyle> base_computed_style_;
109   // Keeps track of the !important declarations used to build the base
110   // computed style. These declarations must not be overwritten by animation
111   // effects, hence we have to disable the base computed style optimization when
112   // !important declarations conflict with active animations.
113   //
114   // If there were no !important declarations in the base style, this field
115   // will be nullptr.
116   //
117   // TODO(andruud): We should be able to simply skip applying the animation
118   // for properties in this set instead of disabling the optimization.
119   // However, we currently need the cascade to handle the case where
120   // an !important declaration appears in a :visited selector.
121   // See https://crbug.com/1062217.
122   std::unique_ptr<CSSBitset> base_important_set_;
123 
124   DISALLOW_COPY_AND_ASSIGN(ElementAnimations);
125 
126   FRIEND_TEST_ALL_PREFIXES(StyleEngineTest, PseudoElementBaseComputedStyle);
127 };
128 
129 }  // namespace blink
130 
131 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ELEMENT_ANIMATIONS_H_
132