1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/base/FrameLayerBuilder.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,673 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef FRAMELAYERBUILDER_H_ 1.10 +#define FRAMELAYERBUILDER_H_ 1.11 + 1.12 +#include "nsTHashtable.h" 1.13 +#include "nsHashKeys.h" 1.14 +#include "nsTArray.h" 1.15 +#include "nsRegion.h" 1.16 +#include "nsIFrame.h" 1.17 +#include "ImageLayers.h" 1.18 +#include "DisplayItemClip.h" 1.19 +#include "mozilla/layers/LayersTypes.h" 1.20 + 1.21 +class nsDisplayListBuilder; 1.22 +class nsDisplayList; 1.23 +class nsDisplayItem; 1.24 +class gfxContext; 1.25 +class nsDisplayItemGeometry; 1.26 + 1.27 +namespace mozilla { 1.28 +namespace layers { 1.29 +class ContainerLayer; 1.30 +class LayerManager; 1.31 +class BasicLayerManager; 1.32 +class ThebesLayer; 1.33 +} 1.34 + 1.35 +class FrameLayerBuilder; 1.36 +class LayerManagerData; 1.37 +class ThebesLayerData; 1.38 + 1.39 +enum LayerState { 1.40 + LAYER_NONE, 1.41 + LAYER_INACTIVE, 1.42 + LAYER_ACTIVE, 1.43 + // Force an active layer even if it causes incorrect rendering, e.g. 1.44 + // when the layer has rounded rect clips. 1.45 + LAYER_ACTIVE_FORCE, 1.46 + // Special layer that is metadata only. 1.47 + LAYER_ACTIVE_EMPTY, 1.48 + // Inactive style layer for rendering SVG effects. 1.49 + LAYER_SVG_EFFECTS 1.50 +}; 1.51 + 1.52 +class RefCountedRegion { 1.53 +public: 1.54 + NS_INLINE_DECL_REFCOUNTING(RefCountedRegion) 1.55 + 1.56 + RefCountedRegion() : mIsInfinite(false) {} 1.57 + nsRegion mRegion; 1.58 + bool mIsInfinite; 1.59 +}; 1.60 + 1.61 +struct ContainerLayerParameters { 1.62 + ContainerLayerParameters() : 1.63 + mXScale(1), mYScale(1), mAncestorClipRect(nullptr), 1.64 + mInTransformedSubtree(false), mInActiveTransformedSubtree(false), 1.65 + mDisableSubpixelAntialiasingInDescendants(false) 1.66 + {} 1.67 + ContainerLayerParameters(float aXScale, float aYScale) : 1.68 + mXScale(aXScale), mYScale(aYScale), mAncestorClipRect(nullptr), 1.69 + mInTransformedSubtree(false), mInActiveTransformedSubtree(false), 1.70 + mDisableSubpixelAntialiasingInDescendants(false) 1.71 + {} 1.72 + ContainerLayerParameters(float aXScale, float aYScale, 1.73 + const nsIntPoint& aOffset, 1.74 + const ContainerLayerParameters& aParent) : 1.75 + mXScale(aXScale), mYScale(aYScale), mAncestorClipRect(nullptr), 1.76 + mOffset(aOffset), 1.77 + mInTransformedSubtree(aParent.mInTransformedSubtree), 1.78 + mInActiveTransformedSubtree(aParent.mInActiveTransformedSubtree), 1.79 + mDisableSubpixelAntialiasingInDescendants(aParent.mDisableSubpixelAntialiasingInDescendants) 1.80 + {} 1.81 + float mXScale, mYScale; 1.82 + /** 1.83 + * An ancestor clip rect that can be applied to restrict the visibility 1.84 + * of this container. Null if none available. 1.85 + */ 1.86 + const nsIntRect* mAncestorClipRect; 1.87 + /** 1.88 + * An offset to append to the transform set on all child layers created. 1.89 + */ 1.90 + nsIntPoint mOffset; 1.91 + 1.92 + bool mInTransformedSubtree; 1.93 + bool mInActiveTransformedSubtree; 1.94 + bool mDisableSubpixelAntialiasingInDescendants; 1.95 + /** 1.96 + * When this is false, ThebesLayer coordinates are drawn to with an integer 1.97 + * translation and the scale in mXScale/mYScale. 1.98 + */ 1.99 + bool AllowResidualTranslation() 1.100 + { 1.101 + // If we're in a transformed subtree, but no ancestor transform is actively 1.102 + // changing, we'll use the residual translation when drawing into the 1.103 + // ThebesLayer to ensure that snapping exactly matches the ideal transform. 1.104 + return mInTransformedSubtree && !mInActiveTransformedSubtree; 1.105 + } 1.106 +}; 1.107 + 1.108 +/** 1.109 + * The FrameLayerBuilder is responsible for converting display lists 1.110 + * into layer trees. Every LayerManager needs a unique FrameLayerBuilder 1.111 + * to build layers. 1.112 + * 1.113 + * The most important API in this class is BuildContainerLayerFor. This 1.114 + * method takes a display list as input and constructs a ContainerLayer 1.115 + * with child layers that render the contents of the display list. It 1.116 + * records the relationship between frames and layers. 1.117 + * 1.118 + * That data enables us to retain layer trees. When constructing a 1.119 + * ContainerLayer, we first check to see if there's an existing 1.120 + * ContainerLayer for the same frame that can be recycled. If we recycle 1.121 + * it, we also try to reuse its existing ThebesLayer children to render 1.122 + * the display items without layers of their own. The idea is that by 1.123 + * recycling layers deterministically, we can ensure that when nothing 1.124 + * changes in a display list, we will reuse the existing layers without 1.125 + * changes. 1.126 + * 1.127 + * We expose a GetLeafLayerFor method that can be called by display items 1.128 + * that make their own layers (e.g. canvas and video); this method 1.129 + * locates the last layer used to render the display item, if any, and 1.130 + * return it as a candidate for recycling. 1.131 + * 1.132 + * FrameLayerBuilder sets up ThebesLayers so that 0,0 in the Thebes layer 1.133 + * corresponds to the (pixel-snapped) top-left of the aAnimatedGeometryRoot. 1.134 + * It sets up ContainerLayers so that 0,0 in the container layer 1.135 + * corresponds to the snapped top-left of the display item reference frame. 1.136 + * 1.137 + * When we construct a container layer, we know the transform that will be 1.138 + * applied to the layer. If the transform scales the content, we can get 1.139 + * better results when intermediate buffers are used by pushing some scale 1.140 + * from the container's transform down to the children. For ThebesLayer 1.141 + * children, the scaling can be achieved by changing the size of the layer 1.142 + * and drawing into it with increased or decreased resolution. By convention, 1.143 + * integer types (nsIntPoint/nsIntSize/nsIntRect/nsIntRegion) are all in layer 1.144 + * coordinates, post-scaling, whereas appunit types are all pre-scaling. 1.145 + */ 1.146 +class FrameLayerBuilder : public layers::LayerUserData { 1.147 +public: 1.148 + typedef layers::ContainerLayer ContainerLayer; 1.149 + typedef layers::Layer Layer; 1.150 + typedef layers::ThebesLayer ThebesLayer; 1.151 + typedef layers::ImageLayer ImageLayer; 1.152 + typedef layers::LayerManager LayerManager; 1.153 + typedef layers::BasicLayerManager BasicLayerManager; 1.154 + typedef layers::EventRegions EventRegions; 1.155 + 1.156 + FrameLayerBuilder() : 1.157 + mRetainingManager(nullptr), 1.158 + mDetectedDOMModification(false), 1.159 + mInvalidateAllLayers(false), 1.160 + mInLayerTreeCompressionMode(false), 1.161 + mContainerLayerGeneration(0), 1.162 + mMaxContainerLayerGeneration(0) 1.163 + { 1.164 + MOZ_COUNT_CTOR(FrameLayerBuilder); 1.165 + } 1.166 + ~FrameLayerBuilder() 1.167 + { 1.168 + MOZ_COUNT_DTOR(FrameLayerBuilder); 1.169 + } 1.170 + 1.171 + static void Shutdown(); 1.172 + 1.173 + void Init(nsDisplayListBuilder* aBuilder, LayerManager* aManager, 1.174 + ThebesLayerData* aLayerData = nullptr); 1.175 + 1.176 + /** 1.177 + * Call this to notify that we have just started a transaction on the 1.178 + * retained layer manager aManager. 1.179 + */ 1.180 + void DidBeginRetainedLayerTransaction(LayerManager* aManager); 1.181 + 1.182 + /** 1.183 + * Call this just before we end a transaction. 1.184 + */ 1.185 + void WillEndTransaction(); 1.186 + 1.187 + /** 1.188 + * Call this after we end a transaction. 1.189 + */ 1.190 + void DidEndTransaction(); 1.191 + 1.192 + enum { 1.193 + CONTAINER_NOT_CLIPPED_BY_ANCESTORS = 0x01 1.194 + }; 1.195 + /** 1.196 + * Build a container layer for a display item that contains a child 1.197 + * list, either reusing an existing one or creating a new one. It 1.198 + * sets the container layer children to layers which together render 1.199 + * the contents of the display list. It reuses existing layers from 1.200 + * the retained layer manager if possible. 1.201 + * aContainer may be null, in which case we construct a root layer. 1.202 + * This gets called by display list code. It calls BuildLayer on the 1.203 + * items in the display list, making items with their own layers 1.204 + * children of the new container, and assigning all other items to 1.205 + * ThebesLayer children created and managed by the FrameLayerBuilder. 1.206 + * Returns a layer with clip rect cleared; it is the 1.207 + * caller's responsibility to add any clip rect. The visible region 1.208 + * is set based on what's in the layer. 1.209 + * The container layer is transformed by aTransform (if non-null), and 1.210 + * the result is transformed by the scale factors in aContainerParameters. 1.211 + */ 1.212 + already_AddRefed<ContainerLayer> 1.213 + BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, 1.214 + LayerManager* aManager, 1.215 + nsIFrame* aContainerFrame, 1.216 + nsDisplayItem* aContainerItem, 1.217 + const nsDisplayList& aChildren, 1.218 + const ContainerLayerParameters& aContainerParameters, 1.219 + const gfx3DMatrix* aTransform, 1.220 + uint32_t aFlags = 0); 1.221 + 1.222 + /** 1.223 + * Get a retained layer for a display item that needs to create its own 1.224 + * layer for rendering (i.e. under nsDisplayItem::BuildLayer). Returns 1.225 + * null if no retained layer is available, which usually means that this 1.226 + * display item didn't have a layer before so the caller will 1.227 + * need to create one. 1.228 + * Returns a layer with clip rect cleared; it is the 1.229 + * caller's responsibility to add any clip rect and set the visible 1.230 + * region. 1.231 + */ 1.232 + Layer* GetLeafLayerFor(nsDisplayListBuilder* aBuilder, 1.233 + nsDisplayItem* aItem); 1.234 + 1.235 + /** 1.236 + * Call this to force all retained layers to be discarded and recreated at 1.237 + * the next paint. 1.238 + */ 1.239 + static void InvalidateAllLayers(LayerManager* aManager); 1.240 + static void InvalidateAllLayersForFrame(nsIFrame *aFrame); 1.241 + 1.242 + /** 1.243 + * Call this to determine if a frame has a dedicated (non-Thebes) layer 1.244 + * for the given display item key. If there isn't one, we return null, 1.245 + * otherwise we return the layer. 1.246 + */ 1.247 + static Layer* GetDedicatedLayer(nsIFrame* aFrame, uint32_t aDisplayItemKey); 1.248 + 1.249 + /** 1.250 + * This callback must be provided to EndTransaction. The callback data 1.251 + * must be the nsDisplayListBuilder containing this FrameLayerBuilder. 1.252 + * This function can be called multiple times in a row to draw 1.253 + * different regions. 1.254 + */ 1.255 + static void DrawThebesLayer(ThebesLayer* aLayer, 1.256 + gfxContext* aContext, 1.257 + const nsIntRegion& aRegionToDraw, 1.258 + mozilla::layers::DrawRegionClip aClip, 1.259 + const nsIntRegion& aRegionToInvalidate, 1.260 + void* aCallbackData); 1.261 + 1.262 +#ifdef MOZ_DUMP_PAINTING 1.263 + /** 1.264 + * Dumps this FrameLayerBuilder's retained layer manager's retained 1.265 + * layer tree. Defaults to dumping to stdout in non-HTML format. 1.266 + */ 1.267 + static void DumpRetainedLayerTree(LayerManager* aManager, FILE* aFile = stdout, bool aDumpHtml = false); 1.268 +#endif 1.269 + 1.270 + /******* PRIVATE METHODS to FrameLayerBuilder.cpp ********/ 1.271 + /* These are only in the public section because they need 1.272 + * to be called by file-scope helper functions in FrameLayerBuilder.cpp. 1.273 + */ 1.274 + 1.275 + /** 1.276 + * Record aItem as a display item that is rendered by aLayer. 1.277 + * 1.278 + * @param aLayer Layer that the display item will be rendered into 1.279 + * @param aItem Display item to be drawn. 1.280 + * @param aLayerState What LayerState the item is using. 1.281 + * @param aTopLeft offset from active scrolled root to reference frame 1.282 + * @param aManager If the layer is in the LAYER_INACTIVE state, 1.283 + * then this is the temporary layer manager to draw with. 1.284 + */ 1.285 + void AddLayerDisplayItem(Layer* aLayer, 1.286 + nsDisplayItem* aItem, 1.287 + const DisplayItemClip& aClip, 1.288 + LayerState aLayerState, 1.289 + const nsPoint& aTopLeft, 1.290 + BasicLayerManager* aManager, 1.291 + nsAutoPtr<nsDisplayItemGeometry> aGeometry); 1.292 + 1.293 + /** 1.294 + * Record aItem as a display item that is rendered by the ThebesLayer 1.295 + * aLayer, with aClipRect, where aContainerLayerFrame is the frame 1.296 + * for the container layer this ThebesItem belongs to. 1.297 + * aItem must have an underlying frame. 1.298 + * @param aTopLeft offset from active scrolled root to reference frame 1.299 + */ 1.300 + void AddThebesDisplayItem(ThebesLayerData* aLayer, 1.301 + nsDisplayItem* aItem, 1.302 + const DisplayItemClip& aClip, 1.303 + nsIFrame* aContainerLayerFrame, 1.304 + LayerState aLayerState, 1.305 + const nsPoint& aTopLeft, 1.306 + nsAutoPtr<nsDisplayItemGeometry> aGeometry); 1.307 + 1.308 + /** 1.309 + * Gets the frame property descriptor for the given manager, or for the current 1.310 + * widget layer manager if nullptr is passed. 1.311 + */ 1.312 + static const FramePropertyDescriptor* GetDescriptorForManager(LayerManager* aManager); 1.313 + 1.314 + /** 1.315 + * Calls GetOldLayerForFrame on the underlying frame of the display item, 1.316 + * and each subsequent merged frame if no layer is found for the underlying 1.317 + * frame. 1.318 + */ 1.319 + Layer* GetOldLayerFor(nsDisplayItem* aItem, 1.320 + nsDisplayItemGeometry** aOldGeometry = nullptr, 1.321 + DisplayItemClip** aOldClip = nullptr, 1.322 + nsTArray<nsIFrame*>* aChangedFrames = nullptr, 1.323 + bool *aIsInvalid = nullptr); 1.324 + 1.325 + static Layer* GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey); 1.326 + 1.327 + /** 1.328 + * Destroy any stored LayerManagerDataProperty and the associated data for 1.329 + * aFrame. 1.330 + */ 1.331 + static void DestroyDisplayItemDataFor(nsIFrame* aFrame); 1.332 + 1.333 + LayerManager* GetRetainingLayerManager() { return mRetainingManager; } 1.334 + 1.335 + /** 1.336 + * Returns true if the given display item was rendered during the previous 1.337 + * paint. Returns false otherwise. 1.338 + */ 1.339 + static bool HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey); 1.340 + 1.341 + class DisplayItemData; 1.342 + typedef void (*DisplayItemDataCallback)(nsIFrame *aFrame, DisplayItemData* aItem); 1.343 + 1.344 + static void IterateRetainedDataFor(nsIFrame* aFrame, DisplayItemDataCallback aCallback); 1.345 + 1.346 + /** 1.347 + * Save transform that was in aLayer when we last painted, and the position 1.348 + * of the active scrolled root frame. It must be an integer 1.349 + * translation. 1.350 + */ 1.351 + void SaveLastPaintOffset(ThebesLayer* aLayer); 1.352 + /** 1.353 + * Get the translation transform that was in aLayer when we last painted. It's either 1.354 + * the transform saved by SaveLastPaintTransform, or else the transform 1.355 + * that's currently in the layer (which must be an integer translation). 1.356 + */ 1.357 + nsIntPoint GetLastPaintOffset(ThebesLayer* aLayer); 1.358 + 1.359 + /** 1.360 + * Return the resolution at which we expect to render aFrame's contents, 1.361 + * assuming they are being painted to retained layers. This takes into account 1.362 + * the resolution the contents of the ContainerLayer containing aFrame are 1.363 + * being rendered at, as well as any currently-inactive transforms between 1.364 + * aFrame and that container layer. 1.365 + */ 1.366 + static gfxSize GetThebesLayerScaleForFrame(nsIFrame* aFrame); 1.367 + 1.368 + /** 1.369 + * Stores a Layer as the dedicated layer in the DisplayItemData for a given frame/key pair. 1.370 + * 1.371 + * Used when we optimize a ThebesLayer into an ImageLayer and want to retroactively update the 1.372 + * DisplayItemData so we can retrieve the layer from within layout. 1.373 + */ 1.374 + void StoreOptimizedLayerForFrame(nsDisplayItem* aItem, Layer* aLayer); 1.375 + 1.376 + NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(LayerManagerDataProperty, 1.377 + RemoveFrameFromLayerManager) 1.378 + 1.379 + /** 1.380 + * Retained data storage: 1.381 + * 1.382 + * Each layer manager (widget, and inactive) stores a LayerManagerData object 1.383 + * that keeps a hash-set of DisplayItemData items that were drawn into it. 1.384 + * Each frame also keeps a list of DisplayItemData pointers that were 1.385 + * created for that frame. DisplayItemData objects manage these lists automatically. 1.386 + * 1.387 + * During layer construction we update the data in the LayerManagerData object, marking 1.388 + * items that are modified. At the end we sweep the LayerManagerData hash-set and remove 1.389 + * all items that haven't been modified. 1.390 + */ 1.391 + 1.392 + /** 1.393 + * Retained data for a display item. 1.394 + */ 1.395 + class DisplayItemData MOZ_FINAL { 1.396 + public: 1.397 + friend class FrameLayerBuilder; 1.398 + 1.399 + uint32_t GetDisplayItemKey() { return mDisplayItemKey; } 1.400 + Layer* GetLayer() { return mLayer; } 1.401 + void Invalidate() { mIsInvalid = true; } 1.402 + 1.403 + private: 1.404 + DisplayItemData(LayerManagerData* aParent, uint32_t aKey, Layer* aLayer, LayerState aLayerState, uint32_t aGeneration); 1.405 + DisplayItemData(DisplayItemData &toCopy); 1.406 + 1.407 + /** 1.408 + * Removes any references to this object from frames 1.409 + * in mFrameList. 1.410 + */ 1.411 + ~DisplayItemData(); 1.412 + 1.413 + NS_INLINE_DECL_REFCOUNTING(DisplayItemData) 1.414 + 1.415 + 1.416 + /** 1.417 + * Associates this DisplayItemData with a frame, and adds it 1.418 + * to the LayerManagerDataProperty list on the frame. 1.419 + */ 1.420 + void AddFrame(nsIFrame* aFrame); 1.421 + void RemoveFrame(nsIFrame* aFrame); 1.422 + void GetFrameListChanges(nsDisplayItem* aOther, nsTArray<nsIFrame*>& aOut); 1.423 + 1.424 + /** 1.425 + * Updates the contents of this item to a new set of data, instead of allocating a new 1.426 + * object. 1.427 + * Set the passed in parameters, and clears the opt layer, inactive manager, geometry 1.428 + * and clip. 1.429 + * Parent, frame list and display item key are assumed to be the same. 1.430 + */ 1.431 + void UpdateContents(Layer* aLayer, LayerState aState, 1.432 + uint32_t aContainerLayerGeneration, nsDisplayItem* aItem = nullptr); 1.433 + 1.434 + LayerManagerData* mParent; 1.435 + nsRefPtr<Layer> mLayer; 1.436 + nsRefPtr<Layer> mOptLayer; 1.437 + nsRefPtr<BasicLayerManager> mInactiveManager; 1.438 + nsAutoTArray<nsIFrame*, 1> mFrameList; 1.439 + nsAutoPtr<nsDisplayItemGeometry> mGeometry; 1.440 + DisplayItemClip mClip; 1.441 + uint32_t mDisplayItemKey; 1.442 + uint32_t mContainerLayerGeneration; 1.443 + LayerState mLayerState; 1.444 + 1.445 + /** 1.446 + * Used to track if data currently stored in mFramesWithLayers (from an existing 1.447 + * paint) has been updated in the current paint. 1.448 + */ 1.449 + bool mUsed; 1.450 + bool mIsInvalid; 1.451 + }; 1.452 + 1.453 +protected: 1.454 + 1.455 + friend class LayerManagerData; 1.456 + 1.457 + static void RemoveFrameFromLayerManager(nsIFrame* aFrame, void* aPropertyValue); 1.458 + 1.459 + /** 1.460 + * Given a frame and a display item key that uniquely identifies a 1.461 + * display item for the frame, find the layer that was last used to 1.462 + * render that display item. Returns null if there is no such layer. 1.463 + * This could be a dedicated layer for the display item, or a ThebesLayer 1.464 + * that renders many display items. 1.465 + */ 1.466 + DisplayItemData* GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey); 1.467 + 1.468 + /** 1.469 + * Stores DisplayItemData associated with aFrame, stores the data in 1.470 + * mNewDisplayItemData. 1.471 + */ 1.472 + DisplayItemData* StoreDataForFrame(nsDisplayItem* aItem, Layer* aLayer, LayerState aState); 1.473 + void StoreDataForFrame(nsIFrame* aFrame, 1.474 + uint32_t aDisplayItemKey, 1.475 + Layer* aLayer, 1.476 + LayerState aState); 1.477 + 1.478 + // Flash the area within the context clip if paint flashing is enabled. 1.479 + static void FlashPaint(gfxContext *aContext); 1.480 + 1.481 + /* 1.482 + * Get the DisplayItemData array associated with this frame, or null if one 1.483 + * doesn't exist. 1.484 + * 1.485 + * Note that the pointer returned here is only valid so long as you don't 1.486 + * poke the LayerManagerData's mFramesWithLayers hashtable. 1.487 + */ 1.488 + DisplayItemData* GetDisplayItemData(nsIFrame *aFrame, uint32_t aKey); 1.489 + 1.490 + /* 1.491 + * Get the DisplayItemData associated with this frame / display item pair, 1.492 + * using the LayerManager instead of FrameLayerBuilder. 1.493 + */ 1.494 + static DisplayItemData* GetDisplayItemDataForManager(nsIFrame* aFrame, 1.495 + uint32_t aDisplayItemKey, 1.496 + LayerManager* aManager); 1.497 + static DisplayItemData* GetDisplayItemDataForManager(nsIFrame* aFrame, 1.498 + uint32_t aDisplayItemKey); 1.499 + static DisplayItemData* GetDisplayItemDataForManager(nsDisplayItem* aItem, LayerManager* aManager); 1.500 + static DisplayItemData* GetDisplayItemDataForManager(nsIFrame* aFrame, 1.501 + uint32_t aDisplayItemKey, 1.502 + LayerManagerData* aData); 1.503 + 1.504 + static PLDHashOperator DumpDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry, 1.505 + void* aClosure); 1.506 + /** 1.507 + * We store one of these for each display item associated with a 1.508 + * ThebesLayer, in a hashtable that maps each ThebesLayer to an array 1.509 + * of ClippedDisplayItems. (ThebesLayerItemsEntry is the hash entry 1.510 + * for that hashtable.) 1.511 + * These are only stored during the paint process, so that the 1.512 + * DrawThebesLayer callback can figure out which items to draw for the 1.513 + * ThebesLayer. 1.514 + */ 1.515 + struct ClippedDisplayItem { 1.516 + ClippedDisplayItem(nsDisplayItem* aItem, uint32_t aGeneration) 1.517 + : mItem(aItem), mContainerLayerGeneration(aGeneration) 1.518 + { 1.519 + } 1.520 + 1.521 + ~ClippedDisplayItem(); 1.522 + 1.523 + nsDisplayItem* mItem; 1.524 + 1.525 + /** 1.526 + * If the display item is being rendered as an inactive 1.527 + * layer, then this stores the layer manager being 1.528 + * used for the inactive transaction. 1.529 + */ 1.530 + nsRefPtr<LayerManager> mInactiveLayerManager; 1.531 + 1.532 + uint32_t mContainerLayerGeneration; 1.533 + }; 1.534 + 1.535 + static void RecomputeVisibilityForItems(nsTArray<ClippedDisplayItem>& aItems, 1.536 + nsDisplayListBuilder* aBuilder, 1.537 + const nsIntRegion& aRegionToDraw, 1.538 + const nsIntPoint& aOffset, 1.539 + int32_t aAppUnitsPerDevPixel, 1.540 + float aXScale, 1.541 + float aYScale); 1.542 + 1.543 + void PaintItems(nsTArray<ClippedDisplayItem>& aItems, 1.544 + const nsIntRect& aRect, 1.545 + gfxContext* aContext, 1.546 + nsRenderingContext* aRC, 1.547 + nsDisplayListBuilder* aBuilder, 1.548 + nsPresContext* aPresContext, 1.549 + const nsIntPoint& aOffset, 1.550 + float aXScale, float aYScale, 1.551 + int32_t aCommonClipCount); 1.552 + 1.553 + /** 1.554 + * We accumulate ClippedDisplayItem elements in a hashtable during 1.555 + * the paint process. This is the hashentry for that hashtable. 1.556 + */ 1.557 +public: 1.558 + class ThebesLayerItemsEntry : public nsPtrHashKey<ThebesLayer> { 1.559 + public: 1.560 + ThebesLayerItemsEntry(const ThebesLayer *key) : 1.561 + nsPtrHashKey<ThebesLayer>(key), mContainerLayerFrame(nullptr), 1.562 + mContainerLayerGeneration(0), 1.563 + mHasExplicitLastPaintOffset(false), mCommonClipCount(0) {} 1.564 + ThebesLayerItemsEntry(const ThebesLayerItemsEntry &toCopy) : 1.565 + nsPtrHashKey<ThebesLayer>(toCopy.mKey), mItems(toCopy.mItems) 1.566 + { 1.567 + NS_ERROR("Should never be called, since we ALLOW_MEMMOVE"); 1.568 + } 1.569 + 1.570 + nsTArray<ClippedDisplayItem> mItems; 1.571 + nsIFrame* mContainerLayerFrame; 1.572 + // The translation set on this ThebesLayer before we started updating the 1.573 + // layer tree. 1.574 + nsIntPoint mLastPaintOffset; 1.575 + uint32_t mContainerLayerGeneration; 1.576 + bool mHasExplicitLastPaintOffset; 1.577 + /** 1.578 + * The first mCommonClipCount rounded rectangle clips are identical for 1.579 + * all items in the layer. Computed in ThebesLayerData. 1.580 + */ 1.581 + uint32_t mCommonClipCount; 1.582 + 1.583 + enum { ALLOW_MEMMOVE = true }; 1.584 + }; 1.585 + 1.586 + /** 1.587 + * Get the ThebesLayerItemsEntry object associated with aLayer in this 1.588 + * FrameLayerBuilder 1.589 + */ 1.590 + ThebesLayerItemsEntry* GetThebesLayerItemsEntry(ThebesLayer* aLayer) 1.591 + { 1.592 + return mThebesLayerItems.GetEntry(aLayer); 1.593 + } 1.594 + 1.595 + ThebesLayerData* GetContainingThebesLayerData() 1.596 + { 1.597 + return mContainingThebesLayer; 1.598 + } 1.599 + 1.600 + /** 1.601 + * Attempt to build the most compressed layer tree possible, even if it means 1.602 + * throwing away existing retained buffers. 1.603 + */ 1.604 + void SetLayerTreeCompressionMode() { mInLayerTreeCompressionMode = true; } 1.605 + bool CheckInLayerTreeCompressionMode(); 1.606 + 1.607 +protected: 1.608 + void RemoveThebesItemsAndOwnerDataForLayerSubtree(Layer* aLayer, 1.609 + bool aRemoveThebesItems, 1.610 + bool aRemoveOwnerData); 1.611 + 1.612 + static PLDHashOperator ProcessRemovedDisplayItems(nsRefPtrHashKey<DisplayItemData>* aEntry, 1.613 + void* aUserArg); 1.614 + static PLDHashOperator RestoreDisplayItemData(nsRefPtrHashKey<DisplayItemData>* aEntry, 1.615 + void *aUserArg); 1.616 + 1.617 + static PLDHashOperator RestoreThebesLayerItemEntries(ThebesLayerItemsEntry* aEntry, 1.618 + void *aUserArg); 1.619 + 1.620 + /** 1.621 + * Returns true if the DOM has been modified since we started painting, 1.622 + * in which case we should bail out and not paint anymore. This should 1.623 + * never happen, but plugins can trigger it in some cases. 1.624 + */ 1.625 + bool CheckDOMModified(); 1.626 + 1.627 + /** 1.628 + * The layer manager belonging to the widget that is being retained 1.629 + * across paints. 1.630 + */ 1.631 + LayerManager* mRetainingManager; 1.632 + /** 1.633 + * The root prescontext for the display list builder reference frame 1.634 + */ 1.635 + nsRefPtr<nsRootPresContext> mRootPresContext; 1.636 + 1.637 + /** 1.638 + * The display list builder being used. 1.639 + */ 1.640 + nsDisplayListBuilder* mDisplayListBuilder; 1.641 + /** 1.642 + * A map from ThebesLayers to the list of display items (plus 1.643 + * clipping data) to be rendered in the layer. 1.644 + */ 1.645 + nsTHashtable<ThebesLayerItemsEntry> mThebesLayerItems; 1.646 + 1.647 + /** 1.648 + * When building layers for an inactive layer, this is where the 1.649 + * inactive layer will be placed. 1.650 + */ 1.651 + ThebesLayerData* mContainingThebesLayer; 1.652 + 1.653 + /** 1.654 + * Saved generation counter so we can detect DOM changes. 1.655 + */ 1.656 + uint32_t mInitialDOMGeneration; 1.657 + /** 1.658 + * Set to true if we have detected and reported DOM modification during 1.659 + * the current paint. 1.660 + */ 1.661 + bool mDetectedDOMModification; 1.662 + /** 1.663 + * Indicates that the entire layer tree should be rerendered 1.664 + * during this paint. 1.665 + */ 1.666 + bool mInvalidateAllLayers; 1.667 + 1.668 + bool mInLayerTreeCompressionMode; 1.669 + 1.670 + uint32_t mContainerLayerGeneration; 1.671 + uint32_t mMaxContainerLayerGeneration; 1.672 +}; 1.673 + 1.674 +} 1.675 + 1.676 +#endif /* FRAMELAYERBUILDER_H_ */