1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef GFX_LAYERS_H 7 #define GFX_LAYERS_H 8 9 #include <map> 10 #include <stdint.h> // for uint32_t, uint64_t, uint8_t 11 #include <stdio.h> // for FILE 12 #include <sys/types.h> // for int32_t, int64_t 13 #include "FrameMetrics.h" // for FrameMetrics 14 #include "Units.h" // for LayerMargin, LayerPoint, ParentLayerIntRect 15 #include "gfxContext.h" 16 #include "gfxTypes.h" 17 #include "gfxPoint.h" // for gfxPoint 18 #include "gfxRect.h" // for gfxRect 19 #include "gfx2DGlue.h" 20 #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2, etc 21 #include "mozilla/DebugOnly.h" // for DebugOnly 22 #include "mozilla/EventForwards.h" // for nsPaintEvent 23 #include "mozilla/Maybe.h" // for Maybe 24 #include "mozilla/Poison.h" 25 #include "mozilla/RefPtr.h" // for already_AddRefed 26 #include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc 27 #include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration 28 #include "mozilla/UniquePtr.h" // for UniquePtr 29 #include "mozilla/gfx/BaseMargin.h" // for BaseMargin 30 #include "mozilla/gfx/BasePoint.h" // for BasePoint 31 #include "mozilla/gfx/Point.h" // for IntSize 32 #include "mozilla/gfx/TiledRegion.h" // for TiledIntRegion 33 #include "mozilla/gfx/Types.h" // for SurfaceFormat 34 #include "mozilla/gfx/UserData.h" // for UserData, etc 35 #include "mozilla/layers/LayersTypes.h" 36 #include "mozilla/mozalloc.h" // for operator delete, etc 37 #include "nsAutoPtr.h" // for nsAutoPtr, nsRefPtr, etc 38 #include "nsCOMPtr.h" // for already_AddRefed 39 #include "nsCSSPropertyID.h" // for nsCSSPropertyID 40 #include "nsDebug.h" // for NS_ASSERTION 41 #include "nsISupportsImpl.h" // for Layer::Release, etc 42 #include "nsRect.h" // for mozilla::gfx::IntRect 43 #include "nsRegion.h" // for nsIntRegion 44 #include "nsString.h" // for nsCString 45 #include "nsTArray.h" // for nsTArray 46 #include "nsTArrayForwardDeclare.h" // for InfallibleTArray 47 #include "nscore.h" // for nsACString, nsAString 48 #include "mozilla/Logging.h" // for PRLogModuleInfo 49 #include "nsIWidget.h" // For plugin window configuration information structs 50 #include "ImageContainer.h" 51 52 class gfxContext; 53 54 extern uint8_t gLayerManagerLayerBuilder; 55 56 namespace mozilla { 57 58 class ComputedTimingFunction; 59 class FrameLayerBuilder; 60 class StyleAnimationValue; 61 62 namespace gl { 63 class GLContext; 64 } // namespace gl 65 66 namespace gfx { 67 class DrawTarget; 68 } // namespace gfx 69 70 namespace dom { 71 class OverfillCallback; 72 } // namespace dom 73 74 namespace layers { 75 76 class Animation; 77 class AnimationData; 78 class AsyncCanvasRenderer; 79 class AsyncPanZoomController; 80 class BasicLayerManager; 81 class ClientLayerManager; 82 class Layer; 83 class LayerMetricsWrapper; 84 class PaintedLayer; 85 class ContainerLayer; 86 class ImageLayer; 87 class ColorLayer; 88 class CanvasLayer; 89 class ReadbackLayer; 90 class ReadbackProcessor; 91 class RefLayer; 92 class LayerComposite; 93 class ShadowableLayer; 94 class ShadowLayerForwarder; 95 class LayerManagerComposite; 96 class SpecificLayerAttributes; 97 class Compositor; 98 class FrameUniformityData; 99 class PersistentBufferProvider; 100 101 namespace layerscope { 102 class LayersPacket; 103 } // namespace layerscope 104 105 #define MOZ_LAYER_DECL_NAME(n, e) \ 106 virtual const char* Name() const override { return n; } \ 107 virtual LayerType GetType() const override { return e; } 108 109 // Defined in LayerUserData.h; please include that file instead. 110 class LayerUserData; 111 112 /* 113 * Motivation: For truly smooth animation and video playback, we need to 114 * be able to compose frames and render them on a dedicated thread (i.e. 115 * off the main thread where DOM manipulation, script execution and layout 116 * induce difficult-to-bound latency). This requires Gecko to construct 117 * some kind of persistent scene structure (graph or tree) that can be 118 * safely transmitted across threads. We have other scenarios (e.g. mobile 119 * browsing) where retaining some rendered data between paints is desired 120 * for performance, so again we need a retained scene structure. 121 * 122 * Our retained scene structure is a layer tree. Each layer represents 123 * content which can be composited onto a destination surface; the root 124 * layer is usually composited into a window, and non-root layers are 125 * composited into their parent layers. Layers have attributes (e.g. 126 * opacity and clipping) that influence their compositing. 127 * 128 * We want to support a variety of layer implementations, including 129 * a simple "immediate mode" implementation that doesn't retain any 130 * rendered data between paints (i.e. uses cairo in just the way that 131 * Gecko used it before layers were introduced). But we also don't want 132 * to have bifurcated "layers"/"non-layers" rendering paths in Gecko. 133 * Therefore the layers API is carefully designed to permit maximally 134 * efficient implementation in an "immediate mode" style. See the 135 * BasicLayerManager for such an implementation. 136 */ 137 138 /** 139 * A LayerManager controls a tree of layers. All layers in the tree 140 * must use the same LayerManager. 141 * 142 * All modifications to a layer tree must happen inside a transaction. 143 * Only the state of the layer tree at the end of a transaction is 144 * rendered. Transactions cannot be nested 145 * 146 * Each transaction has two phases: 147 * 1) Construction: layers are created, inserted, removed and have 148 * properties set on them in this phase. 149 * BeginTransaction and BeginTransactionWithTarget start a transaction in 150 * the Construction phase. 151 * 2) Drawing: PaintedLayers are rendered into in this phase, in tree 152 * order. When the client has finished drawing into the PaintedLayers, it should 153 * call EndTransaction to complete the transaction. 154 * 155 * All layer API calls happen on the main thread. 156 * 157 * Layers are refcounted. The layer manager holds a reference to the 158 * root layer, and each container layer holds a reference to its children. 159 */ 160 class LayerManager { 161 NS_INLINE_DECL_REFCOUNTING(LayerManager) 162 163 protected: 164 typedef mozilla::gfx::DrawTarget DrawTarget; 165 typedef mozilla::gfx::IntSize IntSize; 166 typedef mozilla::gfx::SurfaceFormat SurfaceFormat; 167 168 public: LayerManager()169 LayerManager() 170 : mDestroyed(false) 171 , mSnapEffectiveTransforms(true) 172 , mId(0) 173 , mInTransaction(false) 174 , mPaintedPixelCount(0) 175 {} 176 177 /** 178 * Release layers and resources held by this layer manager, and mark 179 * it as destroyed. Should do any cleanup necessary in preparation 180 * for its widget going away. After this call, only user data calls 181 * are valid on the layer manager. 182 */ Destroy()183 virtual void Destroy() 184 { 185 mDestroyed = true; 186 mUserData.Destroy(); 187 mRoot = nullptr; 188 } IsDestroyed()189 bool IsDestroyed() { return mDestroyed; } 190 AsShadowForwarder()191 virtual ShadowLayerForwarder* AsShadowForwarder() 192 { return nullptr; } 193 AsLayerManagerComposite()194 virtual LayerManagerComposite* AsLayerManagerComposite() 195 { return nullptr; } 196 AsClientLayerManager()197 virtual ClientLayerManager* AsClientLayerManager() 198 { return nullptr; } 199 AsBasicLayerManager()200 virtual BasicLayerManager* AsBasicLayerManager() 201 { return nullptr; } 202 203 /** 204 * Returns true if this LayerManager is owned by an nsIWidget, 205 * and is used for drawing into the widget. 206 */ IsWidgetLayerManager()207 virtual bool IsWidgetLayerManager() { return true; } IsInactiveLayerManager()208 virtual bool IsInactiveLayerManager() { return false; } 209 210 /** 211 * Start a new transaction. Nested transactions are not allowed so 212 * there must be no transaction currently in progress. 213 * This transaction will update the state of the window from which 214 * this LayerManager was obtained. 215 */ 216 virtual bool BeginTransaction() = 0; 217 /** 218 * Start a new transaction. Nested transactions are not allowed so 219 * there must be no transaction currently in progress. 220 * This transaction will render the contents of the layer tree to 221 * the given target context. The rendering will be complete when 222 * EndTransaction returns. 223 */ 224 virtual bool BeginTransactionWithTarget(gfxContext* aTarget) = 0; 225 226 enum EndTransactionFlags { 227 END_DEFAULT = 0, 228 END_NO_IMMEDIATE_REDRAW = 1 << 0, // Do not perform the drawing phase 229 END_NO_COMPOSITE = 1 << 1, // Do not composite after drawing painted layer contents. 230 END_NO_REMOTE_COMPOSITE = 1 << 2 // Do not schedule a composition with a remote Compositor, if one exists. 231 }; 232 GetLayerBuilder()233 FrameLayerBuilder* GetLayerBuilder() { 234 return reinterpret_cast<FrameLayerBuilder*>(GetUserData(&gLayerManagerLayerBuilder)); 235 } 236 237 /** 238 * Attempts to end an "empty transaction". There must have been no 239 * changes to the layer tree since the BeginTransaction(). 240 * It's possible for this to fail; PaintedLayers may need to be updated 241 * due to VRAM data being lost, for example. In such cases this method 242 * returns false, and the caller must proceed with a normal layer tree 243 * update and EndTransaction. 244 */ 245 virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) = 0; 246 247 /** 248 * Function called to draw the contents of each PaintedLayer. 249 * aRegionToDraw contains the region that needs to be drawn. 250 * This would normally be a subregion of the visible region. 251 * The callee must draw all of aRegionToDraw. Drawing outside 252 * aRegionToDraw will be clipped out or ignored. 253 * The callee must draw all of aRegionToDraw. 254 * This region is relative to 0,0 in the PaintedLayer. 255 * 256 * aDirtyRegion should contain the total region that is be due to be painted 257 * during the transaction, even though only aRegionToDraw should be drawn 258 * during this call. aRegionToDraw must be entirely contained within 259 * aDirtyRegion. If the total dirty region is unknown it is okay to pass a 260 * subregion of the total dirty region, e.g. just aRegionToDraw, though it 261 * may not be as efficient. 262 * 263 * aRegionToInvalidate contains a region whose contents have been 264 * changed by the layer manager and which must therefore be invalidated. 265 * For example, this could be non-empty if a retained layer internally 266 * switches from RGBA to RGB or back ... we might want to repaint it to 267 * consistently use subpixel-AA or not. 268 * This region is relative to 0,0 in the PaintedLayer. 269 * aRegionToInvalidate may contain areas that are outside 270 * aRegionToDraw; the callee must ensure that these areas are repainted 271 * in the current layer manager transaction or in a later layer 272 * manager transaction. 273 * 274 * aContext must not be used after the call has returned. 275 * We guarantee that buffered contents in the visible 276 * region are valid once drawing is complete. 277 * 278 * The origin of aContext is 0,0 in the PaintedLayer. 279 */ 280 typedef void (* DrawPaintedLayerCallback)(PaintedLayer* aLayer, 281 gfxContext* aContext, 282 const nsIntRegion& aRegionToDraw, 283 const nsIntRegion& aDirtyRegion, 284 DrawRegionClip aClip, 285 const nsIntRegion& aRegionToInvalidate, 286 void* aCallbackData); 287 288 /** 289 * Finish the construction phase of the transaction, perform the 290 * drawing phase, and end the transaction. 291 * During the drawing phase, all PaintedLayers in the tree are 292 * drawn in tree order, exactly once each, except for those layers 293 * where it is known that the visible region is empty. 294 */ 295 virtual void EndTransaction(DrawPaintedLayerCallback aCallback, 296 void* aCallbackData, 297 EndTransactionFlags aFlags = END_DEFAULT) = 0; 298 299 /** 300 * Schedule a composition with the remote Compositor, if one exists 301 * for this LayerManager. Useful in conjunction with the END_NO_REMOTE_COMPOSITE 302 * flag to EndTransaction. 303 */ Composite()304 virtual void Composite() {} 305 HasShadowManagerInternal()306 virtual bool HasShadowManagerInternal() const { return false; } HasShadowManager()307 bool HasShadowManager() const { return HasShadowManagerInternal(); } StorePluginWidgetConfigurations(const nsTArray<nsIWidget::Configuration> & aConfigurations)308 virtual void StorePluginWidgetConfigurations(const nsTArray<nsIWidget::Configuration>& aConfigurations) {} IsSnappingEffectiveTransforms()309 bool IsSnappingEffectiveTransforms() { return mSnapEffectiveTransforms; } 310 311 312 /** 313 * Returns true if the layer manager can't render component alpha 314 * layers, and layer building should do it's best to avoid 315 * creating them. 316 */ ShouldAvoidComponentAlphaLayers()317 virtual bool ShouldAvoidComponentAlphaLayers() { return false; } 318 319 /** 320 * Returns true if this LayerManager can properly support layers with 321 * SurfaceMode::SURFACE_COMPONENT_ALPHA. LayerManagers that can't will use 322 * transparent surfaces (and lose subpixel-AA for text). 323 */ 324 virtual bool AreComponentAlphaLayersEnabled(); 325 326 /** 327 * CONSTRUCTION PHASE ONLY 328 * Set the root layer. The root layer is initially null. If there is 329 * no root layer, EndTransaction won't draw anything. 330 */ 331 virtual void SetRoot(Layer* aLayer) = 0; 332 /** 333 * Can be called anytime 334 */ GetRoot()335 Layer* GetRoot() { return mRoot; } 336 337 /** 338 * Does a breadth-first search from the root layer to find the first 339 * scrollable layer, and returns its ViewID. Note that there may be 340 * other layers in the tree which share the same ViewID. 341 * Can be called any time. 342 */ 343 FrameMetrics::ViewID GetRootScrollableLayerId(); 344 345 /** 346 * Returns a LayerMetricsWrapper containing the Root 347 * Content Documents layer. 348 */ 349 LayerMetricsWrapper GetRootContentLayer(); 350 351 /** 352 * CONSTRUCTION PHASE ONLY 353 * Called when a managee has mutated. 354 * Subclasses overriding this method must first call their 355 * superclass's impl 356 */ 357 #ifdef DEBUG 358 // In debug builds, we check some properties of |aLayer|. 359 virtual void Mutated(Layer* aLayer); 360 #else Mutated(Layer * aLayer)361 virtual void Mutated(Layer* aLayer) { } 362 #endif 363 364 /** 365 * Hints that can be used during PaintedLayer creation to influence the type 366 * or properties of the layer created. 367 * 368 * NONE: No hint. 369 * SCROLLABLE: This layer may represent scrollable content. 370 */ 371 enum PaintedLayerCreationHint { 372 NONE, SCROLLABLE 373 }; 374 375 /** 376 * CONSTRUCTION PHASE ONLY 377 * Create a PaintedLayer for this manager's layer tree. 378 */ 379 virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() = 0; 380 /** 381 * CONSTRUCTION PHASE ONLY 382 * Create a PaintedLayer for this manager's layer tree, with a creation hint 383 * parameter to help optimise the type of layer created. 384 */ CreatePaintedLayerWithHint(PaintedLayerCreationHint)385 virtual already_AddRefed<PaintedLayer> CreatePaintedLayerWithHint(PaintedLayerCreationHint) { 386 return CreatePaintedLayer(); 387 } 388 /** 389 * CONSTRUCTION PHASE ONLY 390 * Create a ContainerLayer for this manager's layer tree. 391 */ 392 virtual already_AddRefed<ContainerLayer> CreateContainerLayer() = 0; 393 /** 394 * CONSTRUCTION PHASE ONLY 395 * Create an ImageLayer for this manager's layer tree. 396 */ 397 virtual already_AddRefed<ImageLayer> CreateImageLayer() = 0; 398 /** 399 * CONSTRUCTION PHASE ONLY 400 * Create a ColorLayer for this manager's layer tree. 401 */ 402 virtual already_AddRefed<ColorLayer> CreateColorLayer() = 0; 403 /** 404 * CONSTRUCTION PHASE ONLY 405 * Create a CanvasLayer for this manager's layer tree. 406 */ 407 virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() = 0; 408 /** 409 * CONSTRUCTION PHASE ONLY 410 * Create a ReadbackLayer for this manager's layer tree. 411 */ CreateReadbackLayer()412 virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer() { return nullptr; } 413 /** 414 * CONSTRUCTION PHASE ONLY 415 * Create a RefLayer for this manager's layer tree. 416 */ CreateRefLayer()417 virtual already_AddRefed<RefLayer> CreateRefLayer() { return nullptr; } 418 419 420 /** 421 * Can be called anytime, from any thread. 422 * 423 * Creates an Image container which forwards its images to the compositor within 424 * layer transactions on the main thread or asynchronously using the ImageBridge IPDL protocol. 425 * In the case of asynchronous, If the protocol is not available, the returned ImageContainer 426 * will forward images within layer transactions. 427 */ 428 static already_AddRefed<ImageContainer> CreateImageContainer(ImageContainer::Mode flag 429 = ImageContainer::SYNCHRONOUS); 430 431 /** 432 * Type of layer manager his is. This is to be used sparsely in order to 433 * avoid a lot of Layers backend specific code. It should be used only when 434 * Layers backend specific functionality is necessary. 435 */ 436 virtual LayersBackend GetBackendType() = 0; 437 438 /** 439 * Type of layers backend that will be used to composite this layer tree. 440 * When compositing is done remotely, then this returns the layers type 441 * of the compositor. 442 */ GetCompositorBackendType()443 virtual LayersBackend GetCompositorBackendType() { return GetBackendType(); } 444 445 /** 446 * Creates a DrawTarget which is optimized for inter-operating with this 447 * layer manager. 448 */ 449 virtual already_AddRefed<DrawTarget> 450 CreateOptimalDrawTarget(const IntSize &aSize, 451 SurfaceFormat imageFormat); 452 453 /** 454 * Creates a DrawTarget for alpha masks which is optimized for inter- 455 * operating with this layer manager. In contrast to CreateOptimalDrawTarget, 456 * this surface is optimised for drawing alpha only and we assume that 457 * drawing the mask is fairly simple. 458 */ 459 virtual already_AddRefed<DrawTarget> 460 CreateOptimalMaskDrawTarget(const IntSize &aSize); 461 462 /** 463 * Creates a DrawTarget for use with canvas which is optimized for 464 * inter-operating with this layermanager. 465 */ 466 virtual already_AddRefed<mozilla::gfx::DrawTarget> 467 CreateDrawTarget(const mozilla::gfx::IntSize &aSize, 468 mozilla::gfx::SurfaceFormat aFormat); 469 470 /** 471 * Creates a PersistentBufferProvider for use with canvas which is optimized for 472 * inter-operating with this layermanager. 473 */ 474 virtual already_AddRefed<PersistentBufferProvider> 475 CreatePersistentBufferProvider(const mozilla::gfx::IntSize &aSize, 476 mozilla::gfx::SurfaceFormat aFormat); 477 CanUseCanvasLayerForSize(const gfx::IntSize & aSize)478 virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) { return true; } 479 480 /** 481 * returns the maximum texture size on this layer backend, or INT32_MAX 482 * if there is no maximum 483 */ 484 virtual int32_t GetMaxTextureSize() const = 0; 485 486 /** 487 * Return the name of the layer manager's backend. 488 */ 489 virtual void GetBackendName(nsAString& aName) = 0; 490 491 /** 492 * This setter can be used anytime. The user data for all keys is 493 * initially null. Ownership pases to the layer manager. 494 */ SetUserData(void * aKey,LayerUserData * aData)495 void SetUserData(void* aKey, LayerUserData* aData) 496 { 497 mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerUserDataDestroy); 498 } 499 /** 500 * This can be used anytime. Ownership passes to the caller! 501 */ 502 UniquePtr<LayerUserData> RemoveUserData(void* aKey); 503 504 /** 505 * This getter can be used anytime. 506 */ HasUserData(void * aKey)507 bool HasUserData(void* aKey) 508 { 509 return mUserData.Has(static_cast<gfx::UserDataKey*>(aKey)); 510 } 511 /** 512 * This getter can be used anytime. Ownership is retained by the layer 513 * manager. 514 */ GetUserData(void * aKey)515 LayerUserData* GetUserData(void* aKey) const 516 { 517 return static_cast<LayerUserData*>(mUserData.Get(static_cast<gfx::UserDataKey*>(aKey))); 518 } 519 520 /** 521 * Must be called outside of a layers transaction. 522 * 523 * For the subtree rooted at |aSubtree|, this attempts to free up 524 * any free-able resources like retained buffers, but may do nothing 525 * at all. After this call, the layer tree is left in an undefined 526 * state; the layers in |aSubtree|'s subtree may no longer have 527 * buffers with valid content and may no longer be able to draw 528 * their visible and valid regions. 529 * 530 * In general, a painting or forwarding transaction on |this| must 531 * complete on the tree before it returns to a valid state. 532 * 533 * Resource freeing begins from |aSubtree| or |mRoot| if |aSubtree| 534 * is null. |aSubtree|'s manager must be this. 535 */ 536 virtual void ClearCachedResources(Layer* aSubtree = nullptr) {} 537 538 /** 539 * Flag the next paint as the first for a document. 540 */ SetIsFirstPaint()541 virtual void SetIsFirstPaint() {} 542 543 /** 544 * Make sure that the previous transaction has been entirely 545 * completed. 546 * 547 * Note: This may sychronously wait on a remote compositor 548 * to complete rendering. 549 */ FlushRendering()550 virtual void FlushRendering() { } 551 552 /** 553 * Checks if we need to invalidate the OS widget to trigger 554 * painting when updating this layer manager. 555 */ NeedsWidgetInvalidation()556 virtual bool NeedsWidgetInvalidation() { return true; } 557 Name()558 virtual const char* Name() const { return "???"; } 559 560 /** 561 * Dump information about this layer manager and its managed tree to 562 * aStream. 563 */ 564 void Dump(std::stringstream& aStream, const char* aPrefix="", 565 bool aDumpHtml=false, bool aSorted=false); 566 /** 567 * Dump information about just this layer manager itself to aStream 568 */ 569 void DumpSelf(std::stringstream& aStream, const char* aPrefix="", bool aSorted=false); 570 void Dump(bool aSorted=false); 571 572 /** 573 * Dump information about this layer manager and its managed tree to 574 * layerscope packet. 575 */ 576 void Dump(layerscope::LayersPacket* aPacket); 577 578 /** 579 * Log information about this layer manager and its managed tree to 580 * the NSPR log (if enabled for "Layers"). 581 */ 582 void Log(const char* aPrefix=""); 583 /** 584 * Log information about just this layer manager itself to the NSPR 585 * log (if enabled for "Layers"). 586 */ 587 void LogSelf(const char* aPrefix=""); 588 589 /** 590 * Record (and return) frame-intervals and paint-times for frames which were presented 591 * between calling StartFrameTimeRecording and StopFrameTimeRecording. 592 * 593 * - Uses a cyclic buffer and serves concurrent consumers, so if Stop is called too late 594 * (elements were overwritten since Start), result is considered invalid and hence empty. 595 * - Buffer is capable of holding 10 seconds @ 60fps (or more if frames were less frequent). 596 * Can be changed (up to 1 hour) via pref: toolkit.framesRecording.bufferSize. 597 * - Note: the first frame-interval may be longer than expected because last frame 598 * might have been presented some time before calling StartFrameTimeRecording. 599 */ 600 601 /** 602 * Returns a handle which represents current recording start position. 603 */ 604 virtual uint32_t StartFrameTimeRecording(int32_t aBufferSize); 605 606 /** 607 * Clears, then populates aFrameIntervals with the recorded frame timing 608 * data. The array will be empty if data was overwritten since 609 * aStartIndex was obtained. 610 */ 611 virtual void StopFrameTimeRecording(uint32_t aStartIndex, 612 nsTArray<float>& aFrameIntervals); 613 614 void RecordFrame(); 615 void PostPresent(); 616 617 void BeginTabSwitch(); 618 619 static bool IsLogEnabled(); 620 static mozilla::LogModule* GetLog(); 621 IsCompositingCheap(LayersBackend aBackend)622 bool IsCompositingCheap(LayersBackend aBackend) 623 { 624 // LayersBackend::LAYERS_NONE is an error state, but in that case we should try to 625 // avoid loading the compositor! 626 return LayersBackend::LAYERS_BASIC != aBackend && LayersBackend::LAYERS_NONE != aBackend; 627 } 628 IsCompositingCheap()629 virtual bool IsCompositingCheap() { return true; } 630 IsInTransaction()631 bool IsInTransaction() const { return mInTransaction; } GetFrameUniformity(FrameUniformityData * aOutData)632 virtual void GetFrameUniformity(FrameUniformityData* aOutData) { } RequestOverfill(mozilla::dom::OverfillCallback * aCallback)633 virtual bool RequestOverfill(mozilla::dom::OverfillCallback* aCallback) { return true; } RunOverfillCallback(const uint32_t aOverfill)634 virtual void RunOverfillCallback(const uint32_t aOverfill) { } 635 SetRegionToClear(const nsIntRegion & aRegion)636 virtual void SetRegionToClear(const nsIntRegion& aRegion) 637 { 638 mRegionToClear = aRegion; 639 } 640 RequestProperty(const nsAString & property)641 virtual float RequestProperty(const nsAString& property) { return -1; } 642 GetAnimationReadyTime()643 const TimeStamp& GetAnimationReadyTime() const { 644 return mAnimationReadyTime; 645 } 646 AsyncPanZoomEnabled()647 virtual bool AsyncPanZoomEnabled() const { 648 return false; 649 } 650 651 static void LayerUserDataDestroy(void* data); 652 AddPaintedPixelCount(int32_t aCount)653 void AddPaintedPixelCount(int32_t aCount) { 654 mPaintedPixelCount += aCount; 655 } 656 GetAndClearPaintedPixelCount()657 uint32_t GetAndClearPaintedPixelCount() { 658 uint32_t count = mPaintedPixelCount; 659 mPaintedPixelCount = 0; 660 return count; 661 } 662 663 protected: 664 RefPtr<Layer> mRoot; 665 gfx::UserData mUserData; 666 bool mDestroyed; 667 bool mSnapEffectiveTransforms; 668 669 nsIntRegion mRegionToClear; 670 671 // Protected destructor, to discourage deletion outside of Release(): ~LayerManager()672 virtual ~LayerManager() {} 673 674 // Print interesting information about this into aStreamo. Internally 675 // used to implement Dump*() and Log*(). 676 virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix); 677 678 // Print interesting information about this into layerscope packet. 679 // Internally used to implement Dump(). 680 virtual void DumpPacket(layerscope::LayersPacket* aPacket); 681 682 uint64_t mId; 683 bool mInTransaction; 684 // The time when painting most recently finished. This is recorded so that 685 // we can time any play-pending animations from this point. 686 TimeStamp mAnimationReadyTime; 687 // The count of pixels that were painted in the current transaction. 688 uint32_t mPaintedPixelCount; 689 private: 690 struct FramesTimingRecording 691 { 692 // Stores state and data for frame intervals and paint times recording. 693 // see LayerManager::StartFrameTimeRecording() at Layers.cpp for more details. FramesTimingRecordingFramesTimingRecording694 FramesTimingRecording() 695 : mNextIndex(0) 696 , mLatestStartIndex(0) 697 , mCurrentRunStartIndex(0) 698 , mIsPaused(true) 699 {} 700 nsTArray<float> mIntervals; 701 TimeStamp mLastFrameTime; 702 uint32_t mNextIndex; 703 uint32_t mLatestStartIndex; 704 uint32_t mCurrentRunStartIndex; 705 bool mIsPaused; 706 }; 707 FramesTimingRecording mRecording; 708 709 TimeStamp mTabSwitchStart; 710 711 public: 712 /* 713 * Methods to store/get/clear a "pending scroll info update" object on a 714 * per-scrollid basis. This is used for empty transactions that push over 715 * scroll position updates to the APZ code. 716 */ 717 void SetPendingScrollUpdateForNextTransaction(FrameMetrics::ViewID aScrollId, 718 const ScrollUpdateInfo& aUpdateInfo); 719 Maybe<ScrollUpdateInfo> GetPendingScrollInfoUpdate(FrameMetrics::ViewID aScrollId); 720 void ClearPendingScrollInfoUpdate(); 721 private: 722 std::map<FrameMetrics::ViewID,ScrollUpdateInfo> mPendingScrollUpdates; 723 }; 724 725 typedef InfallibleTArray<Animation> AnimationArray; 726 727 struct AnimData { 728 InfallibleTArray<mozilla::StyleAnimationValue> mStartValues; 729 InfallibleTArray<mozilla::StyleAnimationValue> mEndValues; 730 InfallibleTArray<Maybe<mozilla::ComputedTimingFunction>> mFunctions; 731 }; 732 733 /** 734 * A Layer represents anything that can be rendered onto a destination 735 * surface. 736 */ 737 class Layer { 738 NS_INLINE_DECL_REFCOUNTING(Layer) 739 740 public: 741 // Keep these in alphabetical order 742 enum LayerType { 743 TYPE_CANVAS, 744 TYPE_COLOR, 745 TYPE_CONTAINER, 746 TYPE_IMAGE, 747 TYPE_READBACK, 748 TYPE_REF, 749 TYPE_SHADOW, 750 TYPE_PAINTED 751 }; 752 753 /** 754 * Returns the LayerManager this Layer belongs to. Note that the layer 755 * manager might be in a destroyed state, at which point it's only 756 * valid to set/get user data from it. 757 */ Manager()758 LayerManager* Manager() { return mManager; } 759 760 enum { 761 /** 762 * If this is set, the caller is promising that by the end of this 763 * transaction the entire visible region (as specified by 764 * SetVisibleRegion) will be filled with opaque content. 765 */ 766 CONTENT_OPAQUE = 0x01, 767 /** 768 * If this is set, the caller is notifying that the contents of this layer 769 * require per-component alpha for optimal fidelity. However, there is no 770 * guarantee that component alpha will be supported for this layer at 771 * paint time. 772 * This should never be set at the same time as CONTENT_OPAQUE. 773 */ 774 CONTENT_COMPONENT_ALPHA = 0x02, 775 776 /** 777 * If this is set then one of the descendant layers of this one has 778 * CONTENT_COMPONENT_ALPHA set. 779 */ 780 CONTENT_COMPONENT_ALPHA_DESCENDANT = 0x04, 781 782 /** 783 * If this is set then this layer is part of a preserve-3d group, and should 784 * be sorted with sibling layers that are also part of the same group. 785 */ 786 CONTENT_EXTEND_3D_CONTEXT = 0x08, 787 /** 788 * This indicates that the transform may be changed on during an empty 789 * transaction where there is no possibility of redrawing the content, so the 790 * implementation should be ready for that. 791 */ 792 CONTENT_MAY_CHANGE_TRANSFORM = 0x10, 793 794 /** 795 * Disable subpixel AA for this layer. This is used if the display isn't suited 796 * for subpixel AA like hidpi or rotated content. 797 */ 798 CONTENT_DISABLE_SUBPIXEL_AA = 0x20, 799 800 /** 801 * If this is set then the layer contains content that may look objectionable 802 * if not handled as an active layer (such as text with an animated transform). 803 * This is for internal layout/FrameLayerBuilder usage only until flattening 804 * code is obsoleted. See bug 633097 805 */ 806 CONTENT_DISABLE_FLATTENING = 0x40, 807 808 /** 809 * This layer is hidden if the backface of the layer is visible 810 * to user. 811 */ 812 CONTENT_BACKFACE_HIDDEN = 0x80 813 }; 814 /** 815 * CONSTRUCTION PHASE ONLY 816 * This lets layout make some promises about what will be drawn into the 817 * visible region of the PaintedLayer. This enables internal quality 818 * and performance optimizations. 819 */ SetContentFlags(uint32_t aFlags)820 void SetContentFlags(uint32_t aFlags) 821 { 822 NS_ASSERTION((aFlags & (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA)) != 823 (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA), 824 "Can't be opaque and require component alpha"); 825 if (mContentFlags != aFlags) { 826 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ContentFlags", this)); 827 mContentFlags = aFlags; 828 Mutated(); 829 } 830 } 831 832 /** 833 * CONSTRUCTION PHASE ONLY 834 * The union of the bounds of all the display item that got flattened 835 * into this layer. This is intended to be an approximation to the 836 * size of the layer if the nearest scrollable ancestor had an infinitely 837 * large displayport. Computing this more exactly is too expensive, 838 * but this approximation is sufficient for what we need to use it for. 839 */ SetLayerBounds(const gfx::IntRect & aLayerBounds)840 virtual void SetLayerBounds(const gfx::IntRect& aLayerBounds) 841 { 842 if (!mLayerBounds.IsEqualEdges(aLayerBounds)) { 843 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) LayerBounds", this)); 844 mLayerBounds = aLayerBounds; 845 Mutated(); 846 } 847 } 848 849 /** 850 * CONSTRUCTION PHASE ONLY 851 * Tell this layer which region will be visible. The visible region 852 * is a region which contains all the contents of the layer that can 853 * actually affect the rendering of the window. It can exclude areas 854 * that are covered by opaque contents of other layers, and it can 855 * exclude areas where this layer simply contains no content at all. 856 * (This can be an overapproximation to the "true" visible region.) 857 * 858 * There is no general guarantee that drawing outside the bounds of the 859 * visible region will be ignored. So if a layer draws outside the bounds 860 * of its visible region, it needs to ensure that what it draws is valid. 861 */ SetVisibleRegion(const LayerIntRegion & aRegion)862 virtual void SetVisibleRegion(const LayerIntRegion& aRegion) 863 { 864 // IsEmpty is required otherwise we get invalidation glitches. 865 // See bug 1288464 for investigating why. 866 if (!mVisibleRegion.IsEqual(aRegion) || aRegion.IsEmpty()) { 867 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) VisibleRegion was %s is %s", this, 868 mVisibleRegion.ToString().get(), aRegion.ToString().get())); 869 mVisibleRegion = aRegion; 870 Mutated(); 871 } 872 } 873 874 /** 875 * CONSTRUCTION PHASE ONLY 876 * Set the (sub)document metrics used to render the Layer subtree 877 * rooted at this. Note that a layer may have multiple FrameMetrics 878 * objects; calling this function will remove all of them and replace 879 * them with the provided FrameMetrics. See the documentation for 880 * SetFrameMetrics(const nsTArray<FrameMetrics>&) for more details. 881 */ SetScrollMetadata(const ScrollMetadata & aScrollMetadata)882 void SetScrollMetadata(const ScrollMetadata& aScrollMetadata) 883 { 884 Manager()->ClearPendingScrollInfoUpdate(); 885 if (mScrollMetadata.Length() != 1 || mScrollMetadata[0] != aScrollMetadata) { 886 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FrameMetrics", this)); 887 mScrollMetadata.ReplaceElementsAt(0, mScrollMetadata.Length(), aScrollMetadata); 888 ScrollMetadataChanged(); 889 Mutated(); 890 } 891 } 892 893 /** 894 * CONSTRUCTION PHASE ONLY 895 * Set the (sub)document metrics used to render the Layer subtree 896 * rooted at this. There might be multiple metrics on this layer 897 * because the layer may, for example, be contained inside multiple 898 * nested scrolling subdocuments. In general a Layer having multiple 899 * ScrollMetadata objects is conceptually equivalent to having a stack 900 * of ContainerLayers that have been flattened into this Layer. 901 * See the documentation in LayerMetricsWrapper.h for a more detailed 902 * explanation of this conceptual equivalence. 903 * 904 * Note also that there is actually a many-to-many relationship between 905 * Layers and ScrollMetadata, because multiple Layers may have identical 906 * ScrollMetadata objects. This happens when those layers belong to the 907 * same scrolling subdocument and therefore end up with the same async 908 * transform when they are scrolled by the APZ code. 909 */ SetScrollMetadata(const nsTArray<ScrollMetadata> & aMetadataArray)910 void SetScrollMetadata(const nsTArray<ScrollMetadata>& aMetadataArray) 911 { 912 Manager()->ClearPendingScrollInfoUpdate(); 913 if (mScrollMetadata != aMetadataArray) { 914 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FrameMetrics", this)); 915 mScrollMetadata = aMetadataArray; 916 ScrollMetadataChanged(); 917 Mutated(); 918 } 919 } 920 921 /* 922 * Compositor event handling 923 * ========================= 924 * When a touch-start event (or similar) is sent to the AsyncPanZoomController, 925 * it needs to decide whether the event should be sent to the main thread. 926 * Each layer has a list of event handling regions. When the compositor needs 927 * to determine how to handle a touch event, it scans the layer tree from top 928 * to bottom in z-order (traversing children before their parents). Points 929 * outside the clip region for a layer cause that layer (and its subtree) 930 * to be ignored. If a layer has a mask layer, and that mask layer's alpha 931 * value is zero at the event point, then the layer and its subtree should 932 * be ignored. 933 * For each layer, if the point is outside its hit region, we ignore the layer 934 * and move onto the next. If the point is inside its hit region but 935 * outside the dispatch-to-content region, we can initiate a gesture without 936 * consulting the content thread. Otherwise we must dispatch the event to 937 * content. 938 * Note that if a layer or any ancestor layer has a ForceEmptyHitRegion 939 * override in GetEventRegionsOverride() then the hit-region must be treated 940 * as empty. Similarly, if there is a ForceDispatchToContent override then 941 * the dispatch-to-content region must be treated as encompassing the entire 942 * hit region, and therefore we must consult the content thread before 943 * initiating a gesture. (If both flags are set, ForceEmptyHitRegion takes 944 * priority.) 945 */ 946 /** 947 * CONSTRUCTION PHASE ONLY 948 * Set the event handling region. 949 */ SetEventRegions(const EventRegions & aRegions)950 void SetEventRegions(const EventRegions& aRegions) 951 { 952 if (mEventRegions != aRegions) { 953 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) eventregions were %s, now %s", this, 954 mEventRegions.ToString().get(), aRegions.ToString().get())); 955 mEventRegions = aRegions; 956 Mutated(); 957 } 958 } 959 960 /** 961 * CONSTRUCTION PHASE ONLY 962 * Set the opacity which will be applied to this layer as it 963 * is composited to the destination. 964 */ SetOpacity(float aOpacity)965 void SetOpacity(float aOpacity) 966 { 967 if (mOpacity != aOpacity) { 968 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Opacity", this)); 969 mOpacity = aOpacity; 970 Mutated(); 971 } 972 } 973 SetMixBlendMode(gfx::CompositionOp aMixBlendMode)974 void SetMixBlendMode(gfx::CompositionOp aMixBlendMode) 975 { 976 if (mMixBlendMode != aMixBlendMode) { 977 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) MixBlendMode", this)); 978 mMixBlendMode = aMixBlendMode; 979 Mutated(); 980 } 981 } 982 SetForceIsolatedGroup(bool aForceIsolatedGroup)983 void SetForceIsolatedGroup(bool aForceIsolatedGroup) 984 { 985 if(mForceIsolatedGroup != aForceIsolatedGroup) { 986 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ForceIsolatedGroup", this)); 987 mForceIsolatedGroup = aForceIsolatedGroup; 988 Mutated(); 989 } 990 } 991 GetForceIsolatedGroup()992 bool GetForceIsolatedGroup() const 993 { 994 return mForceIsolatedGroup; 995 } 996 997 /** 998 * CONSTRUCTION PHASE ONLY 999 * Set a clip rect which will be applied to this layer as it is 1000 * composited to the destination. The coordinates are relative to 1001 * the parent layer (i.e. the contents of this layer 1002 * are transformed before this clip rect is applied). 1003 * For the root layer, the coordinates are relative to the widget, 1004 * in device pixels. 1005 * If aRect is null no clipping will be performed. 1006 */ SetClipRect(const Maybe<ParentLayerIntRect> & aRect)1007 void SetClipRect(const Maybe<ParentLayerIntRect>& aRect) 1008 { 1009 if (mClipRect) { 1010 if (!aRect) { 1011 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ClipRect was %d,%d,%d,%d is <none>", this, 1012 mClipRect->x, mClipRect->y, mClipRect->width, mClipRect->height)); 1013 mClipRect.reset(); 1014 Mutated(); 1015 } else { 1016 if (!aRect->IsEqualEdges(*mClipRect)) { 1017 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ClipRect was %d,%d,%d,%d is %d,%d,%d,%d", this, 1018 mClipRect->x, mClipRect->y, mClipRect->width, mClipRect->height, 1019 aRect->x, aRect->y, aRect->width, aRect->height)); 1020 mClipRect = aRect; 1021 Mutated(); 1022 } 1023 } 1024 } else { 1025 if (aRect) { 1026 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ClipRect was <none> is %d,%d,%d,%d", this, 1027 aRect->x, aRect->y, aRect->width, aRect->height)); 1028 mClipRect = aRect; 1029 Mutated(); 1030 } 1031 } 1032 } 1033 1034 /** 1035 * CONSTRUCTION PHASE ONLY 1036 * Set an optional scrolled clip on the layer. 1037 * The scrolled clip, if present, consists of a clip rect and an optional mask. 1038 * This scrolled clip is always scrolled by all scroll frames associated with 1039 * this layer. (By contrast, the scroll clips stored in ScrollMetadata are 1040 * only scrolled by scroll frames above that ScrollMetadata, and the layer's 1041 * mClipRect is always fixed to the layer contents (which may or may not be 1042 * scrolled by some of the scroll frames associated with the layer, depending 1043 * on whether the layer is fixed).) 1044 */ SetScrolledClip(const Maybe<LayerClip> & aScrolledClip)1045 void SetScrolledClip(const Maybe<LayerClip>& aScrolledClip) 1046 { 1047 if (mScrolledClip != aScrolledClip) { 1048 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrolledClip", this)); 1049 mScrolledClip = aScrolledClip; 1050 Mutated(); 1051 } 1052 } 1053 1054 /** 1055 * CONSTRUCTION PHASE ONLY 1056 * Set a layer to mask this layer. 1057 * 1058 * The mask layer should be applied using its effective transform (after it 1059 * is calculated by ComputeEffectiveTransformForMaskLayer), this should use 1060 * this layer's parent's transform and the mask layer's transform, but not 1061 * this layer's. That is, the mask layer is specified relative to this layer's 1062 * position in it's parent layer's coord space. 1063 * Currently, only 2D translations are supported for the mask layer transform. 1064 * 1065 * Ownership of aMaskLayer passes to this. 1066 * Typical use would be an ImageLayer with an alpha image used for masking. 1067 * See also ContainerState::BuildMaskLayer in FrameLayerBuilder.cpp. 1068 */ SetMaskLayer(Layer * aMaskLayer)1069 void SetMaskLayer(Layer* aMaskLayer) 1070 { 1071 #ifdef DEBUG 1072 if (aMaskLayer) { 1073 bool maskIs2D = aMaskLayer->GetTransform().CanDraw2D(); 1074 NS_ASSERTION(maskIs2D, "Mask layer has invalid transform."); 1075 } 1076 #endif 1077 1078 if (mMaskLayer != aMaskLayer) { 1079 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) MaskLayer", this)); 1080 mMaskLayer = aMaskLayer; 1081 Mutated(); 1082 } 1083 } 1084 1085 /** 1086 * CONSTRUCTION PHASE ONLY 1087 * Add mask layers associated with LayerClips. 1088 */ SetAncestorMaskLayers(const nsTArray<RefPtr<Layer>> & aLayers)1089 void SetAncestorMaskLayers(const nsTArray<RefPtr<Layer>>& aLayers) { 1090 if (aLayers != mAncestorMaskLayers) { 1091 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) AncestorMaskLayers", this)); 1092 mAncestorMaskLayers = aLayers; 1093 Mutated(); 1094 } 1095 } 1096 1097 /** 1098 * CONSTRUCTION PHASE ONLY 1099 * Add a mask layer associated with a LayerClip. 1100 */ AddAncestorMaskLayer(const RefPtr<Layer> & aLayer)1101 void AddAncestorMaskLayer(const RefPtr<Layer>& aLayer) { 1102 mAncestorMaskLayers.AppendElement(aLayer); 1103 Mutated(); 1104 } 1105 1106 /** 1107 * CONSTRUCTION PHASE ONLY 1108 * Tell this layer what its transform should be. The transformation 1109 * is applied when compositing the layer into its parent container. 1110 */ SetBaseTransform(const gfx::Matrix4x4 & aMatrix)1111 void SetBaseTransform(const gfx::Matrix4x4& aMatrix) 1112 { 1113 NS_ASSERTION(!aMatrix.IsSingular(), 1114 "Shouldn't be trying to draw with a singular matrix!"); 1115 mPendingTransform = nullptr; 1116 if (mTransform == aMatrix) { 1117 return; 1118 } 1119 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) BaseTransform", this)); 1120 mTransform = aMatrix; 1121 Mutated(); 1122 } 1123 1124 /** 1125 * Can be called at any time. 1126 * 1127 * Like SetBaseTransform(), but can be called before the next 1128 * transform (i.e. outside an open transaction). Semantically, this 1129 * method enqueues a new transform value to be set immediately after 1130 * the next transaction is opened. 1131 */ SetBaseTransformForNextTransaction(const gfx::Matrix4x4 & aMatrix)1132 void SetBaseTransformForNextTransaction(const gfx::Matrix4x4& aMatrix) 1133 { 1134 mPendingTransform = new gfx::Matrix4x4(aMatrix); 1135 } 1136 SetPostScale(float aXScale,float aYScale)1137 void SetPostScale(float aXScale, float aYScale) 1138 { 1139 if (mPostXScale == aXScale && mPostYScale == aYScale) { 1140 return; 1141 } 1142 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PostScale", this)); 1143 mPostXScale = aXScale; 1144 mPostYScale = aYScale; 1145 Mutated(); 1146 } 1147 1148 /** 1149 * CONSTRUCTION PHASE ONLY 1150 * A layer is "fixed position" when it draws content from a content 1151 * (not chrome) document, the topmost content document has a root scrollframe 1152 * with a displayport, but the layer does not move when that displayport scrolls. 1153 */ SetIsFixedPosition(bool aFixedPosition)1154 void SetIsFixedPosition(bool aFixedPosition) 1155 { 1156 if (mIsFixedPosition != aFixedPosition) { 1157 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) IsFixedPosition", this)); 1158 mIsFixedPosition = aFixedPosition; 1159 Mutated(); 1160 } 1161 } 1162 1163 /** 1164 * CONSTRUCTION PHASE ONLY 1165 * This flag is true when the transform on the layer is a perspective 1166 * transform. The compositor treats perspective transforms specially 1167 * for async scrolling purposes. 1168 */ SetTransformIsPerspective(bool aTransformIsPerspective)1169 void SetTransformIsPerspective(bool aTransformIsPerspective) 1170 { 1171 if (mTransformIsPerspective != aTransformIsPerspective) { 1172 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) TransformIsPerspective", this)); 1173 mTransformIsPerspective = aTransformIsPerspective; 1174 Mutated(); 1175 } 1176 } 1177 1178 // Call AddAnimation to add a new animation to this layer from layout code. 1179 // Caller must fill in all the properties of the returned animation. 1180 // A later animation overrides an earlier one. 1181 Animation* AddAnimation(); 1182 // ClearAnimations clears animations on this layer. 1183 void ClearAnimations(); 1184 // This is only called when the layer tree is updated. Do not call this from 1185 // layout code. To add an animation to this layer, use AddAnimation. 1186 void SetAnimations(const AnimationArray& aAnimations); 1187 // Go through all animations in this layer and its children and, for 1188 // any animations with a null start time, update their start time such 1189 // that at |aReadyTime| the animation's current time corresponds to its 1190 // 'initial current time' value. 1191 void StartPendingAnimations(const TimeStamp& aReadyTime); 1192 1193 // These are a parallel to AddAnimation and clearAnimations, except 1194 // they add pending animations that apply only when the next 1195 // transaction is begun. (See also 1196 // SetBaseTransformForNextTransaction.) 1197 Animation* AddAnimationForNextTransaction(); 1198 void ClearAnimationsForNextTransaction(); 1199 1200 /** 1201 * CONSTRUCTION PHASE ONLY 1202 * If a layer represents a fixed position element, this data is stored on the 1203 * layer for use by the compositor. 1204 * 1205 * - |aScrollId| identifies the scroll frame that this element is fixed 1206 * with respect to. 1207 * 1208 * - |aAnchor| is the point on the layer that is considered the "anchor" 1209 * point, that is, the point which remains in the same position when 1210 * compositing the layer tree with a transformation (such as when 1211 * asynchronously scrolling and zooming). 1212 * 1213 * - |aSides| is the set of sides to which the element is fixed relative to. 1214 * This is used if the viewport size is changed in the compositor and 1215 * fixed position items need to shift accordingly. This value is made up 1216 * combining appropriate values from mozilla::SideBits. 1217 */ SetFixedPositionData(FrameMetrics::ViewID aScrollId,const LayerPoint & aAnchor,int32_t aSides)1218 void SetFixedPositionData(FrameMetrics::ViewID aScrollId, 1219 const LayerPoint& aAnchor, 1220 int32_t aSides) 1221 { 1222 if (!mFixedPositionData || 1223 mFixedPositionData->mScrollId != aScrollId || 1224 mFixedPositionData->mAnchor != aAnchor || 1225 mFixedPositionData->mSides != aSides) { 1226 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FixedPositionData", this)); 1227 if (!mFixedPositionData) { 1228 mFixedPositionData = MakeUnique<FixedPositionData>(); 1229 } 1230 mFixedPositionData->mScrollId = aScrollId; 1231 mFixedPositionData->mAnchor = aAnchor; 1232 mFixedPositionData->mSides = aSides; 1233 Mutated(); 1234 } 1235 } 1236 1237 /** 1238 * CONSTRUCTION PHASE ONLY 1239 * If a layer is "sticky position", |aScrollId| holds the scroll identifier 1240 * of the scrollable content that contains it. The difference between the two 1241 * rectangles |aOuter| and |aInner| is treated as two intervals in each 1242 * dimension, with the current scroll position at the origin. For each 1243 * dimension, while that component of the scroll position lies within either 1244 * interval, the layer should not move relative to its scrolling container. 1245 */ SetStickyPositionData(FrameMetrics::ViewID aScrollId,LayerRect aOuter,LayerRect aInner)1246 void SetStickyPositionData(FrameMetrics::ViewID aScrollId, LayerRect aOuter, 1247 LayerRect aInner) 1248 { 1249 if (!mStickyPositionData || 1250 !mStickyPositionData->mOuter.IsEqualEdges(aOuter) || 1251 !mStickyPositionData->mInner.IsEqualEdges(aInner)) { 1252 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) StickyPositionData", this)); 1253 if (!mStickyPositionData) { 1254 mStickyPositionData = new StickyPositionData; 1255 } 1256 mStickyPositionData->mScrollId = aScrollId; 1257 mStickyPositionData->mOuter = aOuter; 1258 mStickyPositionData->mInner = aInner; 1259 Mutated(); 1260 } 1261 } 1262 1263 enum ScrollDirection { 1264 NONE, 1265 VERTICAL, 1266 HORIZONTAL 1267 }; 1268 1269 /** 1270 * CONSTRUCTION PHASE ONLY 1271 * If a layer is a scrollbar layer, |aScrollId| holds the scroll identifier 1272 * of the scrollable content that the scrollbar is for. 1273 */ SetScrollbarData(FrameMetrics::ViewID aScrollId,ScrollDirection aDir,float aThumbRatio)1274 void SetScrollbarData(FrameMetrics::ViewID aScrollId, ScrollDirection aDir, float aThumbRatio) 1275 { 1276 if (mScrollbarTargetId != aScrollId || 1277 mScrollbarDirection != aDir || 1278 mScrollbarThumbRatio != aThumbRatio) 1279 { 1280 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrollbarData", this)); 1281 mScrollbarTargetId = aScrollId; 1282 mScrollbarDirection = aDir; 1283 mScrollbarThumbRatio = aThumbRatio; 1284 Mutated(); 1285 } 1286 } 1287 1288 // Set during construction for the container layer of scrollbar components. SetIsScrollbarContainer()1289 void SetIsScrollbarContainer() 1290 { 1291 if (!mIsScrollbarContainer) { 1292 mIsScrollbarContainer = true; 1293 Mutated(); 1294 } 1295 } 1296 1297 // These getters can be used anytime. GetOpacity()1298 float GetOpacity() { return mOpacity; } GetMixBlendMode()1299 gfx::CompositionOp GetMixBlendMode() const { return mMixBlendMode; } GetClipRect()1300 const Maybe<ParentLayerIntRect>& GetClipRect() const { return mClipRect; } GetScrolledClip()1301 const Maybe<LayerClip>& GetScrolledClip() const { return mScrolledClip; } 1302 Maybe<ParentLayerIntRect> GetScrolledClipRect() const; GetContentFlags()1303 uint32_t GetContentFlags() { return mContentFlags; } GetLayerBounds()1304 const gfx::IntRect& GetLayerBounds() const { return mLayerBounds; } GetVisibleRegion()1305 const LayerIntRegion& GetVisibleRegion() const { return mVisibleRegion; } 1306 const ScrollMetadata& GetScrollMetadata(uint32_t aIndex) const; 1307 const FrameMetrics& GetFrameMetrics(uint32_t aIndex) const; GetScrollMetadataCount()1308 uint32_t GetScrollMetadataCount() const { return mScrollMetadata.Length(); } GetAllScrollMetadata()1309 const nsTArray<ScrollMetadata>& GetAllScrollMetadata() { return mScrollMetadata; } 1310 bool HasScrollableFrameMetrics() const; 1311 bool IsScrollInfoLayer() const; GetEventRegions()1312 const EventRegions& GetEventRegions() const { return mEventRegions; } GetParent()1313 ContainerLayer* GetParent() { return mParent; } GetNextSibling()1314 Layer* GetNextSibling() { 1315 if (mNextSibling) { 1316 mNextSibling->CheckCanary(); 1317 } 1318 return mNextSibling; 1319 } GetNextSibling()1320 const Layer* GetNextSibling() const { 1321 if (mNextSibling) { 1322 mNextSibling->CheckCanary(); 1323 } 1324 return mNextSibling; 1325 } GetPrevSibling()1326 Layer* GetPrevSibling() { return mPrevSibling; } GetPrevSibling()1327 const Layer* GetPrevSibling() const { return mPrevSibling; } GetFirstChild()1328 virtual Layer* GetFirstChild() const { return nullptr; } GetLastChild()1329 virtual Layer* GetLastChild() const { return nullptr; } 1330 gfx::Matrix4x4 GetTransform() const; 1331 // Same as GetTransform(), but returns the transform as a strongly-typed 1332 // matrix. Eventually this will replace GetTransform(). 1333 const CSSTransformMatrix GetTransformTyped() const; GetBaseTransform()1334 const gfx::Matrix4x4& GetBaseTransform() const { return mTransform; } 1335 // Note: these are virtual because ContainerLayerComposite overrides them. GetPostXScale()1336 virtual float GetPostXScale() const { return mPostXScale; } GetPostYScale()1337 virtual float GetPostYScale() const { return mPostYScale; } GetIsFixedPosition()1338 bool GetIsFixedPosition() { return mIsFixedPosition; } GetTransformIsPerspective()1339 bool GetTransformIsPerspective() const { return mTransformIsPerspective; } GetIsStickyPosition()1340 bool GetIsStickyPosition() { return mStickyPositionData; } GetFixedPositionScrollContainerId()1341 FrameMetrics::ViewID GetFixedPositionScrollContainerId() { return mFixedPositionData ? mFixedPositionData->mScrollId : FrameMetrics::NULL_SCROLL_ID; } GetFixedPositionAnchor()1342 LayerPoint GetFixedPositionAnchor() { return mFixedPositionData ? mFixedPositionData->mAnchor : LayerPoint(); } GetFixedPositionSides()1343 int32_t GetFixedPositionSides() { return mFixedPositionData ? mFixedPositionData->mSides : eSideBitsNone; } GetStickyScrollContainerId()1344 FrameMetrics::ViewID GetStickyScrollContainerId() { return mStickyPositionData->mScrollId; } GetStickyScrollRangeOuter()1345 const LayerRect& GetStickyScrollRangeOuter() { return mStickyPositionData->mOuter; } GetStickyScrollRangeInner()1346 const LayerRect& GetStickyScrollRangeInner() { return mStickyPositionData->mInner; } GetScrollbarTargetContainerId()1347 FrameMetrics::ViewID GetScrollbarTargetContainerId() { return mScrollbarTargetId; } GetScrollbarDirection()1348 ScrollDirection GetScrollbarDirection() { return mScrollbarDirection; } GetScrollbarThumbRatio()1349 float GetScrollbarThumbRatio() { return mScrollbarThumbRatio; } IsScrollbarContainer()1350 bool IsScrollbarContainer() { return mIsScrollbarContainer; } GetMaskLayer()1351 Layer* GetMaskLayer() const { return mMaskLayer; } CheckCanary()1352 void CheckCanary() const { mCanary.Check(); } 1353 1354 // Ancestor mask layers are associated with FrameMetrics, but for simplicity 1355 // in maintaining the layer tree structure we attach them to the layer. GetAncestorMaskLayerCount()1356 size_t GetAncestorMaskLayerCount() const { 1357 return mAncestorMaskLayers.Length(); 1358 } GetAncestorMaskLayerAt(size_t aIndex)1359 Layer* GetAncestorMaskLayerAt(size_t aIndex) const { 1360 return mAncestorMaskLayers.ElementAt(aIndex); 1361 } GetAllAncestorMaskLayers()1362 const nsTArray<RefPtr<Layer>>& GetAllAncestorMaskLayers() const { 1363 return mAncestorMaskLayers; 1364 } 1365 HasMaskLayers()1366 bool HasMaskLayers() const { 1367 return GetMaskLayer() || mAncestorMaskLayers.Length() > 0; 1368 } 1369 1370 /* 1371 * Get the combined clip rect of the Layer clip and all clips on FrameMetrics. 1372 * This is intended for use in Layout. The compositor needs to apply async 1373 * transforms to find the combined clip. 1374 */ 1375 Maybe<ParentLayerIntRect> GetCombinedClipRect() const; 1376 1377 /** 1378 * Retrieve the root level visible region for |this| taking into account 1379 * clipping applied to parent layers of |this| as well as subtracting 1380 * visible regions of higher siblings of this layer and each ancestor. 1381 * 1382 * Note translation values for offsets of visible regions and accumulated 1383 * aLayerOffset are integer rounded using IntPoint::Round. 1384 * 1385 * @param aResult - the resulting visible region of this layer. 1386 * @param aLayerOffset - this layer's total offset from the root layer. 1387 * @return - false if during layer tree traversal a parent or sibling 1388 * transform is found to be non-translational. This method returns early 1389 * in this case, results will not be valid. Returns true on successful 1390 * traversal. 1391 */ 1392 bool GetVisibleRegionRelativeToRootLayer(nsIntRegion& aResult, 1393 nsIntPoint* aLayerOffset); 1394 1395 // Note that all lengths in animation data are either in CSS pixels or app 1396 // units and must be converted to device pixels by the compositor. GetAnimations()1397 AnimationArray& GetAnimations() { return mAnimations; } GetAnimationData()1398 InfallibleTArray<AnimData>& GetAnimationData() { return mAnimationData; } 1399 GetAnimationGeneration()1400 uint64_t GetAnimationGeneration() { return mAnimationGeneration; } SetAnimationGeneration(uint64_t aCount)1401 void SetAnimationGeneration(uint64_t aCount) { mAnimationGeneration = aCount; } 1402 1403 bool HasTransformAnimation() const; 1404 1405 /** 1406 * Returns the local transform for this layer: either mTransform or, 1407 * for shadow layers, GetShadowBaseTransform(), in either case with the 1408 * pre- and post-scales applied. 1409 */ 1410 gfx::Matrix4x4 GetLocalTransform(); 1411 1412 /** 1413 * Same as GetLocalTransform(), but returns a strongly-typed matrix. 1414 * Eventually, this will replace GetLocalTransform(). 1415 */ 1416 const LayerToParentLayerMatrix4x4 GetLocalTransformTyped(); 1417 1418 /** 1419 * Returns the local opacity for this layer: either mOpacity or, 1420 * for shadow layers, GetShadowOpacity() 1421 */ 1422 float GetLocalOpacity(); 1423 1424 /** 1425 * DRAWING PHASE ONLY 1426 * 1427 * Apply pending changes to layers before drawing them, if those 1428 * pending changes haven't been overridden by later changes. 1429 */ 1430 void ApplyPendingUpdatesToSubtree(); 1431 1432 /** 1433 * DRAWING PHASE ONLY 1434 * 1435 * Write layer-subtype-specific attributes into aAttrs. Used to 1436 * synchronize layer attributes to their shadows'. 1437 */ FillSpecificAttributes(SpecificLayerAttributes & aAttrs)1438 virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) { } 1439 1440 // Returns true if it's OK to save the contents of aLayer in an 1441 // opaque surface (a surface without an alpha channel). 1442 // If we can use a surface without an alpha channel, we should, because 1443 // it will often make painting of antialiased text faster and higher 1444 // quality. 1445 bool CanUseOpaqueSurface(); 1446 GetSurfaceMode()1447 SurfaceMode GetSurfaceMode() 1448 { 1449 if (CanUseOpaqueSurface()) 1450 return SurfaceMode::SURFACE_OPAQUE; 1451 if (mContentFlags & CONTENT_COMPONENT_ALPHA) 1452 return SurfaceMode::SURFACE_COMPONENT_ALPHA; 1453 return SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA; 1454 } 1455 1456 // Returns true if this layer can be treated as opaque for visibility 1457 // computation. A layer may be non-opaque for visibility even if it 1458 // is not transparent, for example, if it has a mix-blend-mode. 1459 bool IsOpaqueForVisibility(); 1460 1461 /** 1462 * This setter can be used anytime. The user data for all keys is 1463 * initially null. Ownership pases to the layer manager. 1464 */ SetUserData(void * aKey,LayerUserData * aData)1465 void SetUserData(void* aKey, LayerUserData* aData) 1466 { 1467 mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerManager::LayerUserDataDestroy); 1468 } 1469 /** 1470 * This can be used anytime. Ownership passes to the caller! 1471 */ 1472 UniquePtr<LayerUserData> RemoveUserData(void* aKey); 1473 /** 1474 * This getter can be used anytime. 1475 */ HasUserData(void * aKey)1476 bool HasUserData(void* aKey) 1477 { 1478 return mUserData.Has(static_cast<gfx::UserDataKey*>(aKey)); 1479 } 1480 /** 1481 * This getter can be used anytime. Ownership is retained by the layer 1482 * manager. 1483 */ GetUserData(void * aKey)1484 LayerUserData* GetUserData(void* aKey) const 1485 { 1486 return static_cast<LayerUserData*>(mUserData.Get(static_cast<gfx::UserDataKey*>(aKey))); 1487 } 1488 1489 /** 1490 * |Disconnect()| is used by layers hooked up over IPC. It may be 1491 * called at any time, and may not be called at all. Using an 1492 * IPC-enabled layer after Destroy() (drawing etc.) results in a 1493 * safe no-op; no crashy or uaf etc. 1494 * 1495 * XXX: this interface is essentially LayerManager::Destroy, but at 1496 * Layer granularity. It might be beneficial to unify them. 1497 */ Disconnect()1498 virtual void Disconnect() {} 1499 1500 /** 1501 * Dynamic downcast to a PaintedLayer. Returns null if this is not 1502 * a PaintedLayer. 1503 */ AsPaintedLayer()1504 virtual PaintedLayer* AsPaintedLayer() { return nullptr; } 1505 1506 /** 1507 * Dynamic cast to a ContainerLayer. Returns null if this is not 1508 * a ContainerLayer. 1509 */ AsContainerLayer()1510 virtual ContainerLayer* AsContainerLayer() { return nullptr; } AsContainerLayer()1511 virtual const ContainerLayer* AsContainerLayer() const { return nullptr; } 1512 1513 /** 1514 * Dynamic cast to a RefLayer. Returns null if this is not a 1515 * RefLayer. 1516 */ AsRefLayer()1517 virtual RefLayer* AsRefLayer() { return nullptr; } 1518 1519 /** 1520 * Dynamic cast to a Color. Returns null if this is not a 1521 * ColorLayer. 1522 */ AsColorLayer()1523 virtual ColorLayer* AsColorLayer() { return nullptr; } 1524 1525 /** 1526 * Dynamic cast to a LayerComposite. Return null if this is not a 1527 * LayerComposite. Can be used anytime. 1528 */ AsLayerComposite()1529 virtual LayerComposite* AsLayerComposite() { return nullptr; } 1530 1531 /** 1532 * Dynamic cast to a ShadowableLayer. Return null if this is not a 1533 * ShadowableLayer. Can be used anytime. 1534 */ AsShadowableLayer()1535 virtual ShadowableLayer* AsShadowableLayer() { return nullptr; } 1536 1537 // These getters can be used anytime. They return the effective 1538 // values that should be used when drawing this layer to screen, 1539 // accounting for this layer possibly being a shadow. 1540 const Maybe<ParentLayerIntRect>& GetLocalClipRect(); 1541 const LayerIntRegion& GetLocalVisibleRegion(); 1542 Extend3DContext()1543 bool Extend3DContext() { 1544 return GetContentFlags() & CONTENT_EXTEND_3D_CONTEXT; 1545 } Combines3DTransformWithAncestors()1546 bool Combines3DTransformWithAncestors() { 1547 return GetParent() && 1548 reinterpret_cast<Layer*>(GetParent())->Extend3DContext(); 1549 } Is3DContextLeaf()1550 bool Is3DContextLeaf() { 1551 return !Extend3DContext() && Combines3DTransformWithAncestors(); 1552 } 1553 /** 1554 * It is true if the user can see the back of the layer and the 1555 * backface is hidden. The compositor should skip the layer if the 1556 * result is true. 1557 */ 1558 bool IsBackfaceHidden(); IsVisible()1559 bool IsVisible() { 1560 // For containers extending 3D context, visible region 1561 // is meaningless, since they are just intermediate result of 1562 // content. 1563 return !GetLocalVisibleRegion().IsEmpty() || Extend3DContext(); 1564 } 1565 1566 /** 1567 * Return true if current layer content is opaque. 1568 * It does not guarantee that layer content is always opaque. 1569 */ IsOpaque()1570 virtual bool IsOpaque() { return GetContentFlags() & CONTENT_OPAQUE; } 1571 1572 /** 1573 * Returns the product of the opacities of this layer and all ancestors up 1574 * to and excluding the nearest ancestor that has UseIntermediateSurface() set. 1575 */ 1576 float GetEffectiveOpacity(); 1577 1578 /** 1579 * Returns the blendmode of this layer. 1580 */ 1581 gfx::CompositionOp GetEffectiveMixBlendMode(); 1582 1583 /** 1584 * This returns the effective transform computed by 1585 * ComputeEffectiveTransforms. Typically this is a transform that transforms 1586 * this layer all the way to some intermediate surface or destination 1587 * surface. For non-BasicLayers this will be a transform to the nearest 1588 * ancestor with UseIntermediateSurface() (or to the root, if there is no 1589 * such ancestor), but for BasicLayers it's different. 1590 */ GetEffectiveTransform()1591 const gfx::Matrix4x4& GetEffectiveTransform() const { return mEffectiveTransform; } 1592 1593 /** 1594 * This returns the effective transform for Layer's buffer computed by 1595 * ComputeEffectiveTransforms. Typically this is a transform that transforms 1596 * this layer's buffer all the way to some intermediate surface or destination 1597 * surface. For non-BasicLayers this will be a transform to the nearest 1598 * ancestor with UseIntermediateSurface() (or to the root, if there is no 1599 * such ancestor), but for BasicLayers it's different. 1600 * 1601 * By default, its value is same to GetEffectiveTransform(). 1602 * When ImageLayer is rendered with ScaleMode::STRETCH, 1603 * it becomes different from GetEffectiveTransform(). 1604 */ GetEffectiveTransformForBuffer()1605 virtual const gfx::Matrix4x4& GetEffectiveTransformForBuffer() const 1606 { 1607 return mEffectiveTransform; 1608 } 1609 1610 /** 1611 * @param aTransformToSurface the composition of the transforms 1612 * from the parent layer (if any) to the destination pixel grid. 1613 * 1614 * Computes mEffectiveTransform for this layer and all its descendants. 1615 * mEffectiveTransform transforms this layer up to the destination 1616 * pixel grid (whatever aTransformToSurface is relative to). 1617 * 1618 * We promise that when this is called on a layer, all ancestor layers 1619 * have already had ComputeEffectiveTransforms called. 1620 */ 1621 virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) = 0; 1622 1623 /** 1624 * Computes the effective transform for mask layers, if this layer has any. 1625 */ 1626 void ComputeEffectiveTransformForMaskLayers(const gfx::Matrix4x4& aTransformToSurface); 1627 static void ComputeEffectiveTransformForMaskLayer(Layer* aMaskLayer, 1628 const gfx::Matrix4x4& aTransformToSurface); 1629 1630 /** 1631 * Calculate the scissor rect required when rendering this layer. 1632 * Returns a rectangle relative to the intermediate surface belonging to the 1633 * nearest ancestor that has an intermediate surface, or relative to the root 1634 * viewport if no ancestor has an intermediate surface, corresponding to the 1635 * clip rect for this layer intersected with aCurrentScissorRect. 1636 */ 1637 RenderTargetIntRect CalculateScissorRect(const RenderTargetIntRect& aCurrentScissorRect); 1638 1639 virtual const char* Name() const =0; 1640 virtual LayerType GetType() const =0; 1641 1642 /** 1643 * Only the implementation should call this. This is per-implementation 1644 * private data. Normally, all layers with a given layer manager 1645 * use the same type of ImplData. 1646 */ ImplData()1647 void* ImplData() { return mImplData; } 1648 1649 /** 1650 * Only the implementation should use these methods. 1651 */ SetParent(ContainerLayer * aParent)1652 void SetParent(ContainerLayer* aParent) { mParent = aParent; } SetNextSibling(Layer * aSibling)1653 void SetNextSibling(Layer* aSibling) { mNextSibling = aSibling; } SetPrevSibling(Layer * aSibling)1654 void SetPrevSibling(Layer* aSibling) { mPrevSibling = aSibling; } 1655 1656 /** 1657 * Dump information about this layer manager and its managed tree to 1658 * aStream. 1659 */ 1660 void Dump(std::stringstream& aStream, const char* aPrefix="", 1661 bool aDumpHtml=false, bool aSorted=false); 1662 /** 1663 * Dump information about just this layer manager itself to aStream. 1664 */ 1665 void DumpSelf(std::stringstream& aStream, const char* aPrefix=""); 1666 1667 /** 1668 * Dump information about this layer and its child & sibling layers to 1669 * layerscope packet. 1670 */ 1671 void Dump(layerscope::LayersPacket* aPacket, const void* aParent); 1672 1673 /** 1674 * Log information about this layer manager and its managed tree to 1675 * the NSPR log (if enabled for "Layers"). 1676 */ 1677 void Log(const char* aPrefix=""); 1678 /** 1679 * Log information about just this layer manager itself to the NSPR 1680 * log (if enabled for "Layers"). 1681 */ 1682 void LogSelf(const char* aPrefix=""); 1683 1684 // Print interesting information about this into aStream. Internally 1685 // used to implement Dump*() and Log*(). If subclasses have 1686 // additional interesting properties, they should override this with 1687 // an implementation that first calls the base implementation then 1688 // appends additional info to aTo. 1689 virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix); 1690 1691 // Just like PrintInfo, but this function dump information into layerscope packet, 1692 // instead of a StringStream. It is also internally used to implement Dump(); 1693 virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent); 1694 1695 /** 1696 * Store display list log. 1697 */ 1698 void SetDisplayListLog(const char *log); 1699 1700 /** 1701 * Return display list log. 1702 */ 1703 void GetDisplayListLog(nsCString& log); 1704 IsLogEnabled()1705 static bool IsLogEnabled() { return LayerManager::IsLogEnabled(); } 1706 1707 /** 1708 * Returns the current area of the layer (in layer-space coordinates) 1709 * marked as needed to be recomposited. 1710 */ GetInvalidRegion()1711 const virtual gfx::TiledIntRegion& GetInvalidRegion() { return mInvalidRegion; } AddInvalidRegion(const nsIntRegion & aRegion)1712 void AddInvalidRegion(const nsIntRegion& aRegion) { 1713 mInvalidRegion.Add(aRegion); 1714 } 1715 1716 /** 1717 * Mark the entirety of the layer's visible region as being invalid. 1718 */ SetInvalidRectToVisibleRegion()1719 void SetInvalidRectToVisibleRegion() 1720 { 1721 mInvalidRegion.SetEmpty(); 1722 mInvalidRegion.Add(GetVisibleRegion().ToUnknownRegion()); 1723 } 1724 1725 /** 1726 * Adds to the current invalid rect. 1727 */ AddInvalidRect(const gfx::IntRect & aRect)1728 void AddInvalidRect(const gfx::IntRect& aRect) { mInvalidRegion.Add(aRect); } 1729 1730 /** 1731 * Clear the invalid rect, marking the layer as being identical to what is currently 1732 * composited. 1733 */ ClearInvalidRect()1734 void ClearInvalidRect() { mInvalidRegion.SetEmpty(); } 1735 1736 // These functions allow attaching an AsyncPanZoomController to this layer, 1737 // and can be used anytime. 1738 // A layer has an APZC at index aIndex only-if GetFrameMetrics(aIndex).IsScrollable(); 1739 // attempting to get an APZC for a non-scrollable metrics will return null. 1740 // The aIndex for these functions must be less than GetScrollMetadataCount(). 1741 void SetAsyncPanZoomController(uint32_t aIndex, AsyncPanZoomController *controller); 1742 AsyncPanZoomController* GetAsyncPanZoomController(uint32_t aIndex) const; 1743 // The ScrollMetadataChanged function is used internally to ensure the APZC array length 1744 // matches the frame metrics array length. 1745 private: 1746 void ScrollMetadataChanged(); 1747 public: 1748 1749 void ApplyPendingUpdatesForThisTransaction(); 1750 1751 #ifdef DEBUG SetDebugColorIndex(uint32_t aIndex)1752 void SetDebugColorIndex(uint32_t aIndex) { mDebugColorIndex = aIndex; } GetDebugColorIndex()1753 uint32_t GetDebugColorIndex() { return mDebugColorIndex; } 1754 #endif 1755 GetRenderState()1756 virtual LayerRenderState GetRenderState() { return LayerRenderState(); } 1757 Mutated()1758 void Mutated() 1759 { 1760 mManager->Mutated(this); 1761 } 1762 GetMaxLayerSize()1763 virtual int32_t GetMaxLayerSize() { return Manager()->GetMaxTextureSize(); } 1764 1765 /** 1766 * Returns true if this layer's effective transform is not just 1767 * a translation by integers, or if this layer or some ancestor layer 1768 * is marked as having a transform that may change without a full layer 1769 * transaction. 1770 */ 1771 bool MayResample(); 1772 1773 RenderTargetRect TransformRectToRenderTarget(const LayerIntRect& aRect); 1774 1775 /** 1776 * Add debugging information to the layer dump. 1777 */ AddExtraDumpInfo(const nsACString & aStr)1778 void AddExtraDumpInfo(const nsACString& aStr) 1779 { 1780 #ifdef MOZ_DUMP_PAINTING 1781 mExtraDumpInfo.AppendElement(aStr); 1782 #endif 1783 } 1784 1785 /** 1786 * Clear debugging information. Useful for recycling. 1787 */ ClearExtraDumpInfo()1788 void ClearExtraDumpInfo() 1789 { 1790 #ifdef MOZ_DUMP_PAINTING 1791 mExtraDumpInfo.Clear(); 1792 #endif 1793 } 1794 1795 protected: 1796 Layer(LayerManager* aManager, void* aImplData); 1797 1798 // Protected destructor, to discourage deletion outside of Release(): 1799 virtual ~Layer(); 1800 1801 /** 1802 * We can snap layer transforms for two reasons: 1803 * 1) To avoid unnecessary resampling when a transform is a translation 1804 * by a non-integer number of pixels. 1805 * Snapping the translation to an integer number of pixels avoids 1806 * blurring the layer and can be faster to composite. 1807 * 2) When a layer is used to render a rectangular object, we need to 1808 * emulate the rendering of rectangular inactive content and snap the 1809 * edges of the rectangle to pixel boundaries. This is both to ensure 1810 * layer rendering is consistent with inactive content rendering, and to 1811 * avoid seams. 1812 * This function implements type 1 snapping. If aTransform is a 2D 1813 * translation, and this layer's layer manager has enabled snapping 1814 * (which is the default), return aTransform with the translation snapped 1815 * to nearest pixels. Otherwise just return aTransform. Call this when the 1816 * layer does not correspond to a single rectangular content object. 1817 * This function does not try to snap if aTransform has a scale, because in 1818 * that case resampling is inevitable and there's no point in trying to 1819 * avoid it. In fact snapping can cause problems because pixel edges in the 1820 * layer's content can be rendered unpredictably (jiggling) as the scale 1821 * interacts with the snapping of the translation, especially with animated 1822 * transforms. 1823 * @param aResidualTransform a transform to apply before the result transform 1824 * in order to get the results to completely match aTransform. 1825 */ 1826 gfx::Matrix4x4 SnapTransformTranslation(const gfx::Matrix4x4& aTransform, 1827 gfx::Matrix* aResidualTransform); 1828 gfx::Matrix4x4 SnapTransformTranslation3D(const gfx::Matrix4x4& aTransform, 1829 gfx::Matrix* aResidualTransform); 1830 /** 1831 * See comment for SnapTransformTranslation. 1832 * This function implements type 2 snapping. If aTransform is a translation 1833 * and/or scale, transform aSnapRect by aTransform, snap to pixel boundaries, 1834 * and return the transform that maps aSnapRect to that rect. Otherwise 1835 * just return aTransform. 1836 * @param aSnapRect a rectangle whose edges should be snapped to pixel 1837 * boundaries in the destination surface. 1838 * @param aResidualTransform a transform to apply before the result transform 1839 * in order to get the results to completely match aTransform. 1840 */ 1841 gfx::Matrix4x4 SnapTransform(const gfx::Matrix4x4& aTransform, 1842 const gfxRect& aSnapRect, 1843 gfx::Matrix* aResidualTransform); 1844 1845 LayerManager* mManager; 1846 ContainerLayer* mParent; 1847 Layer* mNextSibling; 1848 Layer* mPrevSibling; 1849 void* mImplData; 1850 RefPtr<Layer> mMaskLayer; 1851 nsTArray<RefPtr<Layer>> mAncestorMaskLayers; 1852 // Look for out-of-bound in the middle of the structure 1853 mozilla::CorruptionCanary mCanary; 1854 gfx::UserData mUserData; 1855 gfx::IntRect mLayerBounds; 1856 LayerIntRegion mVisibleRegion; 1857 nsTArray<ScrollMetadata> mScrollMetadata; 1858 EventRegions mEventRegions; 1859 gfx::Matrix4x4 mTransform; 1860 // A mutation of |mTransform| that we've queued to be applied at the 1861 // end of the next transaction (if nothing else overrides it in the 1862 // meantime). 1863 nsAutoPtr<gfx::Matrix4x4> mPendingTransform; 1864 float mPostXScale; 1865 float mPostYScale; 1866 gfx::Matrix4x4 mEffectiveTransform; 1867 AnimationArray mAnimations; 1868 // See mPendingTransform above. 1869 nsAutoPtr<AnimationArray> mPendingAnimations; 1870 InfallibleTArray<AnimData> mAnimationData; 1871 float mOpacity; 1872 gfx::CompositionOp mMixBlendMode; 1873 bool mForceIsolatedGroup; 1874 Maybe<ParentLayerIntRect> mClipRect; 1875 Maybe<LayerClip> mScrolledClip; 1876 gfx::IntRect mTileSourceRect; 1877 gfx::TiledIntRegion mInvalidRegion; 1878 nsTArray<RefPtr<AsyncPanZoomController> > mApzcs; 1879 uint32_t mContentFlags; 1880 bool mUseTileSourceRect; 1881 bool mIsFixedPosition; 1882 bool mTransformIsPerspective; 1883 struct FixedPositionData { 1884 FrameMetrics::ViewID mScrollId; 1885 LayerPoint mAnchor; 1886 int32_t mSides; 1887 }; 1888 UniquePtr<FixedPositionData> mFixedPositionData; 1889 struct StickyPositionData { 1890 FrameMetrics::ViewID mScrollId; 1891 LayerRect mOuter; 1892 LayerRect mInner; 1893 }; 1894 nsAutoPtr<StickyPositionData> mStickyPositionData; 1895 FrameMetrics::ViewID mScrollbarTargetId; 1896 ScrollDirection mScrollbarDirection; 1897 // The scrollbar thumb ratio is the ratio of the thumb position (in the CSS 1898 // pixels of the scrollframe's parent's space) to the scroll position (in the 1899 // CSS pixels of the scrollframe's space). 1900 float mScrollbarThumbRatio; 1901 bool mIsScrollbarContainer; 1902 #ifdef DEBUG 1903 uint32_t mDebugColorIndex; 1904 #endif 1905 // If this layer is used for OMTA, then this counter is used to ensure we 1906 // stay in sync with the animation manager 1907 uint64_t mAnimationGeneration; 1908 #ifdef MOZ_DUMP_PAINTING 1909 nsTArray<nsCString> mExtraDumpInfo; 1910 #endif 1911 // Store display list log. 1912 nsCString mDisplayListLog; 1913 }; 1914 1915 /** 1916 * A Layer which we can paint into. It is a conceptually 1917 * infinite surface, but each PaintedLayer has an associated "valid region" 1918 * of contents that it is currently storing, which is finite. PaintedLayer 1919 * implementations can store content between paints. 1920 * 1921 * PaintedLayers are rendered into during the drawing phase of a transaction. 1922 * 1923 * Currently the contents of a PaintedLayer are in the device output color 1924 * space. 1925 */ 1926 class PaintedLayer : public Layer { 1927 public: 1928 /** 1929 * CONSTRUCTION PHASE ONLY 1930 * Tell this layer that the content in some region has changed and 1931 * will need to be repainted. This area is removed from the valid 1932 * region. 1933 */ 1934 virtual void InvalidateRegion(const nsIntRegion& aRegion) = 0; 1935 /** 1936 * CONSTRUCTION PHASE ONLY 1937 * Set whether ComputeEffectiveTransforms should compute the 1938 * "residual translation" --- the translation that should be applied *before* 1939 * mEffectiveTransform to get the ideal transform for this PaintedLayer. 1940 * When this is true, ComputeEffectiveTransforms will compute the residual 1941 * and ensure that the layer is invalidated whenever the residual changes. 1942 * When it's false, a change in the residual will not trigger invalidation 1943 * and GetResidualTranslation will return 0,0. 1944 * So when the residual is to be ignored, set this to false for better 1945 * performance. 1946 */ SetAllowResidualTranslation(bool aAllow)1947 void SetAllowResidualTranslation(bool aAllow) { mAllowResidualTranslation = aAllow; } 1948 1949 /** 1950 * Can be used anytime 1951 */ GetValidRegion()1952 const nsIntRegion& GetValidRegion() const { return mValidRegion; } 1953 AsPaintedLayer()1954 virtual PaintedLayer* AsPaintedLayer() override { return this; } 1955 1956 MOZ_LAYER_DECL_NAME("PaintedLayer", TYPE_PAINTED) 1957 ComputeEffectiveTransforms(const gfx::Matrix4x4 & aTransformToSurface)1958 virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override 1959 { 1960 gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface; 1961 gfx::Matrix residual; 1962 mEffectiveTransform = SnapTransformTranslation(idealTransform, 1963 mAllowResidualTranslation ? &residual : nullptr); 1964 // The residual can only be a translation because SnapTransformTranslation 1965 // only changes the transform if it's a translation 1966 NS_ASSERTION(residual.IsTranslation(), 1967 "Residual transform can only be a translation"); 1968 if (!gfx::ThebesPoint(residual.GetTranslation()).WithinEpsilonOf(mResidualTranslation, 1e-3f)) { 1969 mResidualTranslation = gfx::ThebesPoint(residual.GetTranslation()); 1970 DebugOnly<mozilla::gfx::Point> transformedOrig = 1971 idealTransform.TransformPoint(mozilla::gfx::Point()); 1972 #ifdef DEBUG 1973 DebugOnly<mozilla::gfx::Point> transformed = idealTransform.TransformPoint( 1974 mozilla::gfx::Point(mResidualTranslation.x, mResidualTranslation.y) 1975 ) - *&transformedOrig; 1976 #endif 1977 NS_ASSERTION(-0.5 <= (&transformed)->x && (&transformed)->x < 0.5 && 1978 -0.5 <= (&transformed)->y && (&transformed)->y < 0.5, 1979 "Residual translation out of range"); 1980 mValidRegion.SetEmpty(); 1981 } 1982 ComputeEffectiveTransformForMaskLayers(aTransformToSurface); 1983 } 1984 GetCreationHint()1985 LayerManager::PaintedLayerCreationHint GetCreationHint() const { return mCreationHint; } 1986 UsedForReadback()1987 bool UsedForReadback() { return mUsedForReadback; } SetUsedForReadback(bool aUsed)1988 void SetUsedForReadback(bool aUsed) { mUsedForReadback = aUsed; } 1989 1990 /** 1991 * Returns true if aLayer is optimized for the given PaintedLayerCreationHint. 1992 */ IsOptimizedFor(LayerManager::PaintedLayerCreationHint aCreationHint)1993 virtual bool IsOptimizedFor(LayerManager::PaintedLayerCreationHint aCreationHint) 1994 { return true; } 1995 1996 /** 1997 * Returns the residual translation. Apply this translation when drawing 1998 * into the PaintedLayer so that when mEffectiveTransform is applied afterwards 1999 * by layer compositing, the results exactly match the "ideal transform" 2000 * (the product of the transform of this layer and its ancestors). 2001 * Returns 0,0 unless SetAllowResidualTranslation(true) has been called. 2002 * The residual translation components are always in the range [-0.5, 0.5). 2003 */ GetResidualTranslation()2004 gfxPoint GetResidualTranslation() const { return mResidualTranslation; } 2005 2006 protected: 2007 PaintedLayer(LayerManager* aManager, void* aImplData, 2008 LayerManager::PaintedLayerCreationHint aCreationHint = LayerManager::NONE) Layer(aManager,aImplData)2009 : Layer(aManager, aImplData) 2010 , mValidRegion() 2011 , mCreationHint(aCreationHint) 2012 , mUsedForReadback(false) 2013 , mAllowResidualTranslation(false) 2014 { 2015 mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT 2016 } 2017 2018 virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; 2019 2020 virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override; 2021 2022 /** 2023 * ComputeEffectiveTransforms snaps the ideal transform to get mEffectiveTransform. 2024 * mResidualTranslation is the translation that should be applied *before* 2025 * mEffectiveTransform to get the ideal transform. 2026 */ 2027 gfxPoint mResidualTranslation; 2028 nsIntRegion mValidRegion; 2029 /** 2030 * The creation hint that was used when constructing this layer. 2031 */ 2032 const LayerManager::PaintedLayerCreationHint mCreationHint; 2033 /** 2034 * Set when this PaintedLayer is participating in readback, i.e. some 2035 * ReadbackLayer (may) be getting its background from this layer. 2036 */ 2037 bool mUsedForReadback; 2038 /** 2039 * True when 2040 */ 2041 bool mAllowResidualTranslation; 2042 }; 2043 2044 /** 2045 * A Layer which other layers render into. It holds references to its 2046 * children. 2047 */ 2048 class ContainerLayer : public Layer { 2049 public: 2050 2051 ~ContainerLayer(); 2052 2053 /** 2054 * CONSTRUCTION PHASE ONLY 2055 * Insert aChild into the child list of this container. aChild must 2056 * not be currently in any child list or the root for the layer manager. 2057 * If aAfter is non-null, it must be a child of this container and 2058 * we insert after that layer. If it's null we insert at the start. 2059 */ 2060 virtual bool InsertAfter(Layer* aChild, Layer* aAfter); 2061 /** 2062 * CONSTRUCTION PHASE ONLY 2063 * Remove aChild from the child list of this container. aChild must 2064 * be a child of this container. 2065 */ 2066 virtual bool RemoveChild(Layer* aChild); 2067 /** 2068 * CONSTRUCTION PHASE ONLY 2069 * Reposition aChild from the child list of this container. aChild must 2070 * be a child of this container. 2071 * If aAfter is non-null, it must be a child of this container and we 2072 * reposition after that layer. If it's null, we reposition at the start. 2073 */ 2074 virtual bool RepositionChild(Layer* aChild, Layer* aAfter); 2075 SetPreScale(float aXScale,float aYScale)2076 void SetPreScale(float aXScale, float aYScale) 2077 { 2078 if (mPreXScale == aXScale && mPreYScale == aYScale) { 2079 return; 2080 } 2081 2082 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PreScale", this)); 2083 mPreXScale = aXScale; 2084 mPreYScale = aYScale; 2085 Mutated(); 2086 } 2087 SetInheritedScale(float aXScale,float aYScale)2088 void SetInheritedScale(float aXScale, float aYScale) 2089 { 2090 if (mInheritedXScale == aXScale && mInheritedYScale == aYScale) { 2091 return; 2092 } 2093 2094 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) InheritedScale", this)); 2095 mInheritedXScale = aXScale; 2096 mInheritedYScale = aYScale; 2097 Mutated(); 2098 } 2099 SetScaleToResolution(bool aScaleToResolution,float aResolution)2100 void SetScaleToResolution(bool aScaleToResolution, float aResolution) 2101 { 2102 if (mScaleToResolution == aScaleToResolution && mPresShellResolution == aResolution) { 2103 return; 2104 } 2105 2106 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScaleToResolution", this)); 2107 mScaleToResolution = aScaleToResolution; 2108 mPresShellResolution = aResolution; 2109 Mutated(); 2110 } 2111 2112 virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) override; 2113 2114 void SortChildrenBy3DZOrder(nsTArray<Layer*>& aArray); 2115 2116 // These getters can be used anytime. 2117 AsContainerLayer()2118 virtual ContainerLayer* AsContainerLayer() override { return this; } AsContainerLayer()2119 virtual const ContainerLayer* AsContainerLayer() const override { return this; } 2120 GetFirstChild()2121 virtual Layer* GetFirstChild() const override { return mFirstChild; } GetLastChild()2122 virtual Layer* GetLastChild() const override { return mLastChild; } GetPreXScale()2123 float GetPreXScale() const { return mPreXScale; } GetPreYScale()2124 float GetPreYScale() const { return mPreYScale; } GetInheritedXScale()2125 float GetInheritedXScale() const { return mInheritedXScale; } GetInheritedYScale()2126 float GetInheritedYScale() const { return mInheritedYScale; } GetPresShellResolution()2127 float GetPresShellResolution() const { return mPresShellResolution; } ScaleToResolution()2128 bool ScaleToResolution() const { return mScaleToResolution; } 2129 2130 MOZ_LAYER_DECL_NAME("ContainerLayer", TYPE_CONTAINER) 2131 2132 /** 2133 * ContainerLayer backends need to override ComputeEffectiveTransforms 2134 * since the decision about whether to use a temporary surface for the 2135 * container is backend-specific. ComputeEffectiveTransforms must also set 2136 * mUseIntermediateSurface. 2137 */ 2138 virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override = 0; 2139 2140 /** 2141 * Call this only after ComputeEffectiveTransforms has been invoked 2142 * on this layer. 2143 * Returns true if this will use an intermediate surface. This is largely 2144 * backend-dependent, but it affects the operation of GetEffectiveOpacity(). 2145 */ UseIntermediateSurface()2146 bool UseIntermediateSurface() { return mUseIntermediateSurface; } 2147 2148 /** 2149 * Returns the rectangle covered by the intermediate surface, 2150 * in this layer's coordinate system. 2151 * 2152 * NOTE: Since this layer has an intermediate surface it follows 2153 * that LayerPixel == RenderTargetPixel 2154 */ GetIntermediateSurfaceRect()2155 RenderTargetIntRect GetIntermediateSurfaceRect() 2156 { 2157 NS_ASSERTION(mUseIntermediateSurface, "Must have intermediate surface"); 2158 return RenderTargetIntRect::FromUnknownRect(GetLocalVisibleRegion().ToUnknownRegion().GetBounds()); 2159 } 2160 2161 /** 2162 * Returns true if this container has more than one non-empty child 2163 */ 2164 bool HasMultipleChildren(); 2165 2166 /** 2167 * Returns true if this container supports children with component alpha. 2168 * Should only be called while painting a child of this layer. 2169 */ SupportsComponentAlphaChildren()2170 bool SupportsComponentAlphaChildren() { return mSupportsComponentAlphaChildren; } 2171 2172 /** 2173 * Returns true if aLayer or any layer in its parent chain has the opaque 2174 * content flag set. 2175 */ 2176 static bool HasOpaqueAncestorLayer(Layer* aLayer); 2177 SetChildrenChanged(bool aVal)2178 void SetChildrenChanged(bool aVal) { 2179 mChildrenChanged = aVal; 2180 } 2181 SetEventRegionsOverride(EventRegionsOverride aVal)2182 void SetEventRegionsOverride(EventRegionsOverride aVal) { 2183 if (mEventRegionsOverride == aVal) { 2184 return; 2185 } 2186 2187 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) EventRegionsOverride", this)); 2188 mEventRegionsOverride = aVal; 2189 Mutated(); 2190 } 2191 GetEventRegionsOverride()2192 EventRegionsOverride GetEventRegionsOverride() const { 2193 return mEventRegionsOverride; 2194 } 2195 2196 protected: 2197 friend class ReadbackProcessor; 2198 2199 void DidInsertChild(Layer* aLayer); 2200 void DidRemoveChild(Layer* aLayer); 2201 2202 void Collect3DContextLeaves(nsTArray<Layer*>& aToSort); 2203 2204 ContainerLayer(LayerManager* aManager, void* aImplData); 2205 2206 /** 2207 * A default implementation of ComputeEffectiveTransforms for use by OpenGL 2208 * and D3D. 2209 */ 2210 void DefaultComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface); 2211 2212 /** 2213 * A default implementation to compute and set the value for SupportsComponentAlphaChildren(). 2214 * 2215 * If aNeedsSurfaceCopy is provided, then it is set to true if the caller needs to copy the background 2216 * up into the intermediate surface created, false otherwise. 2217 */ 2218 void DefaultComputeSupportsComponentAlphaChildren(bool* aNeedsSurfaceCopy = nullptr); 2219 2220 /** 2221 * Loops over the children calling ComputeEffectiveTransforms on them. 2222 */ 2223 void ComputeEffectiveTransformsForChildren(const gfx::Matrix4x4& aTransformToSurface); 2224 2225 virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; 2226 2227 virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override; 2228 2229 /** 2230 * True for if the container start a new 3D context extended by one 2231 * or more children. 2232 */ 2233 bool Creates3DContextWithExtendingChildren(); 2234 2235 Layer* mFirstChild; 2236 Layer* mLastChild; 2237 float mPreXScale; 2238 float mPreYScale; 2239 // The resolution scale inherited from the parent layer. This will already 2240 // be part of mTransform. 2241 float mInheritedXScale; 2242 float mInheritedYScale; 2243 // For layers corresponding to an nsDisplayResolution, the resolution of the 2244 // associated pres shell; for other layers, 1.0. 2245 float mPresShellResolution; 2246 // Whether the compositor should scale to mPresShellResolution. 2247 bool mScaleToResolution; 2248 bool mUseIntermediateSurface; 2249 bool mSupportsComponentAlphaChildren; 2250 bool mMayHaveReadbackChild; 2251 // This is updated by ComputeDifferences. This will be true if we need to invalidate 2252 // the intermediate surface. 2253 bool mChildrenChanged; 2254 EventRegionsOverride mEventRegionsOverride; 2255 }; 2256 2257 /** 2258 * A Layer which just renders a solid color in its visible region. It actually 2259 * can fill any area that contains the visible region, so if you need to 2260 * restrict the area filled, set a clip region on this layer. 2261 */ 2262 class ColorLayer : public Layer { 2263 public: AsColorLayer()2264 virtual ColorLayer* AsColorLayer() override { return this; } 2265 2266 /** 2267 * CONSTRUCTION PHASE ONLY 2268 * Set the color of the layer. 2269 */ SetColor(const gfx::Color & aColor)2270 virtual void SetColor(const gfx::Color& aColor) 2271 { 2272 if (mColor != aColor) { 2273 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Color", this)); 2274 mColor = aColor; 2275 Mutated(); 2276 } 2277 } 2278 SetBounds(const gfx::IntRect & aBounds)2279 void SetBounds(const gfx::IntRect& aBounds) 2280 { 2281 if (!mBounds.IsEqualEdges(aBounds)) { 2282 mBounds = aBounds; 2283 Mutated(); 2284 } 2285 } 2286 GetBounds()2287 const gfx::IntRect& GetBounds() 2288 { 2289 return mBounds; 2290 } 2291 2292 // This getter can be used anytime. GetColor()2293 virtual const gfx::Color& GetColor() { return mColor; } 2294 2295 MOZ_LAYER_DECL_NAME("ColorLayer", TYPE_COLOR) 2296 ComputeEffectiveTransforms(const gfx::Matrix4x4 & aTransformToSurface)2297 virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override 2298 { 2299 gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface; 2300 mEffectiveTransform = SnapTransformTranslation(idealTransform, nullptr); 2301 ComputeEffectiveTransformForMaskLayers(aTransformToSurface); 2302 } 2303 2304 protected: ColorLayer(LayerManager * aManager,void * aImplData)2305 ColorLayer(LayerManager* aManager, void* aImplData) 2306 : Layer(aManager, aImplData) 2307 , mColor() 2308 {} 2309 2310 virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; 2311 2312 virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override; 2313 2314 gfx::IntRect mBounds; 2315 gfx::Color mColor; 2316 }; 2317 2318 /** 2319 * A Layer for HTML Canvas elements. It's backed by either a 2320 * gfxASurface or a GLContext (for WebGL layers), and has some control 2321 * for intelligent updating from the source if necessary (for example, 2322 * if hardware compositing is not available, for reading from the GL 2323 * buffer into an image surface that we can layer composite.) 2324 * 2325 * After Initialize is called, the underlying canvas Surface/GLContext 2326 * must not be modified during a layer transaction. 2327 */ 2328 class CanvasLayer : public Layer { 2329 public: 2330 struct Data { DataData2331 Data() 2332 : mBufferProvider(nullptr) 2333 , mGLContext(nullptr) 2334 , mRenderer(nullptr) 2335 , mFrontbufferGLTex(0) 2336 , mSize(0,0) 2337 , mHasAlpha(false) 2338 , mIsGLAlphaPremult(true) 2339 , mIsMirror(false) 2340 { } 2341 2342 // One of these three must be specified for Canvas2D, but never more than one 2343 PersistentBufferProvider* mBufferProvider; // A BufferProvider for the Canvas contents 2344 mozilla::gl::GLContext* mGLContext; // or this, for GL. 2345 AsyncCanvasRenderer* mRenderer; // or this, for OffscreenCanvas 2346 2347 // Frontbuffer override 2348 uint32_t mFrontbufferGLTex; 2349 2350 // The size of the canvas content 2351 gfx::IntSize mSize; 2352 2353 // Whether the canvas drawingbuffer has an alpha channel. 2354 bool mHasAlpha; 2355 2356 // Whether mGLContext contains data that is alpha-premultiplied. 2357 bool mIsGLAlphaPremult; 2358 2359 // Whether the canvas front buffer is already being rendered somewhere else. 2360 // When true, do not swap buffers or Morph() to another factory on mGLContext 2361 bool mIsMirror; 2362 }; 2363 2364 /** 2365 * CONSTRUCTION PHASE ONLY 2366 * Initialize this CanvasLayer with the given data. The data must 2367 * have either mSurface or mGLContext initialized (but not both), as 2368 * well as mSize. 2369 * 2370 * This must only be called once. 2371 */ 2372 virtual void Initialize(const Data& aData) = 0; 2373 2374 /** 2375 * Check the data is owned by this layer is still valid for rendering 2376 */ IsDataValid(const Data & aData)2377 virtual bool IsDataValid(const Data& aData) { return true; } 2378 2379 /** 2380 * Notify this CanvasLayer that the canvas surface contents have 2381 * changed (or will change) before the next transaction. 2382 */ Updated()2383 void Updated() { mDirty = true; SetInvalidRectToVisibleRegion(); } 2384 2385 /** 2386 * Notify this CanvasLayer that the canvas surface contents have 2387 * been painted since the last change. 2388 */ Painted()2389 void Painted() { mDirty = false; } 2390 2391 /** 2392 * Returns true if the canvas surface contents have changed since the 2393 * last paint. 2394 */ IsDirty()2395 bool IsDirty() 2396 { 2397 // We can only tell if we are dirty if we're part of the 2398 // widget's retained layer tree. 2399 if (!mManager || !mManager->IsWidgetLayerManager()) { 2400 return true; 2401 } 2402 return mDirty; 2403 } 2404 2405 /** 2406 * Register a callback to be called at the start of each transaction. 2407 */ 2408 typedef void PreTransactionCallback(void* closureData); SetPreTransactionCallback(PreTransactionCallback * callback,void * closureData)2409 void SetPreTransactionCallback(PreTransactionCallback* callback, void* closureData) 2410 { 2411 mPreTransCallback = callback; 2412 mPreTransCallbackData = closureData; 2413 } 2414 GetBounds()2415 const nsIntRect& GetBounds() const { return mBounds; } 2416 2417 protected: FirePreTransactionCallback()2418 void FirePreTransactionCallback() 2419 { 2420 if (mPreTransCallback) { 2421 mPreTransCallback(mPreTransCallbackData); 2422 } 2423 } 2424 2425 public: 2426 /** 2427 * Register a callback to be called at the end of each transaction. 2428 */ 2429 typedef void (* DidTransactionCallback)(void* aClosureData); SetDidTransactionCallback(DidTransactionCallback aCallback,void * aClosureData)2430 void SetDidTransactionCallback(DidTransactionCallback aCallback, void* aClosureData) 2431 { 2432 mPostTransCallback = aCallback; 2433 mPostTransCallbackData = aClosureData; 2434 } 2435 2436 /** 2437 * CONSTRUCTION PHASE ONLY 2438 * Set the filter used to resample this image (if necessary). 2439 */ SetSamplingFilter(gfx::SamplingFilter aSamplingFilter)2440 void SetSamplingFilter(gfx::SamplingFilter aSamplingFilter) 2441 { 2442 if (mSamplingFilter != aSamplingFilter) { 2443 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Filter", this)); 2444 mSamplingFilter = aSamplingFilter; 2445 Mutated(); 2446 } 2447 } GetSamplingFilter()2448 gfx::SamplingFilter GetSamplingFilter() const { return mSamplingFilter; } 2449 2450 MOZ_LAYER_DECL_NAME("CanvasLayer", TYPE_CANVAS) 2451 ComputeEffectiveTransforms(const gfx::Matrix4x4 & aTransformToSurface)2452 virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override 2453 { 2454 // Snap our local transform first, and snap the inherited transform as well. 2455 // This makes our snapping equivalent to what would happen if our content 2456 // was drawn into a PaintedLayer (gfxContext would snap using the local 2457 // transform, then we'd snap again when compositing the PaintedLayer). 2458 mEffectiveTransform = 2459 SnapTransform(GetLocalTransform(), gfxRect(0, 0, mBounds.width, mBounds.height), 2460 nullptr)* 2461 SnapTransformTranslation(aTransformToSurface, nullptr); 2462 ComputeEffectiveTransformForMaskLayers(aTransformToSurface); 2463 } 2464 GetIsAsyncRenderer()2465 bool GetIsAsyncRenderer() const 2466 { 2467 return !!mAsyncRenderer; 2468 } 2469 2470 protected: 2471 CanvasLayer(LayerManager* aManager, void* aImplData); 2472 virtual ~CanvasLayer(); 2473 2474 virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; 2475 2476 virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override; 2477 FireDidTransactionCallback()2478 void FireDidTransactionCallback() 2479 { 2480 if (mPostTransCallback) { 2481 mPostTransCallback(mPostTransCallbackData); 2482 } 2483 } 2484 2485 /** 2486 * 0, 0, canvaswidth, canvasheight 2487 */ 2488 gfx::IntRect mBounds; 2489 PreTransactionCallback* mPreTransCallback; 2490 void* mPreTransCallbackData; 2491 DidTransactionCallback mPostTransCallback; 2492 void* mPostTransCallbackData; 2493 gfx::SamplingFilter mSamplingFilter; 2494 RefPtr<AsyncCanvasRenderer> mAsyncRenderer; 2495 2496 private: 2497 /** 2498 * Set to true in Updated(), cleared during a transaction. 2499 */ 2500 bool mDirty; 2501 }; 2502 2503 /** 2504 * ContainerLayer that refers to a "foreign" layer tree, through an 2505 * ID. Usage of RefLayer looks like 2506 * 2507 * Construction phase: 2508 * allocate ID for layer subtree 2509 * create RefLayer, SetReferentId(ID) 2510 * 2511 * Composition: 2512 * look up subtree for GetReferentId() 2513 * ConnectReferentLayer(subtree) 2514 * compose 2515 * ClearReferentLayer() 2516 * 2517 * Clients will usually want to Connect/Clear() on each transaction to 2518 * avoid difficulties managing memory across multiple layer subtrees. 2519 */ 2520 class RefLayer : public ContainerLayer { 2521 friend class LayerManager; 2522 2523 private: InsertAfter(Layer * aChild,Layer * aAfter)2524 virtual bool InsertAfter(Layer* aChild, Layer* aAfter) override 2525 { MOZ_CRASH("GFX: RefLayer"); return false; } 2526 RemoveChild(Layer * aChild)2527 virtual bool RemoveChild(Layer* aChild) override 2528 { MOZ_CRASH("GFX: RefLayer"); return false; } 2529 RepositionChild(Layer * aChild,Layer * aAfter)2530 virtual bool RepositionChild(Layer* aChild, Layer* aAfter) override 2531 { MOZ_CRASH("GFX: RefLayer"); return false; } 2532 2533 public: 2534 /** 2535 * CONSTRUCTION PHASE ONLY 2536 * Set the ID of the layer's referent. 2537 */ SetReferentId(uint64_t aId)2538 void SetReferentId(uint64_t aId) 2539 { 2540 MOZ_ASSERT(aId != 0); 2541 if (mId != aId) { 2542 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ReferentId", this)); 2543 mId = aId; 2544 Mutated(); 2545 } 2546 } 2547 /** 2548 * CONSTRUCTION PHASE ONLY 2549 * Connect this ref layer to its referent, temporarily. 2550 * ClearReferentLayer() must be called after composition. 2551 */ ConnectReferentLayer(Layer * aLayer)2552 void ConnectReferentLayer(Layer* aLayer) 2553 { 2554 MOZ_ASSERT(!mFirstChild && !mLastChild); 2555 MOZ_ASSERT(!aLayer->GetParent()); 2556 if (aLayer->Manager() != Manager()) { 2557 // This can happen when e.g. rendering while dragging tabs 2558 // between windows - aLayer's manager may be the manager for the 2559 // old window's tab. In that case, it will be changed before the 2560 // next render (see SetLayerManager). It is simply easier to 2561 // ignore the rendering here than it is to pause it. 2562 NS_WARNING("ConnectReferentLayer failed - Incorrect LayerManager"); 2563 return; 2564 } 2565 2566 mFirstChild = mLastChild = aLayer; 2567 aLayer->SetParent(this); 2568 } 2569 2570 /** 2571 * DRAWING PHASE ONLY 2572 * |aLayer| is the same as the argument to ConnectReferentLayer(). 2573 */ DetachReferentLayer(Layer * aLayer)2574 void DetachReferentLayer(Layer* aLayer) 2575 { 2576 mFirstChild = mLastChild = nullptr; 2577 aLayer->SetParent(nullptr); 2578 } 2579 2580 // These getters can be used anytime. AsRefLayer()2581 virtual RefLayer* AsRefLayer() override { return this; } 2582 GetReferentId()2583 virtual int64_t GetReferentId() { return mId; } 2584 2585 /** 2586 * DRAWING PHASE ONLY 2587 */ 2588 virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) override; 2589 2590 MOZ_LAYER_DECL_NAME("RefLayer", TYPE_REF) 2591 2592 protected: RefLayer(LayerManager * aManager,void * aImplData)2593 RefLayer(LayerManager* aManager, void* aImplData) 2594 : ContainerLayer(aManager, aImplData) , mId(0) 2595 {} 2596 2597 virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; 2598 2599 virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override; 2600 2601 // 0 is a special value that means "no ID". 2602 uint64_t mId; 2603 }; 2604 2605 void SetAntialiasingFlags(Layer* aLayer, gfx::DrawTarget* aTarget); 2606 2607 #ifdef MOZ_DUMP_PAINTING 2608 void WriteSnapshotToDumpFile(Layer* aLayer, gfx::DataSourceSurface* aSurf); 2609 void WriteSnapshotToDumpFile(LayerManager* aManager, gfx::DataSourceSurface* aSurf); 2610 void WriteSnapshotToDumpFile(Compositor* aCompositor, gfx::DrawTarget* aTarget); 2611 #endif 2612 2613 // A utility function used by different LayerManager implementations. 2614 gfx::IntRect ToOutsideIntRect(const gfxRect &aRect); 2615 2616 } // namespace layers 2617 } // namespace mozilla 2618 2619 #endif /* GFX_LAYERS_H */ 2620