WebRenderScrollData.h (13989B)
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_WEBRENDERSCROLLDATA_H 8 #define GFX_WEBRENDERSCROLLDATA_H 9 10 #include <iosfwd> 11 12 #include "chrome/common/ipc_message_utils.h" 13 #include "FrameMetrics.h" 14 #include "ipc/IPCMessageUtils.h" 15 #include "LayersTypes.h" 16 #include "mozilla/Attributes.h" 17 #include "mozilla/GfxMessageUtils.h" 18 #include "mozilla/layers/FocusTarget.h" 19 #include "mozilla/layers/ScrollbarData.h" 20 #include "mozilla/webrender/WebRenderTypes.h" 21 #include "mozilla/HashTable.h" 22 #include "mozilla/Maybe.h" 23 #include "nsTArrayForwardDeclare.h" 24 25 namespace mozilla { 26 27 class nsDisplayItem; 28 class nsDisplayListBuilder; 29 struct ActiveScrolledRoot; 30 31 namespace layers { 32 33 class APZTestAccess; 34 class Layer; 35 class WebRenderLayerManager; 36 class WebRenderScrollData; 37 38 // Data needed by APZ, per layer. One instance of this class is created for 39 // each layer in the layer tree and sent over PWebRenderBridge to the APZ code. 40 // Each WebRenderLayerScrollData is conceptually associated with an "owning" 41 // WebRenderScrollData. 42 class WebRenderLayerScrollData final { 43 public: 44 WebRenderLayerScrollData(); // needed for IPC purposes 45 WebRenderLayerScrollData(WebRenderLayerScrollData&& aOther) = default; 46 ~WebRenderLayerScrollData(); 47 48 using ViewID = ScrollableLayerGuid::ViewID; 49 50 // Helper function for WebRenderScrollData::Validate(). 51 bool ValidateSubtree(const WebRenderScrollData& aParent, 52 std::vector<size_t>& aVisitCounts, 53 size_t aCurrentIndex) const; 54 55 void InitializeRoot(int32_t aDescendantCount); 56 void Initialize(WebRenderScrollData& aOwner, nsDisplayItem* aItem, 57 int32_t aDescendantCount, 58 const ActiveScrolledRoot* aStopAtAsr, 59 const Maybe<gfx::Matrix4x4>& aAncestorTransform, 60 const ViewID& aAncestorTransformId); 61 62 int32_t GetDescendantCount() const; 63 size_t GetScrollMetadataCount() const; 64 65 void AppendScrollMetadata(WebRenderScrollData& aOwner, 66 const ScrollMetadata& aData); 67 // Return the ScrollMetadata object that used to be on the original Layer 68 // at the given index. Since we deduplicate the ScrollMetadata objects into 69 // the array in the owning WebRenderScrollData object, we need to be passed 70 // in a reference to that owner as well. 71 const ScrollMetadata& GetScrollMetadata(const WebRenderScrollData& aOwner, 72 size_t aIndex) const; 73 74 gfx::Matrix4x4 GetAncestorTransform() const { return mAncestorTransform; } 75 ViewID GetAncestorTransformId() const { return mAncestorTransformId; } 76 void SetTransform(const gfx::Matrix4x4& aTransform) { 77 mTransform = aTransform; 78 } 79 gfx::Matrix4x4 GetTransform() const { return mTransform; } 80 CSSTransformMatrix GetTransformTyped() const; 81 void SetTransformIsPerspective(bool aTransformIsPerspective) { 82 mTransformIsPerspective = aTransformIsPerspective; 83 } 84 bool GetTransformIsPerspective() const { return mTransformIsPerspective; } 85 86 void SetEventRegionsOverride(const EventRegionsOverride& aOverride) { 87 mEventRegionsOverride = aOverride; 88 } 89 EventRegionsOverride GetEventRegionsOverride() const { 90 return mEventRegionsOverride; 91 } 92 93 void SetVisibleRect(const LayerIntRect& aRect) { mVisibleRect = aRect; } 94 const LayerIntRect& GetVisibleRect() const { return mVisibleRect; } 95 void SetRemoteDocumentSize(const LayerIntSize& aRemoteDocumentSize) { 96 mRemoteDocumentSize = aRemoteDocumentSize; 97 } 98 const LayerIntSize& GetRemoteDocumentSize() const { 99 return mRemoteDocumentSize; 100 } 101 void SetReferentId(LayersId aReferentId) { mReferentId = Some(aReferentId); } 102 Maybe<LayersId> GetReferentId() const { return mReferentId; } 103 104 void SetScrollbarData(const ScrollbarData& aData) { mScrollbarData = aData; } 105 const ScrollbarData& GetScrollbarData() const { return mScrollbarData; } 106 void SetScrollbarAnimationId(const uint64_t& aId) { 107 mScrollbarAnimationId = Some(aId); 108 } 109 Maybe<uint64_t> GetScrollbarAnimationId() const { 110 return mScrollbarAnimationId; 111 } 112 113 void SetFixedPositionAnimationId(const uint64_t& aId) { 114 mFixedPositionAnimationId = Some(aId); 115 } 116 Maybe<uint64_t> GetFixedPositionAnimationId() const { 117 return mFixedPositionAnimationId; 118 } 119 120 void SetFixedPositionSides(const SideBits& aSideBits) { 121 mFixedPositionSides = aSideBits; 122 } 123 SideBits GetFixedPositionSides() const { return mFixedPositionSides; } 124 125 void SetFixedPositionScrollContainerId(ViewID aId) { 126 mFixedPosScrollContainerId = aId; 127 } 128 ViewID GetFixedPositionScrollContainerId() const { 129 return mFixedPosScrollContainerId; 130 } 131 132 void SetStickyPositionScrollContainerId(ViewID aId) { 133 mStickyPosScrollContainerId = aId; 134 } 135 ViewID GetStickyPositionScrollContainerId() const { 136 return mStickyPosScrollContainerId; 137 } 138 139 void SetStickyScrollRangeOuter(const LayerRectAbsolute& scrollRange) { 140 mStickyScrollRangeOuter = scrollRange; 141 } 142 const LayerRectAbsolute& GetStickyScrollRangeOuter() const { 143 return mStickyScrollRangeOuter; 144 } 145 146 void SetStickyScrollRangeInner(const LayerRectAbsolute& scrollRange) { 147 mStickyScrollRangeInner = scrollRange; 148 } 149 const LayerRectAbsolute& GetStickyScrollRangeInner() const { 150 return mStickyScrollRangeInner; 151 } 152 153 void SetStickyPositionAnimationId(const uint64_t& aId) { 154 mStickyPositionAnimationId = Some(aId); 155 } 156 Maybe<uint64_t> GetStickyPositionAnimationId() const { 157 return mStickyPositionAnimationId; 158 } 159 160 void SetZoomAnimationId(const uint64_t& aId) { mZoomAnimationId = Some(aId); } 161 Maybe<uint64_t> GetZoomAnimationId() const { return mZoomAnimationId; } 162 163 void SetAsyncZoomContainerId(const ViewID& aId) { 164 mAsyncZoomContainerId = Some(aId); 165 } 166 Maybe<ViewID> GetAsyncZoomContainerId() const { 167 return mAsyncZoomContainerId; 168 } 169 170 void Dump(std::ostream& aOut, const WebRenderScrollData& aOwner) const; 171 172 friend struct IPC::ParamTraits<WebRenderLayerScrollData>; 173 174 private: 175 // For test use only 176 friend class APZTestAccess; 177 178 // For use by GTests in building WebRenderLayerScrollData trees. 179 // GTests don't have a display list so they can't use Initialize(). 180 void InitializeForTest(int32_t aDescendantCount); 181 182 ScrollMetadata& GetScrollMetadataMut(WebRenderScrollData& aOwner, 183 size_t aIndex); 184 185 private: 186 // The number of descendants this layer has (not including the layer itself). 187 // This is needed to reconstruct the depth-first layer tree traversal 188 // efficiently. Leaf layers should always have 0 descendants. 189 int32_t mDescendantCount; 190 191 // Handles to the ScrollMetadata objects that were on this layer. The values 192 // stored in this array are indices into the owning WebRenderScrollData's 193 // mScrollMetadatas array. This indirection is used to deduplicate the 194 // ScrollMetadata objects, since there is usually heavy duplication of them 195 // within a layer tree. 196 CopyableTArray<size_t> mScrollIds; 197 198 // Various data that we collect from the Layer in Initialize(), serialize 199 // over IPC, and use on the parent side in APZ. 200 201 gfx::Matrix4x4 mAncestorTransform; 202 ViewID mAncestorTransformId; 203 gfx::Matrix4x4 mTransform; 204 bool mTransformIsPerspective; 205 LayerIntRect mVisibleRect; 206 // The remote documents only need their size because their origin is always 207 // (0, 0). 208 LayerIntSize mRemoteDocumentSize; 209 Maybe<LayersId> mReferentId; 210 EventRegionsOverride mEventRegionsOverride; 211 ScrollbarData mScrollbarData; 212 Maybe<uint64_t> mScrollbarAnimationId; 213 Maybe<uint64_t> mFixedPositionAnimationId; 214 SideBits mFixedPositionSides; 215 ViewID mFixedPosScrollContainerId; 216 ViewID mStickyPosScrollContainerId; 217 LayerRectAbsolute mStickyScrollRangeOuter; 218 LayerRectAbsolute mStickyScrollRangeInner; 219 Maybe<uint64_t> mStickyPositionAnimationId; 220 Maybe<uint64_t> mZoomAnimationId; 221 Maybe<ViewID> mAsyncZoomContainerId; 222 223 #if defined(DEBUG) || defined(MOZ_DUMP_PAINTING) 224 // The display item for which this layer was built. 225 // This is only set on the content side. 226 nsDisplayItem* mInitializedFrom = nullptr; 227 #endif 228 }; 229 230 // Data needed by APZ, for the whole layer tree. One instance of this class 231 // is created for each transaction sent over PWebRenderBridge. It is populated 232 // with information from the WebRender layer tree on the client side and the 233 // information is used by APZ on the parent side. 234 class WebRenderScrollData { 235 public: 236 WebRenderScrollData(); 237 explicit WebRenderScrollData(WebRenderLayerManager* aManager, 238 nsDisplayListBuilder* aBuilder); 239 WebRenderScrollData(WebRenderScrollData&& aOther) = default; 240 WebRenderScrollData& operator=(WebRenderScrollData&& aOther) = default; 241 virtual ~WebRenderScrollData() = default; 242 243 // Validate that the scroll data is well-formed, and particularly that 244 // |mLayerScrollData| encodes a valid tree. This is necessary because 245 // the data can be sent over IPC from a less-trusted content process. 246 bool Validate() const; 247 248 WebRenderLayerManager* GetManager() const; 249 250 nsDisplayListBuilder* GetBuilder() const; 251 252 // Add the given ScrollMetadata if it doesn't already exist. Return an index 253 // that can be used to look up the metadata later. 254 size_t AddMetadata(const ScrollMetadata& aMetadata); 255 // Add the provided WebRenderLayerScrollData and return the index that can 256 // be used to look it up via GetLayerData. 257 size_t AddLayerData(WebRenderLayerScrollData&& aData); 258 259 size_t GetLayerCount() const; 260 261 // Return a pointer to the scroll data at the given index. Use with caution, 262 // as the pointer may be invalidated if this WebRenderScrollData is mutated. 263 const WebRenderLayerScrollData* GetLayerData(size_t aIndex) const; 264 WebRenderLayerScrollData* GetLayerData(size_t aIndex); 265 266 const ScrollMetadata& GetScrollMetadata(size_t aIndex) const; 267 Maybe<size_t> HasMetadataFor( 268 const ScrollableLayerGuid::ViewID& aScrollId) const; 269 270 void SetIsFirstPaint(bool aValue); 271 bool IsFirstPaint() const; 272 void SetPaintSequenceNumber(uint32_t aPaintSequenceNumber); 273 uint32_t GetPaintSequenceNumber() const; 274 275 void ApplyUpdates(ScrollUpdatesMap&& aUpdates, uint32_t aPaintSequenceNumber); 276 277 // Prepend the scroll position updates in the previous data to this data so 278 // that we can handle all scroll position updates in the proper order. 279 void PrependUpdates(const WebRenderScrollData& aPreviousData); 280 281 void SetWasUpdateSkipped(bool aWasUpdateSkipped) { 282 mWasUpdateSkipped = aWasUpdateSkipped; 283 } 284 bool GetWasUpdateSkipped() const { return mWasUpdateSkipped; } 285 286 friend struct IPC::ParamTraits<WebRenderScrollData>; 287 288 friend std::ostream& operator<<(std::ostream& aOut, 289 const WebRenderScrollData& aData); 290 291 private: 292 // For test use only. 293 friend class WebRenderLayerScrollData; 294 ScrollMetadata& GetScrollMetadataMut(size_t aIndex); 295 296 private: 297 // This is called by the ParamTraits implementation to rebuild mScrollIdMap 298 // based on mScrollMetadatas 299 bool RepopulateMap(); 300 301 // This is a helper for the dumping code 302 void DumpSubtree(std::ostream& aOut, size_t aIndex, 303 const std::string& aIndent) const; 304 305 private: 306 // Pointer back to the layer manager; if this is non-null, it will always be 307 // valid, because the WebRenderLayerManager that created |this| will 308 // outlive |this|. 309 WebRenderLayerManager* MOZ_NON_OWNING_REF mManager; 310 311 // Pointer to the display list builder; if this is non-null, it will always be 312 // valid, because the nsDisplayListBuilder that created the layer manager will 313 // outlive |this|. 314 nsDisplayListBuilder* MOZ_NON_OWNING_REF mBuilder; 315 316 // Internal data structure used to maintain uniqueness of mScrollMetadatas. 317 // This is not serialized/deserialized over IPC, but it is rebuilt on the 318 // parent side when mScrollMetadatas is deserialized. So it should always be 319 // valid on both the child and parent. 320 // The key into this map is the scrollId of a ScrollMetadata, and the value is 321 // an index into the mScrollMetadatas array. 322 HashMap<ScrollableLayerGuid::ViewID, size_t> mScrollIdMap; 323 324 // A list of all the unique ScrollMetadata objects from the layer tree. Each 325 // ScrollMetadata in this list must have a unique scroll id. 326 nsTArray<ScrollMetadata> mScrollMetadatas; 327 328 // A list of per-layer scroll data objects, generated via a depth-first, 329 // pre-order, last-to-first traversal of the layer tree (i.e. a recursive 330 // traversal where a node N first pushes itself, followed by its children in 331 // last-to-first order). Each layer's scroll data object knows how many 332 // descendants that layer had, which allows reconstructing the traversal on 333 // the other side. 334 nsTArray<WebRenderLayerScrollData> mLayerScrollData; 335 336 bool mIsFirstPaint; 337 uint32_t mPaintSequenceNumber; 338 339 // Wether this data was skipped to updated because the parent process hasn't 340 // yet gotten the referent LayersId for this data. 341 // 342 // Note this variable is not copied over IPC. 343 bool mWasUpdateSkipped = false; 344 }; 345 346 } // namespace layers 347 } // namespace mozilla 348 349 namespace IPC { 350 351 template <> 352 struct ParamTraits<mozilla::layers::WebRenderLayerScrollData> { 353 typedef mozilla::layers::WebRenderLayerScrollData paramType; 354 355 static void Write(MessageWriter* aWriter, const paramType& aParam); 356 357 static bool Read(MessageReader* aReader, paramType* aResult); 358 }; 359 360 template <> 361 struct ParamTraits<mozilla::layers::WebRenderScrollData> { 362 typedef mozilla::layers::WebRenderScrollData paramType; 363 364 static void Write(MessageWriter* aWriter, const paramType& aParam); 365 366 static bool Read(MessageReader* aReader, paramType* aResult); 367 }; 368 369 } // namespace IPC 370 371 #endif /* GFX_WEBRENDERSCROLLDATA_H */