tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FrameMetrics.h (43888B)


      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_FRAMEMETRICS_H
      8 #define GFX_FRAMEMETRICS_H
      9 
     10 #include <stdint.h>  // for uint8_t, uint32_t, uint64_t
     11 #include <iosfwd>
     12 
     13 #include "Units.h"                  // for CSSRect, CSSPixel, etc
     14 #include "UnitTransforms.h"         // for ViewAs
     15 #include "mozilla/DefineEnum.h"     // for MOZ_DEFINE_ENUM
     16 #include "mozilla/HashFunctions.h"  // for HashGeneric
     17 #include "mozilla/Maybe.h"
     18 #include "mozilla/dom/InteractiveWidget.h"
     19 #include "mozilla/gfx/BasePoint.h"               // for BasePoint
     20 #include "mozilla/gfx/Rect.h"                    // for RoundedIn
     21 #include "mozilla/gfx/ScaleFactor.h"             // for ScaleFactor
     22 #include "mozilla/gfx/Logging.h"                 // for Log
     23 #include "mozilla/layers/LayersTypes.h"          // for ScrollDirection
     24 #include "mozilla/layers/ScrollableLayerGuid.h"  // for ScrollableLayerGuid
     25 #include "mozilla/ScrollPositionUpdate.h"        // for ScrollPositionUpdate
     26 #include "mozilla/ScrollSnapInfo.h"
     27 #include "mozilla/ScrollSnapTargetId.h"
     28 #include "mozilla/StaticPtr.h"  // for StaticAutoPtr
     29 #include "mozilla/TimeStamp.h"  // for TimeStamp
     30 #include "nsTHashMap.h"         // for nsTHashMap
     31 #include "nsString.h"
     32 #include "PLDHashTable.h"  // for PLDHashNumber
     33 
     34 struct nsStyleDisplay;
     35 namespace mozilla {
     36 enum class StyleOverscrollBehavior : uint8_t;
     37 }  // namespace mozilla
     38 
     39 namespace IPC {
     40 template <typename T>
     41 struct ParamTraits;
     42 }  // namespace IPC
     43 
     44 namespace mozilla {
     45 namespace layers {
     46 
     47 /**
     48 * Metrics about a scroll frame that are sent to the compositor and used
     49 * by APZ.
     50 *
     51 * This is used for two main purposes:
     52 *
     53 *   (1) Sending information about a scroll frame to the compositor and APZ
     54 *       as part of a layers or WebRender transaction.
     55 *   (2) Storing information about a scroll frame in APZ that persists
     56 *       between transactions.
     57 *
     58 * TODO: Separate these two uses into two distinct structures.
     59 *
     60 * A related class, RepaintRequest, is used for sending information about a
     61 * scroll frame back from the compositor to the main thread when requesting
     62 * a repaint of the scroll frame's contents.
     63 */
     64 struct FrameMetrics {
     65  friend struct IPC::ParamTraits<mozilla::layers::FrameMetrics>;
     66  friend std::ostream& operator<<(std::ostream& aStream,
     67                                  const FrameMetrics& aMetrics);
     68 
     69  typedef ScrollableLayerGuid::ViewID ViewID;
     70 
     71 public:
     72  // clang-format off
     73  MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE(
     74    ScrollOffsetUpdateType, uint8_t, (
     75      eNone,          // The default; the scroll offset was not updated
     76      eMainThread,    // The scroll offset was updated by the main thread.
     77      eRestore        // The scroll offset was updated by the main thread, but
     78                      // as a restore from history or after a frame
     79                      // reconstruction.  In this case, APZ can ignore the
     80                      // offset change if the user has done an APZ scroll
     81                      // already.
     82  ));
     83  // clang-format on
     84 
     85  FrameMetrics()
     86      : mScrollId(ScrollableLayerGuid::NULL_SCROLL_ID),
     87        mPresShellResolution(1),
     88        mCompositionBounds(0, 0, 0, 0),
     89        mCompositionBoundsWidthIgnoringScrollbars(0),
     90        mDisplayPort(0, 0, 0, 0),
     91        mScrollableRect(0, 0, 0, 0),
     92        mDevPixelsPerCSSPixel(1),
     93        mScrollOffset(0, 0),
     94        mBoundingCompositionSize(0, 0),
     95        mPresShellId(-1),
     96        mLayoutViewport(0, 0, 0, 0),
     97        mVisualDestination(0, 0),
     98        mVisualScrollUpdateType(eNone),
     99        mInteractiveWidget(
    100            dom::InteractiveWidgetUtils::DefaultInteractiveWidgetMode()),
    101        mIsRootContent(false),
    102        mIsScrollInfoLayer(false),
    103        mHasNonZeroDisplayPortMargins(false),
    104        mMinimalDisplayPort(false),
    105        mIsSoftwareKeyboardVisible(false) {}
    106 
    107  // Default copy ctor and operator= are fine
    108 
    109  bool operator==(const FrameMetrics& aOther) const {
    110    // Put mScrollId at the top since it's the most likely one to fail.
    111    return mScrollId == aOther.mScrollId &&
    112           mPresShellResolution == aOther.mPresShellResolution &&
    113           mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) &&
    114           mCompositionBoundsWidthIgnoringScrollbars ==
    115               aOther.mCompositionBoundsWidthIgnoringScrollbars &&
    116           mDisplayPort.IsEqualEdges(aOther.mDisplayPort) &&
    117           mScrollableRect.IsEqualEdges(aOther.mScrollableRect) &&
    118           mCumulativeResolution == aOther.mCumulativeResolution &&
    119           mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel &&
    120           mScrollOffset == aOther.mScrollOffset &&
    121           // don't compare mZoom
    122           mScrollGeneration == aOther.mScrollGeneration &&
    123           mBoundingCompositionSize == aOther.mBoundingCompositionSize &&
    124           mPresShellId == aOther.mPresShellId &&
    125           mLayoutViewport.IsEqualEdges(aOther.mLayoutViewport) &&
    126           mTransformToAncestorScale == aOther.mTransformToAncestorScale &&
    127           mPaintRequestTime == aOther.mPaintRequestTime &&
    128           mVisualDestination == aOther.mVisualDestination &&
    129           mVisualScrollUpdateType == aOther.mVisualScrollUpdateType &&
    130           mInteractiveWidget == aOther.mInteractiveWidget &&
    131           mIsRootContent == aOther.mIsRootContent &&
    132           mIsScrollInfoLayer == aOther.mIsScrollInfoLayer &&
    133           mHasNonZeroDisplayPortMargins ==
    134               aOther.mHasNonZeroDisplayPortMargins &&
    135           mMinimalDisplayPort == aOther.mMinimalDisplayPort &&
    136           mFixedLayerMargins == aOther.mFixedLayerMargins &&
    137           mCompositionSizeWithoutDynamicToolbar ==
    138               aOther.mCompositionSizeWithoutDynamicToolbar &&
    139           mIsSoftwareKeyboardVisible == aOther.mIsSoftwareKeyboardVisible;
    140  }
    141 
    142  bool operator!=(const FrameMetrics& aOther) const {
    143    return !operator==(aOther);
    144  }
    145 
    146  bool IsScrollable() const {
    147    return mScrollId != ScrollableLayerGuid::NULL_SCROLL_ID;
    148  }
    149 
    150  CSSToScreenScale2D DisplayportPixelsPerCSSPixel() const {
    151    // Note: mZoom includes the async zoom. We want to include the async zoom
    152    // even though the size of the pixels of our *current* displayport does not
    153    // yet reflect it, because this function is used in the context of a repaint
    154    // request where we'll be asking for a *new* displayport which does reflect
    155    // the async zoom. Note 2: we include the transform to ancestor scale
    156    // because this function (as the name implies) is used only in various
    157    // displayport calculation related places, and those calculations want the
    158    // transform to ancestor scale to be included becaese they want to reason
    159    // about pixels which are the same size as screen pixels (so displayport
    160    // sizes are e.g. limited to a multiple of the screen size). Whereas mZoom
    161    // and mCumulativeResolution do not include it because of expectations of
    162    // the code where they are used.
    163    return mZoom * mTransformToAncestorScale;
    164  }
    165 
    166  CSSToLayerScale LayersPixelsPerCSSPixel() const {
    167    return mDevPixelsPerCSSPixel * mCumulativeResolution;
    168  }
    169 
    170  // Get the amount by which this frame has been zoomed since the last repaint.
    171  LayerToParentLayerScale GetAsyncZoom() const {
    172    return mZoom / LayersPixelsPerCSSPixel();
    173  }
    174 
    175  // Ensure the scrollableRect is at least as big as the compositionBounds
    176  // because the scrollableRect can be smaller if the content is not large
    177  // and the scrollableRect hasn't been updated yet.
    178  // We move the scrollableRect up because we don't know if we can move it
    179  // down. i.e. we know that scrollableRect can go back as far as zero.
    180  // but we don't know how much further ahead it can go.
    181  CSSRect GetExpandedScrollableRect() const {
    182    CSSRect scrollableRect = mScrollableRect;
    183    CSSSize compSize = CalculateCompositedSizeInCssPixels();
    184    if (scrollableRect.Width() < compSize.width) {
    185      scrollableRect.SetRectX(
    186          std::max(0.f, scrollableRect.X() -
    187                            (compSize.width - scrollableRect.Width())),
    188          compSize.width);
    189    }
    190 
    191    if (scrollableRect.Height() < compSize.height) {
    192      scrollableRect.SetRectY(
    193          std::max(0.f, scrollableRect.Y() -
    194                            (compSize.height - scrollableRect.Height())),
    195          compSize.height);
    196    }
    197 
    198    return scrollableRect;
    199  }
    200 
    201  CSSSize CalculateCompositedSizeInCssPixels() const {
    202    return CalculateCompositedSizeInCssPixels(mCompositionBounds, mZoom);
    203  }
    204 
    205  /*
    206   * Calculate the composition bounds of this frame in the CSS pixels of
    207   * the content surrounding the scroll frame (OuterCSS pixels).
    208   * Note that it does not make sense to ask for the composition bounds in the
    209   * CSS pixels of the scrolled content (that is, regular CSS pixels),
    210   * because the origin of the composition bounds is not meaningful in that
    211   * coordinate space. (The size is, use CalculateCompositedSizeInCssPixels()
    212   * for that.)
    213   */
    214  OuterCSSRect CalculateCompositionBoundsInOuterCssPixels() const {
    215    if (GetZoom() == CSSToParentLayerScale(0)) {
    216      return OuterCSSRect();  // avoid division by zero
    217    }
    218    // The CSS pixels of the scrolled content and the CSS pixels of the
    219    // surrounding content only differ if the scrolled content is rendered
    220    // at a higher resolution, and the difference is the resolution.
    221    return mCompositionBounds / GetZoom() * GetCSSToOuterCSSScale();
    222  }
    223 
    224  CSSSize CalculateBoundedCompositedSizeInCssPixels() const {
    225    CSSSize size = CalculateCompositedSizeInCssPixels();
    226    size.width = std::min(size.width, mBoundingCompositionSize.width);
    227    size.height = std::min(size.height, mBoundingCompositionSize.height);
    228    return size;
    229  }
    230 
    231  CSSRect CalculateScrollRange() const {
    232    return CalculateScrollRange(mScrollableRect, mCompositionBounds, mZoom);
    233  }
    234 
    235  void ScrollBy(const CSSPoint& aPoint) {
    236    SetVisualScrollOffset(GetVisualScrollOffset() + aPoint);
    237  }
    238 
    239  void ZoomBy(float aScale) { mZoom.scale *= aScale; }
    240 
    241  /*
    242   * Compares an APZ frame metrics with an incoming content frame metrics
    243   * to see if APZ has a scroll offset that has not been incorporated into
    244   * the content frame metrics.
    245   */
    246  bool HasPendingScroll(const FrameMetrics& aContentFrameMetrics) const {
    247    return GetVisualScrollOffset() !=
    248           aContentFrameMetrics.GetVisualScrollOffset();
    249  }
    250 
    251  /*
    252   * Returns true if the layout scroll offset or visual scroll offset changed.
    253   */
    254  bool ApplyScrollUpdateFrom(const ScrollPositionUpdate& aUpdate);
    255 
    256  /**
    257   * Applies the relative scroll offset update contained in aOther to the
    258   * scroll offset contained in this. The scroll delta is clamped to the
    259   * scrollable region.
    260   *
    261   * @returns The clamped scroll offset delta that was applied
    262   */
    263  enum class IsDefaultApzc {
    264    No,
    265    Yes,
    266  };
    267  CSSPoint ApplyRelativeScrollUpdateFrom(const ScrollPositionUpdate& aUpdate,
    268                                         IsDefaultApzc aIsDefaultApzc);
    269 
    270  CSSPoint ApplyPureRelativeScrollUpdateFrom(
    271      const ScrollPositionUpdate& aUpdate);
    272 
    273  void UpdatePendingScrollInfo(const ScrollPositionUpdate& aInfo);
    274 
    275  bool ScrollLayoutViewportTo(const CSSPoint& aDestination);
    276 
    277 public:
    278  void SetPresShellResolution(float aPresShellResolution) {
    279    mPresShellResolution = aPresShellResolution;
    280  }
    281 
    282  float GetPresShellResolution() const { return mPresShellResolution; }
    283 
    284  void SetCompositionBounds(const ParentLayerRect& aCompositionBounds) {
    285    mCompositionBounds = aCompositionBounds;
    286  }
    287 
    288  const ParentLayerRect& GetCompositionBounds() const {
    289    return mCompositionBounds;
    290  }
    291 
    292  void SetCompositionBoundsWidthIgnoringScrollbars(
    293      const ParentLayerCoord aCompositionBoundsWidthIgnoringScrollbars) {
    294    mCompositionBoundsWidthIgnoringScrollbars =
    295        aCompositionBoundsWidthIgnoringScrollbars;
    296  }
    297 
    298  const ParentLayerCoord GetCompositionBoundsWidthIgnoringScrollbars() const {
    299    return mCompositionBoundsWidthIgnoringScrollbars;
    300  }
    301 
    302  void SetDisplayPort(const CSSRect& aDisplayPort) {
    303    mDisplayPort = aDisplayPort;
    304  }
    305 
    306  const CSSRect& GetDisplayPort() const { return mDisplayPort; }
    307 
    308  void SetCumulativeResolution(
    309      const LayoutDeviceToLayerScale& aCumulativeResolution) {
    310    mCumulativeResolution = aCumulativeResolution;
    311  }
    312 
    313  const LayoutDeviceToLayerScale& GetCumulativeResolution() const {
    314    return mCumulativeResolution;
    315  }
    316 
    317  void SetDevPixelsPerCSSPixel(
    318      const CSSToLayoutDeviceScale& aDevPixelsPerCSSPixel) {
    319    mDevPixelsPerCSSPixel = aDevPixelsPerCSSPixel;
    320  }
    321 
    322  const CSSToLayoutDeviceScale& GetDevPixelsPerCSSPixel() const {
    323    return mDevPixelsPerCSSPixel;
    324  }
    325 
    326  CSSToOuterCSSScale GetCSSToOuterCSSScale() const {
    327    // The scale difference between CSS and OuterCSS pixels is the
    328    // part of the zoom that's not subject to all enclosing content,
    329    // i.e. the pres shell resolution.
    330    return CSSToOuterCSSScale(mPresShellResolution);
    331  }
    332 
    333  void SetIsRootContent(bool aIsRootContent) {
    334    mIsRootContent = aIsRootContent;
    335  }
    336 
    337  bool IsRootContent() const { return mIsRootContent; }
    338 
    339  // Set scroll offset, first clamping to the scroll range.
    340  // Return true if it changed.
    341  bool ClampAndSetVisualScrollOffset(const CSSPoint& aScrollOffset) {
    342    CSSPoint offsetBefore = GetVisualScrollOffset();
    343    SetVisualScrollOffset(CalculateScrollRange().ClampPoint(aScrollOffset));
    344    return (offsetBefore != GetVisualScrollOffset());
    345  }
    346 
    347  CSSPoint GetLayoutScrollOffset() const { return mLayoutViewport.TopLeft(); }
    348  // Returns true if it changed.
    349  bool SetLayoutScrollOffset(const CSSPoint& aLayoutScrollOffset) {
    350    CSSPoint offsetBefore = GetLayoutScrollOffset();
    351    mLayoutViewport.MoveTo(aLayoutScrollOffset);
    352    return (offsetBefore != GetLayoutScrollOffset());
    353  }
    354 
    355  const CSSPoint& GetVisualScrollOffset() const { return mScrollOffset; }
    356  void SetVisualScrollOffset(const CSSPoint& aVisualScrollOffset) {
    357    mScrollOffset = aVisualScrollOffset;
    358  }
    359 
    360  void SetZoom(const CSSToParentLayerScale& aZoom) { mZoom = aZoom; }
    361 
    362  const CSSToParentLayerScale& GetZoom() const { return mZoom; }
    363 
    364  void SetScrollGeneration(
    365      const MainThreadScrollGeneration& aScrollGeneration) {
    366    mScrollGeneration = aScrollGeneration;
    367  }
    368 
    369  MainThreadScrollGeneration GetScrollGeneration() const {
    370    return mScrollGeneration;
    371  }
    372 
    373  ViewID GetScrollId() const { return mScrollId; }
    374 
    375  void SetScrollId(ViewID scrollId) { mScrollId = scrollId; }
    376 
    377  void SetBoundingCompositionSize(const CSSSize& aBoundingCompositionSize) {
    378    mBoundingCompositionSize = aBoundingCompositionSize;
    379  }
    380 
    381  const CSSSize& GetBoundingCompositionSize() const {
    382    return mBoundingCompositionSize;
    383  }
    384 
    385  uint32_t GetPresShellId() const { return mPresShellId; }
    386 
    387  void SetPresShellId(uint32_t aPresShellId) { mPresShellId = aPresShellId; }
    388 
    389  void SetLayoutViewport(const CSSRect& aLayoutViewport) {
    390    mLayoutViewport = aLayoutViewport;
    391  }
    392 
    393  const CSSRect& GetLayoutViewport() const { return mLayoutViewport; }
    394 
    395  CSSRect GetVisualViewport() const {
    396    return CSSRect(GetVisualScrollOffset(),
    397                   CalculateCompositedSizeInCssPixels());
    398  }
    399 
    400  // TODO Bug 2003420: This function should eventually be able to supercede
    401  // GetVisualViewport and drop the default argument for
    402  // |aFixedLayerBottomMargin|. The difference from GetVisualViewport is this
    403  // function handles the current dynamic toolbar state. In other words
    404  // GetVisualViewport always handles the toolbar state as if the dynamic
    405  // toolbar is completely hidden.
    406  CSSRect GetVisualViewportForLayoutViewportContainment(
    407      ScreenCoord aFixedLayerBottomMargin = 0) const;
    408 
    409  void SetTransformToAncestorScale(
    410      const ParentLayerToScreenScale2D& aTransformToAncestorScale) {
    411    mTransformToAncestorScale = aTransformToAncestorScale;
    412  }
    413 
    414  const ParentLayerToScreenScale2D& GetTransformToAncestorScale() const {
    415    return mTransformToAncestorScale;
    416  }
    417 
    418  const CSSRect& GetScrollableRect() const { return mScrollableRect; }
    419 
    420  void SetScrollableRect(const CSSRect& aScrollableRect) {
    421    mScrollableRect = aScrollableRect;
    422  }
    423 
    424  // If the frame is in vertical-RTL writing mode(E.g. "writing-mode:
    425  // vertical-rl" in CSS), or if it's in horizontal-RTL writing-mode(E.g.
    426  // "writing-mode: horizontal-tb; direction: rtl;" in CSS), then this function
    427  // returns true. From the representation perspective, frames whose horizontal
    428  // contents start at rightside also cause their horizontal scrollbars, if any,
    429  // initially start at rightside. So we can also learn about the initial side
    430  // of the horizontal scrollbar for the frame by calling this function.
    431  bool IsHorizontalContentRightToLeft() const { return mScrollableRect.x < 0; }
    432 
    433  void SetPaintRequestTime(const TimeStamp& aTime) {
    434    mPaintRequestTime = aTime;
    435  }
    436  const TimeStamp& GetPaintRequestTime() const { return mPaintRequestTime; }
    437 
    438  void SetIsScrollInfoLayer(bool aIsScrollInfoLayer) {
    439    mIsScrollInfoLayer = aIsScrollInfoLayer;
    440  }
    441  bool IsScrollInfoLayer() const { return mIsScrollInfoLayer; }
    442 
    443  void SetHasNonZeroDisplayPortMargins(bool aHasNonZeroDisplayPortMargins) {
    444    mHasNonZeroDisplayPortMargins = aHasNonZeroDisplayPortMargins;
    445  }
    446  bool HasNonZeroDisplayPortMargins() const {
    447    return mHasNonZeroDisplayPortMargins;
    448  }
    449 
    450  void SetMinimalDisplayPort(bool aMinimalDisplayPort) {
    451    mMinimalDisplayPort = aMinimalDisplayPort;
    452  }
    453  bool IsMinimalDisplayPort() const { return mMinimalDisplayPort; }
    454 
    455  void SetIsSoftwareKeyboardVisible(bool aValue) {
    456    mIsSoftwareKeyboardVisible = aValue;
    457  }
    458  bool IsSoftwareKeyboardVisible() const { return mIsSoftwareKeyboardVisible; }
    459 
    460  void SetInteractiveWidget(dom::InteractiveWidget aInteractiveWidget) {
    461    mInteractiveWidget = aInteractiveWidget;
    462  }
    463  dom::InteractiveWidget GetInteractiveWidget() const {
    464    return mInteractiveWidget;
    465  }
    466 
    467  void SetVisualDestination(const CSSPoint& aVisualDestination) {
    468    mVisualDestination = aVisualDestination;
    469  }
    470  const CSSPoint& GetVisualDestination() const { return mVisualDestination; }
    471 
    472  void SetVisualScrollUpdateType(ScrollOffsetUpdateType aUpdateType) {
    473    mVisualScrollUpdateType = aUpdateType;
    474  }
    475  ScrollOffsetUpdateType GetVisualScrollUpdateType() const {
    476    return mVisualScrollUpdateType;
    477  }
    478 
    479  // Determine if the visual viewport is outside of the layout viewport and
    480  // adjust the x,y-offset in mLayoutViewport accordingly. This is necessary to
    481  // allow APZ to async-scroll the layout viewport.
    482  //
    483  // This is a no-op if mIsRootContent is false.
    484  void RecalculateLayoutViewportOffset(ScreenCoord aFixedLayerBottomMargin = 0);
    485 
    486  void SetFixedLayerMargins(const ScreenMargin& aFixedLayerMargins) {
    487    mFixedLayerMargins = aFixedLayerMargins;
    488  }
    489  const ScreenMargin& GetFixedLayerMargins() const {
    490    return mFixedLayerMargins;
    491  }
    492 
    493  void SetCompositionSizeWithoutDynamicToolbar(const ParentLayerSize& aSize) {
    494    MOZ_ASSERT(mIsRootContent);
    495    mCompositionSizeWithoutDynamicToolbar = aSize;
    496  }
    497  const ParentLayerSize& GetCompositionSizeWithoutDynamicToolbar() const {
    498    MOZ_ASSERT(mIsRootContent);
    499    return mCompositionSizeWithoutDynamicToolbar;
    500  }
    501 
    502  // Helper function for RecalculateViewportOffset(). Exposed so that
    503  // APZC can perform the operation on other copies of the layout
    504  // and visual viewport rects (e.g. the "effective" ones used to implement
    505  // the frame delay).
    506  // Modifies |aLayoutViewport| to continue enclosing |aVisualViewport|
    507  // if possible.
    508  // The layout viewport needs to remain clamped to the scrollable rect,
    509  // and we pass in the scrollable rect so this function can maintain that
    510  // constraint.
    511  static void KeepLayoutViewportEnclosingVisualViewport(
    512      const CSSRect& aVisualViewport, const CSSRect& aScrollableRect,
    513      CSSRect& aLayoutViewport);
    514 
    515  // Helper functions exposed so we can perform operations on copies outside of
    516  // frame metrics object.
    517  static CSSRect CalculateScrollRange(const CSSRect& aScrollableRect,
    518                                      const ParentLayerRect& aCompositionBounds,
    519                                      const CSSToParentLayerScale& aZoom);
    520  static CSSSize CalculateCompositedSizeInCssPixels(
    521      const ParentLayerRect& aCompositionBounds,
    522      const CSSToParentLayerScale& aZoom);
    523 
    524 private:
    525  // A ID assigned to each scrollable frame, unique within each LayersId..
    526  ViewID mScrollId;
    527 
    528  // The pres-shell resolution that has been induced on the document containing
    529  // this scroll frame as a result of zooming this scroll frame (whether via
    530  // user action, or choosing an initial zoom level on page load). This can
    531  // only be different from 1.0 for frames that are zoomable, which currently
    532  // is just the root content document's root scroll frame
    533  // (mIsRootContent = true).
    534  // This is a plain float rather than a ScaleFactor because in and of itself
    535  // it does not convert between any coordinate spaces for which we have names.
    536  float mPresShellResolution;
    537 
    538  // This is the area within the widget that we're compositing to. It is in the
    539  // layer coordinates of the scrollable content's parent layer.
    540  //
    541  // The size of the composition bounds corresponds to the size of the scroll
    542  // frame's scroll port (but in a coordinate system where the size does not
    543  // change during zooming).
    544  //
    545  // The origin of the composition bounds is relative to the scroll node origin.
    546  // (The "scroll node origin" is the point such that applying the APZC's
    547  //  apzc-to-screen transform to it takes you to the window origin, which is
    548  //  what Screen event coordinates are relative to. In layout terms, it's
    549  //  the origin of the reference frame passed to ComputeScrollMetadata().)
    550  // Unlike the scroll port's origin, it does not change during scrolling of
    551  // the scrollable layer to which it is associated. However, it may change due
    552  // to scrolling of ancestor layers.
    553  //
    554  // This value is provided by Gecko at layout/paint time.
    555  ParentLayerRect mCompositionBounds;
    556 
    557  // For RCD-RSF this is the width of the composition bounds ignoring
    558  // scrollbars. For everything else this will be the same as the width of the
    559  // composition bounds. Only needed for the "resolution changed" check in
    560  // NotifyLayersUpdated, once that switches to using IsResolutionUpdated we can
    561  // remove this.
    562  ParentLayerCoord mCompositionBoundsWidthIgnoringScrollbars;
    563 
    564  // The area of a scroll frame's contents that has been painted, relative to
    565  // GetLayoutScrollOffset().
    566  //
    567  // Should not be larger than GetExpandedScrollableRect().
    568  //
    569  // To pre-render a margin of 100 CSS pixels around the scroll port,
    570  // { x = -100, y = - 100,
    571  //   width = scrollPort.width + 200, height = scrollPort.height + 200 }
    572  // where scrollPort = CalculateCompositedSizeInCssPixels().
    573  CSSRect mDisplayPort;
    574 
    575  // The scrollable bounds of a frame. This is determined by reflow.
    576  // Ordinarily the x and y will be 0 and the width and height will be the
    577  // size of the element being scrolled. However for RTL pages or elements
    578  // the x value may be negative.
    579  //
    580  // For scrollable frames that are overflow:hidden the x and y are usually
    581  // set to the value of the current scroll offset, and the width and height
    582  // will match the composition bounds width and height. In effect this reduces
    583  // the scrollable range to 0.
    584  //
    585  // This is in the same coordinate space as |mScrollOffset|, but a different
    586  // coordinate space than |mDisplayPort|. Note also that this coordinate
    587  // system is understood by window.scrollTo().
    588  CSSRect mScrollableRect;
    589 
    590  // The cumulative resolution of the current frame. This is the product of the
    591  // pres-shell resolutions of the document containing this scroll frame and its
    592  // in-process ancestors. This information is provided by Gecko at layout/paint
    593  // time. Notably, for out of process iframes cumulative resolution will be 1.
    594  // The reason for this is that AsyncPanZoomController::GetTransformToThis does
    595  // not contain the resolution in the process of the root content document, but
    596  // in oop iframes AsyncPanZoomController::GetTransformToThis does contain the
    597  // resolution. This makes coordinate math work out in APZ code because in the
    598  // old layers backend GetTransformToThis was a transform of rendered pixels,
    599  // and the pixels were rendered with the scale applied already. The reason
    600  // that AsyncPanZoomController::GetTransformToThis contains the scale in oop
    601  // iframes is because we include the resolution in the transform that includes
    602  // the iframe via this call
    603  // https://searchfox.org/mozilla-central/rev/2eebd6e256fa0355e08421265e57ee1307836d92/layout/generic/nsSubDocumentFrame.cpp#1404
    604  // So when coordinates are passed to the process of the oop iframe they have
    605  // the resolution removed by unapplying that transform which includes the
    606  // resolution.
    607  LayoutDeviceToLayerScale mCumulativeResolution;
    608 
    609  // The conversion factor between CSS pixels and device pixels for this frame.
    610  // This can vary based on a variety of things, such as reflowing-zoom.
    611  CSSToLayoutDeviceScale mDevPixelsPerCSSPixel;
    612 
    613  // The position of the top-left of the scroll frame's scroll port, relative
    614  // to the scrollable content's origin.
    615  //
    616  // This is in the same coordinate space as |mScrollableRect|, but a different
    617  // coordinate space than |mDisplayPort|.
    618  //
    619  // It is required that the rect:
    620  // { x = mScrollOffset.x, y = mScrollOffset.y,
    621  //   width = scrollPort.width,
    622  //   height = scrollPort.height }
    623  // (where scrollPort = CalculateCompositedSizeInCssPixels())
    624  // be within |mScrollableRect|.
    625  CSSPoint mScrollOffset;
    626 
    627  // The "user zoom". Content is painted by gecko at mCumulativeResolution *
    628  // mDevPixelsPerCSSPixel, but will be drawn to the screen at mZoom. In the
    629  // steady state, the two will be the same, but during an async zoom action the
    630  // two may diverge. This information is initialized in Gecko but updated in
    631  // the APZC.
    632  CSSToParentLayerScale mZoom;
    633 
    634  // The scroll generation counter used to acknowledge the scroll offset update.
    635  MainThreadScrollGeneration mScrollGeneration;
    636 
    637  // A bounding size for our composition bounds (no larger than the
    638  // cross-process RCD-RSF's composition size), in local CSS pixels.
    639  CSSSize mBoundingCompositionSize;
    640 
    641  uint32_t mPresShellId;
    642 
    643  // The scroll frame's layout viewport.
    644  //
    645  // Its origin is the scroll frame's layout scroll position, i.e. the
    646  // scroll position exposed to web content via window.scrollX/Y.
    647  // Its size is the dimensions we're using to constrain the allowed values
    648  // of window.scrollX/Y (e.g. the maximum possible value of scrollY is)
    649  // the one that makes the bottom of the layout viewport line up with the
    650  // bottom of the scrollable rect). This size is also called the "scroll port
    651  // size" in layout code.
    652  //
    653  // For scroll frames other than the root content document's root scroll frame
    654  // (RCD-RSF), this should be the same as mVisualViewport.
    655  //
    656  // For the RCD-RSF, the layout and visual viewports can diverge. On desktop
    657  // platforms, the size of the layout viewport matches the size of the
    658  // document's initial containing block (ICB), which in turn is derived from
    659  // the size of the content viewer. On mobile platforms, the size of the
    660  // layout viewport (also called "fixed viewport", because it serves as the
    661  // containing block for position:fixed content) is the "minimum scale size",
    662  // as discussed in more detail at
    663  // https://github.com/bokand/bokand.github.io/blob/master/web_viewports_explainer.md#minimum-scale-size.
    664  CSSRect mLayoutViewport;
    665 
    666  // The scale induced by css transforms and presshell resolution in this
    667  // process and any ancestor processes that encloses this scroll frame that is
    668  // _not_ included in mCumulativeResolution. This means that in the process of
    669  // the root content document this only includes css transform scale (which
    670  // happens in that process, but we assume there can be no css transform scale
    671  // above the root content document). In other processes it includes css
    672  // transform scale and any resolution scale in the current process and all
    673  // ancestor processes.
    674  ParentLayerToScreenScale2D mTransformToAncestorScale;
    675 
    676  // The time at which the APZC last requested a repaint for this scroll frame.
    677  TimeStamp mPaintRequestTime;
    678 
    679  // These fields are used when the main thread wants to set a visual viewport
    680  // offset that's distinct from the layout viewport offset.
    681  // In this case, mVisualScrollUpdateType is set to eMainThread, and
    682  // mVisualDestination is set to desired visual destination (relative
    683  // to the document, like mScrollOffset).
    684  CSSPoint mVisualDestination;
    685  ScrollOffsetUpdateType mVisualScrollUpdateType;
    686 
    687  // 'fixed layer margins' on the main-thread. This is only used for the
    688  // root-content scroll frame.
    689  ScreenMargin mFixedLayerMargins;
    690 
    691  // Similar to mCompositionBounds.Size() but not including the dynamic toolbar
    692  // height.
    693  // If we are not using a dynamic toolbar, this has the same value as
    694  // mCompositionBounds.Size().
    695  ParentLayerSize mCompositionSizeWithoutDynamicToolbar;
    696 
    697  // The interactive-widget of the root-content document.
    698  // This is only applicable to the root-content scroll frame, it's stored in
    699  // APZTreeManager as APZTreeManager::mInteractiveWidget so that it should not
    700  // be checked on AsyncPanZoomController::mScrollMetadata.
    701  dom::InteractiveWidget mInteractiveWidget;
    702 
    703  // Whether or not this is the root scroll frame for the root content document.
    704  bool mIsRootContent : 1;
    705 
    706  // True if this scroll frame is a scroll info layer. A scroll info layer is
    707  // not layerized and its content cannot be truly async-scrolled, but its
    708  // metrics are still sent to and updated by the compositor, with the updates
    709  // being reflected on the next paint rather than the next composite.
    710  bool mIsScrollInfoLayer : 1;
    711 
    712  // Whether there are non-zero display port margins set on this element.
    713  bool mHasNonZeroDisplayPortMargins : 1;
    714 
    715  // Whether this scroll frame is using a minimal display port, which means that
    716  // any set display port margins are ignored when calculating the display port
    717  // and instead zero margins are used and further no tile or alignment
    718  // boundaries are used that could potentially expand the size.
    719  bool mMinimalDisplayPort : 1;
    720 
    721  // Whether the software keyboard is currently visible.
    722  // This is only applicable to the root-content scroll frame, it's stored in
    723  // APZTreeManager as APZTreeManager::mIsSoftwareKeyboardVisible so that it
    724  // should not be checked on AsyncPanZoomController::mScrollMetadata.
    725  bool mIsSoftwareKeyboardVisible : 1;
    726 
    727  // WARNING!!!!
    728  //
    729  // When adding a new field:
    730  //
    731  //  - First, consider whether the field can be added to ScrollMetadata
    732  //    instead. If so, prefer that.
    733  //
    734  //  - Otherwise, the following places should be updated to include them
    735  //    (as needed):
    736  //      FrameMetrics::operator ==
    737  //      AsyncPanZoomController::NotifyLayersUpdated
    738  //      The ParamTraits specialization in LayersMessageUtils.h
    739  //
    740  // Please add new fields above this comment.
    741 };
    742 
    743 // clang-format off
    744 MOZ_DEFINE_ENUM_CLASS_WITH_BASE(
    745  OverscrollBehavior, uint8_t, (
    746    Auto,
    747    Contain,
    748    None
    749 ));
    750 // clang-format on
    751 
    752 std::ostream& operator<<(std::ostream& aStream,
    753                         const OverscrollBehavior& aBehavior);
    754 
    755 struct OverscrollBehaviorInfo final {
    756  OverscrollBehaviorInfo();
    757 
    758  // Construct from StyleOverscrollBehavior values.
    759  static OverscrollBehaviorInfo FromStyleConstants(
    760      StyleOverscrollBehavior aBehaviorX, StyleOverscrollBehavior aBehaviorY);
    761 
    762  bool operator==(const OverscrollBehaviorInfo& aOther) const;
    763  friend std::ostream& operator<<(std::ostream& aStream,
    764                                  const OverscrollBehaviorInfo& aInfo);
    765 
    766  auto MutTiedFields() { return std::tie(mBehaviorX, mBehaviorY); }
    767 
    768  OverscrollBehavior mBehaviorX;
    769  OverscrollBehavior mBehaviorY;
    770 };
    771 
    772 struct OverflowInfo final {
    773  StyleOverflow mOverflowX = StyleOverflow::Visible;
    774  StyleOverflow mOverflowY = StyleOverflow::Visible;
    775 
    776  bool operator==(const OverflowInfo& aOther) const;
    777 
    778  auto MutTiedFields() { return std::tie(mOverflowX, mOverflowY); }
    779 };
    780 
    781 /**
    782 * Metadata about a scroll frame that's sent to the compositor during a layers
    783 * or WebRender transaction, and also stored by APZ between transactions.
    784 * This includes the scroll frame's FrameMetrics, as well as other metadata.
    785 * We don't put the other metadata into FrameMetrics to avoid FrameMetrics
    786 * becoming too bloated (as a FrameMetrics is e.g. stored in memory shared
    787 * with the content process).
    788 */
    789 struct ScrollMetadata {
    790  friend struct IPC::ParamTraits<mozilla::layers::ScrollMetadata>;
    791  friend std::ostream& operator<<(std::ostream& aStream,
    792                                  const ScrollMetadata& aMetadata);
    793 
    794  typedef ScrollableLayerGuid::ViewID ViewID;
    795 
    796 public:
    797  static StaticAutoPtr<const ScrollMetadata>
    798      sNullMetadata;  // We sometimes need an empty metadata
    799 
    800  ScrollMetadata()
    801      : mScrollParentId(ScrollableLayerGuid::NULL_SCROLL_ID),
    802        mLineScrollAmount(0, 0),
    803        mPageScrollAmount(0, 0),
    804        mIsLayersIdRoot(false),
    805        mIsAutoDirRootContentRTL(false),
    806        mForceDisableApz(false),
    807        mResolutionUpdated(false),
    808        mIsRDMTouchSimulationActive(false),
    809        mDidContentGetPainted(true),
    810        mForceMousewheelAutodir(false),
    811        mForceMousewheelAutodirHonourRoot(false),
    812        mIsPaginatedPresentation(false) {}
    813 
    814  bool operator==(const ScrollMetadata& aOther) const {
    815    return mMetrics == aOther.mMetrics && mSnapInfo == aOther.mSnapInfo &&
    816           mScrollParentId == aOther.mScrollParentId &&
    817           // don't compare mContentDescription
    818           mLineScrollAmount == aOther.mLineScrollAmount &&
    819           mPageScrollAmount == aOther.mPageScrollAmount &&
    820           mIsLayersIdRoot == aOther.mIsLayersIdRoot &&
    821           mIsAutoDirRootContentRTL == aOther.mIsAutoDirRootContentRTL &&
    822           mForceDisableApz == aOther.mForceDisableApz &&
    823           mResolutionUpdated == aOther.mResolutionUpdated &&
    824           mIsRDMTouchSimulationActive == aOther.mIsRDMTouchSimulationActive &&
    825           mDidContentGetPainted == aOther.mDidContentGetPainted &&
    826           mForceMousewheelAutodir == aOther.mForceMousewheelAutodir &&
    827           mForceMousewheelAutodirHonourRoot ==
    828               aOther.mForceMousewheelAutodirHonourRoot &&
    829           mIsPaginatedPresentation == aOther.mIsPaginatedPresentation &&
    830           mDisregardedDirection == aOther.mDisregardedDirection &&
    831           mOverscrollBehavior == aOther.mOverscrollBehavior &&
    832           mOverflow == aOther.mOverflow &&
    833           mScrollUpdates == aOther.mScrollUpdates;
    834  }
    835 
    836  bool operator!=(const ScrollMetadata& aOther) const {
    837    return !operator==(aOther);
    838  }
    839 
    840  bool IsDefault() const {
    841    ScrollMetadata def;
    842 
    843    def.mMetrics.SetPresShellId(mMetrics.GetPresShellId());
    844    return (def == *this);
    845  }
    846 
    847  FrameMetrics& GetMetrics() { return mMetrics; }
    848  const FrameMetrics& GetMetrics() const { return mMetrics; }
    849 
    850  void SetSnapInfo(ScrollSnapInfo&& aSnapInfo) {
    851    mSnapInfo = std::move(aSnapInfo);
    852  }
    853  const ScrollSnapInfo& GetSnapInfo() const { return mSnapInfo; }
    854 
    855  ViewID GetScrollParentId() const { return mScrollParentId; }
    856 
    857  void SetScrollParentId(ViewID aParentId) { mScrollParentId = aParentId; }
    858  const nsCString& GetContentDescription() const { return mContentDescription; }
    859  void SetContentDescription(const nsCString& aContentDescription) {
    860    mContentDescription = aContentDescription;
    861  }
    862  const LayoutDeviceIntSize& GetLineScrollAmount() const {
    863    return mLineScrollAmount;
    864  }
    865  void SetLineScrollAmount(const LayoutDeviceIntSize& size) {
    866    mLineScrollAmount = size;
    867  }
    868  const LayoutDeviceIntSize& GetPageScrollAmount() const {
    869    return mPageScrollAmount;
    870  }
    871  void SetPageScrollAmount(const LayoutDeviceIntSize& size) {
    872    mPageScrollAmount = size;
    873  }
    874  void SetIsLayersIdRoot(bool aValue) { mIsLayersIdRoot = aValue; }
    875  bool IsLayersIdRoot() const { return mIsLayersIdRoot; }
    876  void SetIsAutoDirRootContentRTL(bool aValue) {
    877    mIsAutoDirRootContentRTL = aValue;
    878  }
    879  bool IsAutoDirRootContentRTL() const { return mIsAutoDirRootContentRTL; }
    880  void SetForceDisableApz(bool aForceDisable) {
    881    mForceDisableApz = aForceDisable;
    882  }
    883  bool IsApzForceDisabled() const { return mForceDisableApz; }
    884  void SetResolutionUpdated(bool aUpdated) { mResolutionUpdated = aUpdated; }
    885  bool IsResolutionUpdated() const { return mResolutionUpdated; }
    886 
    887  void SetIsRDMTouchSimulationActive(bool aValue) {
    888    mIsRDMTouchSimulationActive = aValue;
    889  }
    890  bool GetIsRDMTouchSimulationActive() const {
    891    return mIsRDMTouchSimulationActive;
    892  }
    893 
    894  void SetForceMousewheelAutodir(bool aValue) {
    895    mForceMousewheelAutodir = aValue;
    896  }
    897  bool ForceMousewheelAutodir() const { return mForceMousewheelAutodir; }
    898 
    899  void SetForceMousewheelAutodirHonourRoot(bool aValue) {
    900    mForceMousewheelAutodirHonourRoot = aValue;
    901  }
    902  bool ForceMousewheelAutodirHonourRoot() const {
    903    return mForceMousewheelAutodirHonourRoot;
    904  }
    905 
    906  void SetIsPaginatedPresentation(bool aValue) {
    907    mIsPaginatedPresentation = aValue;
    908  }
    909  bool IsPaginatedPresentation() const { return mIsPaginatedPresentation; }
    910 
    911  bool DidContentGetPainted() const { return mDidContentGetPainted; }
    912 
    913 private:
    914  // For use in IPC only
    915  void SetDidContentGetPainted(bool aValue) { mDidContentGetPainted = aValue; }
    916 
    917 public:
    918  // For more details about the concept of a disregarded direction, refer to the
    919  // code which defines mDisregardedDirection.
    920  Maybe<ScrollDirection> GetDisregardedDirection() const {
    921    return mDisregardedDirection;
    922  }
    923  void SetDisregardedDirection(const Maybe<ScrollDirection>& aValue) {
    924    mDisregardedDirection = aValue;
    925  }
    926 
    927  void SetOverscrollBehavior(
    928      const OverscrollBehaviorInfo& aOverscrollBehavior) {
    929    mOverscrollBehavior = aOverscrollBehavior;
    930  }
    931  const OverscrollBehaviorInfo& GetOverscrollBehavior() const {
    932    return mOverscrollBehavior;
    933  }
    934 
    935  void SetOverflow(const OverflowInfo& aOverflow) { mOverflow = aOverflow; }
    936  const OverflowInfo& GetOverflow() const { return mOverflow; }
    937 
    938  void SetScrollUpdates(const nsTArray<ScrollPositionUpdate>& aUpdates) {
    939    mScrollUpdates = aUpdates;
    940  }
    941 
    942  const nsTArray<ScrollPositionUpdate>& GetScrollUpdates() const {
    943    return mScrollUpdates;
    944  }
    945 
    946  void UpdatePendingScrollInfo(nsTArray<ScrollPositionUpdate>&& aUpdates) {
    947    MOZ_ASSERT(!aUpdates.IsEmpty());
    948    mMetrics.UpdatePendingScrollInfo(aUpdates.LastElement());
    949 
    950    mDidContentGetPainted = false;
    951    mScrollUpdates.Clear();
    952    mScrollUpdates.AppendElements(std::move(aUpdates));
    953  }
    954 
    955  void PrependUpdates(const nsTArray<ScrollPositionUpdate>& aUpdates) {
    956    MOZ_ASSERT(!aUpdates.IsEmpty());
    957 
    958    mScrollUpdates.InsertElementsAt(0, aUpdates);
    959  }
    960 
    961 private:
    962  FrameMetrics mMetrics;
    963 
    964  // Information used to determine where to snap to for a given scroll.
    965  ScrollSnapInfo mSnapInfo;
    966 
    967  // The ViewID of the scrollable frame to which overscroll should be handed
    968  // off.
    969  ViewID mScrollParentId;
    970 
    971  // A description of the content element corresponding to this frame.
    972  // This is empty unless this is a scrollable layer and the
    973  // apz.printtree pref is turned on.
    974  nsCString mContentDescription;
    975 
    976  // The value of GetLineScrollAmount(), for scroll frames.
    977  LayoutDeviceIntSize mLineScrollAmount;
    978 
    979  // The value of GetPageScrollAmount(), for scroll frames.
    980  LayoutDeviceIntSize mPageScrollAmount;
    981 
    982  // Whether these framemetrics are for the root scroll frame (root element if
    983  // we don't have a root scroll frame) for its layers id.
    984  bool mIsLayersIdRoot : 1;
    985 
    986  // The AutoDirRootContent is the <body> element in an HTML document, or the
    987  // root scrollframe if there is no body. This member variable indicates
    988  // whether this element's content in the horizontal direction starts from
    989  // right to left (e.g. it's true either if "writing-mode: vertical-rl", or
    990  // "writing-mode: horizontal-tb; direction: rtl" in CSS).
    991  // When we do auto-dir scrolling (@see mozilla::WheelDeltaAdjustmentStrategy
    992  // or refer to bug 1358017 for details), setting a pref can make the code use
    993  // the writing mode of this root element instead of the target scrollframe,
    994  // and so we need to know if the writing mode is RTL or not.
    995  bool mIsAutoDirRootContentRTL : 1;
    996 
    997  // Whether or not the compositor should actually do APZ-scrolling on this
    998  // scrollframe.
    999  bool mForceDisableApz : 1;
   1000 
   1001  // Whether the pres shell resolution stored in mMetrics reflects a change
   1002  // originated by the main thread.
   1003  bool mResolutionUpdated : 1;
   1004 
   1005  // Whether or not RDM and touch simulation are active for this document.
   1006  // It's important to note that if RDM is active then this field will be
   1007  // true for the content document but NOT the chrome document containing
   1008  // the browser UI and RDM controls.
   1009  bool mIsRDMTouchSimulationActive : 1;
   1010 
   1011  // Whether this metadata is part of a transaction that also repainted the
   1012  // content (i.e. updated the displaylist or textures). This gets set to false
   1013  // for "paint-skip" transactions, where the main thread doesn't repaint but
   1014  // instead requests APZ to update the compositor scroll offset instead. APZ
   1015  // needs to be able to distinguish these paint-skip transactions so that it
   1016  // can use the correct transforms.
   1017  bool mDidContentGetPainted : 1;
   1018 
   1019  // Whether privileged code has requested that autodir behaviour be
   1020  // enabled for the scroll frame.
   1021  bool mForceMousewheelAutodir : 1;
   1022  bool mForceMousewheelAutodirHonourRoot : 1;
   1023 
   1024  // Whether this content is being displayed in a paginated fashion
   1025  // such as printing or print preview. In such cases, content that
   1026  // would normally only generate one display item may generated one
   1027  // display item per page, and the different instances may be subject
   1028  // to different transforms, which constrains the assumptions APZ can make.
   1029  bool mIsPaginatedPresentation : 1;
   1030 
   1031  // The disregarded direction means the direction which is disregarded anyway,
   1032  // even if the scroll frame overflows in that direction and the direction is
   1033  // specified as scrollable. This could happen in some scenarios, for instance,
   1034  // a single-line text control frame should disregard wheel scroll in
   1035  // its block-flow direction even if it overflows in that direction.
   1036  Maybe<ScrollDirection> mDisregardedDirection;
   1037 
   1038  // The overscroll behavior for this scroll frame.
   1039  OverscrollBehaviorInfo mOverscrollBehavior;
   1040 
   1041  // The CSS overflow styles for this scroll frame.
   1042  // For a root scroll frame, this stores the viewport styles
   1043  // as defined in https://drafts.csswg.org/css-overflow/#overflow-propagation
   1044  // (i.e. they will always be 'auto', 'hidden', or 'scrol').
   1045  OverflowInfo mOverflow;
   1046 
   1047  // The ordered list of scroll position updates for this scroll frame since
   1048  // the last transaction.
   1049  CopyableTArray<ScrollPositionUpdate> mScrollUpdates;
   1050 
   1051  // WARNING!!!!
   1052  //
   1053  // When adding new fields to ScrollMetadata, the following places should be
   1054  // updated to include them (as needed):
   1055  //    1. ScrollMetadata::operator ==
   1056  //    2. AsyncPanZoomController::NotifyLayersUpdated
   1057  //    3. The ParamTraits specialization in LayersMessageUtils.h
   1058  //
   1059  // Please add new fields above this comment.
   1060 };
   1061 
   1062 typedef nsTHashMap<ScrollableLayerGuid::ViewIDHashKey,
   1063                   nsTArray<ScrollPositionUpdate>>
   1064    ScrollUpdatesMap;
   1065 
   1066 }  // namespace layers
   1067 }  // namespace mozilla
   1068 
   1069 #endif /* GFX_FRAMEMETRICS_H */