diff options
Diffstat (limited to 'gfx/layers/RepaintRequest.h')
-rw-r--r-- | gfx/layers/RepaintRequest.h | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/gfx/layers/RepaintRequest.h b/gfx/layers/RepaintRequest.h new file mode 100644 index 0000000000..44fdcb7d10 --- /dev/null +++ b/gfx/layers/RepaintRequest.h @@ -0,0 +1,337 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef GFX_REPAINTREQUEST_H +#define GFX_REPAINTREQUEST_H + +#include <iosfwd> +#include <stdint.h> // for uint8_t, uint32_t, uint64_t + +#include "FrameMetrics.h" // for FrameMetrics +#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM +#include "mozilla/gfx/BasePoint.h" // for BasePoint +#include "mozilla/gfx/Rect.h" // for RoundedIn +#include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor +#include "mozilla/ScrollSnapTargetId.h" // for ScrollSnapTargetIds +#include "mozilla/TimeStamp.h" // for TimeStamp +#include "Units.h" // for CSSRect, CSSPixel, etc +#include "UnitTransforms.h" // for ViewAs + +namespace IPC { +template <typename T> +struct ParamTraits; +} // namespace IPC + +namespace mozilla { +namespace layers { + +struct RepaintRequest { + friend struct IPC::ParamTraits<mozilla::layers::RepaintRequest>; + + public: + // clang-format off + MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE( + ScrollOffsetUpdateType, uint8_t, ( + eNone, // The default; the scroll offset was not updated. + eUserAction, // The scroll offset was updated by APZ in response + // to user action. + eVisualUpdate // The scroll offset was updated by APZ in response + // to a visual scroll update request from the + // main thread. + )); + // clang-format on + + RepaintRequest() + : mScrollId(ScrollableLayerGuid::NULL_SCROLL_ID), + mPresShellResolution(1), + mCompositionBounds(0, 0, 0, 0), + mCumulativeResolution(), + mDevPixelsPerCSSPixel(1), + mScrollOffset(0, 0), + mZoom(), + mDisplayPortMargins(0, 0, 0, 0), + mPresShellId(-1), + mLayoutViewport(0, 0, 0, 0), + mTransformToAncestorScale(), + mPaintRequestTime(), + mScrollUpdateType(eNone), + mScrollAnimationType(APZScrollAnimationType::No), + mIsRootContent(false), + mIsScrollInfoLayer(false), + mIsInScrollingGesture(false) {} + + RepaintRequest(const FrameMetrics& aOther, + const ScreenMargin& aDisplayportMargins, + const ScrollOffsetUpdateType aScrollUpdateType, + APZScrollAnimationType aScrollAnimationType, + const APZScrollGeneration& aScrollGenerationOnApz, + const ScrollSnapTargetIds& aLastSnapTargetIds, + bool aIsInScrollingGesture) + : mScrollId(aOther.GetScrollId()), + mPresShellResolution(aOther.GetPresShellResolution()), + mCompositionBounds(aOther.GetCompositionBounds()), + mCumulativeResolution(aOther.GetCumulativeResolution()), + mDevPixelsPerCSSPixel(aOther.GetDevPixelsPerCSSPixel()), + mScrollOffset(aOther.GetVisualScrollOffset()), + mZoom(aOther.GetZoom()), + mScrollGeneration(aOther.GetScrollGeneration()), + mScrollGenerationOnApz(aScrollGenerationOnApz), + mDisplayPortMargins(aDisplayportMargins), + mPresShellId(aOther.GetPresShellId()), + mLayoutViewport(aOther.GetLayoutViewport()), + mTransformToAncestorScale(aOther.GetTransformToAncestorScale()), + mPaintRequestTime(aOther.GetPaintRequestTime()), + mScrollUpdateType(aScrollUpdateType), + mScrollAnimationType(aScrollAnimationType), + mLastSnapTargetIds(aLastSnapTargetIds), + mIsRootContent(aOther.IsRootContent()), + mIsScrollInfoLayer(aOther.IsScrollInfoLayer()), + mIsInScrollingGesture(aIsInScrollingGesture) {} + + // Default copy ctor and operator= are fine + + bool operator==(const RepaintRequest& aOther) const { + // Put mScrollId at the top since it's the most likely one to fail. + return mScrollId == aOther.mScrollId && + mPresShellResolution == aOther.mPresShellResolution && + mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) && + mCumulativeResolution == aOther.mCumulativeResolution && + mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel && + mScrollOffset == aOther.mScrollOffset && + // don't compare mZoom + mScrollGeneration == aOther.mScrollGeneration && + mDisplayPortMargins == aOther.mDisplayPortMargins && + mPresShellId == aOther.mPresShellId && + mLayoutViewport.IsEqualEdges(aOther.mLayoutViewport) && + mTransformToAncestorScale == aOther.mTransformToAncestorScale && + mPaintRequestTime == aOther.mPaintRequestTime && + mScrollUpdateType == aOther.mScrollUpdateType && + mScrollAnimationType == aOther.mScrollAnimationType && + mLastSnapTargetIds == aOther.mLastSnapTargetIds && + mIsRootContent == aOther.mIsRootContent && + mIsScrollInfoLayer == aOther.mIsScrollInfoLayer && + mIsInScrollingGesture == aOther.mIsInScrollingGesture; + } + + bool operator!=(const RepaintRequest& aOther) const { + return !operator==(aOther); + } + + friend std::ostream& operator<<(std::ostream& aOut, + const RepaintRequest& aRequest); + + CSSToScreenScale2D DisplayportPixelsPerCSSPixel() const { + // Refer to FrameMetrics::DisplayportPixelsPerCSSPixel() for explanation. + return mZoom * mTransformToAncestorScale; + } + + CSSToLayerScale LayersPixelsPerCSSPixel() const { + return mDevPixelsPerCSSPixel * mCumulativeResolution; + } + + // Get the amount by which this frame has been zoomed since the last repaint. + LayerToParentLayerScale GetAsyncZoom() const { + return mZoom / LayersPixelsPerCSSPixel(); + } + + CSSSize CalculateCompositedSizeInCssPixels() const { + if (GetZoom() == CSSToParentLayerScale(0)) { + return CSSSize(); // avoid division by zero + } + return mCompositionBounds.Size() / GetZoom(); + } + + float GetPresShellResolution() const { return mPresShellResolution; } + + const ParentLayerRect& GetCompositionBounds() const { + return mCompositionBounds; + } + + const LayoutDeviceToLayerScale& GetCumulativeResolution() const { + return mCumulativeResolution; + } + + const CSSToLayoutDeviceScale& GetDevPixelsPerCSSPixel() const { + return mDevPixelsPerCSSPixel; + } + + bool IsAnimationInProgress() const { + return mScrollAnimationType != APZScrollAnimationType::No; + } + + bool IsRootContent() const { return mIsRootContent; } + + CSSPoint GetLayoutScrollOffset() const { return mLayoutViewport.TopLeft(); } + + const CSSPoint& GetVisualScrollOffset() const { return mScrollOffset; } + + const CSSToParentLayerScale& GetZoom() const { return mZoom; } + + ScrollOffsetUpdateType GetScrollUpdateType() const { + return mScrollUpdateType; + } + + bool GetScrollOffsetUpdated() const { return mScrollUpdateType != eNone; } + + MainThreadScrollGeneration GetScrollGeneration() const { + return mScrollGeneration; + } + + APZScrollGeneration GetScrollGenerationOnApz() const { + return mScrollGenerationOnApz; + } + + ScrollableLayerGuid::ViewID GetScrollId() const { return mScrollId; } + + const ScreenMargin& GetDisplayPortMargins() const { + return mDisplayPortMargins; + } + + uint32_t GetPresShellId() const { return mPresShellId; } + + const CSSRect& GetLayoutViewport() const { return mLayoutViewport; } + + const ParentLayerToScreenScale2D& GetTransformToAncestorScale() const { + return mTransformToAncestorScale; + } + + const TimeStamp& GetPaintRequestTime() const { return mPaintRequestTime; } + + bool IsScrollInfoLayer() const { return mIsScrollInfoLayer; } + + bool IsInScrollingGesture() const { return mIsInScrollingGesture; } + + APZScrollAnimationType GetScrollAnimationType() const { + return mScrollAnimationType; + } + + const ScrollSnapTargetIds& GetLastSnapTargetIds() const { + return mLastSnapTargetIds; + } + + protected: + void SetIsRootContent(bool aIsRootContent) { + mIsRootContent = aIsRootContent; + } + + void SetIsScrollInfoLayer(bool aIsScrollInfoLayer) { + mIsScrollInfoLayer = aIsScrollInfoLayer; + } + + void SetIsInScrollingGesture(bool aIsInScrollingGesture) { + mIsInScrollingGesture = aIsInScrollingGesture; + } + + private: + // A ID assigned to each scrollable frame, unique within each LayersId.. + ScrollableLayerGuid::ViewID mScrollId; + + // The pres-shell resolution that has been induced on the document containing + // this scroll frame as a result of zooming this scroll frame (whether via + // user action, or choosing an initial zoom level on page load). This can + // only be different from 1.0 for frames that are zoomable, which currently + // is just the root content document's root scroll frame + // (mIsRootContent = true). + // This is a plain float rather than a ScaleFactor because in and of itself + // it does not convert between any coordinate spaces for which we have names. + float mPresShellResolution; + + // This is the area within the widget that we're compositing to. It is in the + // layer coordinates of the scrollable content's parent layer. + // + // The size of the composition bounds corresponds to the size of the scroll + // frame's scroll port (but in a coordinate system where the size does not + // change during zooming). + // + // The origin of the composition bounds is relative to the layer tree origin. + // Unlike the scroll port's origin, it does not change during scrolling of + // the scrollable layer to which it is associated. However, it may change due + // to scrolling of ancestor layers. + // + // This value is provided by Gecko at layout/paint time. + ParentLayerRect mCompositionBounds; + + // See FrameMetrics::mCumulativeResolution for description. + LayoutDeviceToLayerScale mCumulativeResolution; + + // The conversion factor between CSS pixels and device pixels for this frame. + // This can vary based on a variety of things, such as reflowing-zoom. + CSSToLayoutDeviceScale mDevPixelsPerCSSPixel; + + // The position of the top-left of the scroll frame's scroll port, relative + // to the scrollable content's origin. + CSSPoint mScrollOffset; + + // The "user zoom". Content is painted by gecko at mCumulativeResolution * + // mDevPixelsPerCSSPixel, but will be drawn to the screen at mZoom. In the + // steady state, the two will be the same, but during an async zoom action the + // two may diverge. This information is initialized in Gecko but updated in + // the APZC. + CSSToParentLayerScale mZoom; + + // The scroll generation counter used to acknowledge the scroll offset update + // on the main-thread. + MainThreadScrollGeneration mScrollGeneration; + + // The scroll generation counter stored in each SampledAPZState and the + // scrollable frame on the main-thread and used to compare with each other + // in the WebRender renderer thread to tell which sampled scroll offset + // matches the scroll offset used on the main-thread. + APZScrollGeneration mScrollGenerationOnApz; + + // A display port expressed as layer margins that apply to the rect of what + // is drawn of the scrollable element. + ScreenMargin mDisplayPortMargins; + + uint32_t mPresShellId; + + // For a root scroll frame (RSF), the document's layout viewport + // (sometimes called "CSS viewport" in older code). + // + // Its size is the dimensions we're using to constrain the <html> element + // of the document (i.e. the initial containing block (ICB) size). + // + // Its origin is the RSF's layout scroll position, i.e. the scroll position + // exposed to web content via window.scrollX/Y. + // + // Note that only the root content document's RSF has a layout viewport + // that's distinct from the visual viewport. For an iframe RSF, the two + // are the same. + // + // For a scroll frame that is not an RSF, this metric is meaningless and + // invalid. + CSSRect mLayoutViewport; + + // See FrameMetrics::mTransformToAncestorScale for description. + ParentLayerToScreenScale2D mTransformToAncestorScale; + + // The time at which the APZC last requested a repaint for this scroll frame. + TimeStamp mPaintRequestTime; + + // The type of repaint request this represents. + ScrollOffsetUpdateType mScrollUpdateType; + + APZScrollAnimationType mScrollAnimationType; + + ScrollSnapTargetIds mLastSnapTargetIds; + + // Whether or not this is the root scroll frame for the root content document. + bool mIsRootContent : 1; + + // True if this scroll frame is a scroll info layer. A scroll info layer is + // not layerized and its content cannot be truly async-scrolled, but its + // metrics are still sent to and updated by the compositor, with the updates + // being reflected on the next paint rather than the next composite. + bool mIsScrollInfoLayer : 1; + + // Whether the APZC is in the middle of processing a gesture. + bool mIsInScrollingGesture : 1; +}; + +} // namespace layers +} // namespace mozilla + +#endif /* GFX_REPAINTREQUEST_H */ |