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
10 #include <stdint.h> // for uint8_t, uint32_t, uint64_t
12 #include "FrameMetrics.h" // for FrameMetrics
13 #include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
14 #include "mozilla/gfx/BasePoint.h" // for BasePoint
15 #include "mozilla/gfx/Rect.h" // for RoundedIn
16 #include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor
17 #include "mozilla/TimeStamp.h" // for TimeStamp
18 #include "Units.h" // for CSSRect, CSSPixel, etc
28 struct RepaintRequest
{
29 friend struct IPC::ParamTraits
<mozilla::layers::RepaintRequest
>;
33 MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE(
34 ScrollOffsetUpdateType
, uint8_t, (
35 eNone
, // The default; the scroll offset was not updated.
36 eUserAction
, // The scroll offset was updated by APZ in response
38 eVisualUpdate
// The scroll offset was updated by APZ in response
39 // to a visual scroll update request from the
45 : mScrollId(ScrollableLayerGuid::NULL_SCROLL_ID
),
46 mPresShellResolution(1),
47 mCompositionBounds(0, 0, 0, 0),
48 mCumulativeResolution(),
49 mDevPixelsPerCSSPixel(1),
53 mDisplayPortMargins(0, 0, 0, 0),
55 mLayoutViewport(0, 0, 0, 0),
58 mScrollUpdateType(eNone
),
59 mIsRootContent(false),
60 mIsScrollInfoLayer(false) {}
62 RepaintRequest(const FrameMetrics
& aOther
,
63 const ScrollOffsetUpdateType aScrollUpdateType
)
64 : mScrollId(aOther
.GetScrollId()),
65 mPresShellResolution(aOther
.GetPresShellResolution()),
66 mCompositionBounds(aOther
.GetCompositionBounds()),
67 mCumulativeResolution(aOther
.GetCumulativeResolution()),
68 mDevPixelsPerCSSPixel(aOther
.GetDevPixelsPerCSSPixel()),
69 mScrollOffset(aOther
.GetScrollOffset()),
70 mZoom(aOther
.GetZoom()),
71 mScrollGeneration(aOther
.GetScrollGeneration()),
72 mDisplayPortMargins(aOther
.GetDisplayPortMargins()),
73 mPresShellId(aOther
.GetPresShellId()),
74 mLayoutViewport(aOther
.GetLayoutViewport()),
75 mExtraResolution(aOther
.GetExtraResolution()),
76 mPaintRequestTime(aOther
.GetPaintRequestTime()),
77 mScrollUpdateType(aScrollUpdateType
),
78 mIsRootContent(aOther
.IsRootContent()),
79 mIsScrollInfoLayer(aOther
.IsScrollInfoLayer()) {}
81 // Default copy ctor and operator= are fine
83 bool operator==(const RepaintRequest
& aOther
) const {
84 // Put mScrollId at the top since it's the most likely one to fail.
85 return mScrollId
== aOther
.mScrollId
&&
86 mPresShellResolution
== aOther
.mPresShellResolution
&&
87 mCompositionBounds
.IsEqualEdges(aOther
.mCompositionBounds
) &&
88 mCumulativeResolution
== aOther
.mCumulativeResolution
&&
89 mDevPixelsPerCSSPixel
== aOther
.mDevPixelsPerCSSPixel
&&
90 mScrollOffset
== aOther
.mScrollOffset
&&
91 // don't compare mZoom
92 mScrollGeneration
== aOther
.mScrollGeneration
&&
93 mDisplayPortMargins
== aOther
.mDisplayPortMargins
&&
94 mPresShellId
== aOther
.mPresShellId
&&
95 mLayoutViewport
.IsEqualEdges(aOther
.mLayoutViewport
) &&
96 mExtraResolution
== aOther
.mExtraResolution
&&
97 mPaintRequestTime
== aOther
.mPaintRequestTime
&&
98 mScrollUpdateType
== aOther
.mScrollUpdateType
&&
99 mIsRootContent
== aOther
.mIsRootContent
&&
100 mIsScrollInfoLayer
== aOther
.mIsScrollInfoLayer
;
103 bool operator!=(const RepaintRequest
& aOther
) const {
104 return !operator==(aOther
);
107 CSSToScreenScale2D
DisplayportPixelsPerCSSPixel() const {
108 // Note: use 'mZoom * ParentLayerToLayerScale(1.0f)' as the CSS-to-Layer
109 // scale instead of LayersPixelsPerCSSPixel(), because displayport
110 // calculations are done in the context of a repaint request, where we ask
111 // Layout to repaint at a new resolution that includes any async zoom. Until
112 // this repaint request is processed, LayersPixelsPerCSSPixel() does not yet
113 // include the async zoom, but it will when the displayport is interpreted
115 return mZoom
* ParentLayerToLayerScale(1.0f
) / mExtraResolution
;
118 CSSToLayerScale2D
LayersPixelsPerCSSPixel() const {
119 return mDevPixelsPerCSSPixel
* mCumulativeResolution
;
122 // Get the amount by which this frame has been zoomed since the last repaint.
123 LayerToParentLayerScale
GetAsyncZoom() const {
124 // The async portion of the zoom should be the same along the x and y
126 return (mZoom
/ LayersPixelsPerCSSPixel()).ToScaleFactor();
129 CSSSize
CalculateCompositedSizeInCssPixels() const {
130 if (GetZoom() == CSSToParentLayerScale2D(0, 0)) {
131 return CSSSize(); // avoid division by zero
133 return mCompositionBounds
.Size() / GetZoom();
136 float GetPresShellResolution() const { return mPresShellResolution
; }
138 const ParentLayerRect
& GetCompositionBounds() const {
139 return mCompositionBounds
;
142 const LayoutDeviceToLayerScale2D
& GetCumulativeResolution() const {
143 return mCumulativeResolution
;
146 const CSSToLayoutDeviceScale
& GetDevPixelsPerCSSPixel() const {
147 return mDevPixelsPerCSSPixel
;
150 bool IsRootContent() const { return mIsRootContent
; }
152 const CSSPoint
& GetScrollOffset() const { return mScrollOffset
; }
154 const CSSToParentLayerScale2D
& GetZoom() const { return mZoom
; }
156 ScrollOffsetUpdateType
GetScrollUpdateType() const {
157 return mScrollUpdateType
;
160 bool GetScrollOffsetUpdated() const { return mScrollUpdateType
!= eNone
; }
162 uint32_t GetScrollGeneration() const { return mScrollGeneration
; }
164 ScrollableLayerGuid::ViewID
GetScrollId() const { return mScrollId
; }
166 const ScreenMargin
& GetDisplayPortMargins() const {
167 return mDisplayPortMargins
;
170 uint32_t GetPresShellId() const { return mPresShellId
; }
172 const CSSRect
& GetLayoutViewport() const { return mLayoutViewport
; }
174 const ScreenToLayerScale2D
& GetExtraResolution() const {
175 return mExtraResolution
;
178 const TimeStamp
& GetPaintRequestTime() const { return mPaintRequestTime
; }
180 bool IsScrollInfoLayer() const { return mIsScrollInfoLayer
; }
183 void SetIsRootContent(bool aIsRootContent
) {
184 mIsRootContent
= aIsRootContent
;
187 void SetIsScrollInfoLayer(bool aIsScrollInfoLayer
) {
188 mIsScrollInfoLayer
= aIsScrollInfoLayer
;
192 // A ID assigned to each scrollable frame, unique within each LayersId..
193 ScrollableLayerGuid::ViewID mScrollId
;
195 // The pres-shell resolution that has been induced on the document containing
196 // this scroll frame as a result of zooming this scroll frame (whether via
197 // user action, or choosing an initial zoom level on page load). This can
198 // only be different from 1.0 for frames that are zoomable, which currently
199 // is just the root content document's root scroll frame
200 // (mIsRootContent = true).
201 // This is a plain float rather than a ScaleFactor because in and of itself
202 // it does not convert between any coordinate spaces for which we have names.
203 float mPresShellResolution
;
205 // This is the area within the widget that we're compositing to. It is in the
206 // layer coordinates of the scrollable content's parent layer.
208 // The size of the composition bounds corresponds to the size of the scroll
209 // frame's scroll port (but in a coordinate system where the size does not
210 // change during zooming).
212 // The origin of the composition bounds is relative to the layer tree origin.
213 // Unlike the scroll port's origin, it does not change during scrolling of
214 // the scrollable layer to which it is associated. However, it may change due
215 // to scrolling of ancestor layers.
217 // This value is provided by Gecko at layout/paint time.
218 ParentLayerRect mCompositionBounds
;
220 // The cumulative resolution that the current frame has been painted at.
221 // This is the product of the pres-shell resolutions of the document
222 // containing this scroll frame and its ancestors, and any css-driven
223 // resolution. This information is provided by Gecko at layout/paint time.
224 // Note that this is allowed to have different x- and y-scales, but only
225 // for subframes (mIsRootContent = false). (The same applies to other scales
226 // that "inherit" the 2D-ness of this one, such as mZoom.)
227 LayoutDeviceToLayerScale2D mCumulativeResolution
;
229 // The conversion factor between CSS pixels and device pixels for this frame.
230 // This can vary based on a variety of things, such as reflowing-zoom.
231 CSSToLayoutDeviceScale mDevPixelsPerCSSPixel
;
233 // The position of the top-left of the scroll frame's scroll port, relative
234 // to the scrollable content's origin.
235 CSSPoint mScrollOffset
;
237 // The "user zoom". Content is painted by gecko at mCumulativeResolution *
238 // mDevPixelsPerCSSPixel, but will be drawn to the screen at mZoom. In the
239 // steady state, the two will be the same, but during an async zoom action the
240 // two may diverge. This information is initialized in Gecko but updated in
242 CSSToParentLayerScale2D mZoom
;
244 // The scroll generation counter used to acknowledge the scroll offset update.
245 uint32_t mScrollGeneration
;
247 // A display port expressed as layer margins that apply to the rect of what
248 // is drawn of the scrollable element.
249 ScreenMargin mDisplayPortMargins
;
251 uint32_t mPresShellId
;
253 // For a root scroll frame (RSF), the document's layout viewport
254 // (sometimes called "CSS viewport" in older code).
256 // Its size is the dimensions we're using to constrain the <html> element
257 // of the document (i.e. the initial containing block (ICB) size).
259 // Its origin is the RSF's layout scroll position, i.e. the scroll position
260 // exposed to web content via window.scrollX/Y.
262 // Note that only the root content document's RSF has a layout viewport
263 // that's distinct from the visual viewport. For an iframe RSF, the two
266 // For a scroll frame that is not an RSF, this metric is meaningless and
268 CSSRect mLayoutViewport
;
270 // The extra resolution at which content in this scroll frame is drawn beyond
271 // that necessary to draw one Layer pixel per Screen pixel.
272 ScreenToLayerScale2D mExtraResolution
;
274 // The time at which the APZC last requested a repaint for this scroll frame.
275 TimeStamp mPaintRequestTime
;
277 // The type of repaint request this represents.
278 ScrollOffsetUpdateType mScrollUpdateType
;
280 // Whether or not this is the root scroll frame for the root content document.
281 bool mIsRootContent
: 1;
283 // True if this scroll frame is a scroll info layer. A scroll info layer is
284 // not layerized and its content cannot be truly async-scrolled, but its
285 // metrics are still sent to and updated by the compositor, with the updates
286 // being reflected on the next paint rather than the next composite.
287 bool mIsScrollInfoLayer
: 1;
290 } // namespace layers
291 } // namespace mozilla
293 #endif /* GFX_REPAINTREQUEST_H */