Bug 1632310 [wpt PR 23186] - Add test for computed versus resolved style., a=testonly
[gecko.git] / gfx / layers / RepaintRequest.h
blob003ec030c96eb84f79fb79fe41b76852067fd021
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
20 namespace IPC {
21 template <typename T>
22 struct ParamTraits;
23 } // namespace IPC
25 namespace mozilla {
26 namespace layers {
28 struct RepaintRequest {
29 friend struct IPC::ParamTraits<mozilla::layers::RepaintRequest>;
31 public:
32 // clang-format off
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
37 // to user action.
38 eVisualUpdate // The scroll offset was updated by APZ in response
39 // to a visual scroll update request from the
40 // main thread.
41 ));
42 // clang-format on
44 RepaintRequest()
45 : mScrollId(ScrollableLayerGuid::NULL_SCROLL_ID),
46 mPresShellResolution(1),
47 mCompositionBounds(0, 0, 0, 0),
48 mCumulativeResolution(),
49 mDevPixelsPerCSSPixel(1),
50 mScrollOffset(0, 0),
51 mZoom(),
52 mScrollGeneration(0),
53 mDisplayPortMargins(0, 0, 0, 0),
54 mPresShellId(-1),
55 mLayoutViewport(0, 0, 0, 0),
56 mExtraResolution(),
57 mPaintRequestTime(),
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
114 // for the repaint.
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
125 // axes.
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; }
182 protected:
183 void SetIsRootContent(bool aIsRootContent) {
184 mIsRootContent = aIsRootContent;
187 void SetIsScrollInfoLayer(bool aIsScrollInfoLayer) {
188 mIsScrollInfoLayer = aIsScrollInfoLayer;
191 private:
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
241 // the APZC.
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
264 // are the same.
266 // For a scroll frame that is not an RSF, this metric is meaningless and
267 // invalid.
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 */