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