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 FRAMELAYERBUILDER_H_ 8 #define FRAMELAYERBUILDER_H_ 9 10 #include "nsCSSPropertyIDSet.h" 11 #include "nsTHashtable.h" 12 #include "nsHashKeys.h" 13 #include "nsTArray.h" 14 #include "nsRegion.h" 15 #include "nsIFrame.h" 16 #include "DisplayItemClip.h" 17 #include "mozilla/gfx/MatrixFwd.h" 18 #include "mozilla/layers/LayersTypes.h" 19 #include "mozilla/UniquePtr.h" 20 #include "LayerState.h" 21 #include "Layers.h" 22 #include "LayerUserData.h" 23 #include "nsDisplayItemTypes.h" 24 #include "TransformClipNode.h" 25 26 class nsDisplayListBuilder; 27 class nsDisplayList; 28 class nsDisplayItem; 29 class nsPaintedDisplayItem; 30 class gfxContext; 31 class nsDisplayItemGeometry; 32 class nsDisplayMasksAndClipPaths; 33 34 namespace mozilla { 35 struct ActiveScrolledRoot; 36 struct DisplayItemClipChain; 37 namespace layers { 38 class ContainerLayer; 39 class LayerManager; 40 class BasicLayerManager; 41 class PaintedLayer; 42 class ImageLayer; 43 struct LayerProperties; 44 } // namespace layers 45 46 class FrameLayerBuilder; 47 class LayerManagerData; 48 class PaintedLayerData; 49 class ContainerState; 50 class PaintedDisplayItemLayerUserData; 51 52 enum class DisplayItemEntryType : uint8_t { 53 Item, 54 PushOpacity, 55 PushOpacityWithBg, 56 PopOpacity, 57 PushTransform, 58 PopTransform, 59 HitTestInfo, 60 }; 61 62 /** 63 * Retained data storage: 64 * 65 * Each layer manager (widget, and inactive) stores a LayerManagerData object 66 * that keeps a hash-set of DisplayItemData items that were drawn into it. 67 * Each frame also keeps a list of DisplayItemData pointers that were 68 * created for that frame. DisplayItemData objects manage these lists 69 * automatically. 70 * 71 * During layer construction we update the data in the LayerManagerData object, 72 * marking items that are modified. At the end we sweep the LayerManagerData 73 * hash-set and remove all items that haven't been modified. 74 */ 75 76 /** 77 * Retained data for a display item. 78 */ 79 class DisplayItemData final { 80 public: 81 friend class FrameLayerBuilder; 82 friend class ContainerState; 83 GetDisplayItemKey()84 uint32_t GetDisplayItemKey() { return mDisplayItemKey; } GetLayer()85 layers::Layer* GetLayer() const { return mLayer; } GetGeometry()86 nsDisplayItemGeometry* GetGeometry() const { return mGeometry.get(); } GetClip()87 const DisplayItemClip& GetClip() const { return mClip; } Invalidate()88 void Invalidate() { mIsInvalid = true; } 89 void NotifyRemoved(); SetItem(nsPaintedDisplayItem * aItem)90 void SetItem(nsPaintedDisplayItem* aItem) { mItem = aItem; } GetItem()91 nsPaintedDisplayItem* GetItem() const { return mItem; } FirstFrame()92 nsIFrame* FirstFrame() const { return mFrameList[0]; } InactiveManager()93 layers::BasicLayerManager* InactiveManager() const { 94 return mInactiveManager; 95 } 96 HasMergedFrames()97 bool HasMergedFrames() const { return mFrameList.Length() > 1; } 98 99 static DisplayItemData* AssertDisplayItemData(DisplayItemData* aData); 100 new(size_t sz,nsPresContext * aPresContext)101 void* operator new(size_t sz, nsPresContext* aPresContext) { 102 // Check the recycle list first. 103 return aPresContext->PresShell()->AllocateByObjectID( 104 eArenaObjectID_DisplayItemData, sz); 105 } 106 AddRef()107 nsrefcnt AddRef() { 108 if (mRefCnt == UINT32_MAX) { 109 NS_WARNING("refcount overflow, leaking object"); 110 return mRefCnt; 111 } 112 ++mRefCnt; 113 NS_LOG_ADDREF(this, mRefCnt, "DisplayItemData", sizeof(DisplayItemData)); 114 return mRefCnt; 115 } 116 Release()117 nsrefcnt Release() { 118 if (mRefCnt == UINT32_MAX) { 119 NS_WARNING("refcount overflow, leaking object"); 120 return mRefCnt; 121 } 122 --mRefCnt; 123 NS_LOG_RELEASE(this, mRefCnt, "DisplayItemData"); 124 if (mRefCnt == 0) { 125 Destroy(); 126 return 0; 127 } 128 return mRefCnt; 129 } 130 131 RefPtr<TransformClipNode> mTransform; 132 RefPtr<TransformClipNode> mOldTransform; 133 134 private: 135 DisplayItemData(LayerManagerData* aParent, uint32_t aKey, 136 layers::Layer* aLayer, nsIFrame* aFrame = nullptr); 137 138 /** 139 * Removes any references to this object from frames 140 * in mFrameList. 141 */ 142 ~DisplayItemData(); 143 Destroy()144 void Destroy() { 145 // Get the pres context. 146 RefPtr<nsPresContext> presContext = mFrameList[0]->PresContext(); 147 148 // Call our destructor. 149 this->~DisplayItemData(); 150 151 // Don't let the memory be freed, since it will be recycled 152 // instead. Don't call the global operator delete. 153 presContext->PresShell()->FreeByObjectID(eArenaObjectID_DisplayItemData, 154 this); 155 } 156 157 /** 158 * Associates this DisplayItemData with a frame, and adds it 159 * to the LayerManagerDataProperty list on the frame. 160 */ 161 void AddFrame(nsIFrame* aFrame); 162 void RemoveFrame(nsIFrame* aFrame); 163 const nsRegion& GetChangedFrameInvalidations(); 164 165 /** 166 * Updates the contents of this item to a new set of data, instead of 167 * allocating a new object. Set the passed in parameters, and clears the opt 168 * layer and inactive manager. Parent, and display item key are assumed to be 169 * the same. 170 * 171 * EndUpdate must be called before the end of the transaction to complete the 172 * update. 173 */ 174 void BeginUpdate(layers::Layer* aLayer, LayerState aState, bool aFirstUpdate, 175 nsPaintedDisplayItem* aItem = nullptr); 176 void BeginUpdate(layers::Layer* aLayer, LayerState aState, 177 nsPaintedDisplayItem* aItem, bool aIsReused, bool aIsMerged); 178 179 /** 180 * Completes the update of this, and removes any references to data that won't 181 * live longer than the transaction. 182 * 183 * Updates the geometry, frame list and clip. 184 * For items within a PaintedLayer, a geometry object must be specified to 185 * retain until the next transaction. 186 * 187 */ 188 void EndUpdate(mozilla::UniquePtr<nsDisplayItemGeometry>&& aGeometry); 189 void EndUpdate(); 190 191 uint32_t mRefCnt; 192 LayerManagerData* mParent; 193 RefPtr<layers::Layer> mLayer; 194 RefPtr<layers::Layer> mOptLayer; 195 RefPtr<layers::BasicLayerManager> mInactiveManager; 196 AutoTArray<nsIFrame*, 1> mFrameList; 197 mozilla::UniquePtr<nsDisplayItemGeometry> mGeometry; 198 DisplayItemClip mClip; 199 uint32_t mDisplayItemKey; 200 LayerState mLayerState; 201 202 /** 203 * Temporary stoarage of the display item being referenced, only valid between 204 * BeginUpdate and EndUpdate. 205 */ 206 nsPaintedDisplayItem* mItem; 207 nsRegion mChangedFrameInvalidations; 208 209 /** 210 * Used to track if data currently stored in mFramesWithLayers (from an 211 * existing paint) has been updated in the current paint. 212 */ 213 bool mUsed; 214 bool mIsInvalid; 215 bool mReusedItem; 216 }; 217 218 class RefCountedRegion { 219 private: 220 ~RefCountedRegion() = default; 221 222 public: NS_INLINE_DECL_REFCOUNTING(RefCountedRegion)223 NS_INLINE_DECL_REFCOUNTING(RefCountedRegion) 224 225 RefCountedRegion() : mIsInfinite(false) {} 226 nsRegion mRegion; 227 bool mIsInfinite; 228 }; 229 230 struct InactiveLayerData { 231 RefPtr<layers::BasicLayerManager> mLayerManager; 232 RefPtr<layers::Layer> mLayer; 233 UniquePtr<layers::LayerProperties> mProps; 234 235 ~InactiveLayerData(); 236 }; 237 238 struct AssignedDisplayItem { 239 AssignedDisplayItem(nsPaintedDisplayItem* aItem, LayerState aLayerState, 240 DisplayItemData* aData, const nsRect& aContentRect, 241 DisplayItemEntryType aType, const bool aHasOpacity, 242 const RefPtr<TransformClipNode>& aTransform, 243 const bool aIsMerged); 244 AssignedDisplayItem(AssignedDisplayItem&& aRhs) = default; 245 HasOpacityAssignedDisplayItem246 bool HasOpacity() const { return mHasOpacity; } 247 HasTransformAssignedDisplayItem248 bool HasTransform() const { return mTransform; } 249 250 nsPaintedDisplayItem* mItem; 251 DisplayItemData* mDisplayItemData; 252 253 /** 254 * If the display item is being rendered as an inactive 255 * layer, then this stores the layer manager being 256 * used for the inactive transaction. 257 */ 258 UniquePtr<InactiveLayerData> mInactiveLayerData; 259 RefPtr<TransformClipNode> mTransform; 260 261 nsRect mContentRect; 262 LayerState mLayerState; 263 DisplayItemEntryType mType; 264 265 bool mReused; 266 bool mMerged; 267 bool mHasOpacity; 268 bool mHasPaintRect; 269 }; 270 271 struct ContainerLayerParameters { ContainerLayerParametersContainerLayerParameters272 ContainerLayerParameters() 273 : mXScale(1), 274 mYScale(1), 275 mLayerContentsVisibleRect(nullptr), 276 mBackgroundColor(NS_RGBA(0, 0, 0, 0)), 277 mScrollMetadataASR(nullptr), 278 mCompositorASR(nullptr), 279 mInTransformedSubtree(false), 280 mInActiveTransformedSubtree(false), 281 mDisableSubpixelAntialiasingInDescendants(false), 282 mLayerCreationHint(layers::LayerManager::NONE) {} ContainerLayerParametersContainerLayerParameters283 ContainerLayerParameters(float aXScale, float aYScale) 284 : mXScale(aXScale), 285 mYScale(aYScale), 286 mLayerContentsVisibleRect(nullptr), 287 mItemVisibleRect(nullptr), 288 mBackgroundColor(NS_RGBA(0, 0, 0, 0)), 289 mScrollMetadataASR(nullptr), 290 mCompositorASR(nullptr), 291 mInTransformedSubtree(false), 292 mInActiveTransformedSubtree(false), 293 mDisableSubpixelAntialiasingInDescendants(false), 294 mLayerCreationHint(layers::LayerManager::NONE) {} ContainerLayerParametersContainerLayerParameters295 ContainerLayerParameters(float aXScale, float aYScale, 296 const nsIntPoint& aOffset, 297 const ContainerLayerParameters& aParent) 298 : mXScale(aXScale), 299 mYScale(aYScale), 300 mLayerContentsVisibleRect(nullptr), 301 mItemVisibleRect(nullptr), 302 mOffset(aOffset), 303 mBackgroundColor(aParent.mBackgroundColor), 304 mScrollMetadataASR(aParent.mScrollMetadataASR), 305 mCompositorASR(aParent.mCompositorASR), 306 mInTransformedSubtree(aParent.mInTransformedSubtree), 307 mInActiveTransformedSubtree(aParent.mInActiveTransformedSubtree), 308 mDisableSubpixelAntialiasingInDescendants( 309 aParent.mDisableSubpixelAntialiasingInDescendants), 310 mLayerCreationHint(aParent.mLayerCreationHint) {} 311 312 float mXScale, mYScale; 313 ScaleContainerLayerParameters314 LayoutDeviceToLayerScale2D Scale() const { 315 return LayoutDeviceToLayerScale2D(mXScale, mYScale); 316 } 317 318 /** 319 * If non-null, the rectangle in which BuildContainerLayerFor stores the 320 * visible rect of the layer, in the coordinate system of the created layer. 321 */ 322 nsIntRect* mLayerContentsVisibleRect; 323 324 /** 325 * If non-null, the rectangle which stores the item's visible rect. 326 */ 327 nsRect* mItemVisibleRect; 328 329 /** 330 * An offset to apply to all child layers created. 331 */ 332 nsIntPoint mOffset; 333 OffsetContainerLayerParameters334 LayerIntPoint Offset() const { 335 return LayerIntPoint::FromUnknownPoint(mOffset); 336 } 337 338 nscolor mBackgroundColor; 339 const ActiveScrolledRoot* mScrollMetadataASR; 340 const ActiveScrolledRoot* mCompositorASR; 341 342 bool mInTransformedSubtree; 343 bool mInActiveTransformedSubtree; 344 bool mDisableSubpixelAntialiasingInDescendants; 345 layers::LayerManager::PaintedLayerCreationHint mLayerCreationHint; 346 347 /** 348 * When this is false, PaintedLayer coordinates are drawn to with an integer 349 * translation and the scale in mXScale/mYScale. 350 */ AllowResidualTranslationContainerLayerParameters351 bool AllowResidualTranslation() { 352 // If we're in a transformed subtree, but no ancestor transform is actively 353 // changing, we'll use the residual translation when drawing into the 354 // PaintedLayer to ensure that snapping exactly matches the ideal transform. 355 return mInTransformedSubtree && !mInActiveTransformedSubtree; 356 } 357 }; 358 359 /** 360 * The FrameLayerBuilder is responsible for converting display lists 361 * into layer trees. Every LayerManager needs a unique FrameLayerBuilder 362 * to build layers. 363 * 364 * The most important API in this class is BuildContainerLayerFor. This 365 * method takes a display list as input and constructs a ContainerLayer 366 * with child layers that render the contents of the display list. It 367 * records the relationship between frames and layers. 368 * 369 * That data enables us to retain layer trees. When constructing a 370 * ContainerLayer, we first check to see if there's an existing 371 * ContainerLayer for the same frame that can be recycled. If we recycle 372 * it, we also try to reuse its existing PaintedLayer children to render 373 * the display items without layers of their own. The idea is that by 374 * recycling layers deterministically, we can ensure that when nothing 375 * changes in a display list, we will reuse the existing layers without 376 * changes. 377 * 378 * We expose a GetLeafLayerFor method that can be called by display items 379 * that make their own layers (e.g. canvas and video); this method 380 * locates the last layer used to render the display item, if any, and 381 * return it as a candidate for recycling. 382 * 383 * FrameLayerBuilder sets up PaintedLayers so that 0,0 in the Painted layer 384 * corresponds to the (pixel-snapped) top-left of the aAnimatedGeometryRoot. 385 * It sets up ContainerLayers so that 0,0 in the container layer 386 * corresponds to the snapped top-left of the display item reference frame. 387 * 388 * When we construct a container layer, we know the transform that will be 389 * applied to the layer. If the transform scales the content, we can get 390 * better results when intermediate buffers are used by pushing some scale 391 * from the container's transform down to the children. For PaintedLayer 392 * children, the scaling can be achieved by changing the size of the layer 393 * and drawing into it with increased or decreased resolution. By convention, 394 * integer types (nsIntPoint/nsIntSize/nsIntRect/nsIntRegion) are all in layer 395 * coordinates, post-scaling, whereas appunit types are all pre-scaling. 396 */ 397 class FrameLayerBuilder : public layers::LayerUserData { 398 public: 399 typedef layers::ContainerLayer ContainerLayer; 400 typedef layers::Layer Layer; 401 typedef layers::PaintedLayer PaintedLayer; 402 typedef layers::ImageLayer ImageLayer; 403 typedef layers::LayerManager LayerManager; 404 typedef layers::BasicLayerManager BasicLayerManager; 405 typedef layers::EventRegions EventRegions; 406 407 FrameLayerBuilder(); 408 ~FrameLayerBuilder() override; 409 410 static gfx::Size ChooseScale(nsIFrame* aContainerFrame, 411 nsDisplayItem* aContainerItem, 412 const nsRect& aVisibleRect, float aXScale, 413 float aYScale, const gfx::Matrix& aTransform2d, 414 bool aCanDraw2D); 415 416 static void Shutdown(); 417 418 void Init(nsDisplayListBuilder* aBuilder, LayerManager* aManager, 419 PaintedLayerData* aLayerData = nullptr, 420 bool aIsInactiveLayerManager = false, 421 const DisplayItemClip* aInactiveLayerClip = nullptr); 422 423 /** 424 * Call this to notify that we have just started a transaction on the 425 * retained layer manager aManager. 426 */ 427 void DidBeginRetainedLayerTransaction(LayerManager* aManager); 428 429 /** 430 * Call this just before we end a transaction. 431 */ 432 void WillEndTransaction(); 433 434 /** 435 * Call this after we end a transaction. 436 */ 437 void DidEndTransaction(); 438 439 enum { 440 /** 441 * Set this when pulling an opaque background color from behind the 442 * container layer into the container doesn't change the visual results, 443 * given the effects you're going to apply to the container layer. 444 * For example, this is compatible with opacity or clipping/masking, but 445 * not with non-OVER blend modes or filters. 446 */ 447 CONTAINER_ALLOW_PULL_BACKGROUND_COLOR = 0x01 448 }; 449 /** 450 * Build a container layer for a display item that contains a child 451 * list, either reusing an existing one or creating a new one. It 452 * sets the container layer children to layers which together render 453 * the contents of the display list. It reuses existing layers from 454 * the retained layer manager if possible. 455 * aContainerItem may be null, in which case we construct a root layer. 456 * This gets called by display list code. It calls BuildLayer on the 457 * items in the display list, making items with their own layers 458 * children of the new container, and assigning all other items to 459 * PaintedLayer children created and managed by the FrameLayerBuilder. 460 * Returns a layer with clip rect cleared; it is the 461 * caller's responsibility to add any clip rect. The visible region 462 * is set based on what's in the layer. 463 * The container layer is transformed by aTransform (if non-null), and 464 * the result is transformed by the scale factors in aContainerParameters. 465 * aChildren is modified due to display item merging and flattening. 466 * The visible region of the returned layer is set only if aContainerItem 467 * is null. 468 */ 469 already_AddRefed<ContainerLayer> BuildContainerLayerFor( 470 nsDisplayListBuilder* aBuilder, LayerManager* aManager, 471 nsIFrame* aContainerFrame, nsDisplayItem* aContainerItem, 472 nsDisplayList* aChildren, 473 const ContainerLayerParameters& aContainerParameters, 474 const gfx::Matrix4x4* aTransform, uint32_t aFlags = 0); 475 476 /** 477 * Get a retained layer for a display item that needs to create its own 478 * layer for rendering (i.e. under nsDisplayItem::BuildLayer). Returns 479 * null if no retained layer is available, which usually means that this 480 * display item didn't have a layer before so the caller will 481 * need to create one. 482 * Returns a layer with clip rect cleared; it is the 483 * caller's responsibility to add any clip rect and set the visible 484 * region. 485 */ 486 Layer* GetLeafLayerFor(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem); 487 488 /** 489 * Call this to force all retained layers to be discarded and recreated at 490 * the next paint. 491 */ 492 static void InvalidateAllLayers(LayerManager* aManager); 493 static void InvalidateAllLayersForFrame(nsIFrame* aFrame); 494 495 /** 496 * Call this to determine if a frame has a dedicated (non-Painted) layer 497 * for the given display item key. If there isn't one, we return null, 498 * otherwise we return the layer. 499 */ 500 static Layer* GetDedicatedLayer(nsIFrame* aFrame, 501 DisplayItemType aDisplayItemType); 502 503 using AnimationGenerationCallback = FunctionRef<bool( 504 const Maybe<uint64_t>& aGeneration, DisplayItemType aDisplayItemType)>; 505 /** 506 * Enumerates layers for the all display item types that correspond to 507 * properties we can animate on layers and calls |aCallback| 508 * with the animation generation for the layer. If there is no corresponding 509 * layer for the display item or the layer has no animation, the animation 510 * generation is Nothing(). 511 * 512 * The enumeration stops if |aCallback| returns false. 513 */ 514 static void EnumerateGenerationForDedicatedLayers( 515 const nsIFrame* aFrame, AnimationGenerationCallback); 516 517 /** 518 * This callback must be provided to EndTransaction. The callback data 519 * must be the nsDisplayListBuilder containing this FrameLayerBuilder. 520 * This function can be called multiple times in a row to draw 521 * different regions. This will occur when, for example, progressive paint is 522 * enabled. In these cases aDirtyRegion can be used to specify a larger region 523 * than aRegionToDraw that will be drawn during the transaction, possibly 524 * allowing the callback to make optimizations. 525 */ 526 static void DrawPaintedLayer(PaintedLayer* aLayer, gfxContext* aContext, 527 const nsIntRegion& aRegionToDraw, 528 const nsIntRegion& aDirtyRegion, 529 mozilla::layers::DrawRegionClip aClip, 530 const nsIntRegion& aRegionToInvalidate, 531 void* aCallbackData); 532 533 /** 534 * Dumps this FrameLayerBuilder's retained layer manager's retained 535 * layer tree. Defaults to dumping to stdout in non-HTML format. 536 */ 537 static void DumpRetainedLayerTree(LayerManager* aManager, 538 std::stringstream& aStream, 539 bool aDumpHtml = false); 540 541 /** 542 * Returns the most recently allocated geometry item for the given display 543 * item. 544 * 545 * XXX(seth): The current implementation must iterate through all display 546 * items allocated for this display item's frame. This may lead to O(n^2) 547 * behavior in some situations. 548 */ 549 static nsDisplayItemGeometry* GetMostRecentGeometry(nsDisplayItem* aItem); 550 551 /******* PRIVATE METHODS to FrameLayerBuilder.cpp ********/ 552 /* These are only in the public section because they need 553 * to be called by file-scope helper functions in FrameLayerBuilder.cpp. 554 */ 555 556 /** 557 * Record aItem as a display item that is rendered by the PaintedLayer 558 * aLayer, with aClipRect, where aContainerLayerFrame is the frame 559 * for the container layer this ThebesItem belongs to. 560 * aItem must have an underlying frame. 561 * @param aTopLeft offset from active scrolled root to reference frame 562 */ 563 void AddPaintedDisplayItem(PaintedLayerData* aLayerData, 564 AssignedDisplayItem& aAssignedDisplayItem, 565 Layer* aLayer); 566 567 /** 568 * Calls GetOldLayerForFrame on the underlying frame of the display item, 569 * and each subsequent merged frame if no layer is found for the underlying 570 * frame. 571 */ 572 Layer* GetOldLayerFor(nsDisplayItem* aItem, 573 nsDisplayItemGeometry** aOldGeometry = nullptr, 574 DisplayItemClip** aOldClip = nullptr); 575 576 static DisplayItemData* GetOldDataFor(nsDisplayItem* aItem); 577 578 /** 579 * Return the layer that all display items of aFrame were assigned to in the 580 * last paint, or nullptr if there was no single layer assigned to all of the 581 * frame's display items (i.e. zero, or more than one). 582 * This function is for testing purposes and not performance sensitive. 583 */ 584 template <class T> GetDebugSingleOldLayerForFrame(nsIFrame * aFrame)585 static T* GetDebugSingleOldLayerForFrame(nsIFrame* aFrame) { 586 SmallPointerArray<DisplayItemData>& array = aFrame->DisplayItemData(); 587 588 Layer* layer = nullptr; 589 for (DisplayItemData* data : array) { 590 DisplayItemData::AssertDisplayItemData(data); 591 if (data->mLayer->GetType() != T::Type()) { 592 continue; 593 } 594 if (layer && layer != data->mLayer) { 595 // More than one layer assigned, bail. 596 return nullptr; 597 } 598 layer = data->mLayer; 599 } 600 601 if (!layer) { 602 return nullptr; 603 } 604 605 return static_cast<T*>(layer); 606 } 607 608 /** 609 * Destroy any stored LayerManagerDataProperty and the associated data for 610 * aFrame. 611 */ 612 static void DestroyDisplayItemDataFor(nsIFrame* aFrame); 613 GetRetainingLayerManager()614 LayerManager* GetRetainingLayerManager() { return mRetainingManager; } 615 616 /** 617 * Returns true if the given display item was rendered during the previous 618 * paint. Returns false otherwise. 619 */ 620 static bool HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey); 621 622 typedef void (*DisplayItemDataCallback)(nsIFrame* aFrame, 623 DisplayItemData* aItem); 624 625 /** 626 * Return the resolution at which we expect to render aFrame's contents, 627 * assuming they are being painted to retained layers. This takes into account 628 * the resolution the contents of the ContainerLayer containing aFrame are 629 * being rendered at, as well as any currently-inactive transforms between 630 * aFrame and that container layer. 631 */ 632 static gfxSize GetPaintedLayerScaleForFrame(nsIFrame* aFrame); 633 634 static void RemoveFrameFromLayerManager( 635 const nsIFrame* aFrame, SmallPointerArray<DisplayItemData>& aArray); 636 637 /** 638 * Given a frame and a display item key that uniquely identifies a 639 * display item for the frame, find the layer that was last used to 640 * render that display item. Returns null if there is no such layer. 641 * This could be a dedicated layer for the display item, or a PaintedLayer 642 * that renders many display items. 643 */ 644 DisplayItemData* GetOldLayerForFrame( 645 nsIFrame* aFrame, uint32_t aDisplayItemKey, 646 DisplayItemData* aOldData = nullptr, 647 LayerManager* aOldLayerManager = nullptr); 648 649 /** 650 * Stores DisplayItemData associated with aFrame, stores the data in 651 * mNewDisplayItemData. 652 */ 653 DisplayItemData* StoreDataForFrame(nsPaintedDisplayItem* aItem, Layer* aLayer, 654 LayerState aState, DisplayItemData* aData); 655 void StoreDataForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey, 656 Layer* aLayer, LayerState aState); 657 658 protected: 659 friend class LayerManagerData; 660 661 // Flash the area within the context clip if paint flashing is enabled. 662 static void FlashPaint(gfxContext* aContext); 663 664 /* 665 * Get the DisplayItemData array associated with this frame, or null if one 666 * doesn't exist. 667 * 668 * Note that the pointer returned here is only valid so long as you don't 669 * poke the LayerManagerData's mFramesWithLayers hashtable. 670 */ 671 DisplayItemData* GetDisplayItemData(nsIFrame* aFrame, uint32_t aKey); 672 673 /* 674 * Get the DisplayItemData associated with this display item, 675 * using the LayerManager instead of FrameLayerBuilder. 676 */ 677 static DisplayItemData* GetDisplayItemDataForManager( 678 nsPaintedDisplayItem* aItem, LayerManager* aManager); 679 680 /** 681 * We store one of these for each display item associated with a 682 * PaintedLayer, in a hashtable that maps each PaintedLayer to an array 683 * of ClippedDisplayItems. (PaintedLayerItemsEntry is the hash entry 684 * for that hashtable.) 685 * These are only stored during the paint process, so that the 686 * DrawPaintedLayer callback can figure out which items to draw for the 687 * PaintedLayer. 688 */ 689 690 static void RecomputeVisibilityForItems( 691 std::vector<AssignedDisplayItem>& aItems, nsDisplayListBuilder* aBuilder, 692 const nsIntRegion& aRegionToDraw, nsRect& aPreviousRectToDraw, 693 const nsIntPoint& aOffset, int32_t aAppUnitsPerDevPixel, float aXScale, 694 float aYScale); 695 696 void PaintItems(std::vector<AssignedDisplayItem>& aItems, 697 const nsIntRect& aRect, gfxContext* aContext, 698 nsDisplayListBuilder* aBuilder, nsPresContext* aPresContext, 699 const nsIntPoint& aOffset, float aXScale, float aYScale); 700 701 /** 702 * We accumulate ClippedDisplayItem elements in a hashtable during 703 * the paint process. This is the hashentry for that hashtable. 704 */ 705 public: 706 /** 707 * Add the PaintedDisplayItemLayerUserData object as being used in this 708 * transaction so that we do some end-of-paint maintenance on it. 709 */ 710 void AddPaintedLayerItemsEntry(PaintedDisplayItemLayerUserData* aData); 711 GetContainingPaintedLayerData()712 PaintedLayerData* GetContainingPaintedLayerData() { 713 return mContainingPaintedLayer; 714 } 715 GetInactiveLayerClip()716 const DisplayItemClip* GetInactiveLayerClip() const { 717 return mInactiveLayerClip; 718 } 719 720 /* 721 * If we're building layers for an item with an inactive layer tree, 722 * this function saves the item's clip, which will later be applied 723 * to the event regions. The clip should be relative to 724 * mContainingPaintedLayer->mReferenceFrame. 725 */ SetInactiveLayerClip(const DisplayItemClip * aClip)726 void SetInactiveLayerClip(const DisplayItemClip* aClip) { 727 mInactiveLayerClip = aClip; 728 } 729 IsBuildingRetainedLayers()730 bool IsBuildingRetainedLayers() { 731 return !mIsInactiveLayerManager && mRetainingManager; 732 } 733 734 /** 735 * Attempt to build the most compressed layer tree possible, even if it means 736 * throwing away existing retained buffers. 737 */ SetLayerTreeCompressionMode()738 void SetLayerTreeCompressionMode() { mInLayerTreeCompressionMode = true; } 739 bool CheckInLayerTreeCompressionMode(); 740 741 void ComputeGeometryChangeForItem(DisplayItemData* aData); 742 743 protected: 744 /** 745 * The layer manager belonging to the widget that is being retained 746 * across paints. 747 */ 748 LayerManager* mRetainingManager; 749 /** 750 * The root prescontext for the display list builder reference frame 751 */ 752 RefPtr<nsRootPresContext> mRootPresContext; 753 754 /** 755 * The display list builder being used. 756 */ 757 nsDisplayListBuilder* mDisplayListBuilder; 758 /** 759 * An array of PaintedLayer user data objects containing the 760 * list of display items (plus clipping data) to be rendered in the 761 * layer. We clean these up at the end of the transaction to 762 * remove references to display items. 763 */ 764 AutoTArray<RefPtr<PaintedDisplayItemLayerUserData>, 5> mPaintedLayerItems; 765 766 /** 767 * When building layers for an inactive layer, this is where the 768 * inactive layer will be placed. 769 */ 770 PaintedLayerData* mContainingPaintedLayer; 771 772 /** 773 * When building layers for an inactive layer, this stores the clip 774 * of the display item that built the inactive layer. 775 */ 776 const DisplayItemClip* mInactiveLayerClip; 777 778 /** 779 * Indicates that the entire layer tree should be rerendered 780 * during this paint. 781 */ 782 bool mInvalidateAllLayers; 783 784 bool mInLayerTreeCompressionMode; 785 786 bool mIsInactiveLayerManager; 787 }; 788 789 } // namespace mozilla 790 791 #endif /* FRAMELAYERBUILDER_H_ */ 792