Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/EffectCompositor.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef mozilla_EffectCompositor_h
8
#define mozilla_EffectCompositor_h
9
10
#include "mozilla/EnumeratedArray.h"
11
#include "mozilla/Maybe.h"
12
#include "mozilla/OwningNonNull.h"
13
#include "mozilla/PseudoElementHashEntry.h"
14
#include "mozilla/RefPtr.h"
15
#include "mozilla/ServoTypes.h"
16
#include "nsCSSPropertyID.h"
17
#include "nsCycleCollectionParticipant.h"
18
#include "nsDataHashtable.h"
19
#include "nsTArray.h"
20
21
class nsCSSPropertyIDSet;
22
class nsAtom;
23
class nsIFrame;
24
class nsPresContext;
25
struct RawServoAnimationValueMap;
26
typedef RawServoAnimationValueMap* RawServoAnimationValueMapBorrowedMut;
27
28
namespace mozilla {
29
30
class ComputedStyle;
31
class EffectSet;
32
class RestyleTracker;
33
class StyleAnimationValue;
34
struct AnimationPerformanceWarning;
35
struct AnimationProperty;
36
struct NonOwningAnimationTarget;
37
38
namespace dom {
39
class Animation;
40
class Element;
41
}
42
43
class EffectCompositor
44
{
45
public:
46
  explicit EffectCompositor(nsPresContext* aPresContext)
47
    : mPresContext(aPresContext)
48
0
  {
49
0
  }
50
51
  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(EffectCompositor)
52
  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(EffectCompositor)
53
54
0
  void Disconnect() {
55
0
    mPresContext = nullptr;
56
0
  }
57
58
  // Animations can be applied at two different levels in the CSS cascade:
59
  enum class CascadeLevel : uint32_t {
60
    // The animations sheet (CSS animations, script-generated animations,
61
    // and CSS transitions that are no longer tied to CSS markup)
62
    Animations = 0,
63
    // The transitions sheet (CSS transitions that are tied to CSS markup)
64
    Transitions = 1
65
  };
66
  // We don't define this as part of CascadeLevel as then we'd have to add
67
  // explicit checks for the Count enum value everywhere CascadeLevel is used.
68
  static const size_t kCascadeLevelCount =
69
    static_cast<size_t>(CascadeLevel::Transitions) + 1;
70
71
  // NOTE: This can return null after Disconnect().
72
0
  nsPresContext* PresContext() const { return mPresContext; }
73
74
  enum class RestyleType {
75
    // Animation style has changed but the compositor is applying the same
76
    // change so we might be able to defer updating the main thread until it
77
    // becomes necessary.
78
    Throttled,
79
    // Animation style has changed and needs to be updated on the main thread.
80
    Standard,
81
    // Animation style has changed and needs to be updated on the main thread
82
    // as well as forcing animations on layers to be updated.
83
    // This is needed in cases such as when an animation becomes paused or has
84
    // its playback rate changed. In such cases, although the computed style
85
    // and refresh driver time might not change, we still need to ensure the
86
    // corresponding animations on layers are updated to reflect the new
87
    // configuration of the animation.
88
    Layer
89
  };
90
91
  // Notifies the compositor that the animation rule for the specified
92
  // (pseudo-)element at the specified cascade level needs to be updated.
93
  // The specified steps taken to update the animation rule depend on
94
  // |aRestyleType| whose values are described above.
95
  void RequestRestyle(dom::Element* aElement,
96
                      CSSPseudoElementType aPseudoType,
97
                      RestyleType aRestyleType,
98
                      CascadeLevel aCascadeLevel);
99
100
  // Schedule an animation restyle. This is called automatically by
101
  // RequestRestyle when necessary. However, it is exposed here since we also
102
  // need to perform this step when triggering transitions *without* also
103
  // invalidating the animation style rule (which RequestRestyle would do).
104
  void PostRestyleForAnimation(dom::Element* aElement,
105
                               CSSPseudoElementType aPseudoType,
106
                               CascadeLevel aCascadeLevel);
107
108
  // Posts an animation restyle for any elements whose animation style rule
109
  // is out of date but for which an animation restyle has not yet been
110
  // posted because updates on the main thread are throttled.
111
  void PostRestyleForThrottledAnimations();
112
113
  // Clear all pending restyle requests for the given (pseudo-) element (and its
114
  // ::before and ::after elements if the given element is not pseudo).
115
  void ClearRestyleRequestsFor(dom::Element* aElement);
116
117
  // Called when computed style on the specified (pseudo-) element might
118
  // have changed so that any context-sensitive values stored within
119
  // animation effects (e.g. em-based endpoints used in keyframe effects)
120
  // can be re-resolved to computed values.
121
  void UpdateEffectProperties(const ComputedStyle* aStyle,
122
                              dom::Element* aElement,
123
                              CSSPseudoElementType aPseudoType);
124
125
126
  // Get animation rule for stylo. This is an equivalent of GetAnimationRule
127
  // and will be called from servo side.
128
  // The animation rule is stored in |RawServoAnimationValueMapBorrowed|.
129
  // We need to be careful while doing any modification because it may cause
130
  // some thread-safe issues.
131
  bool GetServoAnimationRule(
132
    const dom::Element* aElement,
133
    CSSPseudoElementType aPseudoType,
134
    CascadeLevel aCascadeLevel,
135
    RawServoAnimationValueMapBorrowedMut aAnimationValues);
136
137
  bool HasPendingStyleUpdates() const;
138
139
140
  static bool HasAnimationsForCompositor(const nsIFrame* aFrame,
141
                                         nsCSSPropertyID aProperty);
142
143
  static nsTArray<RefPtr<dom::Animation>>
144
  GetAnimationsForCompositor(const nsIFrame* aFrame,
145
                             nsCSSPropertyID aProperty);
146
147
  static void ClearIsRunningOnCompositor(const nsIFrame* aFrame,
148
                                         nsCSSPropertyID aProperty);
149
150
  // Update animation cascade results for the specified (pseudo-)element
151
  // but only if we have marked the cascade as needing an update due a
152
  // the change in the set of effects or a change in one of the effects'
153
  // "in effect" state.
154
  //
155
  // This method does NOT detect if other styles that apply above the
156
  // animation level of the cascade have changed.
157
  static void
158
  MaybeUpdateCascadeResults(dom::Element* aElement,
159
                            CSSPseudoElementType aPseudoType);
160
161
  // Update the mPropertiesWithImportantRules and
162
  // mPropertiesForAnimationsLevel members of the given EffectSet, and also
163
  // request any restyles required by changes to the cascade result.
164
  //
165
  // NOTE: This can be expensive so we should only call it if styles that apply
166
  // above the animation level of the cascade might have changed. For all
167
  // other cases we should call MaybeUpdateCascadeResults.
168
  //
169
  // This is typically reserved for internal callers but is public here since
170
  // when we detect changes to the cascade on the Servo side we can't call
171
  // MarkCascadeNeedsUpdate during the traversal so instead we call this as part
172
  // of a follow-up sequential task.
173
  static void
174
  UpdateCascadeResults(EffectSet& aEffectSet,
175
                       dom::Element* aElement,
176
                       CSSPseudoElementType aPseudoType);
177
178
  // Helper to fetch the corresponding element and pseudo-type from a frame.
179
  //
180
  // For frames corresponding to pseudo-elements, the returned element is the
181
  // element on which we store the animations (i.e. the EffectSet and/or
182
  // AnimationCollection), *not* the generated content.
183
  //
184
  // Returns an empty result when a suitable element cannot be found including
185
  // when the frame represents a pseudo-element on which we do not support
186
  // animations.
187
  static Maybe<NonOwningAnimationTarget>
188
  GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame);
189
190
  // Associates a performance warning with effects on |aFrame| that animates
191
  // |aProperty|.
192
  static void SetPerformanceWarning(
193
    const nsIFrame* aFrame,
194
    nsCSSPropertyID aProperty,
195
    const AnimationPerformanceWarning& aWarning);
196
197
  // Do a bunch of stuff that we should avoid doing during the parallel
198
  // traversal (e.g. changing member variables) for all elements that we expect
199
  // to restyle on the next traversal.
200
  //
201
  // Returns true if there are elements needing a restyle for animation.
202
  bool PreTraverse(ServoTraversalFlags aFlags);
203
204
  // Similar to the above but only for the (pseudo-)element.
205
  bool PreTraverse(dom::Element* aElement, CSSPseudoElementType aPseudoType);
206
207
  // Similar to the above but for all elements in the subtree rooted
208
  // at aElement.
209
  bool PreTraverseInSubtree(ServoTraversalFlags aFlags, dom::Element* aElement);
210
211
  // Returns the target element for restyling.
212
  //
213
  // If |aPseudoType| is ::after or ::before, returns the generated content
214
  // element of which |aElement| is the parent. If |aPseudoType| is any other
215
  // pseudo type (other thant CSSPseudoElementType::NotPseudo) returns nullptr.
216
  // Otherwise, returns |aElement|.
217
  static dom::Element* GetElementToRestyle(dom::Element* aElement,
218
                                           CSSPseudoElementType aPseudoType);
219
220
private:
221
  ~EffectCompositor() = default;
222
223
224
  // Get the properties in |aEffectSet| that we are able to animate on the
225
  // compositor but which are also specified at a higher level in the cascade
226
  // than the animations level.
227
  static nsCSSPropertyIDSet
228
  GetOverriddenProperties(EffectSet& aEffectSet,
229
                          dom::Element* aElement,
230
                          CSSPseudoElementType aPseudoType);
231
232
  static nsPresContext* GetPresContext(dom::Element* aElement);
233
234
  nsPresContext* mPresContext;
235
236
  // Elements with a pending animation restyle. The associated bool value is
237
  // true if a pending animation restyle has also been dispatched. For
238
  // animations that can be throttled, we will add an entry to the hashtable to
239
  // indicate that the style rule on the element is out of date but without
240
  // posting a restyle to update it.
241
  EnumeratedArray<CascadeLevel, CascadeLevel(kCascadeLevelCount),
242
                  nsDataHashtable<PseudoElementHashEntry, bool>>
243
                    mElementsToRestyle;
244
245
  bool mIsInPreTraverse = false;
246
247
};
248
249
} // namespace mozilla
250
251
#endif // mozilla_EffectCompositor_h