|
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef FRAMELAYERBUILDER_H_ |
|
7 #define FRAMELAYERBUILDER_H_ |
|
8 |
|
9 #include "nsTHashtable.h" |
|
10 #include "nsHashKeys.h" |
|
11 #include "nsTArray.h" |
|
12 #include "nsRegion.h" |
|
13 #include "nsIFrame.h" |
|
14 #include "ImageLayers.h" |
|
15 #include "DisplayItemClip.h" |
|
16 #include "mozilla/layers/LayersTypes.h" |
|
17 |
|
18 class nsDisplayListBuilder; |
|
19 class nsDisplayList; |
|
20 class nsDisplayItem; |
|
21 class gfxContext; |
|
22 class nsDisplayItemGeometry; |
|
23 |
|
24 namespace mozilla { |
|
25 namespace layers { |
|
26 class ContainerLayer; |
|
27 class LayerManager; |
|
28 class BasicLayerManager; |
|
29 class ThebesLayer; |
|
30 } |
|
31 |
|
32 class FrameLayerBuilder; |
|
33 class LayerManagerData; |
|
34 class ThebesLayerData; |
|
35 |
|
36 enum LayerState { |
|
37 LAYER_NONE, |
|
38 LAYER_INACTIVE, |
|
39 LAYER_ACTIVE, |
|
40 // Force an active layer even if it causes incorrect rendering, e.g. |
|
41 // when the layer has rounded rect clips. |
|
42 LAYER_ACTIVE_FORCE, |
|
43 // Special layer that is metadata only. |
|
44 LAYER_ACTIVE_EMPTY, |
|
45 // Inactive style layer for rendering SVG effects. |
|
46 LAYER_SVG_EFFECTS |
|
47 }; |
|
48 |
|
49 class RefCountedRegion { |
|
50 public: |
|
51 NS_INLINE_DECL_REFCOUNTING(RefCountedRegion) |
|
52 |
|
53 RefCountedRegion() : mIsInfinite(false) {} |
|
54 nsRegion mRegion; |
|
55 bool mIsInfinite; |
|
56 }; |
|
57 |
|
58 struct ContainerLayerParameters { |
|
59 ContainerLayerParameters() : |
|
60 mXScale(1), mYScale(1), mAncestorClipRect(nullptr), |
|
61 mInTransformedSubtree(false), mInActiveTransformedSubtree(false), |
|
62 mDisableSubpixelAntialiasingInDescendants(false) |
|
63 {} |
|
64 ContainerLayerParameters(float aXScale, float aYScale) : |
|
65 mXScale(aXScale), mYScale(aYScale), mAncestorClipRect(nullptr), |
|
66 mInTransformedSubtree(false), mInActiveTransformedSubtree(false), |
|
67 mDisableSubpixelAntialiasingInDescendants(false) |
|
68 {} |
|
69 ContainerLayerParameters(float aXScale, float aYScale, |
|
70 const nsIntPoint& aOffset, |
|
71 const ContainerLayerParameters& aParent) : |
|
72 mXScale(aXScale), mYScale(aYScale), mAncestorClipRect(nullptr), |
|
73 mOffset(aOffset), |
|
74 mInTransformedSubtree(aParent.mInTransformedSubtree), |
|
75 mInActiveTransformedSubtree(aParent.mInActiveTransformedSubtree), |
|
76 mDisableSubpixelAntialiasingInDescendants(aParent.mDisableSubpixelAntialiasingInDescendants) |
|
77 {} |
|
78 float mXScale, mYScale; |
|
79 /** |
|
80 * An ancestor clip rect that can be applied to restrict the visibility |
|
81 * of this container. Null if none available. |
|
82 */ |
|
83 const nsIntRect* mAncestorClipRect; |
|
84 /** |
|
85 * An offset to append to the transform set on all child layers created. |
|
86 */ |
|
87 nsIntPoint mOffset; |
|
88 |
|
89 bool mInTransformedSubtree; |
|
90 bool mInActiveTransformedSubtree; |
|
91 bool mDisableSubpixelAntialiasingInDescendants; |
|
92 /** |
|
93 * When this is false, ThebesLayer coordinates are drawn to with an integer |
|
94 * translation and the scale in mXScale/mYScale. |
|
95 */ |
|
96 bool AllowResidualTranslation() |
|
97 { |
|
98 // If we're in a transformed subtree, but no ancestor transform is actively |
|
99 // changing, we'll use the residual translation when drawing into the |
|
100 // ThebesLayer to ensure that snapping exactly matches the ideal transform. |
|
101 return mInTransformedSubtree && !mInActiveTransformedSubtree; |
|
102 } |
|
103 }; |
|
104 |
|
105 /** |
|
106 * The FrameLayerBuilder is responsible for converting display lists |
|
107 * into layer trees. Every LayerManager needs a unique FrameLayerBuilder |
|
108 * to build layers. |
|
109 * |
|
110 * The most important API in this class is BuildContainerLayerFor. This |
|
111 * method takes a display list as input and constructs a ContainerLayer |
|
112 * with child layers that render the contents of the display list. It |
|
113 * records the relationship between frames and layers. |
|
114 * |
|
115 * That data enables us to retain layer trees. When constructing a |
|
116 * ContainerLayer, we first check to see if there's an existing |
|
117 * ContainerLayer for the same frame that can be recycled. If we recycle |
|
118 * it, we also try to reuse its existing ThebesLayer children to render |
|
119 * the display items without layers of their own. The idea is that by |
|
120 * recycling layers deterministically, we can ensure that when nothing |
|
121 * changes in a display list, we will reuse the existing layers without |
|
122 * changes. |
|
123 * |
|
124 * We expose a GetLeafLayerFor method that can be called by display items |
|
125 * that make their own layers (e.g. canvas and video); this method |
|
126 * locates the last layer used to render the display item, if any, and |
|
127 * return it as a candidate for recycling. |
|
128 * |
|
129 * FrameLayerBuilder sets up ThebesLayers so that 0,0 in the Thebes layer |
|
130 * corresponds to the (pixel-snapped) top-left of the aAnimatedGeometryRoot. |
|
131 * It sets up ContainerLayers so that 0,0 in the container layer |
|
132 * corresponds to the snapped top-left of the display item reference frame. |
|
133 * |
|
134 * When we construct a container layer, we know the transform that will be |
|
135 * applied to the layer. If the transform scales the content, we can get |
|
136 * better results when intermediate buffers are used by pushing some scale |
|
137 * from the container's transform down to the children. For ThebesLayer |
|
138 * children, the scaling can be achieved by changing the size of the layer |
|
139 * and drawing into it with increased or decreased resolution. By convention, |
|
140 * integer types (nsIntPoint/nsIntSize/nsIntRect/nsIntRegion) are all in layer |
|
141 * coordinates, post-scaling, whereas appunit types are all pre-scaling. |
|
142 */ |
|
143 class FrameLayerBuilder : public layers::LayerUserData { |
|
144 public: |
|
145 typedef layers::ContainerLayer ContainerLayer; |
|
146 typedef layers::Layer Layer; |
|
147 typedef layers::ThebesLayer ThebesLayer; |
|
148 typedef layers::ImageLayer ImageLayer; |
|
149 typedef layers::LayerManager LayerManager; |
|
150 typedef layers::BasicLayerManager BasicLayerManager; |
|
151 typedef layers::EventRegions EventRegions; |
|
152 |
|
153 FrameLayerBuilder() : |
|
154 mRetainingManager(nullptr), |
|
155 mDetectedDOMModification(false), |
|
156 mInvalidateAllLayers(false), |
|
157 mInLayerTreeCompressionMode(false), |
|
158 mContainerLayerGeneration(0), |
|
159 mMaxContainerLayerGeneration(0) |
|
160 { |
|
161 MOZ_COUNT_CTOR(FrameLayerBuilder); |
|
162 } |
|
163 ~FrameLayerBuilder() |
|
164 { |
|
165 MOZ_COUNT_DTOR(FrameLayerBuilder); |
|
166 } |
|
167 |
|
168 static void Shutdown(); |
|
169 |
|
170 void Init(nsDisplayListBuilder* aBuilder, LayerManager* aManager, |
|
171 ThebesLayerData* aLayerData = nullptr); |
|
172 |
|
173 /** |
|
174 * Call this to notify that we have just started a transaction on the |
|
175 * retained layer manager aManager. |
|
176 */ |
|
177 void DidBeginRetainedLayerTransaction(LayerManager* aManager); |
|
178 |
|
179 /** |
|
180 * Call this just before we end a transaction. |
|
181 */ |
|
182 void WillEndTransaction(); |
|
183 |
|
184 /** |
|
185 * Call this after we end a transaction. |
|
186 */ |
|
187 void DidEndTransaction(); |
|
188 |
|
189 enum { |
|
190 CONTAINER_NOT_CLIPPED_BY_ANCESTORS = 0x01 |
|
191 }; |
|
192 /** |
|
193 * Build a container layer for a display item that contains a child |
|
194 * list, either reusing an existing one or creating a new one. It |
|
195 * sets the container layer children to layers which together render |
|
196 * the contents of the display list. It reuses existing layers from |
|
197 * the retained layer manager if possible. |
|
198 * aContainer may be null, in which case we construct a root layer. |
|
199 * This gets called by display list code. It calls BuildLayer on the |
|
200 * items in the display list, making items with their own layers |
|
201 * children of the new container, and assigning all other items to |
|
202 * ThebesLayer children created and managed by the FrameLayerBuilder. |
|
203 * Returns a layer with clip rect cleared; it is the |
|
204 * caller's responsibility to add any clip rect. The visible region |
|
205 * is set based on what's in the layer. |
|
206 * The container layer is transformed by aTransform (if non-null), and |
|
207 * the result is transformed by the scale factors in aContainerParameters. |
|
208 */ |
|
209 already_AddRefed<ContainerLayer> |
|
210 BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, |
|
211 LayerManager* aManager, |
|
212 nsIFrame* aContainerFrame, |
|
213 nsDisplayItem* aContainerItem, |
|
214 const nsDisplayList& aChildren, |
|
215 const ContainerLayerParameters& aContainerParameters, |
|
216 const gfx3DMatrix* aTransform, |
|
217 uint32_t aFlags = 0); |
|
218 |
|
219 /** |
|
220 * Get a retained layer for a display item that needs to create its own |
|
221 * layer for rendering (i.e. under nsDisplayItem::BuildLayer). Returns |
|
222 * null if no retained layer is available, which usually means that this |
|
223 * display item didn't have a layer before so the caller will |
|
224 * need to create one. |
|
225 * Returns a layer with clip rect cleared; it is the |
|
226 * caller's responsibility to add any clip rect and set the visible |
|
227 * region. |
|
228 */ |
|
229 Layer* GetLeafLayerFor(nsDisplayListBuilder* aBuilder, |
|
230 nsDisplayItem* aItem); |
|
231 |
|
232 /** |
|
233 * Call this to force all retained layers to be discarded and recreated at |
|
234 * the next paint. |
|
235 */ |
|
236 static void InvalidateAllLayers(LayerManager* aManager); |
|
237 static void InvalidateAllLayersForFrame(nsIFrame *aFrame); |
|
238 |
|
239 /** |
|
240 * Call this to determine if a frame has a dedicated (non-Thebes) layer |
|
241 * for the given display item key. If there isn't one, we return null, |
|
242 * otherwise we return the layer. |
|
243 */ |
|
244 static Layer* GetDedicatedLayer(nsIFrame* aFrame, uint32_t aDisplayItemKey); |
|
245 |
|
246 /** |
|
247 * This callback must be provided to EndTransaction. The callback data |
|
248 * must be the nsDisplayListBuilder containing this FrameLayerBuilder. |
|
249 * This function can be called multiple times in a row to draw |
|
250 * different regions. |
|
251 */ |
|
252 static void DrawThebesLayer(ThebesLayer* aLayer, |
|
253 gfxContext* aContext, |
|
254 const nsIntRegion& aRegionToDraw, |
|
255 mozilla::layers::DrawRegionClip aClip, |
|
256 const nsIntRegion& aRegionToInvalidate, |
|
257 void* aCallbackData); |
|
258 |
|
259 #ifdef MOZ_DUMP_PAINTING |
|
260 /** |
|
261 * Dumps this FrameLayerBuilder's retained layer manager's retained |
|
262 * layer tree. Defaults to dumping to stdout in non-HTML format. |
|
263 */ |
|
264 static void DumpRetainedLayerTree(LayerManager* aManager, FILE* aFile = stdout, bool aDumpHtml = false); |
|
265 #endif |
|
266 |
|
267 /******* PRIVATE METHODS to FrameLayerBuilder.cpp ********/ |
|
268 /* These are only in the public section because they need |
|
269 * to be called by file-scope helper functions in FrameLayerBuilder.cpp. |
|
270 */ |
|
271 |
|
272 /** |
|
273 * Record aItem as a display item that is rendered by aLayer. |
|
274 * |
|
275 * @param aLayer Layer that the display item will be rendered into |
|
276 * @param aItem Display item to be drawn. |
|
277 * @param aLayerState What LayerState the item is using. |
|
278 * @param aTopLeft offset from active scrolled root to reference frame |
|
279 * @param aManager If the layer is in the LAYER_INACTIVE state, |
|
280 * then this is the temporary layer manager to draw with. |
|
281 */ |
|
282 void AddLayerDisplayItem(Layer* aLayer, |
|
283 nsDisplayItem* aItem, |
|
284 const DisplayItemClip& aClip, |
|
285 LayerState aLayerState, |
|
286 const nsPoint& aTopLeft, |
|
287 BasicLayerManager* aManager, |
|
288 nsAutoPtr<nsDisplayItemGeometry> aGeometry); |
|
289 |
|
290 /** |
|
291 * Record aItem as a display item that is rendered by the ThebesLayer |
|
292 * aLayer, with aClipRect, where aContainerLayerFrame is the frame |
|
293 * for the container layer this ThebesItem belongs to. |
|
294 * aItem must have an underlying frame. |
|
295 * @param aTopLeft offset from active scrolled root to reference frame |
|
296 */ |
|
297 void AddThebesDisplayItem(ThebesLayerData* aLayer, |
|
298 nsDisplayItem* aItem, |
|
299 const DisplayItemClip& aClip, |
|
300 nsIFrame* aContainerLayerFrame, |
|
301 LayerState aLayerState, |
|
302 const nsPoint& aTopLeft, |
|
303 nsAutoPtr<nsDisplayItemGeometry> aGeometry); |
|
304 |
|
305 /** |
|
306 * Gets the frame property descriptor for the given manager, or for the current |
|
307 * widget layer manager if nullptr is passed. |
|
308 */ |
|
309 static const FramePropertyDescriptor* GetDescriptorForManager(LayerManager* aManager); |
|
310 |
|
311 /** |
|
312 * Calls GetOldLayerForFrame on the underlying frame of the display item, |
|
313 * and each subsequent merged frame if no layer is found for the underlying |
|
314 * frame. |
|
315 */ |
|
316 Layer* GetOldLayerFor(nsDisplayItem* aItem, |
|
317 nsDisplayItemGeometry** aOldGeometry = nullptr, |
|
318 DisplayItemClip** aOldClip = nullptr, |
|
319 nsTArray<nsIFrame*>* aChangedFrames = nullptr, |
|
320 bool *aIsInvalid = nullptr); |
|
321 |
|
322 static Layer* GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey); |
|
323 |
|
324 /** |
|
325 * Destroy any stored LayerManagerDataProperty and the associated data for |
|
326 * aFrame. |
|
327 */ |
|
328 static void DestroyDisplayItemDataFor(nsIFrame* aFrame); |
|
329 |
|
330 LayerManager* GetRetainingLayerManager() { return mRetainingManager; } |
|
331 |
|
332 /** |
|
333 * Returns true if the given display item was rendered during the previous |
|
334 * paint. Returns false otherwise. |
|
335 */ |
|
336 static bool HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey); |
|
337 |
|
338 class DisplayItemData; |
|
339 typedef void (*DisplayItemDataCallback)(nsIFrame *aFrame, DisplayItemData* aItem); |
|
340 |
|
341 static void IterateRetainedDataFor(nsIFrame* aFrame, DisplayItemDataCallback aCallback); |
|
342 |
|
343 /** |
|
344 * Save transform that was in aLayer when we last painted, and the position |
|
345 * of the active scrolled root frame. It must be an integer |
|
346 * translation. |
|
347 */ |
|
348 void SaveLastPaintOffset(ThebesLayer* aLayer); |
|
349 /** |
|
350 * Get the translation transform that was in aLayer when we last painted. It's either |
|
351 * the transform saved by SaveLastPaintTransform, or else the transform |
|
352 * that's currently in the layer (which must be an integer translation). |
|
353 */ |
|
354 nsIntPoint GetLastPaintOffset(ThebesLayer* aLayer); |
|
355 |
|
356 /** |
|
357 * Return the resolution at which we expect to render aFrame's contents, |
|
358 * assuming they are being painted to retained layers. This takes into account |
|
359 * the resolution the contents of the ContainerLayer containing aFrame are |
|
360 * being rendered at, as well as any currently-inactive transforms between |
|
361 * aFrame and that container layer. |
|
362 */ |
|
363 static gfxSize GetThebesLayerScaleForFrame(nsIFrame* aFrame); |
|
364 |
|
365 /** |
|
366 * Stores a Layer as the dedicated layer in the DisplayItemData for a given frame/key pair. |
|
367 * |
|
368 * Used when we optimize a ThebesLayer into an ImageLayer and want to retroactively update the |
|
369 * DisplayItemData so we can retrieve the layer from within layout. |
|
370 */ |
|
371 void StoreOptimizedLayerForFrame(nsDisplayItem* aItem, Layer* aLayer); |
|
372 |
|
373 NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(LayerManagerDataProperty, |
|
374 RemoveFrameFromLayerManager) |
|
375 |
|
376 /** |
|
377 * Retained data storage: |
|
378 * |
|
379 * Each layer manager (widget, and inactive) stores a LayerManagerData object |
|
380 * that keeps a hash-set of DisplayItemData items that were drawn into it. |
|
381 * Each frame also keeps a list of DisplayItemData pointers that were |
|
382 * created for that frame. DisplayItemData objects manage these lists automatically. |
|
383 * |
|
384 * During layer construction we update the data in the LayerManagerData object, marking |
|
385 * items that are modified. At the end we sweep the LayerManagerData hash-set and remove |
|
386 * all items that haven't been modified. |
|
387 */ |
|
388 |
|
389 /** |
|
390 * Retained data for a display item. |
|
391 */ |
|
392 class DisplayItemData MOZ_FINAL { |
|
393 public: |
|
394 friend class FrameLayerBuilder; |
|
395 |
|
396 uint32_t GetDisplayItemKey() { return mDisplayItemKey; } |
|
397 Layer* GetLayer() { return mLayer; } |
|
398 void Invalidate() { mIsInvalid = true; } |
|
399 |
|
400 private: |
|
401 DisplayItemData(LayerManagerData* aParent, uint32_t aKey, Layer* aLayer, LayerState aLayerState, uint32_t aGeneration); |
|
402 DisplayItemData(DisplayItemData &toCopy); |
|
403 |
|
404 /** |
|
405 * Removes any references to this object from frames |
|
406 * in mFrameList. |
|
407 */ |
|
408 ~DisplayItemData(); |
|
409 |
|
410 NS_INLINE_DECL_REFCOUNTING(DisplayItemData) |
|
411 |
|
412 |
|
413 /** |
|
414 * Associates this DisplayItemData with a frame, and adds it |
|
415 * to the LayerManagerDataProperty list on the frame. |
|
416 */ |
|
417 void AddFrame(nsIFrame* aFrame); |
|
418 void RemoveFrame(nsIFrame* aFrame); |
|
419 void GetFrameListChanges(nsDisplayItem* aOther, nsTArray<nsIFrame*>& aOut); |
|
420 |
|
421 /** |
|
422 * Updates the contents of this item to a new set of data, instead of allocating a new |
|
423 * object. |
|
424 * Set the passed in parameters, and clears the opt layer, inactive manager, geometry |
|
425 * and clip. |
|
426 * Parent, frame list and display item key are assumed to be the same. |
|
427 */ |
|
428 void UpdateContents(Layer* aLayer, LayerState aState, |
|
429 uint32_t aContainerLayerGeneration, nsDisplayItem* aItem = nullptr); |
|
430 |
|
431 LayerManagerData* mParent; |
|
432 nsRefPtr<Layer> mLayer; |
|
433 nsRefPtr<Layer> mOptLayer; |
|
434 nsRefPtr<BasicLayerManager> mInactiveManager; |
|
435 nsAutoTArray<nsIFrame*, 1> mFrameList; |
|
436 nsAutoPtr<nsDisplayItemGeometry> mGeometry; |
|
437 DisplayItemClip mClip; |
|
438 uint32_t mDisplayItemKey; |
|
439 uint32_t mContainerLayerGeneration; |
|
440 LayerState mLayerState; |
|
441 |
|
442 /** |
|
443 * Used to track if data currently stored in mFramesWithLayers (from an existing |
|
444 * paint) has been updated in the current paint. |
|
445 */ |
|
446 bool mUsed; |
|
447 bool mIsInvalid; |
|
448 }; |
|
449 |
|
450 protected: |
|
451 |
|
452 friend class LayerManagerData; |
|
453 |
|
454 static void RemoveFrameFromLayerManager(nsIFrame* aFrame, void* aPropertyValue); |
|
455 |
|
456 /** |
|
457 * Given a frame and a display item key that uniquely identifies a |
|
458 * display item for the frame, find the layer that was last used to |
|
459 * render that display item. Returns null if there is no such layer. |
|
460 * This could be a dedicated layer for the display item, or a ThebesLayer |
|
461 * that renders many display items. |
|
462 */ |
|
463 DisplayItemData* GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey); |
|
464 |
|
465 /** |
|
466 * Stores DisplayItemData associated with aFrame, stores the data in |
|
467 * mNewDisplayItemData. |
|
468 */ |
|
469 DisplayItemData* StoreDataForFrame(nsDisplayItem* aItem, Layer* aLayer, LayerState aState); |
|
470 void StoreDataForFrame(nsIFrame* aFrame, |
|
471 uint32_t aDisplayItemKey, |
|
472 Layer* aLayer, |
|
473 LayerState aState); |
|
474 |
|
475 // Flash the area within the context clip if paint flashing is enabled. |
|
476 static void FlashPaint(gfxContext *aContext); |
|
477 |
|
478 /* |
|
479 * Get the DisplayItemData array associated with this frame, or null if one |
|
480 * doesn't exist. |
|
481 * |
|
482 * Note that the pointer returned here is only valid so long as you don't |
|
483 * poke the LayerManagerData's mFramesWithLayers hashtable. |
|
484 */ |
|
485 DisplayItemData* GetDisplayItemData(nsIFrame *aFrame, uint32_t aKey); |
|
486 |
|
487 /* |
|
488 * Get the DisplayItemData associated with this frame / display item pair, |
|
489 * using the LayerManager instead of FrameLayerBuilder. |
|
490 */ |
|
491 static DisplayItemData* GetDisplayItemDataForManager(nsIFrame* aFrame, |
|
492 uint32_t aDisplayItemKey, |
|
493 LayerManager* aManager); |
|
494 static DisplayItemData* GetDisplayItemDataForManager(nsIFrame* aFrame, |
|
495 uint32_t aDisplayItemKey); |
|
496 static DisplayItemData* GetDisplayItemDataForManager(nsDisplayItem* aItem, LayerManager* aManager); |
|
497 static DisplayItemData* GetDisplayItemDataForManager(nsIFrame* aFrame, |
|
498 uint32_t aDisplayItemKey, |
|
499 LayerManagerData* aData); |
|
500 |
|
501 static PLDHashOperator DumpDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry, |
|
502 void* aClosure); |
|
503 /** |
|
504 * We store one of these for each display item associated with a |
|
505 * ThebesLayer, in a hashtable that maps each ThebesLayer to an array |
|
506 * of ClippedDisplayItems. (ThebesLayerItemsEntry is the hash entry |
|
507 * for that hashtable.) |
|
508 * These are only stored during the paint process, so that the |
|
509 * DrawThebesLayer callback can figure out which items to draw for the |
|
510 * ThebesLayer. |
|
511 */ |
|
512 struct ClippedDisplayItem { |
|
513 ClippedDisplayItem(nsDisplayItem* aItem, uint32_t aGeneration) |
|
514 : mItem(aItem), mContainerLayerGeneration(aGeneration) |
|
515 { |
|
516 } |
|
517 |
|
518 ~ClippedDisplayItem(); |
|
519 |
|
520 nsDisplayItem* mItem; |
|
521 |
|
522 /** |
|
523 * If the display item is being rendered as an inactive |
|
524 * layer, then this stores the layer manager being |
|
525 * used for the inactive transaction. |
|
526 */ |
|
527 nsRefPtr<LayerManager> mInactiveLayerManager; |
|
528 |
|
529 uint32_t mContainerLayerGeneration; |
|
530 }; |
|
531 |
|
532 static void RecomputeVisibilityForItems(nsTArray<ClippedDisplayItem>& aItems, |
|
533 nsDisplayListBuilder* aBuilder, |
|
534 const nsIntRegion& aRegionToDraw, |
|
535 const nsIntPoint& aOffset, |
|
536 int32_t aAppUnitsPerDevPixel, |
|
537 float aXScale, |
|
538 float aYScale); |
|
539 |
|
540 void PaintItems(nsTArray<ClippedDisplayItem>& aItems, |
|
541 const nsIntRect& aRect, |
|
542 gfxContext* aContext, |
|
543 nsRenderingContext* aRC, |
|
544 nsDisplayListBuilder* aBuilder, |
|
545 nsPresContext* aPresContext, |
|
546 const nsIntPoint& aOffset, |
|
547 float aXScale, float aYScale, |
|
548 int32_t aCommonClipCount); |
|
549 |
|
550 /** |
|
551 * We accumulate ClippedDisplayItem elements in a hashtable during |
|
552 * the paint process. This is the hashentry for that hashtable. |
|
553 */ |
|
554 public: |
|
555 class ThebesLayerItemsEntry : public nsPtrHashKey<ThebesLayer> { |
|
556 public: |
|
557 ThebesLayerItemsEntry(const ThebesLayer *key) : |
|
558 nsPtrHashKey<ThebesLayer>(key), mContainerLayerFrame(nullptr), |
|
559 mContainerLayerGeneration(0), |
|
560 mHasExplicitLastPaintOffset(false), mCommonClipCount(0) {} |
|
561 ThebesLayerItemsEntry(const ThebesLayerItemsEntry &toCopy) : |
|
562 nsPtrHashKey<ThebesLayer>(toCopy.mKey), mItems(toCopy.mItems) |
|
563 { |
|
564 NS_ERROR("Should never be called, since we ALLOW_MEMMOVE"); |
|
565 } |
|
566 |
|
567 nsTArray<ClippedDisplayItem> mItems; |
|
568 nsIFrame* mContainerLayerFrame; |
|
569 // The translation set on this ThebesLayer before we started updating the |
|
570 // layer tree. |
|
571 nsIntPoint mLastPaintOffset; |
|
572 uint32_t mContainerLayerGeneration; |
|
573 bool mHasExplicitLastPaintOffset; |
|
574 /** |
|
575 * The first mCommonClipCount rounded rectangle clips are identical for |
|
576 * all items in the layer. Computed in ThebesLayerData. |
|
577 */ |
|
578 uint32_t mCommonClipCount; |
|
579 |
|
580 enum { ALLOW_MEMMOVE = true }; |
|
581 }; |
|
582 |
|
583 /** |
|
584 * Get the ThebesLayerItemsEntry object associated with aLayer in this |
|
585 * FrameLayerBuilder |
|
586 */ |
|
587 ThebesLayerItemsEntry* GetThebesLayerItemsEntry(ThebesLayer* aLayer) |
|
588 { |
|
589 return mThebesLayerItems.GetEntry(aLayer); |
|
590 } |
|
591 |
|
592 ThebesLayerData* GetContainingThebesLayerData() |
|
593 { |
|
594 return mContainingThebesLayer; |
|
595 } |
|
596 |
|
597 /** |
|
598 * Attempt to build the most compressed layer tree possible, even if it means |
|
599 * throwing away existing retained buffers. |
|
600 */ |
|
601 void SetLayerTreeCompressionMode() { mInLayerTreeCompressionMode = true; } |
|
602 bool CheckInLayerTreeCompressionMode(); |
|
603 |
|
604 protected: |
|
605 void RemoveThebesItemsAndOwnerDataForLayerSubtree(Layer* aLayer, |
|
606 bool aRemoveThebesItems, |
|
607 bool aRemoveOwnerData); |
|
608 |
|
609 static PLDHashOperator ProcessRemovedDisplayItems(nsRefPtrHashKey<DisplayItemData>* aEntry, |
|
610 void* aUserArg); |
|
611 static PLDHashOperator RestoreDisplayItemData(nsRefPtrHashKey<DisplayItemData>* aEntry, |
|
612 void *aUserArg); |
|
613 |
|
614 static PLDHashOperator RestoreThebesLayerItemEntries(ThebesLayerItemsEntry* aEntry, |
|
615 void *aUserArg); |
|
616 |
|
617 /** |
|
618 * Returns true if the DOM has been modified since we started painting, |
|
619 * in which case we should bail out and not paint anymore. This should |
|
620 * never happen, but plugins can trigger it in some cases. |
|
621 */ |
|
622 bool CheckDOMModified(); |
|
623 |
|
624 /** |
|
625 * The layer manager belonging to the widget that is being retained |
|
626 * across paints. |
|
627 */ |
|
628 LayerManager* mRetainingManager; |
|
629 /** |
|
630 * The root prescontext for the display list builder reference frame |
|
631 */ |
|
632 nsRefPtr<nsRootPresContext> mRootPresContext; |
|
633 |
|
634 /** |
|
635 * The display list builder being used. |
|
636 */ |
|
637 nsDisplayListBuilder* mDisplayListBuilder; |
|
638 /** |
|
639 * A map from ThebesLayers to the list of display items (plus |
|
640 * clipping data) to be rendered in the layer. |
|
641 */ |
|
642 nsTHashtable<ThebesLayerItemsEntry> mThebesLayerItems; |
|
643 |
|
644 /** |
|
645 * When building layers for an inactive layer, this is where the |
|
646 * inactive layer will be placed. |
|
647 */ |
|
648 ThebesLayerData* mContainingThebesLayer; |
|
649 |
|
650 /** |
|
651 * Saved generation counter so we can detect DOM changes. |
|
652 */ |
|
653 uint32_t mInitialDOMGeneration; |
|
654 /** |
|
655 * Set to true if we have detected and reported DOM modification during |
|
656 * the current paint. |
|
657 */ |
|
658 bool mDetectedDOMModification; |
|
659 /** |
|
660 * Indicates that the entire layer tree should be rerendered |
|
661 * during this paint. |
|
662 */ |
|
663 bool mInvalidateAllLayers; |
|
664 |
|
665 bool mInLayerTreeCompressionMode; |
|
666 |
|
667 uint32_t mContainerLayerGeneration; |
|
668 uint32_t mMaxContainerLayerGeneration; |
|
669 }; |
|
670 |
|
671 } |
|
672 |
|
673 #endif /* FRAMELAYERBUILDER_H_ */ |