Coverage Report

Created: 2018-09-25 14:53

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