summaryrefslogtreecommitdiffstats
path: root/layout/painting/ActiveLayerTracker.h
blob: 1bcd2b0e62c75876c86f4559f9dca92093bf2166 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef ACTIVELAYERTRACKER_H_
#define ACTIVELAYERTRACKER_H_

#include "nsCSSPropertyID.h"

class nsIFrame;
class nsIContent;
class nsCSSPropertyIDSet;
class nsDisplayListBuilder;
class nsDOMCSSDeclaration;

namespace mozilla {

/**
 * This class receives various notifications about style changes and content
 * changes that affect layerization decisions, and implements the heuristics
 * that drive those decisions. It manages per-frame state to support those
 * heuristics.
 */
class ActiveLayerTracker {
 public:
  static void Shutdown();

  /*
   * We track style changes to selected styles:
   *   eCSSProperty_transform, eCSSProperty_translate,
   *   eCSSProperty_rotate, eCSSProperty_scale
   *   eCSSProperty_offset_path, eCSSProperty_offset_distance,
   *   eCSSProperty_offset_rotate, eCSSProperty_offset_anchor,
   *   eCSSProperty_opacity
   *   eCSSProperty_left, eCSSProperty_top,
   *   eCSSProperty_right, eCSSProperty_bottom
   * and use that information to guess whether style changes are animated.
   */

  /**
   * Notify aFrame's style property as having changed due to a restyle,
   * and therefore possibly wanting an active layer to render that style.
   * Any such marking will time out after a short period.
   * @param aProperty the property that has changed
   */
  static void NotifyRestyle(nsIFrame* aFrame, nsCSSPropertyID aProperty);
  /**
   * Notify aFrame's left/top/right/bottom properties as having (maybe)
   * changed due to a restyle, and therefore possibly wanting an active layer
   * to render that style. Any such marking will time out after a short period.
   */
  static void NotifyOffsetRestyle(nsIFrame* aFrame);
  /**
   * Mark aFrame as being known to have an animation of aProperty.
   * Any such marking will time out after a short period.
   * aNewValue and aDOMCSSDecl are used to determine whether the property's
   * value has changed.
   */
  static void NotifyAnimated(nsIFrame* aFrame, nsCSSPropertyID aProperty,
                             const nsACString& aNewValue,
                             nsDOMCSSDeclaration* aDOMCSSDecl);
  /**
   * Notify aFrame as being known to have an animation of aProperty through an
   * inline style modification during aScrollFrame's scroll event handler.
   */
  static void NotifyAnimatedFromScrollHandler(nsIFrame* aFrame,
                                              nsCSSPropertyID aProperty,
                                              nsIFrame* aScrollFrame);
  /**
   * Notify that a property in the inline style rule of aFrame's element
   * has been modified.
   * This notification is incomplete --- not all modifications to inline
   * style will trigger this.
   * aNewValue and aDOMCSSDecl are used to determine whether the property's
   * value has changed.
   */
  static void NotifyInlineStyleRuleModified(nsIFrame* aFrame,
                                            nsCSSPropertyID aProperty,
                                            const nsACString& aNewValue,
                                            nsDOMCSSDeclaration* aDOMCSSDecl);
  /**
   * Notify that a frame needs to be repainted. This is important for layering
   * decisions where, say, aFrame's transform is updated from JS, but we need
   * to repaint aFrame anyway, so we get no benefit from giving it its own
   * layer.
   */
  static void NotifyNeedsRepaint(nsIFrame* aFrame);
  /**
   * Return true if aFrame's property style in |aPropertySet| should be
   * considered as being animated for constructing active layers.
   */
  static bool IsStyleAnimated(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                              const nsCSSPropertyIDSet& aPropertySet);
  /**
   * Return true if any of aFrame's offset property styles should be considered
   * as being animated for constructing active layers.
   */
  static bool IsOffsetStyleAnimated(nsIFrame* aFrame);
  /**
   * Return true if aFrame's background-position-x or background-position-y
   * property is animated.
   */
  static bool IsBackgroundPositionAnimated(nsDisplayListBuilder* aBuilder,
                                           nsIFrame* aFrame);
  /**
   * Return true if aFrame's transform-like property,
   * i.e. transform/translate/rotate/scale, is animated.
   */
  static bool IsTransformAnimated(nsDisplayListBuilder* aBuilder,
                                  nsIFrame* aFrame);
  /**
   * Return true if aFrame's transform style should be considered as being
   * animated for pre-rendering.
   */
  static bool IsTransformMaybeAnimated(nsIFrame* aFrame);
  /**
   * Return true if aFrame either has an animated scale now, or is likely to
   * have one in the future because it has a CSS animation or transition
   * (which may not be playing right now) that affects its scale.
   */
  static bool IsScaleSubjectToAnimation(nsIFrame* aFrame);

  /**
   * Transfer the LayerActivity property to the frame's content node when the
   * frame is about to be destroyed so that layer activity can be tracked
   * throughout reframes of an element. Only call this when aFrame is the
   * primary frame of aContent.
   */
  static void TransferActivityToContent(nsIFrame* aFrame, nsIContent* aContent);
  /**
   * Transfer the LayerActivity property back to the content node's primary
   * frame after the frame has been created.
   */
  static void TransferActivityToFrame(nsIContent* aContent, nsIFrame* aFrame);

  /*
   * We track modifications to the content of certain frames (i.e. canvas
   * frames) and use that to make layering decisions.
   */

  /**
   * Mark aFrame's content as being active. This marking will time out after
   * a short period.
   */
  static void NotifyContentChange(nsIFrame* aFrame);
  /**
   * Return true if this frame's content is still marked as active.
   */
  static bool IsContentActive(nsIFrame* aFrame);

  /**
   * Called before and after a scroll event handler is executed, with the
   * scrollframe or nullptr, respectively. This acts as a hint to treat
   * inline style changes during the handler differently.
   */
  static void SetCurrentScrollHandlerFrame(nsIFrame* aFrame);
};

}  // namespace mozilla

#endif /* ACTIVELAYERTRACKER_H_ */