summaryrefslogtreecommitdiffstats
path: root/gfx/layers/RepaintRequest.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gfx/layers/RepaintRequest.h333
1 files changed, 333 insertions, 0 deletions
diff --git a/gfx/layers/RepaintRequest.h b/gfx/layers/RepaintRequest.h
new file mode 100644
index 0000000000..7a89610c34
--- /dev/null
+++ b/gfx/layers/RepaintRequest.h
@@ -0,0 +1,333 @@
+/* -*- 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),
+ mDevPixelsPerCSSPixel(1),
+ mScrollOffset(0, 0),
+ mDisplayPortMargins(0, 0, 0, 0),
+ mPresShellId(-1),
+ mLayoutViewport(0, 0, 0, 0),
+ 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 */