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 ACTIVELAYERTRACKER_H_
8 #define ACTIVELAYERTRACKER_H_
9 
10 #include "nsCSSPropertyID.h"
11 
12 class nsIFrame;
13 class nsIContent;
14 class nsCSSPropertyIDSet;
15 class nsDisplayListBuilder;
16 class nsDOMCSSDeclaration;
17 
18 namespace mozilla {
19 
20 /**
21  * This class receives various notifications about style changes and content
22  * changes that affect layerization decisions, and implements the heuristics
23  * that drive those decisions. It manages per-frame state to support those
24  * heuristics.
25  */
26 class ActiveLayerTracker {
27  public:
28   static void Shutdown();
29 
30   /*
31    * We track style changes to selected styles:
32    *   eCSSProperty_transform, eCSSProperty_translate,
33    *   eCSSProperty_rotate, eCSSProperty_scale
34    *   eCSSProperty_offset_path, eCSSProperty_offset_distance,
35    *   eCSSProperty_offset_rotate, eCSSProperty_offset_anchor,
36    *   eCSSProperty_opacity
37    *   eCSSProperty_left, eCSSProperty_top,
38    *   eCSSProperty_right, eCSSProperty_bottom
39    * and use that information to guess whether style changes are animated.
40    */
41 
42   /**
43    * Notify aFrame's style property as having changed due to a restyle,
44    * and therefore possibly wanting an active layer to render that style.
45    * Any such marking will time out after a short period.
46    * @param aProperty the property that has changed
47    */
48   static void NotifyRestyle(nsIFrame* aFrame, nsCSSPropertyID aProperty);
49   /**
50    * Notify aFrame's left/top/right/bottom properties as having (maybe)
51    * changed due to a restyle, and therefore possibly wanting an active layer
52    * to render that style. Any such marking will time out after a short period.
53    */
54   static void NotifyOffsetRestyle(nsIFrame* aFrame);
55   /**
56    * Mark aFrame as being known to have an animation of aProperty.
57    * Any such marking will time out after a short period.
58    * aNewValue and aDOMCSSDecl are used to determine whether the property's
59    * value has changed.
60    */
61   static void NotifyAnimated(nsIFrame* aFrame, nsCSSPropertyID aProperty,
62                              const nsACString& aNewValue,
63                              nsDOMCSSDeclaration* aDOMCSSDecl);
64   /**
65    * Notify aFrame as being known to have an animation of aProperty through an
66    * inline style modification during aScrollFrame's scroll event handler.
67    */
68   static void NotifyAnimatedFromScrollHandler(nsIFrame* aFrame,
69                                               nsCSSPropertyID aProperty,
70                                               nsIFrame* aScrollFrame);
71   /**
72    * Notify that a property in the inline style rule of aFrame's element
73    * has been modified.
74    * This notification is incomplete --- not all modifications to inline
75    * style will trigger this.
76    * aNewValue and aDOMCSSDecl are used to determine whether the property's
77    * value has changed.
78    */
79   static void NotifyInlineStyleRuleModified(nsIFrame* aFrame,
80                                             nsCSSPropertyID aProperty,
81                                             const nsACString& aNewValue,
82                                             nsDOMCSSDeclaration* aDOMCSSDecl);
83   /**
84    * Notify that a frame needs to be repainted. This is important for layering
85    * decisions where, say, aFrame's transform is updated from JS, but we need
86    * to repaint aFrame anyway, so we get no benefit from giving it its own
87    * layer.
88    */
89   static void NotifyNeedsRepaint(nsIFrame* aFrame);
90   /**
91    * Return true if aFrame's property style in |aPropertySet| should be
92    * considered as being animated for constructing active layers.
93    */
94   static bool IsStyleAnimated(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
95                               const nsCSSPropertyIDSet& aPropertySet);
96   /**
97    * Return true if any of aFrame's offset property styles should be considered
98    * as being animated for constructing active layers.
99    */
100   static bool IsOffsetStyleAnimated(nsIFrame* aFrame);
101   /**
102    * Return true if aFrame's background-position-x or background-position-y
103    * property is animated.
104    */
105   static bool IsBackgroundPositionAnimated(nsDisplayListBuilder* aBuilder,
106                                            nsIFrame* aFrame);
107   /**
108    * Return true if aFrame's transform-like property,
109    * i.e. transform/translate/rotate/scale, is animated.
110    */
111   static bool IsTransformAnimated(nsDisplayListBuilder* aBuilder,
112                                   nsIFrame* aFrame);
113   /**
114    * Return true if aFrame's transform style should be considered as being
115    * animated for pre-rendering.
116    */
117   static bool IsTransformMaybeAnimated(nsIFrame* aFrame);
118   /**
119    * Return true if aFrame either has an animated scale now, or is likely to
120    * have one in the future because it has a CSS animation or transition
121    * (which may not be playing right now) that affects its scale.
122    */
123   static bool IsScaleSubjectToAnimation(nsIFrame* aFrame);
124 
125   /**
126    * Transfer the LayerActivity property to the frame's content node when the
127    * frame is about to be destroyed so that layer activity can be tracked
128    * throughout reframes of an element. Only call this when aFrame is the
129    * primary frame of aContent.
130    */
131   static void TransferActivityToContent(nsIFrame* aFrame, nsIContent* aContent);
132   /**
133    * Transfer the LayerActivity property back to the content node's primary
134    * frame after the frame has been created.
135    */
136   static void TransferActivityToFrame(nsIContent* aContent, nsIFrame* aFrame);
137 
138   /*
139    * We track modifications to the content of certain frames (i.e. canvas
140    * frames) and use that to make layering decisions.
141    */
142 
143   /**
144    * Mark aFrame's content as being active. This marking will time out after
145    * a short period.
146    */
147   static void NotifyContentChange(nsIFrame* aFrame);
148   /**
149    * Return true if this frame's content is still marked as active.
150    */
151   static bool IsContentActive(nsIFrame* aFrame);
152 
153   /**
154    * Called before and after a scroll event handler is executed, with the
155    * scrollframe or nullptr, respectively. This acts as a hint to treat
156    * inline style changes during the handler differently.
157    */
158   static void SetCurrentScrollHandlerFrame(nsIFrame* aFrame);
159 };
160 
161 }  // namespace mozilla
162 
163 #endif /* ACTIVELAYERTRACKER_H_ */
164