/* -*- 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 mozilla_gfx_layers_LayerAttributes_h #define mozilla_gfx_layers_LayerAttributes_h #include "mozilla/Maybe.h" #include "mozilla/gfx/Types.h" #include "mozilla/layers/LayersTypes.h" namespace IPC { template struct ParamTraits; } // namespace IPC namespace mozilla { namespace layers { enum class ScrollbarLayerType : uint8_t { None, Thumb, Container }; /** * It stores data for scroll thumb layer or container layers. */ struct ScrollbarData { private: /** * This constructor is for Thumb layer type. */ ScrollbarData(ScrollDirection aDirection, float aThumbRatio, CSSCoord aThumbStart, CSSCoord aThumbLength, bool aThumbIsAsyncDraggable, CSSCoord aScrollTrackStart, CSSCoord aScrollTrackLength, uint64_t aTargetViewId) : mDirection(Some(aDirection)), mScrollbarLayerType(ScrollbarLayerType::Thumb), mThumbRatio(aThumbRatio), mThumbStart(aThumbStart), mThumbLength(aThumbLength), mThumbIsAsyncDraggable(aThumbIsAsyncDraggable), mScrollTrackStart(aScrollTrackStart), mScrollTrackLength(aScrollTrackLength), mTargetViewId(aTargetViewId) {} /** * This constructor is for Container layer type. */ ScrollbarData(const Maybe& aDirection, uint64_t aTargetViewId) : mDirection(aDirection), mScrollbarLayerType(ScrollbarLayerType::Container), mTargetViewId(aTargetViewId) {} public: ScrollbarData() = default; static ScrollbarData CreateForThumb(ScrollDirection aDirection, float aThumbRatio, CSSCoord aThumbStart, CSSCoord aThumbLength, bool aThumbIsAsyncDraggable, CSSCoord aScrollTrackStart, CSSCoord aScrollTrackLength, uint64_t aTargetViewId) { return ScrollbarData(aDirection, aThumbRatio, aThumbStart, aThumbLength, aThumbIsAsyncDraggable, aScrollTrackStart, aScrollTrackLength, aTargetViewId); } static ScrollbarData CreateForScrollbarContainer( const Maybe& aDirection, uint64_t aTargetViewId) { return ScrollbarData(aDirection, aTargetViewId); } /** * The mDirection contains a direction if mScrollbarLayerType is Thumb * or Container, otherwise it's empty. */ Maybe mDirection; /** * Indicate what kind of layer this data is for. All possibilities are defined * in enum ScrollbarLayerType */ ScrollbarLayerType mScrollbarLayerType = ScrollbarLayerType::None; /** * The scrollbar thumb ratio is the ratio of the thumb position (in the CSS * pixels of the scrollframe's parent's space) to the scroll position (in the * CSS pixels of the scrollframe's space). */ float mThumbRatio = 0.0f; CSSCoord mThumbStart; CSSCoord mThumbLength; /** * Whether the scrollbar thumb can be dragged asynchronously. */ bool mThumbIsAsyncDraggable = false; CSSCoord mScrollTrackStart; CSSCoord mScrollTrackLength; uint64_t mTargetViewId = ScrollableLayerGuid::NULL_SCROLL_ID; bool operator==(const ScrollbarData& aOther) const { return mDirection == aOther.mDirection && mScrollbarLayerType == aOther.mScrollbarLayerType && mThumbRatio == aOther.mThumbRatio && mThumbStart == aOther.mThumbStart && mThumbLength == aOther.mThumbLength && mThumbIsAsyncDraggable == aOther.mThumbIsAsyncDraggable && mScrollTrackStart == aOther.mScrollTrackStart && mScrollTrackLength == aOther.mScrollTrackLength && mTargetViewId == aOther.mTargetViewId; } bool operator!=(const ScrollbarData& aOther) const { return !(*this == aOther); } bool IsThumb() const { return mScrollbarLayerType == ScrollbarLayerType::Thumb; } }; /** * Infrequently changing layer attributes that require no special * serialization work. */ class SimpleLayerAttributes final { friend struct IPC::ParamTraits; public: SimpleLayerAttributes() : mTransformIsPerspective(false), mPostXScale(1.0f), mPostYScale(1.0f), mContentFlags(0), mOpacity(1.0f), mIsFixedPosition(false), mMixBlendMode(gfx::CompositionOp::OP_OVER), mForceIsolatedGroup(false) {} /** * Setters. * All set methods return true if values changed, false otherwise. */ bool SetPostScale(float aXScale, float aYScale) { if (mPostXScale == aXScale && mPostYScale == aYScale) { return false; } mPostXScale = aXScale; mPostYScale = aYScale; return true; } bool SetContentFlags(uint32_t aFlags) { if (aFlags == mContentFlags) { return false; } mContentFlags = aFlags; return true; } bool SetOpacity(float aOpacity) { if (aOpacity == mOpacity) { return false; } mOpacity = aOpacity; return true; } bool SetIsFixedPosition(bool aFixedPosition) { if (mIsFixedPosition == aFixedPosition) { return false; } mIsFixedPosition = aFixedPosition; return true; } bool SetScrollbarData(const ScrollbarData& aScrollbarData) { if (mScrollbarData == aScrollbarData) { return false; } mScrollbarData = aScrollbarData; return true; } bool SetMixBlendMode(gfx::CompositionOp aMixBlendMode) { if (mMixBlendMode == aMixBlendMode) { return false; } mMixBlendMode = aMixBlendMode; return true; } bool SetForceIsolatedGroup(bool aForceIsolatedGroup) { if (mForceIsolatedGroup == aForceIsolatedGroup) { return false; } mForceIsolatedGroup = aForceIsolatedGroup; return true; } bool SetTransform(const gfx::Matrix4x4& aMatrix) { if (mTransform == aMatrix) { return false; } mTransform = aMatrix; return true; } bool SetTransformIsPerspective(bool aIsPerspective) { if (mTransformIsPerspective == aIsPerspective) { return false; } mTransformIsPerspective = aIsPerspective; return true; } bool SetScrolledClip(const Maybe& aScrolledClip) { if (mScrolledClip == aScrolledClip) { return false; } mScrolledClip = aScrolledClip; return true; } bool SetFixedPositionData(ScrollableLayerGuid::ViewID aTargetViewId, const LayerPoint& aAnchor, int32_t aSides) { if (mFixedPositionData && mFixedPositionData->mScrollId == aTargetViewId && mFixedPositionData->mAnchor == aAnchor && mFixedPositionData->mSides == aSides) { return false; } if (!mFixedPositionData) { mFixedPositionData.emplace(); } mFixedPositionData->mScrollId = aTargetViewId; mFixedPositionData->mAnchor = aAnchor; mFixedPositionData->mSides = aSides; return true; } bool SetStickyPositionData(ScrollableLayerGuid::ViewID aScrollId, LayerRectAbsolute aOuter, LayerRectAbsolute aInner) { if (mStickyPositionData && mStickyPositionData->mOuter.IsEqualEdges(aOuter) && mStickyPositionData->mInner.IsEqualEdges(aInner)) { return false; } if (!mStickyPositionData) { mStickyPositionData.emplace(); } mStickyPositionData->mScrollId = aScrollId; mStickyPositionData->mOuter = aOuter; mStickyPositionData->mInner = aInner; return true; } /** * This returns true if scrolling info is equivalent for the purposes of * APZ hit testing. */ bool HitTestingInfoIsEqual(const SimpleLayerAttributes& aOther) const { if (mScrollbarData != aOther.mScrollbarData) { return false; } if (GetFixedPositionScrollContainerId() != aOther.GetFixedPositionScrollContainerId()) { return false; } if (mTransform != aOther.mTransform) { return false; } return true; } /** * Getters. */ float GetPostXScale() const { return mPostXScale; } float GetPostYScale() const { return mPostYScale; } uint32_t GetContentFlags() const { return mContentFlags; } float GetOpacity() const { return mOpacity; } bool IsFixedPosition() const { return mIsFixedPosition; } const ScrollbarData& GetScrollbarData() const { return mScrollbarData; } gfx::CompositionOp GetMixBlendMode() const { return mMixBlendMode; } bool GetForceIsolatedGroup() const { return mForceIsolatedGroup; } const gfx::Matrix4x4& GetTransform() const { return mTransform; } bool GetTransformIsPerspective() const { return mTransformIsPerspective; } const Maybe& GetScrolledClip() const { return mScrolledClip; } ScrollableLayerGuid::ViewID GetFixedPositionScrollContainerId() const { return (mIsFixedPosition && mFixedPositionData) ? mFixedPositionData->mScrollId : ScrollableLayerGuid::NULL_SCROLL_ID; } LayerPoint GetFixedPositionAnchor() const { return mFixedPositionData ? mFixedPositionData->mAnchor : LayerPoint(); } int32_t GetFixedPositionSides() const { return mFixedPositionData ? mFixedPositionData->mSides : eSideBitsNone; } bool IsStickyPosition() const { return !!mStickyPositionData; } ScrollableLayerGuid::ViewID GetStickyScrollContainerId() const { return mStickyPositionData->mScrollId; } const LayerRectAbsolute& GetStickyScrollRangeOuter() const { return mStickyPositionData->mOuter; } const LayerRectAbsolute& GetStickyScrollRangeInner() const { return mStickyPositionData->mInner; } bool operator==(const SimpleLayerAttributes& aOther) const { return mTransform == aOther.mTransform && mTransformIsPerspective == aOther.mTransformIsPerspective && mScrolledClip == aOther.mScrolledClip && mPostXScale == aOther.mPostXScale && mPostYScale == aOther.mPostYScale && mContentFlags == aOther.mContentFlags && mOpacity == aOther.mOpacity && mIsFixedPosition == aOther.mIsFixedPosition && mScrollbarData == aOther.mScrollbarData && mMixBlendMode == aOther.mMixBlendMode && mForceIsolatedGroup == aOther.mForceIsolatedGroup; } private: gfx::Matrix4x4 mTransform; bool mTransformIsPerspective; Maybe mScrolledClip; float mPostXScale; float mPostYScale; uint32_t mContentFlags; float mOpacity; bool mIsFixedPosition; ScrollbarData mScrollbarData; gfx::CompositionOp mMixBlendMode; bool mForceIsolatedGroup; struct FixedPositionData { ScrollableLayerGuid::ViewID mScrollId; LayerPoint mAnchor; int32_t mSides; }; Maybe mFixedPositionData; struct StickyPositionData { ScrollableLayerGuid::ViewID mScrollId; LayerRectAbsolute mOuter; LayerRectAbsolute mInner; }; Maybe mStickyPositionData; /** * This class may only contain plain-old-data members that can be safely * copied over IPC. Make sure to add new members to operator ==. */ }; } // namespace layers } // namespace mozilla #endif // mozilla_gfx_layers_LayerAttributes_h