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 GFX_LAYERS_H 8 #define GFX_LAYERS_H 9 10 #include <cstdint> // for uint32_t, uint64_t, int32_t, uint8_t 11 #include <cstring> // for memcpy, size_t 12 #include <iosfwd> // for stringstream 13 #include <new> // for operator new 14 #include <unordered_set> // for unordered_set 15 #include <utility> // for forward, move 16 #include "FrameMetrics.h" // for ScrollMetadata, FrameMetrics::ViewID, FrameMetrics 17 #include "Units.h" // for LayerIntRegion, ParentLayerIntRect, LayerIntSize, Lay... 18 #include "gfxPoint.h" // for gfxPoint 19 #include "gfxRect.h" // for gfxRect 20 #include "mozilla/Maybe.h" // for Maybe, Nothing (ptr only) 21 #include "mozilla/Poison.h" // for CorruptionCanary 22 #include "mozilla/RefPtr.h" // for RefPtr, operator!= 23 #include "mozilla/TimeStamp.h" // for TimeStamp 24 #include "mozilla/UniquePtr.h" // for UniquePtr, MakeUnique 25 #include "mozilla/gfx/BasePoint.h" // for BasePoint<>::(anonymous union)::(anonymous), BasePoin... 26 #include "mozilla/gfx/BaseSize.h" // for BaseSize 27 #include "mozilla/gfx/Matrix.h" // for Matrix4x4, Matrix, Matrix4x4Typed 28 #include "mozilla/gfx/Point.h" // for Point, PointTyped 29 #include "mozilla/gfx/Polygon.h" // for Polygon 30 #include "mozilla/gfx/Rect.h" // for IntRectTyped, IntRect 31 #include "mozilla/gfx/TiledRegion.h" // for TiledIntRegion 32 #include "mozilla/gfx/Types.h" // for CompositionOp, DeviceColor, SamplingFilter, SideBits 33 #include "mozilla/gfx/UserData.h" // for UserData, UserDataKey (ptr only) 34 #include "mozilla/layers/AnimationInfo.h" // for AnimationInfo 35 #include "mozilla/layers/LayerAttributes.h" // for SimpleLayerAttributes, ScrollbarData (ptr only) 36 #include "mozilla/layers/LayerManager.h" // for LayerManager, LayerManager::PaintedLayerCreationHint 37 #include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid, ScrollableLayerGuid::ViewID 38 #include "mozilla/layers/BSPTree.h" 39 #include "nsISupports.h" // for NS_INLINE_DECL_REFCOUNTING 40 #include "nsPoint.h" // for nsIntPoint 41 #include "nsRect.h" // for nsIntRect 42 #include "nsRegion.h" // for nsIntRegion 43 #include "nsStringFlags.h" // for operator& 44 #include "nsStringFwd.h" // for nsCString, nsACString 45 #include "nsTArray.h" // for nsTArray, nsTArray_Impl, nsTArray_Impl<>::elem_type 46 47 // XXX These includes could be avoided by moving function implementations to the 48 // cpp file 49 #include "gfx2DGlue.h" // for ThebesPoint 50 #include "mozilla/Assertions.h" // for AssertionConditionType, MOZ_ASSERT, MOZ_A... 51 #include "mozilla/DebugOnly.h" // for DebugOnly 52 #include "mozilla/layers/CanvasRenderer.h" // for CanvasRenderer 53 #include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG_IF_SHADOWABLE, LayersId, EventRegionsO... 54 #include "nsDebug.h" // for NS_ASSERTION, NS_WARNING 55 56 namespace mozilla { 57 58 namespace gfx { 59 class DataSourceSurface; 60 class DrawTarget; 61 class Path; 62 } // namespace gfx 63 64 namespace layers { 65 66 class Animation; 67 class AsyncPanZoomController; 68 class HostLayerManager; 69 class PaintedLayer; 70 class ContainerLayer; 71 class ImageLayer; 72 class ColorLayer; 73 class CompositorAnimations; 74 class CanvasLayer; 75 class RefLayer; 76 class HostLayer; 77 class ShadowableLayer; 78 class SpecificLayerAttributes; 79 class Compositor; 80 class TransformData; 81 struct PropertyAnimationGroup; 82 83 namespace layerscope { 84 class LayersPacket; 85 } // namespace layerscope 86 87 #define MOZ_LAYER_DECL_NAME(n, e) \ 88 const char* Name() const override { return n; } \ 89 LayerType GetType() const override { return e; } \ 90 static LayerType Type() { return e; } 91 92 /* 93 * Motivation: For truly smooth animation and video playback, we need to 94 * be able to compose frames and render them on a dedicated thread (i.e. 95 * off the main thread where DOM manipulation, script execution and layout 96 * induce difficult-to-bound latency). This requires Gecko to construct 97 * some kind of persistent scene structure (graph or tree) that can be 98 * safely transmitted across threads. We have other scenarios (e.g. mobile 99 * browsing) where retaining some rendered data between paints is desired 100 * for performance, so again we need a retained scene structure. 101 * 102 * Our retained scene structure is a layer tree. Each layer represents 103 * content which can be composited onto a destination surface; the root 104 * layer is usually composited into a window, and non-root layers are 105 * composited into their parent layers. Layers have attributes (e.g. 106 * opacity and clipping) that influence their compositing. 107 * 108 * We want to support a variety of layer implementations, including 109 * a simple "immediate mode" implementation that doesn't retain any 110 * rendered data between paints (i.e. uses cairo in just the way that 111 * Gecko used it before layers were introduced). But we also don't want 112 * to have bifurcated "layers"/"non-layers" rendering paths in Gecko. 113 * Therefore the layers API is carefully designed to permit maximally 114 * efficient implementation in an "immediate mode" style. See the 115 * BasicLayerManager for such an implementation. 116 */ 117 118 /** 119 * A Layer represents anything that can be rendered onto a destination 120 * surface. 121 */ 122 class Layer { 123 NS_INLINE_DECL_REFCOUNTING(Layer) 124 125 using AnimationArray = nsTArray<layers::Animation>; 126 127 public: 128 // Keep these in alphabetical order 129 enum LayerType { 130 TYPE_CANVAS, 131 TYPE_COLOR, 132 TYPE_CONTAINER, 133 TYPE_DISPLAYITEM, 134 TYPE_IMAGE, 135 TYPE_READBACK, 136 TYPE_REF, 137 TYPE_SHADOW, 138 TYPE_PAINTED 139 }; 140 141 /** 142 * Returns the LayerManager this Layer belongs to. Note that the layer 143 * manager might be in a destroyed state, at which point it's only 144 * valid to set/get user data from it. 145 */ Manager()146 LayerManager* Manager() { return mManager; } 147 148 /** 149 * This should only be called when changing layer managers from HostLayers. 150 */ 151 void SetManager(LayerManager* aManager, HostLayer* aSelf); 152 153 enum { 154 /** 155 * If this is set, the caller is promising that by the end of this 156 * transaction the entire visible region (as specified by 157 * SetVisibleRegion) will be filled with opaque content. 158 */ 159 CONTENT_OPAQUE = 0x01, 160 /** 161 * If this is set, the caller is notifying that the contents of this layer 162 * require per-component alpha for optimal fidelity. However, there is no 163 * guarantee that component alpha will be supported for this layer at 164 * paint time. 165 * This should never be set at the same time as CONTENT_OPAQUE. 166 */ 167 CONTENT_COMPONENT_ALPHA = 0x02, 168 169 /** 170 * If this is set then one of the descendant layers of this one has 171 * CONTENT_COMPONENT_ALPHA set. 172 */ 173 CONTENT_COMPONENT_ALPHA_DESCENDANT = 0x04, 174 175 /** 176 * If this is set then this layer is part of a preserve-3d group, and should 177 * be sorted with sibling layers that are also part of the same group. 178 */ 179 CONTENT_EXTEND_3D_CONTEXT = 0x08, 180 /** 181 * This indicates that the transform may be changed on during an empty 182 * transaction where there is no possibility of redrawing the content, so 183 * the implementation should be ready for that. 184 */ 185 CONTENT_MAY_CHANGE_TRANSFORM = 0x10, 186 187 /** 188 * Disable subpixel AA for this layer. This is used if the display isn't 189 * suited for subpixel AA like hidpi or rotated content. 190 */ 191 CONTENT_DISABLE_SUBPIXEL_AA = 0x20, 192 193 /** 194 * If this is set then the layer contains content that may look 195 * objectionable if not handled as an active layer (such as text with an 196 * animated transform). This is for internal layout/FrameLayerBuilder usage 197 * only until flattening code is obsoleted. See bug 633097 198 */ 199 CONTENT_DISABLE_FLATTENING = 0x40, 200 201 /** 202 * This layer is hidden if the backface of the layer is visible 203 * to user. 204 */ 205 CONTENT_BACKFACE_HIDDEN = 0x80, 206 207 /** 208 * This layer should be snapped to the pixel grid. 209 */ 210 CONTENT_SNAP_TO_GRID = 0x100 211 }; 212 /** 213 * CONSTRUCTION PHASE ONLY 214 * This lets layout make some promises about what will be drawn into the 215 * visible region of the PaintedLayer. This enables internal quality 216 * and performance optimizations. 217 */ SetContentFlags(uint32_t aFlags)218 void SetContentFlags(uint32_t aFlags) { 219 NS_ASSERTION((aFlags & (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA)) != 220 (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA), 221 "Can't be opaque and require component alpha"); 222 if (mSimpleAttrs.SetContentFlags(aFlags)) { 223 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, 224 ("Layer::Mutated(%p) ContentFlags", this)); 225 MutatedSimple(); 226 } 227 } 228 229 /** 230 * CONSTRUCTION PHASE ONLY 231 * Tell this layer which region will be visible. The visible region 232 * is a region which contains all the contents of the layer that can 233 * actually affect the rendering of the window. It can exclude areas 234 * that are covered by opaque contents of other layers, and it can 235 * exclude areas where this layer simply contains no content at all. 236 * (This can be an overapproximation to the "true" visible region.) 237 * 238 * There is no general guarantee that drawing outside the bounds of the 239 * visible region will be ignored. So if a layer draws outside the bounds 240 * of its visible region, it needs to ensure that what it draws is valid. 241 */ SetVisibleRegion(const LayerIntRegion & aRegion)242 virtual void SetVisibleRegion(const LayerIntRegion& aRegion) { 243 // IsEmpty is required otherwise we get invalidation glitches. 244 // See bug 1288464 for investigating why. 245 if (!mVisibleRegion.IsEqual(aRegion) || aRegion.IsEmpty()) { 246 MOZ_LAYERS_LOG_IF_SHADOWABLE( 247 this, ("Layer::Mutated(%p) VisibleRegion was %s is %s", this, 248 mVisibleRegion.ToString().get(), aRegion.ToString().get())); 249 mVisibleRegion = aRegion; 250 Mutated(); 251 } 252 } 253 254 /** 255 * CONSTRUCTION PHASE ONLY 256 * Set the (sub)document metrics used to render the Layer subtree 257 * rooted at this. Note that a layer may have multiple FrameMetrics 258 * objects; calling this function will remove all of them and replace 259 * them with the provided FrameMetrics. See the documentation for 260 * SetFrameMetrics(const nsTArray<FrameMetrics>&) for more details. 261 */ SetScrollMetadata(const ScrollMetadata & aScrollMetadata)262 void SetScrollMetadata(const ScrollMetadata& aScrollMetadata) { 263 Manager()->ClearPendingScrollInfoUpdate(); 264 if (mScrollMetadata.Length() != 1 || 265 mScrollMetadata[0] != aScrollMetadata) { 266 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, 267 ("Layer::Mutated(%p) ScrollMetadata", this)); 268 mScrollMetadata.ReplaceElementsAt(0, mScrollMetadata.Length(), 269 aScrollMetadata); 270 ScrollMetadataChanged(); 271 Mutated(); 272 } 273 } 274 275 /** 276 * CONSTRUCTION PHASE ONLY 277 * Set the (sub)document metrics used to render the Layer subtree 278 * rooted at this. There might be multiple metrics on this layer 279 * because the layer may, for example, be contained inside multiple 280 * nested scrolling subdocuments. In general a Layer having multiple 281 * ScrollMetadata objects is conceptually equivalent to having a stack 282 * of ContainerLayers that have been flattened into this Layer. 283 * See the documentation in LayerMetricsWrapper.h for a more detailed 284 * explanation of this conceptual equivalence. 285 * 286 * Note also that there is actually a many-to-many relationship between 287 * Layers and ScrollMetadata, because multiple Layers may have identical 288 * ScrollMetadata objects. This happens when those layers belong to the 289 * same scrolling subdocument and therefore end up with the same async 290 * transform when they are scrolled by the APZ code. 291 */ SetScrollMetadata(const nsTArray<ScrollMetadata> & aMetadataArray)292 void SetScrollMetadata(const nsTArray<ScrollMetadata>& aMetadataArray) { 293 Manager()->ClearPendingScrollInfoUpdate(); 294 if (mScrollMetadata != aMetadataArray) { 295 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, 296 ("Layer::Mutated(%p) ScrollMetadata", this)); 297 mScrollMetadata = aMetadataArray.Clone(); 298 ScrollMetadataChanged(); 299 Mutated(); 300 } 301 } 302 303 /* 304 * Compositor event handling 305 * ========================= 306 * When a touch-start event (or similar) is sent to the 307 * AsyncPanZoomController, it needs to decide whether the event should be sent 308 * to the main thread. Each layer has a list of event handling regions. When 309 * the compositor needs to determine how to handle a touch event, it scans the 310 * layer tree from top to bottom in z-order (traversing children before their 311 * parents). Points outside the clip region for a layer cause that layer (and 312 * its subtree) to be ignored. If a layer has a mask layer, and that mask 313 * layer's alpha value is zero at the event point, then the layer and its 314 * subtree should be ignored. For each layer, if the point is outside its hit 315 * region, we ignore the layer and move onto the next. If the point is inside 316 * its hit region but outside the dispatch-to-content region, we can initiate 317 * a gesture without consulting the content thread. Otherwise we must dispatch 318 * the event to content. Note that if a layer or any ancestor layer has a 319 * ForceEmptyHitRegion override in GetEventRegionsOverride() then the 320 * hit-region must be treated as empty. Similarly, if there is a 321 * ForceDispatchToContent override then the dispatch-to-content region must be 322 * treated as encompassing the entire hit region, and therefore we must 323 * consult the content thread before initiating a gesture. (If both flags are 324 * set, ForceEmptyHitRegion takes priority.) 325 */ 326 /** 327 * CONSTRUCTION PHASE ONLY 328 * Set the event handling region. 329 */ 330 void SetEventRegions(const EventRegions& aRegions); 331 332 /** 333 * CONSTRUCTION PHASE ONLY 334 * Set the opacity which will be applied to this layer as it 335 * is composited to the destination. 336 */ SetOpacity(float aOpacity)337 void SetOpacity(float aOpacity) { 338 if (mSimpleAttrs.SetOpacity(aOpacity)) { 339 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Opacity", this)); 340 MutatedSimple(); 341 } 342 } 343 SetMixBlendMode(gfx::CompositionOp aMixBlendMode)344 void SetMixBlendMode(gfx::CompositionOp aMixBlendMode) { 345 if (mSimpleAttrs.SetMixBlendMode(aMixBlendMode)) { 346 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, 347 ("Layer::Mutated(%p) MixBlendMode", this)); 348 MutatedSimple(); 349 } 350 } 351 SetForceIsolatedGroup(bool aForceIsolatedGroup)352 void SetForceIsolatedGroup(bool aForceIsolatedGroup) { 353 if (mSimpleAttrs.SetForceIsolatedGroup(aForceIsolatedGroup)) { 354 MOZ_LAYERS_LOG_IF_SHADOWABLE( 355 this, ("Layer::Mutated(%p) ForceIsolatedGroup", this)); 356 MutatedSimple(); 357 } 358 } 359 GetForceIsolatedGroup()360 bool GetForceIsolatedGroup() const { 361 return mSimpleAttrs.GetForceIsolatedGroup(); 362 } 363 364 /** 365 * CONSTRUCTION PHASE ONLY 366 * Set a clip rect which will be applied to this layer as it is 367 * composited to the destination. The coordinates are relative to 368 * the parent layer (i.e. the contents of this layer 369 * are transformed before this clip rect is applied). 370 * For the root layer, the coordinates are relative to the widget, 371 * in device pixels. 372 * If aRect is null no clipping will be performed. 373 */ SetClipRect(const Maybe<ParentLayerIntRect> & aRect)374 void SetClipRect(const Maybe<ParentLayerIntRect>& aRect) { 375 if (mClipRect) { 376 if (!aRect) { 377 MOZ_LAYERS_LOG_IF_SHADOWABLE( 378 this, ("Layer::Mutated(%p) ClipRect was %d,%d,%d,%d is <none>", 379 this, mClipRect->X(), mClipRect->Y(), mClipRect->Width(), 380 mClipRect->Height())); 381 mClipRect.reset(); 382 Mutated(); 383 } else { 384 if (!aRect->IsEqualEdges(*mClipRect)) { 385 MOZ_LAYERS_LOG_IF_SHADOWABLE( 386 this, 387 ("Layer::Mutated(%p) ClipRect was %d,%d,%d,%d is %d,%d,%d,%d", 388 this, mClipRect->X(), mClipRect->Y(), mClipRect->Width(), 389 mClipRect->Height(), aRect->X(), aRect->Y(), aRect->Width(), 390 aRect->Height())); 391 mClipRect = aRect; 392 Mutated(); 393 } 394 } 395 } else { 396 if (aRect) { 397 MOZ_LAYERS_LOG_IF_SHADOWABLE( 398 this, 399 ("Layer::Mutated(%p) ClipRect was <none> is %d,%d,%d,%d", this, 400 aRect->X(), aRect->Y(), aRect->Width(), aRect->Height())); 401 mClipRect = aRect; 402 Mutated(); 403 } 404 } 405 } 406 407 /** 408 * CONSTRUCTION PHASE ONLY 409 * Set an optional scrolled clip on the layer. 410 * The scrolled clip, if present, consists of a clip rect and an optional 411 * mask. This scrolled clip is always scrolled by all scroll frames associated 412 * with this layer. (By contrast, the scroll clips stored in ScrollMetadata 413 * are only scrolled by scroll frames above that ScrollMetadata, and the 414 * layer's mClipRect is always fixed to the layer contents (which may or may 415 * not be scrolled by some of the scroll frames associated with the layer, 416 * depending on whether the layer is fixed).) 417 */ SetScrolledClip(const Maybe<LayerClip> & aScrolledClip)418 void SetScrolledClip(const Maybe<LayerClip>& aScrolledClip) { 419 if (mSimpleAttrs.SetScrolledClip(aScrolledClip)) { 420 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, 421 ("Layer::Mutated(%p) ScrolledClip", this)); 422 MutatedSimple(); 423 } 424 } 425 426 /** 427 * CONSTRUCTION PHASE ONLY 428 * Set a layer to mask this layer. 429 * 430 * The mask layer should be applied using its effective transform (after it 431 * is calculated by ComputeEffectiveTransformForMaskLayer), this should use 432 * this layer's parent's transform and the mask layer's transform, but not 433 * this layer's. That is, the mask layer is specified relative to this layer's 434 * position in it's parent layer's coord space. 435 * Currently, only 2D translations are supported for the mask layer transform. 436 * 437 * Ownership of aMaskLayer passes to this. 438 * Typical use would be an ImageLayer with an alpha image used for masking. 439 * See also ContainerState::BuildMaskLayer in FrameLayerBuilder.cpp. 440 */ SetMaskLayer(Layer * aMaskLayer)441 void SetMaskLayer(Layer* aMaskLayer) { 442 #ifdef DEBUG 443 if (aMaskLayer) { 444 bool maskIs2D = aMaskLayer->GetTransform().CanDraw2D(); 445 NS_ASSERTION(maskIs2D, "Mask layer has invalid transform."); 446 } 447 #endif 448 449 if (mMaskLayer != aMaskLayer) { 450 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, 451 ("Layer::Mutated(%p) MaskLayer", this)); 452 mMaskLayer = aMaskLayer; 453 Mutated(); 454 } 455 } 456 457 /** 458 * CONSTRUCTION PHASE ONLY 459 * Add mask layers associated with LayerClips. 460 */ SetAncestorMaskLayers(const nsTArray<RefPtr<Layer>> & aLayers)461 void SetAncestorMaskLayers(const nsTArray<RefPtr<Layer>>& aLayers) { 462 if (aLayers != mAncestorMaskLayers) { 463 MOZ_LAYERS_LOG_IF_SHADOWABLE( 464 this, ("Layer::Mutated(%p) AncestorMaskLayers", this)); 465 mAncestorMaskLayers = aLayers.Clone(); 466 Mutated(); 467 } 468 } 469 470 /** 471 * CONSTRUCTION PHASE ONLY 472 * Add a mask layer associated with a LayerClip. 473 */ AddAncestorMaskLayer(const RefPtr<Layer> & aLayer)474 void AddAncestorMaskLayer(const RefPtr<Layer>& aLayer) { 475 mAncestorMaskLayers.AppendElement(aLayer); 476 Mutated(); 477 } 478 479 /** 480 * CONSTRUCTION PHASE ONLY 481 * Tell this layer what its transform should be. The transformation 482 * is applied when compositing the layer into its parent container. 483 */ SetBaseTransform(const gfx::Matrix4x4 & aMatrix)484 void SetBaseTransform(const gfx::Matrix4x4& aMatrix) { 485 NS_ASSERTION(!aMatrix.IsSingular(), 486 "Shouldn't be trying to draw with a singular matrix!"); 487 mPendingTransform = nullptr; 488 if (!mSimpleAttrs.SetTransform(aMatrix)) { 489 return; 490 } 491 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, 492 ("Layer::Mutated(%p) BaseTransform", this)); 493 MutatedSimple(); 494 } 495 496 /** 497 * Can be called at any time. 498 * 499 * Like SetBaseTransform(), but can be called before the next 500 * transform (i.e. outside an open transaction). Semantically, this 501 * method enqueues a new transform value to be set immediately after 502 * the next transaction is opened. 503 */ SetBaseTransformForNextTransaction(const gfx::Matrix4x4 & aMatrix)504 void SetBaseTransformForNextTransaction(const gfx::Matrix4x4& aMatrix) { 505 mPendingTransform = mozilla::MakeUnique<gfx::Matrix4x4>(aMatrix); 506 } 507 SetPostScale(float aXScale,float aYScale)508 void SetPostScale(float aXScale, float aYScale) { 509 if (!mSimpleAttrs.SetPostScale(aXScale, aYScale)) { 510 return; 511 } 512 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PostScale", this)); 513 MutatedSimple(); 514 } 515 516 /** 517 * CONSTRUCTION PHASE ONLY 518 * A layer is "fixed position" when it draws content from a content 519 * (not chrome) document, the topmost content document has a root scrollframe 520 * with a displayport, but the layer does not move when that displayport 521 * scrolls. 522 */ SetIsFixedPosition(bool aFixedPosition)523 void SetIsFixedPosition(bool aFixedPosition) { 524 if (mSimpleAttrs.SetIsFixedPosition(aFixedPosition)) { 525 MOZ_LAYERS_LOG_IF_SHADOWABLE( 526 this, ("Layer::Mutated(%p) IsFixedPosition", this)); 527 MutatedSimple(); 528 } 529 } 530 SetAsyncZoomContainerId(const Maybe<FrameMetrics::ViewID> & aViewId)531 void SetAsyncZoomContainerId(const Maybe<FrameMetrics::ViewID>& aViewId) { 532 if (mSimpleAttrs.SetAsyncZoomContainerId(aViewId)) { 533 MOZ_LAYERS_LOG_IF_SHADOWABLE( 534 this, ("Layer::Mutated(%p) AsyncZoomContainerId", this)); 535 MutatedSimple(); 536 } 537 } 538 539 /** 540 * CONSTRUCTION PHASE ONLY 541 * This flag is true when the transform on the layer is a perspective 542 * transform. The compositor treats perspective transforms specially 543 * for async scrolling purposes. 544 */ SetTransformIsPerspective(bool aTransformIsPerspective)545 void SetTransformIsPerspective(bool aTransformIsPerspective) { 546 if (mSimpleAttrs.SetTransformIsPerspective(aTransformIsPerspective)) { 547 MOZ_LAYERS_LOG_IF_SHADOWABLE( 548 this, ("Layer::Mutated(%p) TransformIsPerspective", this)); 549 MutatedSimple(); 550 } 551 } 552 // This is only called when the layer tree is updated. Do not call this from 553 // layout code. To add an animation to this layer, use AddAnimation. 554 void SetCompositorAnimations( 555 const LayersId& aLayersId, 556 const CompositorAnimations& aCompositorAnimations); 557 // Go through all animations in this layer and its children and, for 558 // any animations with a null start time, update their start time such 559 // that at |aReadyTime| the animation's current time corresponds to its 560 // 'initial current time' value. 561 void StartPendingAnimations(const TimeStamp& aReadyTime); 562 563 void ClearCompositorAnimations(); 564 565 /** 566 * CONSTRUCTION PHASE ONLY 567 * If a layer represents a fixed position element, this data is stored on the 568 * layer for use by the compositor. 569 * 570 * - |aScrollId| identifies the scroll frame that this element is fixed 571 * with respect to. 572 * 573 * - |aAnchor| is the point on the layer that is considered the "anchor" 574 * point, that is, the point which remains in the same position when 575 * compositing the layer tree with a transformation (such as when 576 * asynchronously scrolling and zooming). 577 * 578 * - |aSides| is the set of sides to which the element is fixed relative to. 579 * This is used if the viewport size is changed in the compositor and 580 * fixed position items need to shift accordingly. This value is made up 581 * combining appropriate values from mozilla::SideBits. 582 */ SetFixedPositionData(ScrollableLayerGuid::ViewID aScrollId,const LayerPoint & aAnchor,SideBits aSides)583 void SetFixedPositionData(ScrollableLayerGuid::ViewID aScrollId, 584 const LayerPoint& aAnchor, SideBits aSides) { 585 if (mSimpleAttrs.SetFixedPositionData(aScrollId, aAnchor, aSides)) { 586 MOZ_LAYERS_LOG_IF_SHADOWABLE( 587 this, ("Layer::Mutated(%p) FixedPositionData", this)); 588 MutatedSimple(); 589 } 590 } 591 592 /** 593 * CONSTRUCTION PHASE ONLY 594 * If a layer is "sticky position", |aScrollId| holds the scroll identifier 595 * of the scrollable content that contains it. The difference between the two 596 * rectangles |aOuter| and |aInner| is treated as two intervals in each 597 * dimension, with the current scroll position at the origin. For each 598 * dimension, while that component of the scroll position lies within either 599 * interval, the layer should not move relative to its scrolling container. 600 */ SetStickyPositionData(ScrollableLayerGuid::ViewID aScrollId,LayerRectAbsolute aOuter,LayerRectAbsolute aInner)601 void SetStickyPositionData(ScrollableLayerGuid::ViewID aScrollId, 602 LayerRectAbsolute aOuter, 603 LayerRectAbsolute aInner) { 604 if (mSimpleAttrs.SetStickyPositionData(aScrollId, aOuter, aInner)) { 605 MOZ_LAYERS_LOG_IF_SHADOWABLE( 606 this, ("Layer::Mutated(%p) StickyPositionData", this)); 607 MutatedSimple(); 608 } 609 } 610 611 /** 612 * CONSTRUCTION PHASE ONLY 613 * If a layer is a scroll thumb container layer or a scrollbar container 614 * layer, set the scroll identifier of the scroll frame scrolled by 615 * the scrollbar, and other data related to the scrollbar. 616 */ SetScrollbarData(const ScrollbarData & aThumbData)617 void SetScrollbarData(const ScrollbarData& aThumbData) { 618 if (mSimpleAttrs.SetScrollbarData(aThumbData)) { 619 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, 620 ("Layer::Mutated(%p) ScrollbarData", this)); 621 MutatedSimple(); 622 } 623 } 624 625 // Used when forwarding transactions. Do not use at any other time. SetSimpleAttributes(const SimpleLayerAttributes & aAttrs)626 void SetSimpleAttributes(const SimpleLayerAttributes& aAttrs) { 627 mSimpleAttrs = aAttrs; 628 } GetSimpleAttributes()629 const SimpleLayerAttributes& GetSimpleAttributes() const { 630 return mSimpleAttrs; 631 } 632 633 // These getters can be used anytime. GetOpacity()634 float GetOpacity() { return mSimpleAttrs.GetOpacity(); } GetMixBlendMode()635 gfx::CompositionOp GetMixBlendMode() const { 636 return mSimpleAttrs.GetMixBlendMode(); 637 } GetClipRect()638 const Maybe<ParentLayerIntRect>& GetClipRect() const { return mClipRect; } GetScrolledClip()639 const Maybe<LayerClip>& GetScrolledClip() const { 640 return mSimpleAttrs.GetScrolledClip(); 641 } 642 Maybe<ParentLayerIntRect> GetScrolledClipRect() const; GetContentFlags()643 uint32_t GetContentFlags() { return mSimpleAttrs.GetContentFlags(); } GetVisibleRegion()644 const LayerIntRegion& GetVisibleRegion() const { return mVisibleRegion; } 645 const ScrollMetadata& GetScrollMetadata(uint32_t aIndex) const; 646 const FrameMetrics& GetFrameMetrics(uint32_t aIndex) const; GetScrollMetadataCount()647 uint32_t GetScrollMetadataCount() const { return mScrollMetadata.Length(); } GetAllScrollMetadata()648 const nsTArray<ScrollMetadata>& GetAllScrollMetadata() { 649 return mScrollMetadata; 650 } 651 bool HasScrollableFrameMetrics() const; 652 bool IsScrollableWithoutContent() const; GetEventRegions()653 const EventRegions& GetEventRegions() const { return mEventRegions; } GetParent()654 ContainerLayer* GetParent() const { return mParent; } GetNextSibling()655 Layer* GetNextSibling() { 656 if (mNextSibling) { 657 mNextSibling->CheckCanary(); 658 } 659 return mNextSibling; 660 } GetNextSibling()661 const Layer* GetNextSibling() const { 662 if (mNextSibling) { 663 mNextSibling->CheckCanary(); 664 } 665 return mNextSibling; 666 } GetPrevSibling()667 Layer* GetPrevSibling() { return mPrevSibling; } GetPrevSibling()668 const Layer* GetPrevSibling() const { return mPrevSibling; } GetFirstChild()669 virtual Layer* GetFirstChild() const { return nullptr; } GetLastChild()670 virtual Layer* GetLastChild() const { return nullptr; } 671 gfx::Matrix4x4 GetTransform() const; 672 // Same as GetTransform(), but returns the transform as a strongly-typed 673 // matrix. Eventually this will replace GetTransform(). 674 const CSSTransformMatrix GetTransformTyped() const; GetBaseTransform()675 const gfx::Matrix4x4& GetBaseTransform() const { 676 return mSimpleAttrs.GetTransform(); 677 } 678 // Note: these are virtual because ContainerLayerComposite overrides them. GetPostXScale()679 virtual float GetPostXScale() const { return mSimpleAttrs.GetPostXScale(); } GetPostYScale()680 virtual float GetPostYScale() const { return mSimpleAttrs.GetPostYScale(); } GetIsFixedPosition()681 bool GetIsFixedPosition() { return mSimpleAttrs.IsFixedPosition(); } GetAsyncZoomContainerId()682 Maybe<FrameMetrics::ViewID> GetAsyncZoomContainerId() { 683 return mSimpleAttrs.GetAsyncZoomContainerId(); 684 } GetTransformIsPerspective()685 bool GetTransformIsPerspective() const { 686 return mSimpleAttrs.GetTransformIsPerspective(); 687 } GetIsStickyPosition()688 bool GetIsStickyPosition() { return mSimpleAttrs.IsStickyPosition(); } GetFixedPositionScrollContainerId()689 ScrollableLayerGuid::ViewID GetFixedPositionScrollContainerId() { 690 return mSimpleAttrs.GetFixedPositionScrollContainerId(); 691 } GetFixedPositionAnchor()692 LayerPoint GetFixedPositionAnchor() { 693 return mSimpleAttrs.GetFixedPositionAnchor(); 694 } GetFixedPositionSides()695 SideBits GetFixedPositionSides() { 696 return mSimpleAttrs.GetFixedPositionSides(); 697 } GetStickyScrollContainerId()698 ScrollableLayerGuid::ViewID GetStickyScrollContainerId() { 699 return mSimpleAttrs.GetStickyScrollContainerId(); 700 } GetStickyScrollRangeOuter()701 const LayerRectAbsolute& GetStickyScrollRangeOuter() { 702 return mSimpleAttrs.GetStickyScrollRangeOuter(); 703 } GetStickyScrollRangeInner()704 const LayerRectAbsolute& GetStickyScrollRangeInner() { 705 return mSimpleAttrs.GetStickyScrollRangeInner(); 706 } GetScrollbarData()707 const ScrollbarData& GetScrollbarData() const { 708 return mSimpleAttrs.GetScrollbarData(); 709 } 710 bool IsScrollbarContainer() const; GetMaskLayer()711 Layer* GetMaskLayer() const { return mMaskLayer; } HasPendingTransform()712 bool HasPendingTransform() const { return !!mPendingTransform; } 713 CheckCanary()714 void CheckCanary() const { mCanary.Check(); } 715 716 // Ancestor mask layers are associated with FrameMetrics, but for simplicity 717 // in maintaining the layer tree structure we attach them to the layer. GetAncestorMaskLayerCount()718 size_t GetAncestorMaskLayerCount() const { 719 return mAncestorMaskLayers.Length(); 720 } GetAncestorMaskLayerAt(size_t aIndex)721 Layer* GetAncestorMaskLayerAt(size_t aIndex) const { 722 return mAncestorMaskLayers.ElementAt(aIndex); 723 } GetAllAncestorMaskLayers()724 const nsTArray<RefPtr<Layer>>& GetAllAncestorMaskLayers() const { 725 return mAncestorMaskLayers; 726 } 727 HasMaskLayers()728 bool HasMaskLayers() const { 729 return GetMaskLayer() || mAncestorMaskLayers.Length() > 0; 730 } 731 732 /* 733 * Get the combined clip rect of the Layer clip and all clips on FrameMetrics. 734 * This is intended for use in Layout. The compositor needs to apply async 735 * transforms to find the combined clip. 736 */ 737 Maybe<ParentLayerIntRect> GetCombinedClipRect() const; 738 739 /** 740 * Retrieve the root level visible region for |this| taking into account 741 * clipping applied to parent layers of |this| as well as subtracting 742 * visible regions of higher siblings of this layer and each ancestor. 743 * 744 * Note translation values for offsets of visible regions and accumulated 745 * aLayerOffset are integer rounded using IntPoint::Round. 746 * 747 * @param aResult - the resulting visible region of this layer. 748 * @param aLayerOffset - this layer's total offset from the root layer. 749 * @return - false if during layer tree traversal a parent or sibling 750 * transform is found to be non-translational. This method returns early 751 * in this case, results will not be valid. Returns true on successful 752 * traversal. 753 */ 754 bool GetVisibleRegionRelativeToRootLayer(nsIntRegion& aResult, 755 nsIntPoint* aLayerOffset); 756 757 // Note that all lengths in animation data are either in CSS pixels or app 758 // units and must be converted to device pixels by the compositor. 759 // Besides, this should only be called on the compositor thread. GetAnimations()760 AnimationArray& GetAnimations() { return mAnimationInfo.GetAnimations(); } GetCompositorAnimationsId()761 uint64_t GetCompositorAnimationsId() { 762 return mAnimationInfo.GetCompositorAnimationsId(); 763 } GetPropertyAnimationGroups()764 nsTArray<PropertyAnimationGroup>& GetPropertyAnimationGroups() { 765 return mAnimationInfo.GetPropertyAnimationGroups(); 766 } GetTransformData()767 const Maybe<TransformData>& GetTransformData() const { 768 return mAnimationInfo.GetTransformData(); 769 } GetAnimationLayersId()770 const LayersId& GetAnimationLayersId() const { 771 return mAnimationInfo.GetLayersId(); 772 } 773 GetAnimationGeneration()774 Maybe<uint64_t> GetAnimationGeneration() const { 775 return mAnimationInfo.GetAnimationGeneration(); 776 } 777 CachedMotionPath()778 gfx::Path* CachedMotionPath() { return mAnimationInfo.CachedMotionPath(); } 779 780 bool HasTransformAnimation() const; 781 782 /** 783 * Returns the local transform for this layer: either mTransform or, 784 * for shadow layers, GetShadowBaseTransform(), in either case with the 785 * pre- and post-scales applied. 786 */ 787 gfx::Matrix4x4 GetLocalTransform(); 788 789 /** 790 * Same as GetLocalTransform(), but returns a strongly-typed matrix. 791 * Eventually, this will replace GetLocalTransform(). 792 */ 793 const LayerToParentLayerMatrix4x4 GetLocalTransformTyped(); 794 795 /** 796 * Returns the local opacity for this layer: either mOpacity or, 797 * for shadow layers, GetShadowOpacity() 798 */ 799 float GetLocalOpacity(); 800 801 /** 802 * DRAWING PHASE ONLY 803 * 804 * Apply pending changes to layers before drawing them, if those 805 * pending changes haven't been overridden by later changes. 806 * 807 * Returns a list of scroll ids which had pending updates. 808 */ 809 std::unordered_set<ScrollableLayerGuid::ViewID> 810 ApplyPendingUpdatesToSubtree(); 811 812 /** 813 * DRAWING PHASE ONLY 814 * 815 * Write layer-subtype-specific attributes into aAttrs. Used to 816 * synchronize layer attributes to their shadows'. 817 */ FillSpecificAttributes(SpecificLayerAttributes & aAttrs)818 virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) {} 819 820 // Returns true if it's OK to save the contents of aLayer in an 821 // opaque surface (a surface without an alpha channel). 822 // If we can use a surface without an alpha channel, we should, because 823 // it will often make painting of antialiased text faster and higher 824 // quality. 825 bool CanUseOpaqueSurface(); 826 GetSurfaceMode()827 SurfaceMode GetSurfaceMode() { 828 if (CanUseOpaqueSurface()) return SurfaceMode::SURFACE_OPAQUE; 829 if (GetContentFlags() & CONTENT_COMPONENT_ALPHA) 830 return SurfaceMode::SURFACE_COMPONENT_ALPHA; 831 return SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA; 832 } 833 834 // Returns true if this layer can be treated as opaque for visibility 835 // computation. A layer may be non-opaque for visibility even if it 836 // is not transparent, for example, if it has a mix-blend-mode. 837 bool IsOpaqueForVisibility(); 838 839 /** 840 * This setter can be used anytime. The user data for all keys is 841 * initially null. Ownership pases to the layer manager. 842 */ 843 void SetUserData( 844 void* aKey, LayerUserData* aData, 845 void (*aDestroy)(void*) = LayerManager::LayerUserDataDestroy) { 846 mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, aDestroy); 847 } 848 /** 849 * This can be used anytime. Ownership passes to the caller! 850 */ 851 UniquePtr<LayerUserData> RemoveUserData(void* aKey); 852 /** 853 * This getter can be used anytime. 854 */ HasUserData(void * aKey)855 bool HasUserData(void* aKey) { 856 return mUserData.Has(static_cast<gfx::UserDataKey*>(aKey)); 857 } 858 /** 859 * This getter can be used anytime. Ownership is retained by the layer 860 * manager. 861 */ GetUserData(void * aKey)862 LayerUserData* GetUserData(void* aKey) const { 863 return static_cast<LayerUserData*>( 864 mUserData.Get(static_cast<gfx::UserDataKey*>(aKey))); 865 } 866 867 /** 868 * |Disconnect()| is used by layers hooked up over IPC. It may be 869 * called at any time, and may not be called at all. Using an 870 * IPC-enabled layer after Destroy() (drawing etc.) results in a 871 * safe no-op; no crashy or uaf etc. 872 * 873 * XXX: this interface is essentially LayerManager::Destroy, but at 874 * Layer granularity. It might be beneficial to unify them. 875 */ Disconnect()876 virtual void Disconnect() {} 877 878 /** 879 * Dynamic downcast to a PaintedLayer. Returns null if this is not 880 * a PaintedLayer. 881 */ AsPaintedLayer()882 virtual PaintedLayer* AsPaintedLayer() { return nullptr; } 883 884 /** 885 * Dynamic cast to a ContainerLayer. Returns null if this is not 886 * a ContainerLayer. 887 */ AsContainerLayer()888 virtual ContainerLayer* AsContainerLayer() { return nullptr; } AsContainerLayer()889 virtual const ContainerLayer* AsContainerLayer() const { return nullptr; } 890 891 /** 892 * Dynamic cast to a RefLayer. Returns null if this is not a 893 * RefLayer. 894 */ AsRefLayer()895 virtual RefLayer* AsRefLayer() { return nullptr; } 896 897 /** 898 * Dynamic cast to a Color. Returns null if this is not a 899 * ColorLayer. 900 */ AsColorLayer()901 virtual ColorLayer* AsColorLayer() { return nullptr; } 902 903 /** 904 * Dynamic cast to a Canvas. Returns null if this is not a 905 * ColorLayer. 906 */ AsCanvasLayer()907 virtual CanvasLayer* AsCanvasLayer() { return nullptr; } 908 909 /** 910 * Dynamic cast to an Image. Returns null if this is not a 911 * ColorLayer. 912 */ AsImageLayer()913 virtual ImageLayer* AsImageLayer() { return nullptr; } 914 915 /** 916 * Dynamic cast to a LayerComposite. Return null if this is not a 917 * LayerComposite. Can be used anytime. 918 */ AsHostLayer()919 virtual HostLayer* AsHostLayer() { return nullptr; } 920 921 /** 922 * Dynamic cast to a ShadowableLayer. Return null if this is not a 923 * ShadowableLayer. Can be used anytime. 924 */ AsShadowableLayer()925 virtual ShadowableLayer* AsShadowableLayer() { return nullptr; } 926 927 // These getters can be used anytime. They return the effective 928 // values that should be used when drawing this layer to screen, 929 // accounting for this layer possibly being a shadow. 930 const Maybe<ParentLayerIntRect>& GetLocalClipRect(); 931 const LayerIntRegion& GetLocalVisibleRegion(); 932 Extend3DContext()933 bool Extend3DContext() { 934 return GetContentFlags() & CONTENT_EXTEND_3D_CONTEXT; 935 } Combines3DTransformWithAncestors()936 bool Combines3DTransformWithAncestors() { 937 return GetParent() && 938 reinterpret_cast<Layer*>(GetParent())->Extend3DContext(); 939 } Is3DContextLeaf()940 bool Is3DContextLeaf() { 941 return !Extend3DContext() && Combines3DTransformWithAncestors(); 942 } 943 /** 944 * It is true if the user can see the back of the layer and the 945 * backface is hidden. The compositor should skip the layer if the 946 * result is true. 947 */ 948 bool IsBackfaceHidden(); IsVisible()949 bool IsVisible() { 950 // For containers extending 3D context, visible region 951 // is meaningless, since they are just intermediate result of 952 // content. 953 return !GetLocalVisibleRegion().IsEmpty() || Extend3DContext(); 954 } 955 956 /** 957 * Return true if current layer content is opaque. 958 * It does not guarantee that layer content is always opaque. 959 */ IsOpaque()960 virtual bool IsOpaque() { return GetContentFlags() & CONTENT_OPAQUE; } 961 962 /** 963 * Returns the product of the opacities of this layer and all ancestors up 964 * to and excluding the nearest ancestor that has UseIntermediateSurface() 965 * set. 966 */ 967 float GetEffectiveOpacity(); 968 969 /** 970 * Returns the blendmode of this layer. 971 */ 972 gfx::CompositionOp GetEffectiveMixBlendMode(); 973 974 /** 975 * This returns the effective transform computed by 976 * ComputeEffectiveTransforms. Typically this is a transform that transforms 977 * this layer all the way to some intermediate surface or destination 978 * surface. For non-BasicLayers this will be a transform to the nearest 979 * ancestor with UseIntermediateSurface() (or to the root, if there is no 980 * such ancestor), but for BasicLayers it's different. 981 */ GetEffectiveTransform()982 const gfx::Matrix4x4& GetEffectiveTransform() const { 983 return mEffectiveTransform; 984 } 985 986 /** 987 * This returns the effective transform for Layer's buffer computed by 988 * ComputeEffectiveTransforms. Typically this is a transform that transforms 989 * this layer's buffer all the way to some intermediate surface or destination 990 * surface. For non-BasicLayers this will be a transform to the nearest 991 * ancestor with UseIntermediateSurface() (or to the root, if there is no 992 * such ancestor), but for BasicLayers it's different. 993 * 994 * By default, its value is same to GetEffectiveTransform(). 995 * When ImageLayer is rendered with ScaleMode::STRETCH, 996 * it becomes different from GetEffectiveTransform(). 997 */ GetEffectiveTransformForBuffer()998 virtual const gfx::Matrix4x4& GetEffectiveTransformForBuffer() const { 999 return mEffectiveTransform; 1000 } 1001 1002 /** 1003 * If the current layers participates in a preserve-3d 1004 * context (returns true for Combines3DTransformWithAncestors), 1005 * returns the combined transform up to the preserve-3d (nearest 1006 * ancestor that doesn't Extend3DContext()). Otherwise returns 1007 * the local transform. 1008 */ 1009 gfx::Matrix4x4 ComputeTransformToPreserve3DRoot(); 1010 1011 /** 1012 * @param aTransformToSurface the composition of the transforms 1013 * from the parent layer (if any) to the destination pixel grid. 1014 * 1015 * Computes mEffectiveTransform for this layer and all its descendants. 1016 * mEffectiveTransform transforms this layer up to the destination 1017 * pixel grid (whatever aTransformToSurface is relative to). 1018 * 1019 * We promise that when this is called on a layer, all ancestor layers 1020 * have already had ComputeEffectiveTransforms called. 1021 */ 1022 virtual void ComputeEffectiveTransforms( 1023 const gfx::Matrix4x4& aTransformToSurface) = 0; 1024 1025 /** 1026 * Computes the effective transform for mask layers, if this layer has any. 1027 */ 1028 void ComputeEffectiveTransformForMaskLayers( 1029 const gfx::Matrix4x4& aTransformToSurface); 1030 static void ComputeEffectiveTransformForMaskLayer( 1031 Layer* aMaskLayer, const gfx::Matrix4x4& aTransformToSurface); 1032 1033 /** 1034 * Calculate the scissor rect required when rendering this layer. 1035 * Returns a rectangle relative to the intermediate surface belonging to the 1036 * nearest ancestor that has an intermediate surface, or relative to the root 1037 * viewport if no ancestor has an intermediate surface, corresponding to the 1038 * clip rect for this layer intersected with aCurrentScissorRect. 1039 */ 1040 RenderTargetIntRect CalculateScissorRect( 1041 const RenderTargetIntRect& aCurrentScissorRect); 1042 1043 virtual const char* Name() const = 0; 1044 virtual LayerType GetType() const = 0; 1045 1046 /** 1047 * Only the implementation should call this. This is per-implementation 1048 * private data. Normally, all layers with a given layer manager 1049 * use the same type of ImplData. 1050 */ ImplData()1051 void* ImplData() { return mImplData; } 1052 1053 /** 1054 * Only the implementation should use these methods. 1055 */ SetParent(ContainerLayer * aParent)1056 void SetParent(ContainerLayer* aParent) { mParent = aParent; } SetNextSibling(Layer * aSibling)1057 void SetNextSibling(Layer* aSibling) { mNextSibling = aSibling; } SetPrevSibling(Layer * aSibling)1058 void SetPrevSibling(Layer* aSibling) { mPrevSibling = aSibling; } 1059 1060 /** 1061 * Dump information about this layer manager and its managed tree to 1062 * aStream. 1063 */ 1064 void Dump(std::stringstream& aStream, const char* aPrefix = "", 1065 bool aDumpHtml = false, bool aSorted = false, 1066 const Maybe<gfx::Polygon>& aGeometry = Nothing()); 1067 /** 1068 * Dump information about just this layer manager itself to aStream. 1069 */ 1070 void DumpSelf(std::stringstream& aStream, const char* aPrefix = "", 1071 const Maybe<gfx::Polygon>& aGeometry = Nothing()); 1072 1073 /** 1074 * Dump information about this layer and its child & sibling layers to 1075 * layerscope packet. 1076 */ 1077 void Dump(layerscope::LayersPacket* aPacket, const void* aParent); 1078 1079 /** 1080 * Log information about this layer manager and its managed tree to 1081 * the NSPR log (if enabled for "Layers"). 1082 */ 1083 void Log(const char* aPrefix = ""); 1084 /** 1085 * Log information about just this layer manager itself to the NSPR 1086 * log (if enabled for "Layers"). 1087 */ 1088 void LogSelf(const char* aPrefix = ""); 1089 1090 // Print interesting information about this into aStream. Internally 1091 // used to implement Dump*() and Log*(). If subclasses have 1092 // additional interesting properties, they should override this with 1093 // an implementation that first calls the base implementation then 1094 // appends additional info to aTo. 1095 virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix); 1096 1097 // Just like PrintInfo, but this function dump information into layerscope 1098 // packet, instead of a StringStream. It is also internally used to implement 1099 // Dump(); 1100 virtual void DumpPacket(layerscope::LayersPacket* aPacket, 1101 const void* aParent); 1102 1103 /** 1104 * Store display list log. 1105 */ 1106 void SetDisplayListLog(const char* log); 1107 1108 /** 1109 * Return display list log. 1110 */ 1111 void GetDisplayListLog(nsCString& log); 1112 IsLogEnabled()1113 static bool IsLogEnabled() { return LayerManager::IsLogEnabled(); } 1114 1115 /** 1116 * Returns the current area of the layer (in layer-space coordinates) 1117 * marked as needed to be recomposited. 1118 */ GetInvalidRegion()1119 const virtual gfx::TiledIntRegion& GetInvalidRegion() { 1120 return mInvalidRegion; 1121 } AddInvalidRegion(const nsIntRegion & aRegion)1122 void AddInvalidRegion(const nsIntRegion& aRegion) { 1123 mInvalidRegion.Add(aRegion); 1124 } 1125 1126 /** 1127 * Mark the entirety of the layer's visible region as being invalid. 1128 */ SetInvalidRectToVisibleRegion()1129 void SetInvalidRectToVisibleRegion() { 1130 mInvalidRegion.SetEmpty(); 1131 mInvalidRegion.Add(GetVisibleRegion().ToUnknownRegion()); 1132 } 1133 1134 /** 1135 * Adds to the current invalid rect. 1136 */ AddInvalidRect(const gfx::IntRect & aRect)1137 void AddInvalidRect(const gfx::IntRect& aRect) { mInvalidRegion.Add(aRect); } 1138 1139 /** 1140 * Clear the invalid rect, marking the layer as being identical to what is 1141 * currently composited. 1142 */ ClearInvalidRegion()1143 virtual void ClearInvalidRegion() { mInvalidRegion.SetEmpty(); } 1144 1145 // These functions allow attaching an AsyncPanZoomController to this layer, 1146 // and can be used anytime. 1147 // A layer has an APZC at index aIndex only-if 1148 // GetFrameMetrics(aIndex).IsScrollable(); attempting to get an APZC for a 1149 // non-scrollable metrics will return null. The reverse is also generally true 1150 // (that if GetFrameMetrics(aIndex).IsScrollable() is true, then the layer 1151 // will have an APZC). However, it only holds on the the compositor-side layer 1152 // tree, and only after the APZ code has had a chance to rebuild its internal 1153 // hit-testing tree using the layer tree. Also, it may not hold in certain 1154 // "exceptional" scenarios such as if the layer tree doesn't have a 1155 // GeckoContentController registered for it, or if there is a malicious 1156 // content process trying to trip up the compositor over IPC. The aIndex for 1157 // these functions must be less than GetScrollMetadataCount(). 1158 void SetAsyncPanZoomController(uint32_t aIndex, 1159 AsyncPanZoomController* controller); 1160 AsyncPanZoomController* GetAsyncPanZoomController(uint32_t aIndex) const; 1161 // The ScrollMetadataChanged function is used internally to ensure the APZC 1162 // array length matches the frame metrics array length. 1163 ClearCachedResources()1164 virtual void ClearCachedResources() {} 1165 SupportsAsyncUpdate()1166 virtual bool SupportsAsyncUpdate() { return false; } 1167 1168 private: 1169 void ScrollMetadataChanged(); 1170 1171 public: 1172 void ApplyPendingUpdatesForThisTransaction(); 1173 1174 #ifdef DEBUG SetDebugColorIndex(uint32_t aIndex)1175 void SetDebugColorIndex(uint32_t aIndex) { mDebugColorIndex = aIndex; } GetDebugColorIndex()1176 uint32_t GetDebugColorIndex() { return mDebugColorIndex; } 1177 #endif 1178 Mutated()1179 void Mutated() { mManager->Mutated(this); } MutatedSimple()1180 void MutatedSimple() { mManager->MutatedSimple(this); } 1181 GetMaxLayerSize()1182 virtual int32_t GetMaxLayerSize() { return Manager()->GetMaxTextureSize(); } 1183 1184 /** 1185 * Returns true if this layer's effective transform is not just 1186 * a translation by integers, or if this layer or some ancestor layer 1187 * is marked as having a transform that may change without a full layer 1188 * transaction. 1189 * 1190 * Note: This function ignores ancestor layers across layer tree boundaries 1191 * so that it returns a consistent value when compositing and when painting. 1192 */ 1193 bool MayResample(); 1194 1195 RenderTargetRect TransformRectToRenderTarget(const LayerIntRect& aRect); 1196 1197 /** 1198 * Add debugging information to the layer dump. 1199 */ AddExtraDumpInfo(const nsACString & aStr)1200 void AddExtraDumpInfo(const nsACString& aStr) { 1201 #ifdef MOZ_DUMP_PAINTING 1202 mExtraDumpInfo.AppendElement(aStr); 1203 #endif 1204 } 1205 1206 /** 1207 * Clear debugging information. Useful for recycling. 1208 */ ClearExtraDumpInfo()1209 void ClearExtraDumpInfo() { 1210 #ifdef MOZ_DUMP_PAINTING 1211 mExtraDumpInfo.Clear(); 1212 #endif 1213 } 1214 GetAnimationInfo()1215 AnimationInfo& GetAnimationInfo() { return mAnimationInfo; } 1216 1217 protected: 1218 Layer(LayerManager* aManager, void* aImplData); 1219 1220 // Protected destructor, to discourage deletion outside of Release(): 1221 virtual ~Layer(); 1222 1223 /** 1224 * We can snap layer transforms for two reasons: 1225 * 1) To avoid unnecessary resampling when a transform is a translation 1226 * by a non-integer number of pixels. 1227 * Snapping the translation to an integer number of pixels avoids 1228 * blurring the layer and can be faster to composite. 1229 * 2) When a layer is used to render a rectangular object, we need to 1230 * emulate the rendering of rectangular inactive content and snap the 1231 * edges of the rectangle to pixel boundaries. This is both to ensure 1232 * layer rendering is consistent with inactive content rendering, and to 1233 * avoid seams. 1234 * This function implements type 1 snapping. If aTransform is a 2D 1235 * translation, and this layer's layer manager has enabled snapping 1236 * (which is the default), return aTransform with the translation snapped 1237 * to nearest pixels. Otherwise just return aTransform. Call this when the 1238 * layer does not correspond to a single rectangular content object. 1239 * This function does not try to snap if aTransform has a scale, because in 1240 * that case resampling is inevitable and there's no point in trying to 1241 * avoid it. In fact snapping can cause problems because pixel edges in the 1242 * layer's content can be rendered unpredictably (jiggling) as the scale 1243 * interacts with the snapping of the translation, especially with animated 1244 * transforms. 1245 * @param aResidualTransform a transform to apply before the result transform 1246 * in order to get the results to completely match aTransform. 1247 */ 1248 gfx::Matrix4x4 SnapTransformTranslation(const gfx::Matrix4x4& aTransform, 1249 gfx::Matrix* aResidualTransform); 1250 gfx::Matrix4x4 SnapTransformTranslation3D(const gfx::Matrix4x4& aTransform, 1251 gfx::Matrix* aResidualTransform); 1252 /** 1253 * See comment for SnapTransformTranslation. 1254 * This function implements type 2 snapping. If aTransform is a translation 1255 * and/or scale, transform aSnapRect by aTransform, snap to pixel boundaries, 1256 * and return the transform that maps aSnapRect to that rect. Otherwise 1257 * just return aTransform. 1258 * @param aSnapRect a rectangle whose edges should be snapped to pixel 1259 * boundaries in the destination surface. 1260 * @param aResidualTransform a transform to apply before the result transform 1261 * in order to get the results to completely match aTransform. 1262 */ 1263 gfx::Matrix4x4 SnapTransform(const gfx::Matrix4x4& aTransform, 1264 const gfxRect& aSnapRect, 1265 gfx::Matrix* aResidualTransform); 1266 1267 LayerManager* mManager; 1268 ContainerLayer* mParent; 1269 Layer* mNextSibling; 1270 Layer* mPrevSibling; 1271 void* mImplData; 1272 RefPtr<Layer> mMaskLayer; 1273 nsTArray<RefPtr<Layer>> mAncestorMaskLayers; 1274 // Look for out-of-bound in the middle of the structure 1275 mozilla::CorruptionCanary mCanary; 1276 gfx::UserData mUserData; 1277 SimpleLayerAttributes mSimpleAttrs; 1278 LayerIntRegion mVisibleRegion; 1279 nsTArray<ScrollMetadata> mScrollMetadata; 1280 EventRegions mEventRegions; 1281 // A mutation of |mTransform| that we've queued to be applied at the 1282 // end of the next transaction (if nothing else overrides it in the 1283 // meantime). 1284 UniquePtr<gfx::Matrix4x4> mPendingTransform; 1285 gfx::Matrix4x4 mEffectiveTransform; 1286 AnimationInfo mAnimationInfo; 1287 Maybe<ParentLayerIntRect> mClipRect; 1288 gfx::IntRect mTileSourceRect; 1289 gfx::TiledIntRegion mInvalidRegion; 1290 nsTArray<RefPtr<AsyncPanZoomController>> mApzcs; 1291 bool mUseTileSourceRect; 1292 #ifdef DEBUG 1293 uint32_t mDebugColorIndex; 1294 #endif 1295 #ifdef MOZ_DUMP_PAINTING 1296 nsTArray<nsCString> mExtraDumpInfo; 1297 #endif 1298 // Store display list log. 1299 nsCString mDisplayListLog; 1300 }; 1301 1302 /** 1303 * A Layer which we can paint into. It is a conceptually 1304 * infinite surface, but each PaintedLayer has an associated "valid region" 1305 * of contents that it is currently storing, which is finite. PaintedLayer 1306 * implementations can store content between paints. 1307 * 1308 * PaintedLayers are rendered into during the drawing phase of a transaction. 1309 * 1310 * Currently the contents of a PaintedLayer are in the device output color 1311 * space. 1312 */ 1313 class PaintedLayer : public Layer { 1314 public: 1315 /** 1316 * CONSTRUCTION PHASE ONLY 1317 * Tell this layer that the content in some region has changed and 1318 * will need to be repainted. This area is removed from the valid 1319 * region. 1320 */ 1321 virtual void InvalidateRegion(const nsIntRegion& aRegion) = 0; 1322 /** 1323 * CONSTRUCTION PHASE ONLY 1324 * Set whether ComputeEffectiveTransforms should compute the 1325 * "residual translation" --- the translation that should be applied *before* 1326 * mEffectiveTransform to get the ideal transform for this PaintedLayer. 1327 * When this is true, ComputeEffectiveTransforms will compute the residual 1328 * and ensure that the layer is invalidated whenever the residual changes. 1329 * When it's false, a change in the residual will not trigger invalidation 1330 * and GetResidualTranslation will return 0,0. 1331 * So when the residual is to be ignored, set this to false for better 1332 * performance. 1333 */ SetAllowResidualTranslation(bool aAllow)1334 void SetAllowResidualTranslation(bool aAllow) { 1335 mAllowResidualTranslation = aAllow; 1336 } 1337 SetValidRegion(const nsIntRegion & aRegion)1338 void SetValidRegion(const nsIntRegion& aRegion) { 1339 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, 1340 ("Layer::Mutated(%p) ValidRegion", this)); 1341 mValidRegion = aRegion; 1342 mValidRegionIsCurrent = true; 1343 Mutated(); 1344 } 1345 1346 /** 1347 * Can be used anytime 1348 */ GetValidRegion()1349 const nsIntRegion& GetValidRegion() const { 1350 EnsureValidRegionIsCurrent(); 1351 return mValidRegion; 1352 } 1353 InvalidateWholeLayer()1354 void InvalidateWholeLayer() { 1355 mInvalidRegion.Add(GetValidRegion().GetBounds()); 1356 ClearValidRegion(); 1357 } 1358 ClearValidRegion()1359 void ClearValidRegion() { 1360 mValidRegion.SetEmpty(); 1361 mValidRegionIsCurrent = true; 1362 } AddToValidRegion(const nsIntRegion & aRegion)1363 void AddToValidRegion(const nsIntRegion& aRegion) { 1364 EnsureValidRegionIsCurrent(); 1365 mValidRegion.OrWith(aRegion); 1366 } SubtractFromValidRegion(const nsIntRegion & aRegion)1367 void SubtractFromValidRegion(const nsIntRegion& aRegion) { 1368 EnsureValidRegionIsCurrent(); 1369 mValidRegion.SubOut(aRegion); 1370 } UpdateValidRegionAfterInvalidRegionChanged()1371 void UpdateValidRegionAfterInvalidRegionChanged() { 1372 // Changes to mInvalidRegion will be applied to mValidRegion on the next 1373 // call to EnsureValidRegionIsCurrent(). 1374 mValidRegionIsCurrent = false; 1375 } 1376 ClearInvalidRegion()1377 void ClearInvalidRegion() override { 1378 // mInvalidRegion is about to be reset. This is the last chance to apply 1379 // any pending changes from it to mValidRegion. Do that by calling 1380 // EnsureValidRegionIsCurrent(). 1381 EnsureValidRegionIsCurrent(); 1382 mInvalidRegion.SetEmpty(); 1383 } 1384 AsPaintedLayer()1385 PaintedLayer* AsPaintedLayer() override { return this; } 1386 1387 MOZ_LAYER_DECL_NAME("PaintedLayer", TYPE_PAINTED) 1388 ComputeEffectiveTransforms(const gfx::Matrix4x4 & aTransformToSurface)1389 void ComputeEffectiveTransforms( 1390 const gfx::Matrix4x4& aTransformToSurface) override { 1391 gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface; 1392 gfx::Matrix residual; 1393 mEffectiveTransform = SnapTransformTranslation( 1394 idealTransform, mAllowResidualTranslation ? &residual : nullptr); 1395 // The residual can only be a translation because SnapTransformTranslation 1396 // only changes the transform if it's a translation 1397 NS_ASSERTION(residual.IsTranslation(), 1398 "Residual transform can only be a translation"); 1399 if (!gfx::ThebesPoint(residual.GetTranslation()) 1400 .WithinEpsilonOf(mResidualTranslation, 1e-3f)) { 1401 mResidualTranslation = gfx::ThebesPoint(residual.GetTranslation()); 1402 DebugOnly<mozilla::gfx::Point> transformedOrig = 1403 idealTransform.TransformPoint(mozilla::gfx::Point()); 1404 #ifdef DEBUG 1405 DebugOnly<mozilla::gfx::Point> transformed = 1406 idealTransform.TransformPoint(mozilla::gfx::Point( 1407 mResidualTranslation.x, mResidualTranslation.y)) - 1408 *&transformedOrig; 1409 #endif 1410 NS_ASSERTION(-0.5 <= (&transformed)->x && (&transformed)->x < 0.5 && 1411 -0.5 <= (&transformed)->y && (&transformed)->y < 0.5, 1412 "Residual translation out of range"); 1413 ClearValidRegion(); 1414 } 1415 ComputeEffectiveTransformForMaskLayers(aTransformToSurface); 1416 } 1417 GetCreationHint()1418 LayerManager::PaintedLayerCreationHint GetCreationHint() const { 1419 return mCreationHint; 1420 } 1421 UsedForReadback()1422 bool UsedForReadback() { return mUsedForReadback; } SetUsedForReadback(bool aUsed)1423 void SetUsedForReadback(bool aUsed) { mUsedForReadback = aUsed; } 1424 1425 /** 1426 * Returns true if aLayer is optimized for the given PaintedLayerCreationHint. 1427 */ IsOptimizedFor(LayerManager::PaintedLayerCreationHint aCreationHint)1428 virtual bool IsOptimizedFor( 1429 LayerManager::PaintedLayerCreationHint aCreationHint) { 1430 return true; 1431 } 1432 1433 /** 1434 * Returns the residual translation. Apply this translation when drawing 1435 * into the PaintedLayer so that when mEffectiveTransform is applied 1436 * afterwards by layer compositing, the results exactly match the "ideal 1437 * transform" (the product of the transform of this layer and its ancestors). 1438 * Returns 0,0 unless SetAllowResidualTranslation(true) has been called. 1439 * The residual translation components are always in the range [-0.5, 0.5). 1440 */ GetResidualTranslation()1441 gfxPoint GetResidualTranslation() const { return mResidualTranslation; } 1442 1443 protected: 1444 PaintedLayer( 1445 LayerManager* aManager, void* aImplData, 1446 LayerManager::PaintedLayerCreationHint aCreationHint = LayerManager::NONE) Layer(aManager,aImplData)1447 : Layer(aManager, aImplData), 1448 mValidRegion(), 1449 mValidRegionIsCurrent(true), 1450 mCreationHint(aCreationHint), 1451 mUsedForReadback(false), 1452 mAllowResidualTranslation(false) {} 1453 1454 void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; 1455 1456 void DumpPacket(layerscope::LayersPacket* aPacket, 1457 const void* aParent) override; 1458 1459 /** 1460 * ComputeEffectiveTransforms snaps the ideal transform to get 1461 * mEffectiveTransform. mResidualTranslation is the translation that should be 1462 * applied *before* mEffectiveTransform to get the ideal transform. 1463 */ 1464 gfxPoint mResidualTranslation; 1465 1466 private: 1467 /** 1468 * Needs to be called prior to accessing mValidRegion, unless mValidRegion is 1469 * being completely overwritten. 1470 */ EnsureValidRegionIsCurrent()1471 void EnsureValidRegionIsCurrent() const { 1472 if (!mValidRegionIsCurrent) { 1473 // Apply any pending mInvalidRegion changes to mValidRegion. 1474 if (!mValidRegion.IsEmpty()) { 1475 // Calling mInvalidRegion.GetRegion() is expensive. 1476 // That's why we delay the adjustment of mValidRegion for as long as 1477 // possible, so that multiple modifications to mInvalidRegion can be 1478 // applied to mValidRegion in one go. 1479 mValidRegion.SubOut(mInvalidRegion.GetRegion()); 1480 } 1481 mValidRegionIsCurrent = true; 1482 } 1483 } 1484 1485 /** 1486 * The layer's valid region. If mValidRegionIsCurrent is false, then 1487 * mValidRegion has not yet been updated for recent changes to 1488 * mInvalidRegion. Those pending changes can be applied by calling 1489 * EnsureValidRegionIsCurrent(). 1490 */ 1491 mutable nsIntRegion mValidRegion; 1492 1493 mutable bool mValidRegionIsCurrent; 1494 1495 protected: 1496 /** 1497 * The creation hint that was used when constructing this layer. 1498 */ 1499 const LayerManager::PaintedLayerCreationHint mCreationHint; 1500 /** 1501 * Set when this PaintedLayer is participating in readback, i.e. some 1502 * ReadbackLayer (may) be getting its background from this layer. 1503 */ 1504 bool mUsedForReadback; 1505 /** 1506 * True when 1507 */ 1508 bool mAllowResidualTranslation; 1509 }; 1510 1511 /** 1512 * A Layer which other layers render into. It holds references to its 1513 * children. 1514 */ 1515 class ContainerLayer : public Layer { 1516 public: 1517 virtual ~ContainerLayer(); 1518 1519 /** 1520 * CONSTRUCTION PHASE ONLY 1521 * Insert aChild into the child list of this container. aChild must 1522 * not be currently in any child list or the root for the layer manager. 1523 * If aAfter is non-null, it must be a child of this container and 1524 * we insert after that layer. If it's null we insert at the start. 1525 */ 1526 virtual bool InsertAfter(Layer* aChild, Layer* aAfter); 1527 /** 1528 * CONSTRUCTION PHASE ONLY 1529 * Remove aChild from the child list of this container. aChild must 1530 * be a child of this container. 1531 */ 1532 virtual bool RemoveChild(Layer* aChild); 1533 /** 1534 * CONSTRUCTION PHASE ONLY 1535 * Reposition aChild from the child list of this container. aChild must 1536 * be a child of this container. 1537 * If aAfter is non-null, it must be a child of this container and we 1538 * reposition after that layer. If it's null, we reposition at the start. 1539 */ 1540 virtual bool RepositionChild(Layer* aChild, Layer* aAfter); 1541 SetPreScale(float aXScale,float aYScale)1542 void SetPreScale(float aXScale, float aYScale) { 1543 if (mPreXScale == aXScale && mPreYScale == aYScale) { 1544 return; 1545 } 1546 1547 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PreScale", this)); 1548 mPreXScale = aXScale; 1549 mPreYScale = aYScale; 1550 Mutated(); 1551 } 1552 SetInheritedScale(float aXScale,float aYScale)1553 void SetInheritedScale(float aXScale, float aYScale) { 1554 if (mInheritedXScale == aXScale && mInheritedYScale == aYScale) { 1555 return; 1556 } 1557 1558 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, 1559 ("Layer::Mutated(%p) InheritedScale", this)); 1560 mInheritedXScale = aXScale; 1561 mInheritedYScale = aYScale; 1562 Mutated(); 1563 } 1564 SetScaleToResolution(float aResolution)1565 void SetScaleToResolution(float aResolution) { 1566 if (mPresShellResolution == aResolution) { 1567 return; 1568 } 1569 1570 MOZ_LAYERS_LOG_IF_SHADOWABLE( 1571 this, ("Layer::Mutated(%p) ScaleToResolution", this)); 1572 mPresShellResolution = aResolution; 1573 Mutated(); 1574 } 1575 1576 void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) override; 1577 1578 enum class SortMode { 1579 WITH_GEOMETRY, 1580 WITHOUT_GEOMETRY, 1581 }; 1582 1583 nsTArray<LayerPolygon> SortChildrenBy3DZOrder(SortMode aSortMode); 1584 AsContainerLayer()1585 ContainerLayer* AsContainerLayer() override { return this; } AsContainerLayer()1586 const ContainerLayer* AsContainerLayer() const override { return this; } 1587 1588 // These getters can be used anytime. GetFirstChild()1589 Layer* GetFirstChild() const override { return mFirstChild; } GetLastChild()1590 Layer* GetLastChild() const override { return mLastChild; } GetPreXScale()1591 float GetPreXScale() const { return mPreXScale; } GetPreYScale()1592 float GetPreYScale() const { return mPreYScale; } GetInheritedXScale()1593 float GetInheritedXScale() const { return mInheritedXScale; } GetInheritedYScale()1594 float GetInheritedYScale() const { return mInheritedYScale; } GetPresShellResolution()1595 float GetPresShellResolution() const { return mPresShellResolution; } 1596 1597 MOZ_LAYER_DECL_NAME("ContainerLayer", TYPE_CONTAINER) 1598 1599 /** 1600 * ContainerLayer backends need to override ComputeEffectiveTransforms 1601 * since the decision about whether to use a temporary surface for the 1602 * container is backend-specific. ComputeEffectiveTransforms must also set 1603 * mUseIntermediateSurface. 1604 */ 1605 void ComputeEffectiveTransforms( 1606 const gfx::Matrix4x4& aTransformToSurface) override = 0; 1607 1608 /** 1609 * Call this only after ComputeEffectiveTransforms has been invoked 1610 * on this layer. 1611 * Returns true if this will use an intermediate surface. This is largely 1612 * backend-dependent, but it affects the operation of GetEffectiveOpacity(). 1613 */ UseIntermediateSurface()1614 bool UseIntermediateSurface() { return mUseIntermediateSurface; } 1615 1616 /** 1617 * Returns the rectangle covered by the intermediate surface, 1618 * in this layer's coordinate system. 1619 * 1620 * NOTE: Since this layer has an intermediate surface it follows 1621 * that LayerPixel == RenderTargetPixel 1622 */ 1623 RenderTargetIntRect GetIntermediateSurfaceRect(); 1624 1625 /** 1626 * Returns true if this container has more than one non-empty child 1627 */ 1628 bool HasMultipleChildren(); 1629 1630 /** 1631 * Returns true if this container supports children with component alpha. 1632 * Should only be called while painting a child of this layer. 1633 */ SupportsComponentAlphaChildren()1634 bool SupportsComponentAlphaChildren() { 1635 return mSupportsComponentAlphaChildren; 1636 } 1637 1638 /** 1639 * Returns true if aLayer or any layer in its parent chain has the opaque 1640 * content flag set. 1641 */ 1642 static bool HasOpaqueAncestorLayer(Layer* aLayer); 1643 SetChildrenChanged(bool aVal)1644 void SetChildrenChanged(bool aVal) { mChildrenChanged = aVal; } 1645 1646 // If |aRect| is null, the entire layer should be considered invalid for 1647 // compositing. SetInvalidCompositeRect(const gfx::IntRect * aRect)1648 virtual void SetInvalidCompositeRect(const gfx::IntRect* aRect) {} 1649 1650 protected: 1651 friend class ReadbackProcessor; 1652 1653 // Note that this is not virtual, and is based on the implementation of 1654 // ContainerLayer::RemoveChild, so it should only be called where you would 1655 // want to explicitly call the base class implementation of RemoveChild; 1656 // e.g., while (mFirstChild) ContainerLayer::RemoveChild(mFirstChild); 1657 void RemoveAllChildren(); 1658 1659 void DidInsertChild(Layer* aLayer); 1660 void DidRemoveChild(Layer* aLayer); 1661 1662 bool AnyAncestorOrThisIs3DContextLeaf(); 1663 1664 void Collect3DContextLeaves(nsTArray<Layer*>& aToSort); 1665 1666 // Collects child layers that do not extend 3D context. For ContainerLayers 1667 // that do extend 3D context, the 3D context leaves are collected. CollectChildren()1668 nsTArray<Layer*> CollectChildren() { 1669 nsTArray<Layer*> children; 1670 1671 for (Layer* layer = GetFirstChild(); layer; 1672 layer = layer->GetNextSibling()) { 1673 ContainerLayer* container = layer->AsContainerLayer(); 1674 1675 if (container && container->Extend3DContext() && 1676 !container->UseIntermediateSurface()) { 1677 container->Collect3DContextLeaves(children); 1678 } else { 1679 children.AppendElement(layer); 1680 } 1681 } 1682 1683 return children; 1684 } 1685 1686 ContainerLayer(LayerManager* aManager, void* aImplData); 1687 1688 /** 1689 * A default implementation of ComputeEffectiveTransforms for use by OpenGL 1690 * and D3D. 1691 */ 1692 void DefaultComputeEffectiveTransforms( 1693 const gfx::Matrix4x4& aTransformToSurface); 1694 1695 /** 1696 * A default implementation to compute and set the value for 1697 * SupportsComponentAlphaChildren(). 1698 * 1699 * If aNeedsSurfaceCopy is provided, then it is set to true if the caller 1700 * needs to copy the background up into the intermediate surface created, 1701 * false otherwise. 1702 */ 1703 void DefaultComputeSupportsComponentAlphaChildren( 1704 bool* aNeedsSurfaceCopy = nullptr); 1705 1706 /** 1707 * Loops over the children calling ComputeEffectiveTransforms on them. 1708 */ 1709 void ComputeEffectiveTransformsForChildren( 1710 const gfx::Matrix4x4& aTransformToSurface); 1711 1712 virtual void PrintInfo(std::stringstream& aStream, 1713 const char* aPrefix) override; 1714 1715 virtual void DumpPacket(layerscope::LayersPacket* aPacket, 1716 const void* aParent) override; 1717 1718 /** 1719 * True for if the container start a new 3D context extended by one 1720 * or more children. 1721 */ 1722 bool Creates3DContextWithExtendingChildren(); 1723 1724 Layer* mFirstChild; 1725 Layer* mLastChild; 1726 float mPreXScale; 1727 float mPreYScale; 1728 // The resolution scale inherited from the parent layer. This will already 1729 // be part of mTransform. 1730 float mInheritedXScale; 1731 float mInheritedYScale; 1732 // For layers corresponding to an nsDisplayAsyncZoom, the resolution of the 1733 // associated pres shell; for other layers, 1.0. 1734 float mPresShellResolution; 1735 bool mUseIntermediateSurface; 1736 bool mSupportsComponentAlphaChildren; 1737 bool mMayHaveReadbackChild; 1738 // This is updated by ComputeDifferences. This will be true if we need to 1739 // invalidate the intermediate surface. 1740 bool mChildrenChanged; 1741 }; 1742 1743 /** 1744 * A Layer which just renders a solid color in its visible region. It actually 1745 * can fill any area that contains the visible region, so if you need to 1746 * restrict the area filled, set a clip region on this layer. 1747 */ 1748 class ColorLayer : public Layer { 1749 public: AsColorLayer()1750 ColorLayer* AsColorLayer() override { return this; } 1751 1752 /** 1753 * CONSTRUCTION PHASE ONLY 1754 * Set the color of the layer. 1755 */ SetColor(const gfx::DeviceColor & aColor)1756 virtual void SetColor(const gfx::DeviceColor& aColor) { 1757 if (mColor != aColor) { 1758 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Color", this)); 1759 mColor = aColor; 1760 Mutated(); 1761 } 1762 } 1763 SetBounds(const gfx::IntRect & aBounds)1764 void SetBounds(const gfx::IntRect& aBounds) { 1765 if (!mBounds.IsEqualEdges(aBounds)) { 1766 mBounds = aBounds; 1767 Mutated(); 1768 } 1769 } 1770 GetBounds()1771 const gfx::IntRect& GetBounds() { return mBounds; } 1772 1773 // This getter can be used anytime. GetColor()1774 virtual const gfx::DeviceColor& GetColor() { return mColor; } 1775 1776 MOZ_LAYER_DECL_NAME("ColorLayer", TYPE_COLOR) 1777 ComputeEffectiveTransforms(const gfx::Matrix4x4 & aTransformToSurface)1778 void ComputeEffectiveTransforms( 1779 const gfx::Matrix4x4& aTransformToSurface) override { 1780 gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface; 1781 mEffectiveTransform = SnapTransformTranslation(idealTransform, nullptr); 1782 ComputeEffectiveTransformForMaskLayers(aTransformToSurface); 1783 } 1784 1785 protected: ColorLayer(LayerManager * aManager,void * aImplData)1786 ColorLayer(LayerManager* aManager, void* aImplData) 1787 : Layer(aManager, aImplData), mColor() {} 1788 1789 void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; 1790 1791 void DumpPacket(layerscope::LayersPacket* aPacket, 1792 const void* aParent) override; 1793 1794 gfx::IntRect mBounds; 1795 gfx::DeviceColor mColor; 1796 }; 1797 1798 /** 1799 * A Layer for HTML Canvas elements. It's backed by either a 1800 * gfxASurface or a GLContext (for WebGL layers), and has some control 1801 * for intelligent updating from the source if necessary (for example, 1802 * if hardware compositing is not available, for reading from the GL 1803 * buffer into an image surface that we can layer composite.) 1804 * 1805 * After Initialize is called, the underlying canvas Surface/GLContext 1806 * must not be modified during a layer transaction. 1807 */ 1808 class CanvasLayer : public Layer { 1809 public: SetBounds(gfx::IntRect aBounds)1810 void SetBounds(gfx::IntRect aBounds) { mBounds = aBounds; } 1811 AsCanvasLayer()1812 CanvasLayer* AsCanvasLayer() override { return this; } 1813 1814 /** 1815 * Notify this CanvasLayer that the canvas surface contents have 1816 * changed (or will change) before the next transaction. 1817 */ Updated()1818 void Updated() { 1819 mCanvasRenderer->SetDirty(); 1820 SetInvalidRectToVisibleRegion(); 1821 } 1822 1823 /** 1824 * Notify this CanvasLayer that the canvas surface contents have 1825 * been painted since the last change. 1826 */ Painted()1827 void Painted() { mCanvasRenderer->ResetDirty(); } 1828 1829 /** 1830 * Returns true if the canvas surface contents have changed since the 1831 * last paint. 1832 */ IsDirty()1833 bool IsDirty() { 1834 // We can only tell if we are dirty if we're part of the 1835 // widget's retained layer tree. 1836 if (!mManager || !mManager->IsWidgetLayerManager()) { 1837 return true; 1838 } 1839 return mCanvasRenderer->IsDirty(); 1840 } 1841 GetBounds()1842 const nsIntRect& GetBounds() const { return mBounds; } 1843 1844 RefPtr<CanvasRenderer> CreateOrGetCanvasRenderer(); 1845 1846 public: 1847 /** 1848 * CONSTRUCTION PHASE ONLY 1849 * Set the filter used to resample this image (if necessary). 1850 */ SetSamplingFilter(gfx::SamplingFilter aSamplingFilter)1851 void SetSamplingFilter(gfx::SamplingFilter aSamplingFilter) { 1852 if (mSamplingFilter != aSamplingFilter) { 1853 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Filter", this)); 1854 mSamplingFilter = aSamplingFilter; 1855 Mutated(); 1856 } 1857 } GetSamplingFilter()1858 gfx::SamplingFilter GetSamplingFilter() const { return mSamplingFilter; } 1859 1860 MOZ_LAYER_DECL_NAME("CanvasLayer", TYPE_CANVAS) 1861 ComputeEffectiveTransforms(const gfx::Matrix4x4 & aTransformToSurface)1862 void ComputeEffectiveTransforms( 1863 const gfx::Matrix4x4& aTransformToSurface) override { 1864 // Snap our local transform first, and snap the inherited transform as well. 1865 // This makes our snapping equivalent to what would happen if our content 1866 // was drawn into a PaintedLayer (gfxContext would snap using the local 1867 // transform, then we'd snap again when compositing the PaintedLayer). 1868 mEffectiveTransform = 1869 SnapTransform(GetLocalTransform(), 1870 gfxRect(0, 0, mBounds.Width(), mBounds.Height()), 1871 nullptr) * 1872 SnapTransformTranslation(aTransformToSurface, nullptr); 1873 ComputeEffectiveTransformForMaskLayers(aTransformToSurface); 1874 } 1875 1876 protected: 1877 CanvasLayer(LayerManager* aManager, void* aImplData); 1878 virtual ~CanvasLayer(); 1879 1880 void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; 1881 1882 void DumpPacket(layerscope::LayersPacket* aPacket, 1883 const void* aParent) override; 1884 1885 virtual RefPtr<CanvasRenderer> CreateCanvasRendererInternal() = 0; 1886 1887 RefPtr<CanvasRenderer> mCanvasRenderer; 1888 gfx::SamplingFilter mSamplingFilter; 1889 1890 /** 1891 * 0, 0, canvaswidth, canvasheight 1892 */ 1893 gfx::IntRect mBounds; 1894 }; 1895 1896 /** 1897 * ContainerLayer that refers to a "foreign" layer tree, through an 1898 * ID. Usage of RefLayer looks like 1899 * 1900 * Construction phase: 1901 * allocate ID for layer subtree 1902 * create RefLayer, SetReferentId(ID) 1903 * 1904 * Composition: 1905 * look up subtree for GetReferentId() 1906 * ConnectReferentLayer(subtree) 1907 * compose 1908 * ClearReferentLayer() 1909 * 1910 * Clients will usually want to Connect/Clear() on each transaction to 1911 * avoid difficulties managing memory across multiple layer subtrees. 1912 */ 1913 class RefLayer : public ContainerLayer { 1914 friend class LayerManager; 1915 1916 private: InsertAfter(Layer * aChild,Layer * aAfter)1917 bool InsertAfter(Layer* aChild, Layer* aAfter) override { 1918 MOZ_CRASH("GFX: RefLayer"); 1919 return false; 1920 } 1921 RemoveChild(Layer * aChild)1922 bool RemoveChild(Layer* aChild) override { 1923 MOZ_CRASH("GFX: RefLayer"); 1924 return false; 1925 } 1926 RepositionChild(Layer * aChild,Layer * aAfter)1927 bool RepositionChild(Layer* aChild, Layer* aAfter) override { 1928 MOZ_CRASH("GFX: RefLayer"); 1929 return false; 1930 } 1931 1932 public: 1933 /** 1934 * CONSTRUCTION PHASE ONLY 1935 * Set the ID of the layer's referent. 1936 */ SetReferentId(LayersId aId)1937 void SetReferentId(LayersId aId) { 1938 MOZ_ASSERT(aId.IsValid()); 1939 if (mId != aId) { 1940 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, 1941 ("Layer::Mutated(%p) ReferentId", this)); 1942 mId = aId; 1943 Mutated(); 1944 } 1945 } 1946 /** 1947 * CONSTRUCTION PHASE ONLY 1948 * Connect this ref layer to its referent, temporarily. 1949 * ClearReferentLayer() must be called after composition. 1950 */ ConnectReferentLayer(Layer * aLayer)1951 void ConnectReferentLayer(Layer* aLayer) { 1952 MOZ_ASSERT(!mFirstChild && !mLastChild); 1953 MOZ_ASSERT(!aLayer->GetParent()); 1954 if (aLayer->Manager() != Manager()) { 1955 // This can happen when e.g. rendering while dragging tabs 1956 // between windows - aLayer's manager may be the manager for the 1957 // old window's tab. In that case, it will be changed before the 1958 // next render (see SetLayerManager). It is simply easier to 1959 // ignore the rendering here than it is to pause it. 1960 NS_WARNING("ConnectReferentLayer failed - Incorrect LayerManager"); 1961 return; 1962 } 1963 1964 mFirstChild = mLastChild = aLayer; 1965 aLayer->SetParent(this); 1966 } 1967 1968 /** 1969 * CONSTRUCTION PHASE ONLY 1970 * Set flags that indicate how event regions in the child layer tree need 1971 * to be overridden because of properties of the parent layer tree. 1972 */ SetEventRegionsOverride(EventRegionsOverride aVal)1973 void SetEventRegionsOverride(EventRegionsOverride aVal) { 1974 if (mEventRegionsOverride == aVal) { 1975 return; 1976 } 1977 1978 MOZ_LAYERS_LOG_IF_SHADOWABLE( 1979 this, ("Layer::Mutated(%p) EventRegionsOverride", this)); 1980 mEventRegionsOverride = aVal; 1981 Mutated(); 1982 } 1983 GetEventRegionsOverride()1984 EventRegionsOverride GetEventRegionsOverride() const { 1985 return mEventRegionsOverride; 1986 } 1987 1988 /** 1989 * CONSTRUCTION PHASE ONLY 1990 * Set remote subdocument iframe size. 1991 */ SetRemoteDocumentSize(const LayerIntSize & aRemoteDocumentSize)1992 void SetRemoteDocumentSize(const LayerIntSize& aRemoteDocumentSize) { 1993 if (mRemoteDocumentSize == aRemoteDocumentSize) { 1994 return; 1995 } 1996 mRemoteDocumentSize = aRemoteDocumentSize; 1997 Mutated(); 1998 } 1999 GetRemoteDocumentSize()2000 const LayerIntSize& GetRemoteDocumentSize() const { 2001 return mRemoteDocumentSize; 2002 } 2003 2004 /** 2005 * DRAWING PHASE ONLY 2006 * |aLayer| is the same as the argument to ConnectReferentLayer(). 2007 */ DetachReferentLayer(Layer * aLayer)2008 void DetachReferentLayer(Layer* aLayer) { 2009 mFirstChild = mLastChild = nullptr; 2010 aLayer->SetParent(nullptr); 2011 } 2012 2013 // These getters can be used anytime. AsRefLayer()2014 RefLayer* AsRefLayer() override { return this; } 2015 GetReferentId()2016 virtual LayersId GetReferentId() { return mId; } 2017 2018 /** 2019 * DRAWING PHASE ONLY 2020 */ 2021 void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) override; 2022 2023 MOZ_LAYER_DECL_NAME("RefLayer", TYPE_REF) 2024 2025 protected: RefLayer(LayerManager * aManager,void * aImplData)2026 RefLayer(LayerManager* aManager, void* aImplData) 2027 : ContainerLayer(aManager, aImplData), 2028 mId{0}, 2029 mEventRegionsOverride(EventRegionsOverride::NoOverride) {} 2030 2031 void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; 2032 2033 void DumpPacket(layerscope::LayersPacket* aPacket, 2034 const void* aParent) override; 2035 2036 // 0 is a special value that means "no ID". 2037 LayersId mId; 2038 EventRegionsOverride mEventRegionsOverride; 2039 // The remote documents only need their size because their origin is always 2040 // (0, 0). 2041 LayerIntSize mRemoteDocumentSize; 2042 }; 2043 2044 void SetAntialiasingFlags(Layer* aLayer, gfx::DrawTarget* aTarget); 2045 2046 #ifdef MOZ_DUMP_PAINTING 2047 void WriteSnapshotToDumpFile(Layer* aLayer, gfx::DataSourceSurface* aSurf); 2048 void WriteSnapshotToDumpFile(LayerManager* aManager, 2049 gfx::DataSourceSurface* aSurf); 2050 void WriteSnapshotToDumpFile(Compositor* aCompositor, gfx::DrawTarget* aTarget); 2051 #endif 2052 2053 // A utility function used by different LayerManager implementations. 2054 gfx::IntRect ToOutsideIntRect(const gfxRect& aRect); 2055 2056 void RecordCompositionPayloadsPresented( 2057 const TimeStamp& aCompositionEndTime, 2058 const nsTArray<CompositionPayload>& aPayloads); 2059 2060 } // namespace layers 2061 } // namespace mozilla 2062 2063 #endif /* GFX_LAYERS_H */ 2064