/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_ */ |