layout/base/FrameLayerBuilder.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial