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/. */
7 #ifndef GFX_REPAINTREQUEST_H
8 #define GFX_REPAINTREQUEST_H
11 #include <stdint.h> // for uint8_t, uint32_t, uint64_t
13 #include "FrameMetrics.h" // for FrameMetrics
14 #include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
15 #include "mozilla/gfx/BasePoint.h" // for BasePoint
16 #include "mozilla/gfx/Rect.h" // for RoundedIn
17 #include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor
18 #include "mozilla/ScrollSnapTargetId.h" // for ScrollSnapTargetIds
19 #include "mozilla/TimeStamp.h" // for TimeStamp
20 #include "Units.h" // for CSSRect, CSSPixel, etc
21 #include "UnitTransforms.h" // for ViewAs
31 struct RepaintRequest
{
32 friend struct IPC::ParamTraits
<mozilla::layers::RepaintRequest
>;
36 MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE(
37 ScrollOffsetUpdateType
, uint8_t, (
38 eNone
, // The default; the scroll offset was not updated.
39 eUserAction
, // The scroll offset was updated by APZ in response
41 eVisualUpdate
// The scroll offset was updated by APZ in response
42 // to a visual scroll update request from the
48 : mScrollId(ScrollableLayerGuid::NULL_SCROLL_ID
),
49 mPresShellResolution(1),
50 mCompositionBounds(0, 0, 0, 0),
51 mDevPixelsPerCSSPixel(1),
53 mDisplayPortMargins(0, 0, 0, 0),
55 mLayoutViewport(0, 0, 0, 0),
56 mScrollUpdateType(eNone
),
57 mScrollAnimationType(APZScrollAnimationType::No
),
58 mIsRootContent(false),
59 mIsScrollInfoLayer(false),
60 mIsInScrollingGesture(false) {}
62 RepaintRequest(const FrameMetrics
& aOther
,
63 const ScreenMargin
& aDisplayportMargins
,
64 const ScrollOffsetUpdateType aScrollUpdateType
,
65 APZScrollAnimationType aScrollAnimationType
,
66 const APZScrollGeneration
& aScrollGenerationOnApz
,
67 const ScrollSnapTargetIds
& aLastSnapTargetIds
,
68 bool aIsInScrollingGesture
)
69 : mScrollId(aOther
.GetScrollId()),
70 mPresShellResolution(aOther
.GetPresShellResolution()),
71 mCompositionBounds(aOther
.GetCompositionBounds()),
72 mCumulativeResolution(aOther
.GetCumulativeResolution()),
73 mDevPixelsPerCSSPixel(aOther
.GetDevPixelsPerCSSPixel()),
74 mScrollOffset(aOther
.GetVisualScrollOffset()),
75 mZoom(aOther
.GetZoom()),
76 mScrollGeneration(aOther
.GetScrollGeneration()),
77 mScrollGenerationOnApz(aScrollGenerationOnApz
),
78 mDisplayPortMargins(aDisplayportMargins
),
79 mPresShellId(aOther
.GetPresShellId()),
80 mLayoutViewport(aOther
.GetLayoutViewport()),
81 mTransformToAncestorScale(aOther
.GetTransformToAncestorScale()),
82 mPaintRequestTime(aOther
.GetPaintRequestTime()),
83 mScrollUpdateType(aScrollUpdateType
),
84 mScrollAnimationType(aScrollAnimationType
),
85 mLastSnapTargetIds(aLastSnapTargetIds
),
86 mIsRootContent(aOther
.IsRootContent()),
87 mIsScrollInfoLayer(aOther
.IsScrollInfoLayer()),
88 mIsInScrollingGesture(aIsInScrollingGesture
) {}
90 // Default copy ctor and operator= are fine
92 bool operator==(const RepaintRequest
& aOther
) const {
93 // Put mScrollId at the top since it's the most likely one to fail.
94 return mScrollId
== aOther
.mScrollId
&&
95 mPresShellResolution
== aOther
.mPresShellResolution
&&
96 mCompositionBounds
.IsEqualEdges(aOther
.mCompositionBounds
) &&
97 mCumulativeResolution
== aOther
.mCumulativeResolution
&&
98 mDevPixelsPerCSSPixel
== aOther
.mDevPixelsPerCSSPixel
&&
99 mScrollOffset
== aOther
.mScrollOffset
&&
100 // don't compare mZoom
101 mScrollGeneration
== aOther
.mScrollGeneration
&&
102 mDisplayPortMargins
== aOther
.mDisplayPortMargins
&&
103 mPresShellId
== aOther
.mPresShellId
&&
104 mLayoutViewport
.IsEqualEdges(aOther
.mLayoutViewport
) &&
105 mTransformToAncestorScale
== aOther
.mTransformToAncestorScale
&&
106 mPaintRequestTime
== aOther
.mPaintRequestTime
&&
107 mScrollUpdateType
== aOther
.mScrollUpdateType
&&
108 mScrollAnimationType
== aOther
.mScrollAnimationType
&&
109 mLastSnapTargetIds
== aOther
.mLastSnapTargetIds
&&
110 mIsRootContent
== aOther
.mIsRootContent
&&
111 mIsScrollInfoLayer
== aOther
.mIsScrollInfoLayer
&&
112 mIsInScrollingGesture
== aOther
.mIsInScrollingGesture
;
115 bool operator!=(const RepaintRequest
& aOther
) const {
116 return !operator==(aOther
);
119 friend std::ostream
& operator<<(std::ostream
& aOut
,
120 const RepaintRequest
& aRequest
);
122 CSSToScreenScale2D
DisplayportPixelsPerCSSPixel() const {
123 // Refer to FrameMetrics::DisplayportPixelsPerCSSPixel() for explanation.
124 return mZoom
* mTransformToAncestorScale
;
127 CSSToLayerScale
LayersPixelsPerCSSPixel() const {
128 return mDevPixelsPerCSSPixel
* mCumulativeResolution
;
131 // Get the amount by which this frame has been zoomed since the last repaint.
132 LayerToParentLayerScale
GetAsyncZoom() const {
133 return mZoom
/ LayersPixelsPerCSSPixel();
136 CSSSize
CalculateCompositedSizeInCssPixels() const {
137 if (GetZoom() == CSSToParentLayerScale(0)) {
138 return CSSSize(); // avoid division by zero
140 return mCompositionBounds
.Size() / GetZoom();
143 float GetPresShellResolution() const { return mPresShellResolution
; }
145 const ParentLayerRect
& GetCompositionBounds() const {
146 return mCompositionBounds
;
149 const LayoutDeviceToLayerScale
& GetCumulativeResolution() const {
150 return mCumulativeResolution
;
153 const CSSToLayoutDeviceScale
& GetDevPixelsPerCSSPixel() const {
154 return mDevPixelsPerCSSPixel
;
157 bool IsAnimationInProgress() const {
158 return mScrollAnimationType
!= APZScrollAnimationType::No
;
161 bool IsRootContent() const { return mIsRootContent
; }
163 CSSPoint
GetLayoutScrollOffset() const { return mLayoutViewport
.TopLeft(); }
165 const CSSPoint
& GetVisualScrollOffset() const { return mScrollOffset
; }
167 const CSSToParentLayerScale
& GetZoom() const { return mZoom
; }
169 ScrollOffsetUpdateType
GetScrollUpdateType() const {
170 return mScrollUpdateType
;
173 bool GetScrollOffsetUpdated() const { return mScrollUpdateType
!= eNone
; }
175 MainThreadScrollGeneration
GetScrollGeneration() const {
176 return mScrollGeneration
;
179 APZScrollGeneration
GetScrollGenerationOnApz() const {
180 return mScrollGenerationOnApz
;
183 ScrollableLayerGuid::ViewID
GetScrollId() const { return mScrollId
; }
185 const ScreenMargin
& GetDisplayPortMargins() const {
186 return mDisplayPortMargins
;
189 uint32_t GetPresShellId() const { return mPresShellId
; }
191 const CSSRect
& GetLayoutViewport() const { return mLayoutViewport
; }
193 const ParentLayerToScreenScale2D
& GetTransformToAncestorScale() const {
194 return mTransformToAncestorScale
;
197 const TimeStamp
& GetPaintRequestTime() const { return mPaintRequestTime
; }
199 bool IsScrollInfoLayer() const { return mIsScrollInfoLayer
; }
201 bool IsInScrollingGesture() const { return mIsInScrollingGesture
; }
203 APZScrollAnimationType
GetScrollAnimationType() const {
204 return mScrollAnimationType
;
207 const ScrollSnapTargetIds
& GetLastSnapTargetIds() const {
208 return mLastSnapTargetIds
;
212 void SetIsRootContent(bool aIsRootContent
) {
213 mIsRootContent
= aIsRootContent
;
216 void SetIsScrollInfoLayer(bool aIsScrollInfoLayer
) {
217 mIsScrollInfoLayer
= aIsScrollInfoLayer
;
220 void SetIsInScrollingGesture(bool aIsInScrollingGesture
) {
221 mIsInScrollingGesture
= aIsInScrollingGesture
;
225 // A ID assigned to each scrollable frame, unique within each LayersId..
226 ScrollableLayerGuid::ViewID mScrollId
;
228 // The pres-shell resolution that has been induced on the document containing
229 // this scroll frame as a result of zooming this scroll frame (whether via
230 // user action, or choosing an initial zoom level on page load). This can
231 // only be different from 1.0 for frames that are zoomable, which currently
232 // is just the root content document's root scroll frame
233 // (mIsRootContent = true).
234 // This is a plain float rather than a ScaleFactor because in and of itself
235 // it does not convert between any coordinate spaces for which we have names.
236 float mPresShellResolution
;
238 // This is the area within the widget that we're compositing to. It is in the
239 // layer coordinates of the scrollable content's parent layer.
241 // The size of the composition bounds corresponds to the size of the scroll
242 // frame's scroll port (but in a coordinate system where the size does not
243 // change during zooming).
245 // The origin of the composition bounds is relative to the layer tree origin.
246 // Unlike the scroll port's origin, it does not change during scrolling of
247 // the scrollable layer to which it is associated. However, it may change due
248 // to scrolling of ancestor layers.
250 // This value is provided by Gecko at layout/paint time.
251 ParentLayerRect mCompositionBounds
;
253 // See FrameMetrics::mCumulativeResolution for description.
254 LayoutDeviceToLayerScale mCumulativeResolution
;
256 // The conversion factor between CSS pixels and device pixels for this frame.
257 // This can vary based on a variety of things, such as reflowing-zoom.
258 CSSToLayoutDeviceScale mDevPixelsPerCSSPixel
;
260 // The position of the top-left of the scroll frame's scroll port, relative
261 // to the scrollable content's origin.
262 CSSPoint mScrollOffset
;
264 // The "user zoom". Content is painted by gecko at mCumulativeResolution *
265 // mDevPixelsPerCSSPixel, but will be drawn to the screen at mZoom. In the
266 // steady state, the two will be the same, but during an async zoom action the
267 // two may diverge. This information is initialized in Gecko but updated in
269 CSSToParentLayerScale mZoom
;
271 // The scroll generation counter used to acknowledge the scroll offset update
272 // on the main-thread.
273 MainThreadScrollGeneration mScrollGeneration
;
275 // The scroll generation counter stored in each SampledAPZState and the
276 // scrollable frame on the main-thread and used to compare with each other
277 // in the WebRender renderer thread to tell which sampled scroll offset
278 // matches the scroll offset used on the main-thread.
279 APZScrollGeneration mScrollGenerationOnApz
;
281 // A display port expressed as layer margins that apply to the rect of what
282 // is drawn of the scrollable element.
283 ScreenMargin mDisplayPortMargins
;
285 uint32_t mPresShellId
;
287 // For a root scroll frame (RSF), the document's layout viewport
288 // (sometimes called "CSS viewport" in older code).
290 // Its size is the dimensions we're using to constrain the <html> element
291 // of the document (i.e. the initial containing block (ICB) size).
293 // Its origin is the RSF's layout scroll position, i.e. the scroll position
294 // exposed to web content via window.scrollX/Y.
296 // Note that only the root content document's RSF has a layout viewport
297 // that's distinct from the visual viewport. For an iframe RSF, the two
300 // For a scroll frame that is not an RSF, this metric is meaningless and
302 CSSRect mLayoutViewport
;
304 // See FrameMetrics::mTransformToAncestorScale for description.
305 ParentLayerToScreenScale2D mTransformToAncestorScale
;
307 // The time at which the APZC last requested a repaint for this scroll frame.
308 TimeStamp mPaintRequestTime
;
310 // The type of repaint request this represents.
311 ScrollOffsetUpdateType mScrollUpdateType
;
313 APZScrollAnimationType mScrollAnimationType
;
315 ScrollSnapTargetIds mLastSnapTargetIds
;
317 // Whether or not this is the root scroll frame for the root content document.
318 bool mIsRootContent
: 1;
320 // True if this scroll frame is a scroll info layer. A scroll info layer is
321 // not layerized and its content cannot be truly async-scrolled, but its
322 // metrics are still sent to and updated by the compositor, with the updates
323 // being reflected on the next paint rather than the next composite.
324 bool mIsScrollInfoLayer
: 1;
326 // Whether the APZC is in the middle of processing a gesture.
327 bool mIsInScrollingGesture
: 1;
330 } // namespace layers
331 } // namespace mozilla
333 #endif /* GFX_REPAINTREQUEST_H */