RepaintRequest.h (12943B)
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 GFX_REPAINTREQUEST_H 8 #define GFX_REPAINTREQUEST_H 9 10 #include <iosfwd> 11 #include <stdint.h> // for uint8_t, uint32_t, uint64_t 12 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 22 23 namespace IPC { 24 template <typename T> 25 struct ParamTraits; 26 } // namespace IPC 27 28 namespace mozilla { 29 namespace layers { 30 31 struct RepaintRequest { 32 friend struct IPC::ParamTraits<mozilla::layers::RepaintRequest>; 33 34 public: 35 // clang-format off 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 40 // to user action. 41 eVisualUpdate // The scroll offset was updated by APZ in response 42 // to a visual scroll update request from the 43 // main thread. 44 )); 45 // clang-format on 46 47 RepaintRequest() 48 : mScrollId(ScrollableLayerGuid::NULL_SCROLL_ID), 49 mPresShellResolution(1), 50 mCompositionBounds(0, 0, 0, 0), 51 mDevPixelsPerCSSPixel(1), 52 mScrollOffset(0, 0), 53 mDisplayPortMargins(0, 0, 0, 0), 54 mPresShellId(-1), 55 mLayoutViewport(0, 0, 0, 0), 56 mScrollUpdateType(eNone), 57 mScrollAnimationType(APZScrollAnimationType::No), 58 mIsRootContent(false), 59 mIsScrollInfoLayer(false), 60 mIsInScrollingGesture(false) {} 61 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) {} 89 90 // Default copy ctor and operator= are fine 91 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; 113 } 114 115 bool operator!=(const RepaintRequest& aOther) const { 116 return !operator==(aOther); 117 } 118 119 friend std::ostream& operator<<(std::ostream& aOut, 120 const RepaintRequest& aRequest); 121 122 CSSToScreenScale2D DisplayportPixelsPerCSSPixel() const { 123 // Refer to FrameMetrics::DisplayportPixelsPerCSSPixel() for explanation. 124 return mZoom * mTransformToAncestorScale; 125 } 126 127 CSSToLayerScale LayersPixelsPerCSSPixel() const { 128 return mDevPixelsPerCSSPixel * mCumulativeResolution; 129 } 130 131 // Get the amount by which this frame has been zoomed since the last repaint. 132 LayerToParentLayerScale GetAsyncZoom() const { 133 return mZoom / LayersPixelsPerCSSPixel(); 134 } 135 136 CSSSize CalculateCompositedSizeInCssPixels() const { 137 if (GetZoom() == CSSToParentLayerScale(0)) { 138 return CSSSize(); // avoid division by zero 139 } 140 return mCompositionBounds.Size() / GetZoom(); 141 } 142 143 float GetPresShellResolution() const { return mPresShellResolution; } 144 145 const ParentLayerRect& GetCompositionBounds() const { 146 return mCompositionBounds; 147 } 148 149 const LayoutDeviceToLayerScale& GetCumulativeResolution() const { 150 return mCumulativeResolution; 151 } 152 153 const CSSToLayoutDeviceScale& GetDevPixelsPerCSSPixel() const { 154 return mDevPixelsPerCSSPixel; 155 } 156 157 bool IsAnimationInProgress() const { 158 return mScrollAnimationType != APZScrollAnimationType::No; 159 } 160 161 bool IsRootContent() const { return mIsRootContent; } 162 163 CSSPoint GetLayoutScrollOffset() const { return mLayoutViewport.TopLeft(); } 164 165 const CSSPoint& GetVisualScrollOffset() const { return mScrollOffset; } 166 167 const CSSToParentLayerScale& GetZoom() const { return mZoom; } 168 169 ScrollOffsetUpdateType GetScrollUpdateType() const { 170 return mScrollUpdateType; 171 } 172 173 bool GetScrollOffsetUpdated() const { return mScrollUpdateType != eNone; } 174 175 MainThreadScrollGeneration GetScrollGeneration() const { 176 return mScrollGeneration; 177 } 178 179 APZScrollGeneration GetScrollGenerationOnApz() const { 180 return mScrollGenerationOnApz; 181 } 182 183 ScrollableLayerGuid::ViewID GetScrollId() const { return mScrollId; } 184 185 const ScreenMargin& GetDisplayPortMargins() const { 186 return mDisplayPortMargins; 187 } 188 189 uint32_t GetPresShellId() const { return mPresShellId; } 190 191 const CSSRect& GetLayoutViewport() const { return mLayoutViewport; } 192 193 const ParentLayerToScreenScale2D& GetTransformToAncestorScale() const { 194 return mTransformToAncestorScale; 195 } 196 197 const TimeStamp& GetPaintRequestTime() const { return mPaintRequestTime; } 198 199 bool IsScrollInfoLayer() const { return mIsScrollInfoLayer; } 200 201 bool IsInScrollingGesture() const { return mIsInScrollingGesture; } 202 203 APZScrollAnimationType GetScrollAnimationType() const { 204 return mScrollAnimationType; 205 } 206 207 const ScrollSnapTargetIds& GetLastSnapTargetIds() const { 208 return mLastSnapTargetIds; 209 } 210 211 protected: 212 void SetIsRootContent(bool aIsRootContent) { 213 mIsRootContent = aIsRootContent; 214 } 215 216 void SetIsScrollInfoLayer(bool aIsScrollInfoLayer) { 217 mIsScrollInfoLayer = aIsScrollInfoLayer; 218 } 219 220 void SetIsInScrollingGesture(bool aIsInScrollingGesture) { 221 mIsInScrollingGesture = aIsInScrollingGesture; 222 } 223 224 private: 225 // A ID assigned to each scrollable frame, unique within each LayersId.. 226 ScrollableLayerGuid::ViewID mScrollId; 227 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; 237 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. 240 // 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). 244 // 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. 249 // 250 // This value is provided by Gecko at layout/paint time. 251 ParentLayerRect mCompositionBounds; 252 253 // See FrameMetrics::mCumulativeResolution for description. 254 LayoutDeviceToLayerScale mCumulativeResolution; 255 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; 259 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; 263 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 268 // the APZC. 269 CSSToParentLayerScale mZoom; 270 271 // The scroll generation counter used to acknowledge the scroll offset update 272 // on the main-thread. 273 MainThreadScrollGeneration mScrollGeneration; 274 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; 280 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; 284 285 uint32_t mPresShellId; 286 287 // For a root scroll frame (RSF), the document's layout viewport 288 // (sometimes called "CSS viewport" in older code). 289 // 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). 292 // 293 // Its origin is the RSF's layout scroll position, i.e. the scroll position 294 // exposed to web content via window.scrollX/Y. 295 // 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 298 // are the same. 299 // 300 // For a scroll frame that is not an RSF, this metric is meaningless and 301 // invalid. 302 CSSRect mLayoutViewport; 303 304 // See FrameMetrics::mTransformToAncestorScale for description. 305 ParentLayerToScreenScale2D mTransformToAncestorScale; 306 307 // The time at which the APZC last requested a repaint for this scroll frame. 308 TimeStamp mPaintRequestTime; 309 310 // The type of repaint request this represents. 311 ScrollOffsetUpdateType mScrollUpdateType; 312 313 APZScrollAnimationType mScrollAnimationType; 314 315 ScrollSnapTargetIds mLastSnapTargetIds; 316 317 // Whether or not this is the root scroll frame for the root content document. 318 bool mIsRootContent : 1; 319 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; 325 326 // Whether the APZC is in the middle of processing a gesture. 327 bool mIsInScrollingGesture : 1; 328 }; 329 330 } // namespace layers 331 } // namespace mozilla 332 333 #endif /* GFX_REPAINTREQUEST_H */