Bug 1632310 [wpt PR 23186] - Add test for computed versus resolved style., a=testonly
[gecko.git] / gfx / layers / Layers.h
blob606e49c77580d43c760cdb4b1b5580030a5784f1
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef GFX_LAYERS_H
8 #define GFX_LAYERS_H
10 #include <map>
11 #include <unordered_set>
12 #include <stdint.h> // for uint32_t, uint64_t, uint8_t
13 #include <stdio.h> // for FILE
14 #include <sys/types.h> // for int32_t
15 #include "FrameMetrics.h" // for FrameMetrics
16 #include "Units.h" // for LayerMargin, LayerPoint, ParentLayerIntRect
17 #include "gfxContext.h"
18 #include "gfxTypes.h"
19 #include "gfxPoint.h" // for gfxPoint
20 #include "gfxRect.h" // for gfxRect
21 #include "gfx2DGlue.h"
22 #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2, etc
23 #include "mozilla/Array.h"
24 #include "mozilla/DebugOnly.h" // for DebugOnly
25 #include "mozilla/EventForwards.h" // for nsPaintEvent
26 #include "mozilla/Maybe.h" // for Maybe
27 #include "mozilla/Poison.h"
28 #include "mozilla/RefPtr.h" // for already_AddRefed
29 #include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
30 #include "mozilla/UniquePtr.h" // for UniquePtr
31 #include "mozilla/gfx/BaseMargin.h" // for BaseMargin
32 #include "mozilla/gfx/BasePoint.h" // for BasePoint
33 #include "mozilla/gfx/Point.h" // for IntSize
34 #include "mozilla/gfx/TiledRegion.h" // for TiledIntRegion
35 #include "mozilla/gfx/Types.h" // for SurfaceFormat
36 #include "mozilla/gfx/UserData.h" // for UserData, etc
37 #include "mozilla/layers/AnimationInfo.h" // for AnimationInfo
38 #include "mozilla/layers/BSPTree.h" // for LayerPolygon
39 #include "mozilla/layers/CanvasRenderer.h"
40 #include "mozilla/layers/LayerAttributes.h"
41 #include "mozilla/layers/LayersTypes.h"
42 #include "mozilla/webrender/WebRenderTypes.h"
43 #include "mozilla/mozalloc.h" // for operator delete, etc
44 #include "nsCOMPtr.h" // for already_AddRefed
45 #include "nsCSSPropertyID.h" // for nsCSSPropertyID
46 #include "nsDebug.h" // for NS_ASSERTION
47 #include "nsISupportsImpl.h" // for Layer::Release, etc
48 #include "nsRect.h" // for mozilla::gfx::IntRect
49 #include "nsRegion.h" // for nsIntRegion
50 #include "nsString.h" // for nsCString
51 #include "nsTArray.h" // for nsTArray
52 #include "nsTArrayForwardDeclare.h" // for nsTArray
53 #include "nscore.h" // for nsACString, nsAString
54 #include "mozilla/Logging.h" // for PRLogModuleInfo
55 #include "nsIWidget.h" // For plugin window configuration information structs
56 #include "ImageContainer.h"
58 class gfxContext;
59 class nsDisplayListBuilder;
60 class nsDisplayItem;
62 extern uint8_t gLayerManagerLayerBuilder;
64 namespace mozilla {
66 class ComputedTimingFunction;
67 class FrameLayerBuilder;
69 namespace gl {
70 class GLContext;
71 } // namespace gl
73 namespace gfx {
74 class DrawTarget;
75 } // namespace gfx
77 namespace layers {
79 class Animation;
80 class AsyncCanvasRenderer;
81 class AsyncPanZoomController;
82 class BasicLayerManager;
83 class ClientLayerManager;
84 class HostLayerManager;
85 class Layer;
86 class LayerMetricsWrapper;
87 class PaintedLayer;
88 class ContainerLayer;
89 class ImageLayer;
90 class ColorLayer;
91 class CompositorAnimations;
92 class CompositorBridgeChild;
93 class CanvasLayer;
94 class ReadbackLayer;
95 class ReadbackProcessor;
96 class RefLayer;
97 class HostLayer;
98 class FocusTarget;
99 class KnowsCompositor;
100 class ShadowableLayer;
101 class ShadowLayerForwarder;
102 class LayerManagerComposite;
103 class SpecificLayerAttributes;
104 class TransactionIdAllocator;
105 class Compositor;
106 class FrameUniformityData;
107 class PersistentBufferProvider;
108 class GlyphArray;
109 class WebRenderLayerManager;
110 struct AnimData;
112 namespace layerscope {
113 class LayersPacket;
114 } // namespace layerscope
116 #define MOZ_LAYER_DECL_NAME(n, e) \
117 const char* Name() const override { return n; } \
118 LayerType GetType() const override { return e; } \
119 static LayerType Type() { return e; }
121 // Defined in LayerUserData.h; please include that file instead.
122 class LayerUserData;
124 class DidCompositeObserver {
125 public:
126 virtual void DidComposite() = 0;
129 class FrameRecorder {
130 public:
132 * Record (and return) frame-intervals and paint-times for frames which were
133 * presented between calling StartFrameTimeRecording and
134 * StopFrameTimeRecording.
136 * - Uses a cyclic buffer and serves concurrent consumers, so if Stop is
137 * called too late
138 * (elements were overwritten since Start), result is considered invalid
139 * and hence empty.)
140 * - Buffer is capable of holding 10 seconds @ 60fps (or more if frames were
141 * less frequent).
142 * Can be changed (up to 1 hour) via pref:
143 * toolkit.framesRecording.bufferSize.
144 * - Note: the first frame-interval may be longer than expected because last
145 * frame
146 * might have been presented some time before calling
147 * StartFrameTimeRecording.
151 * Returns a handle which represents current recording start position.
153 virtual uint32_t StartFrameTimeRecording(int32_t aBufferSize);
156 * Clears, then populates aFrameIntervals with the recorded frame timing
157 * data. The array will be empty if data was overwritten since
158 * aStartIndex was obtained.
160 virtual void StopFrameTimeRecording(uint32_t aStartIndex,
161 nsTArray<float>& aFrameIntervals);
163 void RecordFrame();
165 private:
166 struct FramesTimingRecording {
167 // Stores state and data for frame intervals and paint times recording.
168 // see LayerManager::StartFrameTimeRecording() at Layers.cpp for more
169 // details.
170 FramesTimingRecording()
171 : mNextIndex(0),
172 mLatestStartIndex(0),
173 mCurrentRunStartIndex(0),
174 mIsPaused(true) {}
175 nsTArray<float> mIntervals;
176 TimeStamp mLastFrameTime;
177 uint32_t mNextIndex;
178 uint32_t mLatestStartIndex;
179 uint32_t mCurrentRunStartIndex;
180 bool mIsPaused;
182 FramesTimingRecording mRecording;
186 * Motivation: For truly smooth animation and video playback, we need to
187 * be able to compose frames and render them on a dedicated thread (i.e.
188 * off the main thread where DOM manipulation, script execution and layout
189 * induce difficult-to-bound latency). This requires Gecko to construct
190 * some kind of persistent scene structure (graph or tree) that can be
191 * safely transmitted across threads. We have other scenarios (e.g. mobile
192 * browsing) where retaining some rendered data between paints is desired
193 * for performance, so again we need a retained scene structure.
195 * Our retained scene structure is a layer tree. Each layer represents
196 * content which can be composited onto a destination surface; the root
197 * layer is usually composited into a window, and non-root layers are
198 * composited into their parent layers. Layers have attributes (e.g.
199 * opacity and clipping) that influence their compositing.
201 * We want to support a variety of layer implementations, including
202 * a simple "immediate mode" implementation that doesn't retain any
203 * rendered data between paints (i.e. uses cairo in just the way that
204 * Gecko used it before layers were introduced). But we also don't want
205 * to have bifurcated "layers"/"non-layers" rendering paths in Gecko.
206 * Therefore the layers API is carefully designed to permit maximally
207 * efficient implementation in an "immediate mode" style. See the
208 * BasicLayerManager for such an implementation.
212 * A LayerManager controls a tree of layers. All layers in the tree
213 * must use the same LayerManager.
215 * All modifications to a layer tree must happen inside a transaction.
216 * Only the state of the layer tree at the end of a transaction is
217 * rendered. Transactions cannot be nested
219 * Each transaction has two phases:
220 * 1) Construction: layers are created, inserted, removed and have
221 * properties set on them in this phase.
222 * BeginTransaction and BeginTransactionWithTarget start a transaction in
223 * the Construction phase.
224 * 2) Drawing: PaintedLayers are rendered into in this phase, in tree
225 * order. When the client has finished drawing into the PaintedLayers, it should
226 * call EndTransaction to complete the transaction.
228 * All layer API calls happen on the main thread.
230 * Layers are refcounted. The layer manager holds a reference to the
231 * root layer, and each container layer holds a reference to its children.
233 class LayerManager : public FrameRecorder {
234 NS_INLINE_DECL_REFCOUNTING(LayerManager)
236 protected:
237 typedef mozilla::gfx::DrawTarget DrawTarget;
238 typedef mozilla::gfx::IntSize IntSize;
239 typedef mozilla::gfx::SurfaceFormat SurfaceFormat;
241 public:
242 LayerManager()
243 : mDestroyed(false),
244 mSnapEffectiveTransforms(true),
245 mId(0),
246 mInTransaction(false),
247 mContainsSVG(false),
248 mPaintedPixelCount(0) {}
251 * Release layers and resources held by this layer manager, and mark
252 * it as destroyed. Should do any cleanup necessary in preparation
253 * for its widget going away. After this call, only user data calls
254 * are valid on the layer manager.
256 virtual void Destroy() {
257 mDestroyed = true;
258 mUserData.Destroy();
259 mRoot = nullptr;
261 bool IsDestroyed() { return mDestroyed; }
263 virtual ShadowLayerForwarder* AsShadowForwarder() { return nullptr; }
265 virtual KnowsCompositor* AsKnowsCompositor() { return nullptr; }
267 virtual LayerManagerComposite* AsLayerManagerComposite() { return nullptr; }
269 virtual ClientLayerManager* AsClientLayerManager() { return nullptr; }
271 virtual BasicLayerManager* AsBasicLayerManager() { return nullptr; }
272 virtual HostLayerManager* AsHostLayerManager() { return nullptr; }
274 virtual WebRenderLayerManager* AsWebRenderLayerManager() { return nullptr; }
277 * Returns true if this LayerManager is owned by an nsIWidget,
278 * and is used for drawing into the widget.
280 virtual bool IsWidgetLayerManager() { return true; }
281 virtual bool IsInactiveLayerManager() { return false; }
284 * Start a new transaction. Nested transactions are not allowed so
285 * there must be no transaction currently in progress.
286 * This transaction will update the state of the window from which
287 * this LayerManager was obtained.
289 virtual bool BeginTransaction(const nsCString& aURL = nsCString()) = 0;
291 * Start a new transaction. Nested transactions are not allowed so
292 * there must be no transaction currently in progress.
293 * This transaction will render the contents of the layer tree to
294 * the given target context. The rendering will be complete when
295 * EndTransaction returns.
297 virtual bool BeginTransactionWithTarget(
298 gfxContext* aTarget, const nsCString& aURL = nsCString()) = 0;
300 enum EndTransactionFlags {
301 END_DEFAULT = 0,
302 END_NO_IMMEDIATE_REDRAW = 1 << 0, // Do not perform the drawing phase
303 END_NO_COMPOSITE =
304 1 << 1, // Do not composite after drawing painted layer contents.
305 END_NO_REMOTE_COMPOSITE = 1 << 2 // Do not schedule a composition with a
306 // remote Compositor, if one exists.
309 FrameLayerBuilder* GetLayerBuilder() {
310 return reinterpret_cast<FrameLayerBuilder*>(
311 GetUserData(&gLayerManagerLayerBuilder));
315 * Attempts to end an "empty transaction". There must have been no
316 * changes to the layer tree since the BeginTransaction().
317 * It's possible for this to fail; PaintedLayers may need to be updated
318 * due to VRAM data being lost, for example. In such cases this method
319 * returns false, and the caller must proceed with a normal layer tree
320 * update and EndTransaction.
322 virtual bool EndEmptyTransaction(
323 EndTransactionFlags aFlags = END_DEFAULT) = 0;
326 * Function called to draw the contents of each PaintedLayer.
327 * aRegionToDraw contains the region that needs to be drawn.
328 * This would normally be a subregion of the visible region.
329 * The callee must draw all of aRegionToDraw. Drawing outside
330 * aRegionToDraw will be clipped out or ignored.
331 * The callee must draw all of aRegionToDraw.
332 * This region is relative to 0,0 in the PaintedLayer.
334 * aDirtyRegion should contain the total region that is be due to be painted
335 * during the transaction, even though only aRegionToDraw should be drawn
336 * during this call. aRegionToDraw must be entirely contained within
337 * aDirtyRegion. If the total dirty region is unknown it is okay to pass a
338 * subregion of the total dirty region, e.g. just aRegionToDraw, though it
339 * may not be as efficient.
341 * aRegionToInvalidate contains a region whose contents have been
342 * changed by the layer manager and which must therefore be invalidated.
343 * For example, this could be non-empty if a retained layer internally
344 * switches from RGBA to RGB or back ... we might want to repaint it to
345 * consistently use subpixel-AA or not.
346 * This region is relative to 0,0 in the PaintedLayer.
347 * aRegionToInvalidate may contain areas that are outside
348 * aRegionToDraw; the callee must ensure that these areas are repainted
349 * in the current layer manager transaction or in a later layer
350 * manager transaction.
352 * aContext must not be used after the call has returned.
353 * We guarantee that buffered contents in the visible
354 * region are valid once drawing is complete.
356 * The origin of aContext is 0,0 in the PaintedLayer.
358 typedef void (*DrawPaintedLayerCallback)(
359 PaintedLayer* aLayer, gfxContext* aContext,
360 const nsIntRegion& aRegionToDraw, const nsIntRegion& aDirtyRegion,
361 DrawRegionClip aClip, const nsIntRegion& aRegionToInvalidate,
362 void* aCallbackData);
365 * Finish the construction phase of the transaction, perform the
366 * drawing phase, and end the transaction.
367 * During the drawing phase, all PaintedLayers in the tree are
368 * drawn in tree order, exactly once each, except for those layers
369 * where it is known that the visible region is empty.
371 virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
372 void* aCallbackData,
373 EndTransactionFlags aFlags = END_DEFAULT) = 0;
376 * Schedule a composition with the remote Compositor, if one exists
377 * for this LayerManager. Useful in conjunction with the
378 * END_NO_REMOTE_COMPOSITE flag to EndTransaction.
380 virtual void ScheduleComposite() {}
382 virtual void SetNeedsComposite(bool aNeedsComposite) {}
383 virtual bool NeedsComposite() const { return false; }
385 virtual bool HasShadowManagerInternal() const { return false; }
386 bool HasShadowManager() const { return HasShadowManagerInternal(); }
387 virtual void StorePluginWidgetConfigurations(
388 const nsTArray<nsIWidget::Configuration>& aConfigurations) {}
389 bool IsSnappingEffectiveTransforms() { return mSnapEffectiveTransforms; }
392 * Returns true if the underlying platform can properly support layers with
393 * SurfaceMode::SURFACE_COMPONENT_ALPHA.
395 static bool LayersComponentAlphaEnabled();
398 * Returns true if this LayerManager can properly support layers with
399 * SurfaceMode::SURFACE_COMPONENT_ALPHA. LayerManagers that can't will use
400 * transparent surfaces (and lose subpixel-AA for text).
402 virtual bool AreComponentAlphaLayersEnabled();
405 * Returns true if this LayerManager always requires an intermediate surface
406 * to render blend operations.
408 virtual bool BlendingRequiresIntermediateSurface() { return false; }
411 * CONSTRUCTION PHASE ONLY
412 * Set the root layer. The root layer is initially null. If there is
413 * no root layer, EndTransaction won't draw anything.
415 virtual void SetRoot(Layer* aLayer) = 0;
417 * Can be called anytime
419 Layer* GetRoot() { return mRoot; }
422 * Does a breadth-first search from the root layer to find the first
423 * scrollable layer, and returns its ViewID. Note that there may be
424 * other layers in the tree which share the same ViewID.
425 * Can be called any time.
427 ScrollableLayerGuid::ViewID GetRootScrollableLayerId();
430 * Returns a LayerMetricsWrapper containing the Root
431 * Content Documents layer.
433 LayerMetricsWrapper GetRootContentLayer();
436 * CONSTRUCTION PHASE ONLY
437 * Called when a managee has mutated.
438 * Subclasses overriding this method must first call their
439 * superclass's impl
441 virtual void Mutated(Layer* aLayer) {}
442 virtual void MutatedSimple(Layer* aLayer) {}
445 * Hints that can be used during PaintedLayer creation to influence the type
446 * or properties of the layer created.
448 * NONE: No hint.
449 * SCROLLABLE: This layer may represent scrollable content.
451 enum PaintedLayerCreationHint { NONE, SCROLLABLE };
454 * CONSTRUCTION PHASE ONLY
455 * Create a PaintedLayer for this manager's layer tree.
457 virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() = 0;
459 * CONSTRUCTION PHASE ONLY
460 * Create a PaintedLayer for this manager's layer tree, with a creation hint
461 * parameter to help optimise the type of layer created.
463 virtual already_AddRefed<PaintedLayer> CreatePaintedLayerWithHint(
464 PaintedLayerCreationHint) {
465 return CreatePaintedLayer();
468 * CONSTRUCTION PHASE ONLY
469 * Create a ContainerLayer for this manager's layer tree.
471 virtual already_AddRefed<ContainerLayer> CreateContainerLayer() = 0;
473 * CONSTRUCTION PHASE ONLY
474 * Create an ImageLayer for this manager's layer tree.
476 virtual already_AddRefed<ImageLayer> CreateImageLayer() = 0;
478 * CONSTRUCTION PHASE ONLY
479 * Create a ColorLayer for this manager's layer tree.
481 virtual already_AddRefed<ColorLayer> CreateColorLayer() = 0;
483 * CONSTRUCTION PHASE ONLY
484 * Create a CanvasLayer for this manager's layer tree.
486 virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() = 0;
488 * CONSTRUCTION PHASE ONLY
489 * Create a ReadbackLayer for this manager's layer tree.
491 virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer() {
492 return nullptr;
495 * CONSTRUCTION PHASE ONLY
496 * Create a RefLayer for this manager's layer tree.
498 virtual already_AddRefed<RefLayer> CreateRefLayer() { return nullptr; }
500 * Can be called anytime, from any thread.
502 * Creates an Image container which forwards its images to the compositor
503 * within layer transactions on the main thread or asynchronously using the
504 * ImageBridge IPDL protocol. In the case of asynchronous, If the protocol is
505 * not available, the returned ImageContainer will forward images within layer
506 * transactions.
508 static already_AddRefed<ImageContainer> CreateImageContainer(
509 ImageContainer::Mode flag = ImageContainer::SYNCHRONOUS);
512 * Type of layer manager his is. This is to be used sparsely in order to
513 * avoid a lot of Layers backend specific code. It should be used only when
514 * Layers backend specific functionality is necessary.
516 virtual LayersBackend GetBackendType() = 0;
519 * Type of layers backend that will be used to composite this layer tree.
520 * When compositing is done remotely, then this returns the layers type
521 * of the compositor.
523 virtual LayersBackend GetCompositorBackendType() { return GetBackendType(); }
526 * Creates a DrawTarget which is optimized for inter-operating with this
527 * layer manager.
529 virtual already_AddRefed<DrawTarget> CreateOptimalDrawTarget(
530 const IntSize& aSize, SurfaceFormat imageFormat);
533 * Creates a DrawTarget for alpha masks which is optimized for inter-
534 * operating with this layer manager. In contrast to CreateOptimalDrawTarget,
535 * this surface is optimised for drawing alpha only and we assume that
536 * drawing the mask is fairly simple.
538 virtual already_AddRefed<DrawTarget> CreateOptimalMaskDrawTarget(
539 const IntSize& aSize);
542 * Creates a DrawTarget for use with canvas which is optimized for
543 * inter-operating with this layermanager.
545 virtual already_AddRefed<mozilla::gfx::DrawTarget> CreateDrawTarget(
546 const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat);
549 * Creates a PersistentBufferProvider for use with canvas which is optimized
550 * for inter-operating with this layermanager.
552 virtual already_AddRefed<PersistentBufferProvider>
553 CreatePersistentBufferProvider(const mozilla::gfx::IntSize& aSize,
554 mozilla::gfx::SurfaceFormat aFormat);
556 virtual bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) {
557 return true;
561 * returns the maximum texture size on this layer backend, or INT32_MAX
562 * if there is no maximum
564 virtual int32_t GetMaxTextureSize() const = 0;
567 * Return the name of the layer manager's backend.
569 virtual void GetBackendName(nsAString& aName) = 0;
572 * This setter can be used anytime. The user data for all keys is
573 * initially null. Ownership pases to the layer manager.
575 void SetUserData(void* aKey, LayerUserData* aData) {
576 mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData,
577 LayerUserDataDestroy);
580 * This can be used anytime. Ownership passes to the caller!
582 UniquePtr<LayerUserData> RemoveUserData(void* aKey);
585 * This getter can be used anytime.
587 bool HasUserData(void* aKey) {
588 return mUserData.Has(static_cast<gfx::UserDataKey*>(aKey));
591 * This getter can be used anytime. Ownership is retained by the layer
592 * manager.
594 LayerUserData* GetUserData(void* aKey) const {
595 return static_cast<LayerUserData*>(
596 mUserData.Get(static_cast<gfx::UserDataKey*>(aKey)));
600 * Must be called outside of a layers transaction.
602 * For the subtree rooted at |aSubtree|, this attempts to free up
603 * any free-able resources like retained buffers, but may do nothing
604 * at all. After this call, the layer tree is left in an undefined
605 * state; the layers in |aSubtree|'s subtree may no longer have
606 * buffers with valid content and may no longer be able to draw
607 * their visible and valid regions.
609 * In general, a painting or forwarding transaction on |this| must
610 * complete on the tree before it returns to a valid state.
612 * Resource freeing begins from |aSubtree| or |mRoot| if |aSubtree|
613 * is null. |aSubtree|'s manager must be this.
615 virtual void ClearCachedResources(Layer* aSubtree = nullptr) {}
618 * Flag the next paint as the first for a document.
620 virtual void SetIsFirstPaint() {}
621 virtual bool GetIsFirstPaint() const { return false; }
624 * Set the current focus target to be sent with the next paint.
626 virtual void SetFocusTarget(const FocusTarget& aFocusTarget) {}
629 * Make sure that the previous transaction has been entirely
630 * completed.
632 * Note: This may sychronously wait on a remote compositor
633 * to complete rendering.
635 virtual void FlushRendering() {}
638 * Make sure that the previous transaction has been
639 * received. This will synchronsly wait on a remote compositor. */
640 virtual void WaitOnTransactionProcessed() {}
642 virtual void SendInvalidRegion(const nsIntRegion& aRegion) {}
645 * Checks if we need to invalidate the OS widget to trigger
646 * painting when updating this layer manager.
648 virtual bool NeedsWidgetInvalidation() { return true; }
650 virtual const char* Name() const { return "???"; }
653 * Dump information about this layer manager and its managed tree to
654 * aStream.
656 void Dump(std::stringstream& aStream, const char* aPrefix = "",
657 bool aDumpHtml = false, bool aSorted = false);
659 * Dump information about just this layer manager itself to aStream
661 void DumpSelf(std::stringstream& aStream, const char* aPrefix = "",
662 bool aSorted = false);
663 void Dump(bool aSorted = false);
666 * Dump information about this layer manager and its managed tree to
667 * layerscope packet.
669 void Dump(layerscope::LayersPacket* aPacket);
672 * Log information about this layer manager and its managed tree to
673 * the NSPR log (if enabled for "Layers").
675 void Log(const char* aPrefix = "");
677 * Log information about just this layer manager itself to the NSPR
678 * log (if enabled for "Layers").
680 void LogSelf(const char* aPrefix = "");
682 static bool IsLogEnabled();
683 static mozilla::LogModule* GetLog();
685 bool IsCompositingCheap(LayersBackend aBackend) {
686 // LayersBackend::LAYERS_NONE is an error state, but in that case we should
687 // try to avoid loading the compositor!
688 return LayersBackend::LAYERS_BASIC != aBackend &&
689 LayersBackend::LAYERS_NONE != aBackend;
692 virtual bool IsCompositingCheap() { return true; }
694 bool IsInTransaction() const { return mInTransaction; }
695 virtual void GetFrameUniformity(FrameUniformityData* aOutData) {}
697 virtual void SetRegionToClear(const nsIntRegion& aRegion) {
698 mRegionToClear = aRegion;
701 virtual float RequestProperty(const nsAString& property) { return -1; }
703 const TimeStamp& GetAnimationReadyTime() const { return mAnimationReadyTime; }
705 virtual bool AsyncPanZoomEnabled() const { return false; }
707 static void LayerUserDataDestroy(void* data);
709 void AddPaintedPixelCount(int32_t aCount) { mPaintedPixelCount += aCount; }
711 uint32_t GetAndClearPaintedPixelCount() {
712 uint32_t count = mPaintedPixelCount;
713 mPaintedPixelCount = 0;
714 return count;
717 virtual void SetLayersObserverEpoch(LayersObserverEpoch aEpoch) {}
719 virtual void DidComposite(TransactionId aTransactionId,
720 const mozilla::TimeStamp& aCompositeStart,
721 const mozilla::TimeStamp& aCompositeEnd) {}
723 virtual void AddDidCompositeObserver(DidCompositeObserver* aObserver) {
724 MOZ_CRASH("GFX: LayerManager");
726 virtual void RemoveDidCompositeObserver(DidCompositeObserver* aObserver) {
727 MOZ_CRASH("GFX: LayerManager");
730 virtual void UpdateTextureFactoryIdentifier(
731 const TextureFactoryIdentifier& aNewIdentifier) {}
733 virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() {
734 return TextureFactoryIdentifier();
737 virtual void SetTransactionIdAllocator(TransactionIdAllocator* aAllocator) {}
739 virtual TransactionId GetLastTransactionId() { return TransactionId{0}; }
741 virtual CompositorBridgeChild* GetCompositorBridgeChild() { return nullptr; }
743 void RegisterPayload(const CompositionPayload& aPayload) {
744 mPayload.AppendElement(aPayload);
745 MOZ_ASSERT(mPayload.Length() < 10000);
748 void RegisterPayloads(const nsTArray<CompositionPayload>& aPayload) {
749 mPayload.AppendElements(aPayload);
750 MOZ_ASSERT(mPayload.Length() < 10000);
753 virtual void PayloadPresented();
755 void SetContainsSVG(bool aContainsSVG) { mContainsSVG = aContainsSVG; }
757 protected:
758 RefPtr<Layer> mRoot;
759 gfx::UserData mUserData;
760 bool mDestroyed;
761 bool mSnapEffectiveTransforms;
763 nsIntRegion mRegionToClear;
765 // Protected destructor, to discourage deletion outside of Release():
766 virtual ~LayerManager() = default;
768 // Print interesting information about this into aStreamo. Internally
769 // used to implement Dump*() and Log*().
770 virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
772 // Print interesting information about this into layerscope packet.
773 // Internally used to implement Dump().
774 virtual void DumpPacket(layerscope::LayersPacket* aPacket);
776 uint64_t mId;
777 bool mInTransaction;
779 // Used for tracking CONTENT_FRAME_TIME_WITH_SVG
780 bool mContainsSVG;
781 // The time when painting most recently finished. This is recorded so that
782 // we can time any play-pending animations from this point.
783 TimeStamp mAnimationReadyTime;
784 // The count of pixels that were painted in the current transaction.
785 uint32_t mPaintedPixelCount;
786 // The payload associated with currently pending painting work, for
787 // client layer managers that typically means payload that is part of the
788 // 'upcoming transaction', for HostLayerManagers this typically means
789 // what has been included in received transactions to be presented on the
790 // next composite.
791 // IMPORTANT: Clients should take care to clear this or risk it slowly
792 // growing out of control.
793 nsTArray<CompositionPayload> mPayload;
795 public:
797 * Methods to store/get/clear a "pending scroll info update" object on a
798 * per-scrollid basis. This is used for empty transactions that push over
799 * scroll position updates to the APZ code.
801 virtual bool SetPendingScrollUpdateForNextTransaction(
802 ScrollableLayerGuid::ViewID aScrollId,
803 const ScrollUpdateInfo& aUpdateInfo);
804 Maybe<ScrollUpdateInfo> GetPendingScrollInfoUpdate(
805 ScrollableLayerGuid::ViewID aScrollId);
806 std::unordered_set<ScrollableLayerGuid::ViewID>
807 ClearPendingScrollInfoUpdate();
809 protected:
810 ScrollUpdatesMap mPendingScrollUpdates;
814 * A Layer represents anything that can be rendered onto a destination
815 * surface.
817 class Layer {
818 NS_INLINE_DECL_REFCOUNTING(Layer)
820 typedef nsTArray<Animation> AnimationArray;
822 public:
823 // Keep these in alphabetical order
824 enum LayerType {
825 TYPE_CANVAS,
826 TYPE_COLOR,
827 TYPE_CONTAINER,
828 TYPE_DISPLAYITEM,
829 TYPE_IMAGE,
830 TYPE_READBACK,
831 TYPE_REF,
832 TYPE_SHADOW,
833 TYPE_PAINTED
837 * Returns the LayerManager this Layer belongs to. Note that the layer
838 * manager might be in a destroyed state, at which point it's only
839 * valid to set/get user data from it.
841 LayerManager* Manager() { return mManager; }
844 * This should only be called when changing layer managers from HostLayers.
846 void SetManager(LayerManager* aManager, HostLayer* aSelf);
848 enum {
850 * If this is set, the caller is promising that by the end of this
851 * transaction the entire visible region (as specified by
852 * SetVisibleRegion) will be filled with opaque content.
854 CONTENT_OPAQUE = 0x01,
856 * If this is set, the caller is notifying that the contents of this layer
857 * require per-component alpha for optimal fidelity. However, there is no
858 * guarantee that component alpha will be supported for this layer at
859 * paint time.
860 * This should never be set at the same time as CONTENT_OPAQUE.
862 CONTENT_COMPONENT_ALPHA = 0x02,
865 * If this is set then one of the descendant layers of this one has
866 * CONTENT_COMPONENT_ALPHA set.
868 CONTENT_COMPONENT_ALPHA_DESCENDANT = 0x04,
871 * If this is set then this layer is part of a preserve-3d group, and should
872 * be sorted with sibling layers that are also part of the same group.
874 CONTENT_EXTEND_3D_CONTEXT = 0x08,
876 * This indicates that the transform may be changed on during an empty
877 * transaction where there is no possibility of redrawing the content, so
878 * the implementation should be ready for that.
880 CONTENT_MAY_CHANGE_TRANSFORM = 0x10,
883 * Disable subpixel AA for this layer. This is used if the display isn't
884 * suited for subpixel AA like hidpi or rotated content.
886 CONTENT_DISABLE_SUBPIXEL_AA = 0x20,
889 * If this is set then the layer contains content that may look
890 * objectionable if not handled as an active layer (such as text with an
891 * animated transform). This is for internal layout/FrameLayerBuilder usage
892 * only until flattening code is obsoleted. See bug 633097
894 CONTENT_DISABLE_FLATTENING = 0x40,
897 * This layer is hidden if the backface of the layer is visible
898 * to user.
900 CONTENT_BACKFACE_HIDDEN = 0x80
903 * CONSTRUCTION PHASE ONLY
904 * This lets layout make some promises about what will be drawn into the
905 * visible region of the PaintedLayer. This enables internal quality
906 * and performance optimizations.
908 void SetContentFlags(uint32_t aFlags) {
909 NS_ASSERTION((aFlags & (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA)) !=
910 (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA),
911 "Can't be opaque and require component alpha");
912 if (mSimpleAttrs.SetContentFlags(aFlags)) {
913 MOZ_LAYERS_LOG_IF_SHADOWABLE(this,
914 ("Layer::Mutated(%p) ContentFlags", this));
915 MutatedSimple();
920 * CONSTRUCTION PHASE ONLY
921 * Tell this layer which region will be visible. The visible region
922 * is a region which contains all the contents of the layer that can
923 * actually affect the rendering of the window. It can exclude areas
924 * that are covered by opaque contents of other layers, and it can
925 * exclude areas where this layer simply contains no content at all.
926 * (This can be an overapproximation to the "true" visible region.)
928 * There is no general guarantee that drawing outside the bounds of the
929 * visible region will be ignored. So if a layer draws outside the bounds
930 * of its visible region, it needs to ensure that what it draws is valid.
932 virtual void SetVisibleRegion(const LayerIntRegion& aRegion) {
933 // IsEmpty is required otherwise we get invalidation glitches.
934 // See bug 1288464 for investigating why.
935 if (!mVisibleRegion.IsEqual(aRegion) || aRegion.IsEmpty()) {
936 MOZ_LAYERS_LOG_IF_SHADOWABLE(
937 this, ("Layer::Mutated(%p) VisibleRegion was %s is %s", this,
938 mVisibleRegion.ToString().get(), aRegion.ToString().get()));
939 mVisibleRegion = aRegion;
940 Mutated();
945 * CONSTRUCTION PHASE ONLY
946 * Set the (sub)document metrics used to render the Layer subtree
947 * rooted at this. Note that a layer may have multiple FrameMetrics
948 * objects; calling this function will remove all of them and replace
949 * them with the provided FrameMetrics. See the documentation for
950 * SetFrameMetrics(const nsTArray<FrameMetrics>&) for more details.
952 void SetScrollMetadata(const ScrollMetadata& aScrollMetadata) {
953 Manager()->ClearPendingScrollInfoUpdate();
954 if (mScrollMetadata.Length() != 1 ||
955 mScrollMetadata[0] != aScrollMetadata) {
956 MOZ_LAYERS_LOG_IF_SHADOWABLE(this,
957 ("Layer::Mutated(%p) FrameMetrics", this));
958 mScrollMetadata.ReplaceElementsAt(0, mScrollMetadata.Length(),
959 aScrollMetadata);
960 ScrollMetadataChanged();
961 Mutated();
966 * CONSTRUCTION PHASE ONLY
967 * Set the (sub)document metrics used to render the Layer subtree
968 * rooted at this. There might be multiple metrics on this layer
969 * because the layer may, for example, be contained inside multiple
970 * nested scrolling subdocuments. In general a Layer having multiple
971 * ScrollMetadata objects is conceptually equivalent to having a stack
972 * of ContainerLayers that have been flattened into this Layer.
973 * See the documentation in LayerMetricsWrapper.h for a more detailed
974 * explanation of this conceptual equivalence.
976 * Note also that there is actually a many-to-many relationship between
977 * Layers and ScrollMetadata, because multiple Layers may have identical
978 * ScrollMetadata objects. This happens when those layers belong to the
979 * same scrolling subdocument and therefore end up with the same async
980 * transform when they are scrolled by the APZ code.
982 void SetScrollMetadata(const nsTArray<ScrollMetadata>& aMetadataArray) {
983 Manager()->ClearPendingScrollInfoUpdate();
984 if (mScrollMetadata != aMetadataArray) {
985 MOZ_LAYERS_LOG_IF_SHADOWABLE(this,
986 ("Layer::Mutated(%p) FrameMetrics", this));
987 mScrollMetadata = aMetadataArray;
988 ScrollMetadataChanged();
989 Mutated();
994 * Compositor event handling
995 * =========================
996 * When a touch-start event (or similar) is sent to the
997 * AsyncPanZoomController, it needs to decide whether the event should be sent
998 * to the main thread. Each layer has a list of event handling regions. When
999 * the compositor needs to determine how to handle a touch event, it scans the
1000 * layer tree from top to bottom in z-order (traversing children before their
1001 * parents). Points outside the clip region for a layer cause that layer (and
1002 * its subtree) to be ignored. If a layer has a mask layer, and that mask
1003 * layer's alpha value is zero at the event point, then the layer and its
1004 * subtree should be ignored. For each layer, if the point is outside its hit
1005 * region, we ignore the layer and move onto the next. If the point is inside
1006 * its hit region but outside the dispatch-to-content region, we can initiate
1007 * a gesture without consulting the content thread. Otherwise we must dispatch
1008 * the event to content. Note that if a layer or any ancestor layer has a
1009 * ForceEmptyHitRegion override in GetEventRegionsOverride() then the
1010 * hit-region must be treated as empty. Similarly, if there is a
1011 * ForceDispatchToContent override then the dispatch-to-content region must be
1012 * treated as encompassing the entire hit region, and therefore we must
1013 * consult the content thread before initiating a gesture. (If both flags are
1014 * set, ForceEmptyHitRegion takes priority.)
1017 * CONSTRUCTION PHASE ONLY
1018 * Set the event handling region.
1020 void SetEventRegions(const EventRegions& aRegions) {
1021 if (mEventRegions != aRegions) {
1022 MOZ_LAYERS_LOG_IF_SHADOWABLE(
1023 this, ("Layer::Mutated(%p) eventregions were %s, now %s", this,
1024 mEventRegions.ToString().get(), aRegions.ToString().get()));
1025 mEventRegions = aRegions;
1026 Mutated();
1031 * CONSTRUCTION PHASE ONLY
1032 * Set the opacity which will be applied to this layer as it
1033 * is composited to the destination.
1035 void SetOpacity(float aOpacity) {
1036 if (mSimpleAttrs.SetOpacity(aOpacity)) {
1037 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Opacity", this));
1038 MutatedSimple();
1042 void SetMixBlendMode(gfx::CompositionOp aMixBlendMode) {
1043 if (mSimpleAttrs.SetMixBlendMode(aMixBlendMode)) {
1044 MOZ_LAYERS_LOG_IF_SHADOWABLE(this,
1045 ("Layer::Mutated(%p) MixBlendMode", this));
1046 MutatedSimple();
1050 void SetForceIsolatedGroup(bool aForceIsolatedGroup) {
1051 if (mSimpleAttrs.SetForceIsolatedGroup(aForceIsolatedGroup)) {
1052 MOZ_LAYERS_LOG_IF_SHADOWABLE(
1053 this, ("Layer::Mutated(%p) ForceIsolatedGroup", this));
1054 MutatedSimple();
1058 bool GetForceIsolatedGroup() const {
1059 return mSimpleAttrs.GetForceIsolatedGroup();
1063 * CONSTRUCTION PHASE ONLY
1064 * Set a clip rect which will be applied to this layer as it is
1065 * composited to the destination. The coordinates are relative to
1066 * the parent layer (i.e. the contents of this layer
1067 * are transformed before this clip rect is applied).
1068 * For the root layer, the coordinates are relative to the widget,
1069 * in device pixels.
1070 * If aRect is null no clipping will be performed.
1072 void SetClipRect(const Maybe<ParentLayerIntRect>& aRect) {
1073 if (mClipRect) {
1074 if (!aRect) {
1075 MOZ_LAYERS_LOG_IF_SHADOWABLE(
1076 this, ("Layer::Mutated(%p) ClipRect was %d,%d,%d,%d is <none>",
1077 this, mClipRect->X(), mClipRect->Y(), mClipRect->Width(),
1078 mClipRect->Height()));
1079 mClipRect.reset();
1080 Mutated();
1081 } else {
1082 if (!aRect->IsEqualEdges(*mClipRect)) {
1083 MOZ_LAYERS_LOG_IF_SHADOWABLE(
1084 this,
1085 ("Layer::Mutated(%p) ClipRect was %d,%d,%d,%d is %d,%d,%d,%d",
1086 this, mClipRect->X(), mClipRect->Y(), mClipRect->Width(),
1087 mClipRect->Height(), aRect->X(), aRect->Y(), aRect->Width(),
1088 aRect->Height()));
1089 mClipRect = aRect;
1090 Mutated();
1093 } else {
1094 if (aRect) {
1095 MOZ_LAYERS_LOG_IF_SHADOWABLE(
1096 this,
1097 ("Layer::Mutated(%p) ClipRect was <none> is %d,%d,%d,%d", this,
1098 aRect->X(), aRect->Y(), aRect->Width(), aRect->Height()));
1099 mClipRect = aRect;
1100 Mutated();
1106 * CONSTRUCTION PHASE ONLY
1107 * Set an optional scrolled clip on the layer.
1108 * The scrolled clip, if present, consists of a clip rect and an optional
1109 * mask. This scrolled clip is always scrolled by all scroll frames associated
1110 * with this layer. (By contrast, the scroll clips stored in ScrollMetadata
1111 * are only scrolled by scroll frames above that ScrollMetadata, and the
1112 * layer's mClipRect is always fixed to the layer contents (which may or may
1113 * not be scrolled by some of the scroll frames associated with the layer,
1114 * depending on whether the layer is fixed).)
1116 void SetScrolledClip(const Maybe<LayerClip>& aScrolledClip) {
1117 if (mSimpleAttrs.SetScrolledClip(aScrolledClip)) {
1118 MOZ_LAYERS_LOG_IF_SHADOWABLE(this,
1119 ("Layer::Mutated(%p) ScrolledClip", this));
1120 MutatedSimple();
1125 * CONSTRUCTION PHASE ONLY
1126 * Set a layer to mask this layer.
1128 * The mask layer should be applied using its effective transform (after it
1129 * is calculated by ComputeEffectiveTransformForMaskLayer), this should use
1130 * this layer's parent's transform and the mask layer's transform, but not
1131 * this layer's. That is, the mask layer is specified relative to this layer's
1132 * position in it's parent layer's coord space.
1133 * Currently, only 2D translations are supported for the mask layer transform.
1135 * Ownership of aMaskLayer passes to this.
1136 * Typical use would be an ImageLayer with an alpha image used for masking.
1137 * See also ContainerState::BuildMaskLayer in FrameLayerBuilder.cpp.
1139 void SetMaskLayer(Layer* aMaskLayer) {
1140 #ifdef DEBUG
1141 if (aMaskLayer) {
1142 bool maskIs2D = aMaskLayer->GetTransform().CanDraw2D();
1143 NS_ASSERTION(maskIs2D, "Mask layer has invalid transform.");
1145 #endif
1147 if (mMaskLayer != aMaskLayer) {
1148 MOZ_LAYERS_LOG_IF_SHADOWABLE(this,
1149 ("Layer::Mutated(%p) MaskLayer", this));
1150 mMaskLayer = aMaskLayer;
1151 Mutated();
1156 * CONSTRUCTION PHASE ONLY
1157 * Add mask layers associated with LayerClips.
1159 void SetAncestorMaskLayers(const nsTArray<RefPtr<Layer>>& aLayers) {
1160 if (aLayers != mAncestorMaskLayers) {
1161 MOZ_LAYERS_LOG_IF_SHADOWABLE(
1162 this, ("Layer::Mutated(%p) AncestorMaskLayers", this));
1163 mAncestorMaskLayers = aLayers;
1164 Mutated();
1169 * CONSTRUCTION PHASE ONLY
1170 * Add a mask layer associated with a LayerClip.
1172 void AddAncestorMaskLayer(const RefPtr<Layer>& aLayer) {
1173 mAncestorMaskLayers.AppendElement(aLayer);
1174 Mutated();
1178 * CONSTRUCTION PHASE ONLY
1179 * Tell this layer what its transform should be. The transformation
1180 * is applied when compositing the layer into its parent container.
1182 void SetBaseTransform(const gfx::Matrix4x4& aMatrix) {
1183 NS_ASSERTION(!aMatrix.IsSingular(),
1184 "Shouldn't be trying to draw with a singular matrix!");
1185 mPendingTransform = nullptr;
1186 if (!mSimpleAttrs.SetTransform(aMatrix)) {
1187 return;
1189 MOZ_LAYERS_LOG_IF_SHADOWABLE(this,
1190 ("Layer::Mutated(%p) BaseTransform", this));
1191 MutatedSimple();
1195 * Can be called at any time.
1197 * Like SetBaseTransform(), but can be called before the next
1198 * transform (i.e. outside an open transaction). Semantically, this
1199 * method enqueues a new transform value to be set immediately after
1200 * the next transaction is opened.
1202 void SetBaseTransformForNextTransaction(const gfx::Matrix4x4& aMatrix) {
1203 mPendingTransform = mozilla::MakeUnique<gfx::Matrix4x4>(aMatrix);
1206 void SetPostScale(float aXScale, float aYScale) {
1207 if (!mSimpleAttrs.SetPostScale(aXScale, aYScale)) {
1208 return;
1210 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PostScale", this));
1211 MutatedSimple();
1215 * CONSTRUCTION PHASE ONLY
1216 * A layer is "fixed position" when it draws content from a content
1217 * (not chrome) document, the topmost content document has a root scrollframe
1218 * with a displayport, but the layer does not move when that displayport
1219 * scrolls.
1221 void SetIsFixedPosition(bool aFixedPosition) {
1222 if (mSimpleAttrs.SetIsFixedPosition(aFixedPosition)) {
1223 MOZ_LAYERS_LOG_IF_SHADOWABLE(
1224 this, ("Layer::Mutated(%p) IsFixedPosition", this));
1225 MutatedSimple();
1229 void SetIsAsyncZoomContainer(const Maybe<FrameMetrics::ViewID>& aViewId) {
1230 if (mSimpleAttrs.SetIsAsyncZoomContainer(aViewId)) {
1231 MOZ_LAYERS_LOG_IF_SHADOWABLE(
1232 this, ("Layer::Mutated(%p) IsAsyncZoomContainer", this));
1233 MutatedSimple();
1238 * CONSTRUCTION PHASE ONLY
1239 * This flag is true when the transform on the layer is a perspective
1240 * transform. The compositor treats perspective transforms specially
1241 * for async scrolling purposes.
1243 void SetTransformIsPerspective(bool aTransformIsPerspective) {
1244 if (mSimpleAttrs.SetTransformIsPerspective(aTransformIsPerspective)) {
1245 MOZ_LAYERS_LOG_IF_SHADOWABLE(
1246 this, ("Layer::Mutated(%p) TransformIsPerspective", this));
1247 MutatedSimple();
1250 // This is only called when the layer tree is updated. Do not call this from
1251 // layout code. To add an animation to this layer, use AddAnimation.
1252 void SetCompositorAnimations(
1253 const CompositorAnimations& aCompositorAnimations);
1254 // Go through all animations in this layer and its children and, for
1255 // any animations with a null start time, update their start time such
1256 // that at |aReadyTime| the animation's current time corresponds to its
1257 // 'initial current time' value.
1258 void StartPendingAnimations(const TimeStamp& aReadyTime);
1260 void ClearCompositorAnimations();
1263 * CONSTRUCTION PHASE ONLY
1264 * If a layer represents a fixed position element, this data is stored on the
1265 * layer for use by the compositor.
1267 * - |aScrollId| identifies the scroll frame that this element is fixed
1268 * with respect to.
1270 * - |aAnchor| is the point on the layer that is considered the "anchor"
1271 * point, that is, the point which remains in the same position when
1272 * compositing the layer tree with a transformation (such as when
1273 * asynchronously scrolling and zooming).
1275 * - |aSides| is the set of sides to which the element is fixed relative to.
1276 * This is used if the viewport size is changed in the compositor and
1277 * fixed position items need to shift accordingly. This value is made up
1278 * combining appropriate values from mozilla::SideBits.
1280 void SetFixedPositionData(ScrollableLayerGuid::ViewID aScrollId,
1281 const LayerPoint& aAnchor, SideBits aSides) {
1282 if (mSimpleAttrs.SetFixedPositionData(aScrollId, aAnchor, aSides)) {
1283 MOZ_LAYERS_LOG_IF_SHADOWABLE(
1284 this, ("Layer::Mutated(%p) FixedPositionData", this));
1285 MutatedSimple();
1290 * CONSTRUCTION PHASE ONLY
1291 * If a layer is "sticky position", |aScrollId| holds the scroll identifier
1292 * of the scrollable content that contains it. The difference between the two
1293 * rectangles |aOuter| and |aInner| is treated as two intervals in each
1294 * dimension, with the current scroll position at the origin. For each
1295 * dimension, while that component of the scroll position lies within either
1296 * interval, the layer should not move relative to its scrolling container.
1298 void SetStickyPositionData(ScrollableLayerGuid::ViewID aScrollId,
1299 LayerRectAbsolute aOuter,
1300 LayerRectAbsolute aInner) {
1301 if (mSimpleAttrs.SetStickyPositionData(aScrollId, aOuter, aInner)) {
1302 MOZ_LAYERS_LOG_IF_SHADOWABLE(
1303 this, ("Layer::Mutated(%p) StickyPositionData", this));
1304 MutatedSimple();
1309 * CONSTRUCTION PHASE ONLY
1310 * If a layer is a scroll thumb container layer or a scrollbar container
1311 * layer, set the scroll identifier of the scroll frame scrolled by
1312 * the scrollbar, and other data related to the scrollbar.
1314 void SetScrollbarData(const ScrollbarData& aThumbData) {
1315 if (mSimpleAttrs.SetScrollbarData(aThumbData)) {
1316 MOZ_LAYERS_LOG_IF_SHADOWABLE(this,
1317 ("Layer::Mutated(%p) ScrollbarData", this));
1318 MutatedSimple();
1322 // Used when forwarding transactions. Do not use at any other time.
1323 void SetSimpleAttributes(const SimpleLayerAttributes& aAttrs) {
1324 mSimpleAttrs = aAttrs;
1326 const SimpleLayerAttributes& GetSimpleAttributes() const {
1327 return mSimpleAttrs;
1330 // These getters can be used anytime.
1331 float GetOpacity() { return mSimpleAttrs.GetOpacity(); }
1332 gfx::CompositionOp GetMixBlendMode() const {
1333 return mSimpleAttrs.GetMixBlendMode();
1335 const Maybe<ParentLayerIntRect>& GetClipRect() const { return mClipRect; }
1336 const Maybe<LayerClip>& GetScrolledClip() const {
1337 return mSimpleAttrs.GetScrolledClip();
1339 Maybe<ParentLayerIntRect> GetScrolledClipRect() const;
1340 uint32_t GetContentFlags() { return mSimpleAttrs.GetContentFlags(); }
1341 const LayerIntRegion& GetVisibleRegion() const { return mVisibleRegion; }
1342 const ScrollMetadata& GetScrollMetadata(uint32_t aIndex) const;
1343 const FrameMetrics& GetFrameMetrics(uint32_t aIndex) const;
1344 uint32_t GetScrollMetadataCount() const { return mScrollMetadata.Length(); }
1345 const nsTArray<ScrollMetadata>& GetAllScrollMetadata() {
1346 return mScrollMetadata;
1348 bool HasScrollableFrameMetrics() const;
1349 bool IsScrollableWithoutContent() const;
1350 const EventRegions& GetEventRegions() const { return mEventRegions; }
1351 ContainerLayer* GetParent() { return mParent; }
1352 Layer* GetNextSibling() {
1353 if (mNextSibling) {
1354 mNextSibling->CheckCanary();
1356 return mNextSibling;
1358 const Layer* GetNextSibling() const {
1359 if (mNextSibling) {
1360 mNextSibling->CheckCanary();
1362 return mNextSibling;
1364 Layer* GetPrevSibling() { return mPrevSibling; }
1365 const Layer* GetPrevSibling() const { return mPrevSibling; }
1366 virtual Layer* GetFirstChild() const { return nullptr; }
1367 virtual Layer* GetLastChild() const { return nullptr; }
1368 gfx::Matrix4x4 GetTransform() const;
1369 // Same as GetTransform(), but returns the transform as a strongly-typed
1370 // matrix. Eventually this will replace GetTransform().
1371 const CSSTransformMatrix GetTransformTyped() const;
1372 const gfx::Matrix4x4& GetBaseTransform() const {
1373 return mSimpleAttrs.GetTransform();
1375 // Note: these are virtual because ContainerLayerComposite overrides them.
1376 virtual float GetPostXScale() const { return mSimpleAttrs.GetPostXScale(); }
1377 virtual float GetPostYScale() const { return mSimpleAttrs.GetPostYScale(); }
1378 bool GetIsFixedPosition() { return mSimpleAttrs.IsFixedPosition(); }
1379 Maybe<FrameMetrics::ViewID> IsAsyncZoomContainer() {
1380 return mSimpleAttrs.IsAsyncZoomContainer();
1382 bool GetTransformIsPerspective() const {
1383 return mSimpleAttrs.GetTransformIsPerspective();
1385 bool GetIsStickyPosition() { return mSimpleAttrs.IsStickyPosition(); }
1386 ScrollableLayerGuid::ViewID GetFixedPositionScrollContainerId() {
1387 return mSimpleAttrs.GetFixedPositionScrollContainerId();
1389 LayerPoint GetFixedPositionAnchor() {
1390 return mSimpleAttrs.GetFixedPositionAnchor();
1392 SideBits GetFixedPositionSides() {
1393 return mSimpleAttrs.GetFixedPositionSides();
1395 ScrollableLayerGuid::ViewID GetStickyScrollContainerId() {
1396 return mSimpleAttrs.GetStickyScrollContainerId();
1398 const LayerRectAbsolute& GetStickyScrollRangeOuter() {
1399 return mSimpleAttrs.GetStickyScrollRangeOuter();
1401 const LayerRectAbsolute& GetStickyScrollRangeInner() {
1402 return mSimpleAttrs.GetStickyScrollRangeInner();
1404 const ScrollbarData& GetScrollbarData() const {
1405 return mSimpleAttrs.GetScrollbarData();
1407 bool IsScrollbarContainer() const;
1408 Layer* GetMaskLayer() const { return mMaskLayer; }
1409 bool HasPendingTransform() const { return !!mPendingTransform; }
1411 void CheckCanary() const { mCanary.Check(); }
1413 // Ancestor mask layers are associated with FrameMetrics, but for simplicity
1414 // in maintaining the layer tree structure we attach them to the layer.
1415 size_t GetAncestorMaskLayerCount() const {
1416 return mAncestorMaskLayers.Length();
1418 Layer* GetAncestorMaskLayerAt(size_t aIndex) const {
1419 return mAncestorMaskLayers.ElementAt(aIndex);
1421 const nsTArray<RefPtr<Layer>>& GetAllAncestorMaskLayers() const {
1422 return mAncestorMaskLayers;
1425 bool HasMaskLayers() const {
1426 return GetMaskLayer() || mAncestorMaskLayers.Length() > 0;
1430 * Get the combined clip rect of the Layer clip and all clips on FrameMetrics.
1431 * This is intended for use in Layout. The compositor needs to apply async
1432 * transforms to find the combined clip.
1434 Maybe<ParentLayerIntRect> GetCombinedClipRect() const;
1437 * Retrieve the root level visible region for |this| taking into account
1438 * clipping applied to parent layers of |this| as well as subtracting
1439 * visible regions of higher siblings of this layer and each ancestor.
1441 * Note translation values for offsets of visible regions and accumulated
1442 * aLayerOffset are integer rounded using IntPoint::Round.
1444 * @param aResult - the resulting visible region of this layer.
1445 * @param aLayerOffset - this layer's total offset from the root layer.
1446 * @return - false if during layer tree traversal a parent or sibling
1447 * transform is found to be non-translational. This method returns early
1448 * in this case, results will not be valid. Returns true on successful
1449 * traversal.
1451 bool GetVisibleRegionRelativeToRootLayer(nsIntRegion& aResult,
1452 nsIntPoint* aLayerOffset);
1454 // Note that all lengths in animation data are either in CSS pixels or app
1455 // units and must be converted to device pixels by the compositor.
1456 // Besides, this should only be called on the compositor thread.
1457 AnimationArray& GetAnimations() { return mAnimationInfo.GetAnimations(); }
1458 uint64_t GetCompositorAnimationsId() {
1459 return mAnimationInfo.GetCompositorAnimationsId();
1461 nsTArray<PropertyAnimationGroup>& GetPropertyAnimationGroups() {
1462 return mAnimationInfo.GetPropertyAnimationGroups();
1464 const Maybe<TransformData>& GetTransformData() const {
1465 return mAnimationInfo.GetTransformData();
1468 Maybe<uint64_t> GetAnimationGeneration() const {
1469 return mAnimationInfo.GetAnimationGeneration();
1472 gfx::Path* CachedMotionPath() { return mAnimationInfo.CachedMotionPath(); }
1474 bool HasTransformAnimation() const;
1477 * Returns the local transform for this layer: either mTransform or,
1478 * for shadow layers, GetShadowBaseTransform(), in either case with the
1479 * pre- and post-scales applied.
1481 gfx::Matrix4x4 GetLocalTransform();
1484 * Same as GetLocalTransform(), but returns a strongly-typed matrix.
1485 * Eventually, this will replace GetLocalTransform().
1487 const LayerToParentLayerMatrix4x4 GetLocalTransformTyped();
1490 * Returns the local opacity for this layer: either mOpacity or,
1491 * for shadow layers, GetShadowOpacity()
1493 float GetLocalOpacity();
1496 * DRAWING PHASE ONLY
1498 * Apply pending changes to layers before drawing them, if those
1499 * pending changes haven't been overridden by later changes.
1501 * Returns a list of scroll ids which had pending updates.
1503 std::unordered_set<ScrollableLayerGuid::ViewID>
1504 ApplyPendingUpdatesToSubtree();
1507 * DRAWING PHASE ONLY
1509 * Write layer-subtype-specific attributes into aAttrs. Used to
1510 * synchronize layer attributes to their shadows'.
1512 virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) {}
1514 // Returns true if it's OK to save the contents of aLayer in an
1515 // opaque surface (a surface without an alpha channel).
1516 // If we can use a surface without an alpha channel, we should, because
1517 // it will often make painting of antialiased text faster and higher
1518 // quality.
1519 bool CanUseOpaqueSurface();
1521 SurfaceMode GetSurfaceMode() {
1522 if (CanUseOpaqueSurface()) return SurfaceMode::SURFACE_OPAQUE;
1523 if (GetContentFlags() & CONTENT_COMPONENT_ALPHA)
1524 return SurfaceMode::SURFACE_COMPONENT_ALPHA;
1525 return SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
1528 // Returns true if this layer can be treated as opaque for visibility
1529 // computation. A layer may be non-opaque for visibility even if it
1530 // is not transparent, for example, if it has a mix-blend-mode.
1531 bool IsOpaqueForVisibility();
1534 * This setter can be used anytime. The user data for all keys is
1535 * initially null. Ownership pases to the layer manager.
1537 void SetUserData(
1538 void* aKey, LayerUserData* aData,
1539 void (*aDestroy)(void*) = LayerManager::LayerUserDataDestroy) {
1540 mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, aDestroy);
1543 * This can be used anytime. Ownership passes to the caller!
1545 UniquePtr<LayerUserData> RemoveUserData(void* aKey);
1547 * This getter can be used anytime.
1549 bool HasUserData(void* aKey) {
1550 return mUserData.Has(static_cast<gfx::UserDataKey*>(aKey));
1553 * This getter can be used anytime. Ownership is retained by the layer
1554 * manager.
1556 LayerUserData* GetUserData(void* aKey) const {
1557 return static_cast<LayerUserData*>(
1558 mUserData.Get(static_cast<gfx::UserDataKey*>(aKey)));
1562 * |Disconnect()| is used by layers hooked up over IPC. It may be
1563 * called at any time, and may not be called at all. Using an
1564 * IPC-enabled layer after Destroy() (drawing etc.) results in a
1565 * safe no-op; no crashy or uaf etc.
1567 * XXX: this interface is essentially LayerManager::Destroy, but at
1568 * Layer granularity. It might be beneficial to unify them.
1570 virtual void Disconnect() {}
1573 * Dynamic downcast to a PaintedLayer. Returns null if this is not
1574 * a PaintedLayer.
1576 virtual PaintedLayer* AsPaintedLayer() { return nullptr; }
1579 * Dynamic cast to a ContainerLayer. Returns null if this is not
1580 * a ContainerLayer.
1582 virtual ContainerLayer* AsContainerLayer() { return nullptr; }
1583 virtual const ContainerLayer* AsContainerLayer() const { return nullptr; }
1586 * Dynamic cast to a RefLayer. Returns null if this is not a
1587 * RefLayer.
1589 virtual RefLayer* AsRefLayer() { return nullptr; }
1592 * Dynamic cast to a Color. Returns null if this is not a
1593 * ColorLayer.
1595 virtual ColorLayer* AsColorLayer() { return nullptr; }
1598 * Dynamic cast to a Canvas. Returns null if this is not a
1599 * ColorLayer.
1601 virtual CanvasLayer* AsCanvasLayer() { return nullptr; }
1604 * Dynamic cast to an Image. Returns null if this is not a
1605 * ColorLayer.
1607 virtual ImageLayer* AsImageLayer() { return nullptr; }
1610 * Dynamic cast to a LayerComposite. Return null if this is not a
1611 * LayerComposite. Can be used anytime.
1613 virtual HostLayer* AsHostLayer() { return nullptr; }
1616 * Dynamic cast to a ShadowableLayer. Return null if this is not a
1617 * ShadowableLayer. Can be used anytime.
1619 virtual ShadowableLayer* AsShadowableLayer() { return nullptr; }
1621 // These getters can be used anytime. They return the effective
1622 // values that should be used when drawing this layer to screen,
1623 // accounting for this layer possibly being a shadow.
1624 const Maybe<ParentLayerIntRect>& GetLocalClipRect();
1625 const LayerIntRegion& GetLocalVisibleRegion();
1627 bool Extend3DContext() {
1628 return GetContentFlags() & CONTENT_EXTEND_3D_CONTEXT;
1630 bool Combines3DTransformWithAncestors() {
1631 return GetParent() &&
1632 reinterpret_cast<Layer*>(GetParent())->Extend3DContext();
1634 bool Is3DContextLeaf() {
1635 return !Extend3DContext() && Combines3DTransformWithAncestors();
1638 * It is true if the user can see the back of the layer and the
1639 * backface is hidden. The compositor should skip the layer if the
1640 * result is true.
1642 bool IsBackfaceHidden();
1643 bool IsVisible() {
1644 // For containers extending 3D context, visible region
1645 // is meaningless, since they are just intermediate result of
1646 // content.
1647 return !GetLocalVisibleRegion().IsEmpty() || Extend3DContext();
1651 * Return true if current layer content is opaque.
1652 * It does not guarantee that layer content is always opaque.
1654 virtual bool IsOpaque() { return GetContentFlags() & CONTENT_OPAQUE; }
1657 * Returns the product of the opacities of this layer and all ancestors up
1658 * to and excluding the nearest ancestor that has UseIntermediateSurface()
1659 * set.
1661 float GetEffectiveOpacity();
1664 * Returns the blendmode of this layer.
1666 gfx::CompositionOp GetEffectiveMixBlendMode();
1669 * This returns the effective transform computed by
1670 * ComputeEffectiveTransforms. Typically this is a transform that transforms
1671 * this layer all the way to some intermediate surface or destination
1672 * surface. For non-BasicLayers this will be a transform to the nearest
1673 * ancestor with UseIntermediateSurface() (or to the root, if there is no
1674 * such ancestor), but for BasicLayers it's different.
1676 const gfx::Matrix4x4& GetEffectiveTransform() const {
1677 return mEffectiveTransform;
1681 * This returns the effective transform for Layer's buffer computed by
1682 * ComputeEffectiveTransforms. Typically this is a transform that transforms
1683 * this layer's buffer all the way to some intermediate surface or destination
1684 * surface. For non-BasicLayers this will be a transform to the nearest
1685 * ancestor with UseIntermediateSurface() (or to the root, if there is no
1686 * such ancestor), but for BasicLayers it's different.
1688 * By default, its value is same to GetEffectiveTransform().
1689 * When ImageLayer is rendered with ScaleMode::STRETCH,
1690 * it becomes different from GetEffectiveTransform().
1692 virtual const gfx::Matrix4x4& GetEffectiveTransformForBuffer() const {
1693 return mEffectiveTransform;
1697 * If the current layers participates in a preserve-3d
1698 * context (returns true for Combines3DTransformWithAncestors),
1699 * returns the combined transform up to the preserve-3d (nearest
1700 * ancestor that doesn't Extend3DContext()). Otherwise returns
1701 * the local transform.
1703 gfx::Matrix4x4 ComputeTransformToPreserve3DRoot();
1706 * @param aTransformToSurface the composition of the transforms
1707 * from the parent layer (if any) to the destination pixel grid.
1709 * Computes mEffectiveTransform for this layer and all its descendants.
1710 * mEffectiveTransform transforms this layer up to the destination
1711 * pixel grid (whatever aTransformToSurface is relative to).
1713 * We promise that when this is called on a layer, all ancestor layers
1714 * have already had ComputeEffectiveTransforms called.
1716 virtual void ComputeEffectiveTransforms(
1717 const gfx::Matrix4x4& aTransformToSurface) = 0;
1720 * Computes the effective transform for mask layers, if this layer has any.
1722 void ComputeEffectiveTransformForMaskLayers(
1723 const gfx::Matrix4x4& aTransformToSurface);
1724 static void ComputeEffectiveTransformForMaskLayer(
1725 Layer* aMaskLayer, const gfx::Matrix4x4& aTransformToSurface);
1728 * Calculate the scissor rect required when rendering this layer.
1729 * Returns a rectangle relative to the intermediate surface belonging to the
1730 * nearest ancestor that has an intermediate surface, or relative to the root
1731 * viewport if no ancestor has an intermediate surface, corresponding to the
1732 * clip rect for this layer intersected with aCurrentScissorRect.
1734 RenderTargetIntRect CalculateScissorRect(
1735 const RenderTargetIntRect& aCurrentScissorRect);
1737 virtual const char* Name() const = 0;
1738 virtual LayerType GetType() const = 0;
1741 * Only the implementation should call this. This is per-implementation
1742 * private data. Normally, all layers with a given layer manager
1743 * use the same type of ImplData.
1745 void* ImplData() { return mImplData; }
1748 * Only the implementation should use these methods.
1750 void SetParent(ContainerLayer* aParent) { mParent = aParent; }
1751 void SetNextSibling(Layer* aSibling) { mNextSibling = aSibling; }
1752 void SetPrevSibling(Layer* aSibling) { mPrevSibling = aSibling; }
1755 * Dump information about this layer manager and its managed tree to
1756 * aStream.
1758 void Dump(std::stringstream& aStream, const char* aPrefix = "",
1759 bool aDumpHtml = false, bool aSorted = false,
1760 const Maybe<gfx::Polygon>& aGeometry = Nothing());
1762 * Dump information about just this layer manager itself to aStream.
1764 void DumpSelf(std::stringstream& aStream, const char* aPrefix = "",
1765 const Maybe<gfx::Polygon>& aGeometry = Nothing());
1768 * Dump information about this layer and its child & sibling layers to
1769 * layerscope packet.
1771 void Dump(layerscope::LayersPacket* aPacket, const void* aParent);
1774 * Log information about this layer manager and its managed tree to
1775 * the NSPR log (if enabled for "Layers").
1777 void Log(const char* aPrefix = "");
1779 * Log information about just this layer manager itself to the NSPR
1780 * log (if enabled for "Layers").
1782 void LogSelf(const char* aPrefix = "");
1784 // Print interesting information about this into aStream. Internally
1785 // used to implement Dump*() and Log*(). If subclasses have
1786 // additional interesting properties, they should override this with
1787 // an implementation that first calls the base implementation then
1788 // appends additional info to aTo.
1789 virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
1791 // Just like PrintInfo, but this function dump information into layerscope
1792 // packet, instead of a StringStream. It is also internally used to implement
1793 // Dump();
1794 virtual void DumpPacket(layerscope::LayersPacket* aPacket,
1795 const void* aParent);
1798 * Store display list log.
1800 void SetDisplayListLog(const char* log);
1803 * Return display list log.
1805 void GetDisplayListLog(nsCString& log);
1807 static bool IsLogEnabled() { return LayerManager::IsLogEnabled(); }
1810 * Returns the current area of the layer (in layer-space coordinates)
1811 * marked as needed to be recomposited.
1813 const virtual gfx::TiledIntRegion& GetInvalidRegion() {
1814 return mInvalidRegion;
1816 void AddInvalidRegion(const nsIntRegion& aRegion) {
1817 mInvalidRegion.Add(aRegion);
1821 * Mark the entirety of the layer's visible region as being invalid.
1823 void SetInvalidRectToVisibleRegion() {
1824 mInvalidRegion.SetEmpty();
1825 mInvalidRegion.Add(GetVisibleRegion().ToUnknownRegion());
1829 * Adds to the current invalid rect.
1831 void AddInvalidRect(const gfx::IntRect& aRect) { mInvalidRegion.Add(aRect); }
1834 * Clear the invalid rect, marking the layer as being identical to what is
1835 * currently composited.
1837 virtual void ClearInvalidRegion() { mInvalidRegion.SetEmpty(); }
1839 // These functions allow attaching an AsyncPanZoomController to this layer,
1840 // and can be used anytime.
1841 // A layer has an APZC at index aIndex only-if
1842 // GetFrameMetrics(aIndex).IsScrollable(); attempting to get an APZC for a
1843 // non-scrollable metrics will return null. The reverse is also generally true
1844 // (that if GetFrameMetrics(aIndex).IsScrollable() is true, then the layer
1845 // will have an APZC). However, it only holds on the the compositor-side layer
1846 // tree, and only after the APZ code has had a chance to rebuild its internal
1847 // hit-testing tree using the layer tree. Also, it may not hold in certain
1848 // "exceptional" scenarios such as if the layer tree doesn't have a
1849 // GeckoContentController registered for it, or if there is a malicious
1850 // content process trying to trip up the compositor over IPC. The aIndex for
1851 // these functions must be less than GetScrollMetadataCount().
1852 void SetAsyncPanZoomController(uint32_t aIndex,
1853 AsyncPanZoomController* controller);
1854 AsyncPanZoomController* GetAsyncPanZoomController(uint32_t aIndex) const;
1855 // The ScrollMetadataChanged function is used internally to ensure the APZC
1856 // array length matches the frame metrics array length.
1858 virtual void ClearCachedResources() {}
1860 virtual bool SupportsAsyncUpdate() { return false; }
1862 private:
1863 void ScrollMetadataChanged();
1865 public:
1866 void ApplyPendingUpdatesForThisTransaction();
1868 #ifdef DEBUG
1869 void SetDebugColorIndex(uint32_t aIndex) { mDebugColorIndex = aIndex; }
1870 uint32_t GetDebugColorIndex() { return mDebugColorIndex; }
1871 #endif
1873 void Mutated() { mManager->Mutated(this); }
1874 void MutatedSimple() { mManager->MutatedSimple(this); }
1876 virtual int32_t GetMaxLayerSize() { return Manager()->GetMaxTextureSize(); }
1879 * Returns true if this layer's effective transform is not just
1880 * a translation by integers, or if this layer or some ancestor layer
1881 * is marked as having a transform that may change without a full layer
1882 * transaction.
1884 * Note: This function ignores ancestor layers across layer tree boundaries
1885 * so that it returns a consistent value when compositing and when painting.
1887 bool MayResample();
1889 RenderTargetRect TransformRectToRenderTarget(const LayerIntRect& aRect);
1892 * Add debugging information to the layer dump.
1894 void AddExtraDumpInfo(const nsACString& aStr) {
1895 #ifdef MOZ_DUMP_PAINTING
1896 mExtraDumpInfo.AppendElement(aStr);
1897 #endif
1901 * Clear debugging information. Useful for recycling.
1903 void ClearExtraDumpInfo() {
1904 #ifdef MOZ_DUMP_PAINTING
1905 mExtraDumpInfo.Clear();
1906 #endif
1909 AnimationInfo& GetAnimationInfo() { return mAnimationInfo; }
1911 protected:
1912 Layer(LayerManager* aManager, void* aImplData);
1914 // Protected destructor, to discourage deletion outside of Release():
1915 virtual ~Layer();
1918 * We can snap layer transforms for two reasons:
1919 * 1) To avoid unnecessary resampling when a transform is a translation
1920 * by a non-integer number of pixels.
1921 * Snapping the translation to an integer number of pixels avoids
1922 * blurring the layer and can be faster to composite.
1923 * 2) When a layer is used to render a rectangular object, we need to
1924 * emulate the rendering of rectangular inactive content and snap the
1925 * edges of the rectangle to pixel boundaries. This is both to ensure
1926 * layer rendering is consistent with inactive content rendering, and to
1927 * avoid seams.
1928 * This function implements type 1 snapping. If aTransform is a 2D
1929 * translation, and this layer's layer manager has enabled snapping
1930 * (which is the default), return aTransform with the translation snapped
1931 * to nearest pixels. Otherwise just return aTransform. Call this when the
1932 * layer does not correspond to a single rectangular content object.
1933 * This function does not try to snap if aTransform has a scale, because in
1934 * that case resampling is inevitable and there's no point in trying to
1935 * avoid it. In fact snapping can cause problems because pixel edges in the
1936 * layer's content can be rendered unpredictably (jiggling) as the scale
1937 * interacts with the snapping of the translation, especially with animated
1938 * transforms.
1939 * @param aResidualTransform a transform to apply before the result transform
1940 * in order to get the results to completely match aTransform.
1942 gfx::Matrix4x4 SnapTransformTranslation(const gfx::Matrix4x4& aTransform,
1943 gfx::Matrix* aResidualTransform);
1944 gfx::Matrix4x4 SnapTransformTranslation3D(const gfx::Matrix4x4& aTransform,
1945 gfx::Matrix* aResidualTransform);
1947 * See comment for SnapTransformTranslation.
1948 * This function implements type 2 snapping. If aTransform is a translation
1949 * and/or scale, transform aSnapRect by aTransform, snap to pixel boundaries,
1950 * and return the transform that maps aSnapRect to that rect. Otherwise
1951 * just return aTransform.
1952 * @param aSnapRect a rectangle whose edges should be snapped to pixel
1953 * boundaries in the destination surface.
1954 * @param aResidualTransform a transform to apply before the result transform
1955 * in order to get the results to completely match aTransform.
1957 gfx::Matrix4x4 SnapTransform(const gfx::Matrix4x4& aTransform,
1958 const gfxRect& aSnapRect,
1959 gfx::Matrix* aResidualTransform);
1961 LayerManager* mManager;
1962 ContainerLayer* mParent;
1963 Layer* mNextSibling;
1964 Layer* mPrevSibling;
1965 void* mImplData;
1966 RefPtr<Layer> mMaskLayer;
1967 nsTArray<RefPtr<Layer>> mAncestorMaskLayers;
1968 // Look for out-of-bound in the middle of the structure
1969 mozilla::CorruptionCanary mCanary;
1970 gfx::UserData mUserData;
1971 SimpleLayerAttributes mSimpleAttrs;
1972 LayerIntRegion mVisibleRegion;
1973 nsTArray<ScrollMetadata> mScrollMetadata;
1974 EventRegions mEventRegions;
1975 // A mutation of |mTransform| that we've queued to be applied at the
1976 // end of the next transaction (if nothing else overrides it in the
1977 // meantime).
1978 UniquePtr<gfx::Matrix4x4> mPendingTransform;
1979 gfx::Matrix4x4 mEffectiveTransform;
1980 AnimationInfo mAnimationInfo;
1981 Maybe<ParentLayerIntRect> mClipRect;
1982 gfx::IntRect mTileSourceRect;
1983 gfx::TiledIntRegion mInvalidRegion;
1984 nsTArray<RefPtr<AsyncPanZoomController>> mApzcs;
1985 bool mUseTileSourceRect;
1986 #ifdef DEBUG
1987 uint32_t mDebugColorIndex;
1988 #endif
1989 #ifdef MOZ_DUMP_PAINTING
1990 nsTArray<nsCString> mExtraDumpInfo;
1991 #endif
1992 // Store display list log.
1993 nsCString mDisplayListLog;
1997 * A Layer which we can paint into. It is a conceptually
1998 * infinite surface, but each PaintedLayer has an associated "valid region"
1999 * of contents that it is currently storing, which is finite. PaintedLayer
2000 * implementations can store content between paints.
2002 * PaintedLayers are rendered into during the drawing phase of a transaction.
2004 * Currently the contents of a PaintedLayer are in the device output color
2005 * space.
2007 class PaintedLayer : public Layer {
2008 public:
2010 * CONSTRUCTION PHASE ONLY
2011 * Tell this layer that the content in some region has changed and
2012 * will need to be repainted. This area is removed from the valid
2013 * region.
2015 virtual void InvalidateRegion(const nsIntRegion& aRegion) = 0;
2017 * CONSTRUCTION PHASE ONLY
2018 * Set whether ComputeEffectiveTransforms should compute the
2019 * "residual translation" --- the translation that should be applied *before*
2020 * mEffectiveTransform to get the ideal transform for this PaintedLayer.
2021 * When this is true, ComputeEffectiveTransforms will compute the residual
2022 * and ensure that the layer is invalidated whenever the residual changes.
2023 * When it's false, a change in the residual will not trigger invalidation
2024 * and GetResidualTranslation will return 0,0.
2025 * So when the residual is to be ignored, set this to false for better
2026 * performance.
2028 void SetAllowResidualTranslation(bool aAllow) {
2029 mAllowResidualTranslation = aAllow;
2032 void SetValidRegion(const nsIntRegion& aRegion) {
2033 MOZ_LAYERS_LOG_IF_SHADOWABLE(this,
2034 ("Layer::Mutated(%p) ValidRegion", this));
2035 mValidRegion = aRegion;
2036 mValidRegionIsCurrent = true;
2037 Mutated();
2041 * Can be used anytime
2043 const nsIntRegion& GetValidRegion() const {
2044 EnsureValidRegionIsCurrent();
2045 return mValidRegion;
2048 void InvalidateWholeLayer() {
2049 mInvalidRegion.Add(GetValidRegion().GetBounds());
2050 ClearValidRegion();
2053 void ClearValidRegion() {
2054 mValidRegion.SetEmpty();
2055 mValidRegionIsCurrent = true;
2057 void AddToValidRegion(const nsIntRegion& aRegion) {
2058 EnsureValidRegionIsCurrent();
2059 mValidRegion.OrWith(aRegion);
2061 void SubtractFromValidRegion(const nsIntRegion& aRegion) {
2062 EnsureValidRegionIsCurrent();
2063 mValidRegion.SubOut(aRegion);
2065 void UpdateValidRegionAfterInvalidRegionChanged() {
2066 // Changes to mInvalidRegion will be applied to mValidRegion on the next
2067 // call to EnsureValidRegionIsCurrent().
2068 mValidRegionIsCurrent = false;
2071 void ClearInvalidRegion() override {
2072 // mInvalidRegion is about to be reset. This is the last chance to apply
2073 // any pending changes from it to mValidRegion. Do that by calling
2074 // EnsureValidRegionIsCurrent().
2075 EnsureValidRegionIsCurrent();
2076 mInvalidRegion.SetEmpty();
2079 PaintedLayer* AsPaintedLayer() override { return this; }
2081 MOZ_LAYER_DECL_NAME("PaintedLayer", TYPE_PAINTED)
2083 void ComputeEffectiveTransforms(
2084 const gfx::Matrix4x4& aTransformToSurface) override {
2085 gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface;
2086 gfx::Matrix residual;
2087 mEffectiveTransform = SnapTransformTranslation(
2088 idealTransform, mAllowResidualTranslation ? &residual : nullptr);
2089 // The residual can only be a translation because SnapTransformTranslation
2090 // only changes the transform if it's a translation
2091 NS_ASSERTION(residual.IsTranslation(),
2092 "Residual transform can only be a translation");
2093 if (!gfx::ThebesPoint(residual.GetTranslation())
2094 .WithinEpsilonOf(mResidualTranslation, 1e-3f)) {
2095 mResidualTranslation = gfx::ThebesPoint(residual.GetTranslation());
2096 DebugOnly<mozilla::gfx::Point> transformedOrig =
2097 idealTransform.TransformPoint(mozilla::gfx::Point());
2098 #ifdef DEBUG
2099 DebugOnly<mozilla::gfx::Point> transformed =
2100 idealTransform.TransformPoint(mozilla::gfx::Point(
2101 mResidualTranslation.x, mResidualTranslation.y)) -
2102 *&transformedOrig;
2103 #endif
2104 NS_ASSERTION(-0.5 <= (&transformed)->x && (&transformed)->x < 0.5 &&
2105 -0.5 <= (&transformed)->y && (&transformed)->y < 0.5,
2106 "Residual translation out of range");
2107 ClearValidRegion();
2109 ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
2112 LayerManager::PaintedLayerCreationHint GetCreationHint() const {
2113 return mCreationHint;
2116 bool UsedForReadback() { return mUsedForReadback; }
2117 void SetUsedForReadback(bool aUsed) { mUsedForReadback = aUsed; }
2120 * Returns true if aLayer is optimized for the given PaintedLayerCreationHint.
2122 virtual bool IsOptimizedFor(
2123 LayerManager::PaintedLayerCreationHint aCreationHint) {
2124 return true;
2128 * Returns the residual translation. Apply this translation when drawing
2129 * into the PaintedLayer so that when mEffectiveTransform is applied
2130 * afterwards by layer compositing, the results exactly match the "ideal
2131 * transform" (the product of the transform of this layer and its ancestors).
2132 * Returns 0,0 unless SetAllowResidualTranslation(true) has been called.
2133 * The residual translation components are always in the range [-0.5, 0.5).
2135 gfxPoint GetResidualTranslation() const { return mResidualTranslation; }
2137 protected:
2138 PaintedLayer(
2139 LayerManager* aManager, void* aImplData,
2140 LayerManager::PaintedLayerCreationHint aCreationHint = LayerManager::NONE)
2141 : Layer(aManager, aImplData),
2142 mValidRegion(),
2143 mValidRegionIsCurrent(true),
2144 mCreationHint(aCreationHint),
2145 mUsedForReadback(false),
2146 mAllowResidualTranslation(false) {}
2148 void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
2150 void DumpPacket(layerscope::LayersPacket* aPacket,
2151 const void* aParent) override;
2154 * ComputeEffectiveTransforms snaps the ideal transform to get
2155 * mEffectiveTransform. mResidualTranslation is the translation that should be
2156 * applied *before* mEffectiveTransform to get the ideal transform.
2158 gfxPoint mResidualTranslation;
2160 private:
2162 * Needs to be called prior to accessing mValidRegion, unless mValidRegion is
2163 * being completely overwritten.
2165 void EnsureValidRegionIsCurrent() const {
2166 if (!mValidRegionIsCurrent) {
2167 // Apply any pending mInvalidRegion changes to mValidRegion.
2168 if (!mValidRegion.IsEmpty()) {
2169 // Calling mInvalidRegion.GetRegion() is expensive.
2170 // That's why we delay the adjustment of mValidRegion for as long as
2171 // possible, so that multiple modifications to mInvalidRegion can be
2172 // applied to mValidRegion in one go.
2173 mValidRegion.SubOut(mInvalidRegion.GetRegion());
2175 mValidRegionIsCurrent = true;
2180 * The layer's valid region. If mValidRegionIsCurrent is false, then
2181 * mValidRegion has not yet been updated for recent changes to
2182 * mInvalidRegion. Those pending changes can be applied by calling
2183 * EnsureValidRegionIsCurrent().
2185 mutable nsIntRegion mValidRegion;
2187 mutable bool mValidRegionIsCurrent;
2189 protected:
2191 * The creation hint that was used when constructing this layer.
2193 const LayerManager::PaintedLayerCreationHint mCreationHint;
2195 * Set when this PaintedLayer is participating in readback, i.e. some
2196 * ReadbackLayer (may) be getting its background from this layer.
2198 bool mUsedForReadback;
2200 * True when
2202 bool mAllowResidualTranslation;
2206 * A Layer which other layers render into. It holds references to its
2207 * children.
2209 class ContainerLayer : public Layer {
2210 public:
2211 virtual ~ContainerLayer();
2214 * CONSTRUCTION PHASE ONLY
2215 * Insert aChild into the child list of this container. aChild must
2216 * not be currently in any child list or the root for the layer manager.
2217 * If aAfter is non-null, it must be a child of this container and
2218 * we insert after that layer. If it's null we insert at the start.
2220 virtual bool InsertAfter(Layer* aChild, Layer* aAfter);
2222 * CONSTRUCTION PHASE ONLY
2223 * Remove aChild from the child list of this container. aChild must
2224 * be a child of this container.
2226 virtual bool RemoveChild(Layer* aChild);
2228 * CONSTRUCTION PHASE ONLY
2229 * Reposition aChild from the child list of this container. aChild must
2230 * be a child of this container.
2231 * If aAfter is non-null, it must be a child of this container and we
2232 * reposition after that layer. If it's null, we reposition at the start.
2234 virtual bool RepositionChild(Layer* aChild, Layer* aAfter);
2236 void SetPreScale(float aXScale, float aYScale) {
2237 if (mPreXScale == aXScale && mPreYScale == aYScale) {
2238 return;
2241 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PreScale", this));
2242 mPreXScale = aXScale;
2243 mPreYScale = aYScale;
2244 Mutated();
2247 void SetInheritedScale(float aXScale, float aYScale) {
2248 if (mInheritedXScale == aXScale && mInheritedYScale == aYScale) {
2249 return;
2252 MOZ_LAYERS_LOG_IF_SHADOWABLE(this,
2253 ("Layer::Mutated(%p) InheritedScale", this));
2254 mInheritedXScale = aXScale;
2255 mInheritedYScale = aYScale;
2256 Mutated();
2259 void SetScaleToResolution(float aResolution) {
2260 if (mPresShellResolution == aResolution) {
2261 return;
2264 MOZ_LAYERS_LOG_IF_SHADOWABLE(
2265 this, ("Layer::Mutated(%p) ScaleToResolution", this));
2266 mPresShellResolution = aResolution;
2267 Mutated();
2270 void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) override;
2272 enum class SortMode {
2273 WITH_GEOMETRY,
2274 WITHOUT_GEOMETRY,
2277 nsTArray<LayerPolygon> SortChildrenBy3DZOrder(SortMode aSortMode);
2279 ContainerLayer* AsContainerLayer() override { return this; }
2280 const ContainerLayer* AsContainerLayer() const override { return this; }
2282 // These getters can be used anytime.
2283 Layer* GetFirstChild() const override { return mFirstChild; }
2284 Layer* GetLastChild() const override { return mLastChild; }
2285 float GetPreXScale() const { return mPreXScale; }
2286 float GetPreYScale() const { return mPreYScale; }
2287 float GetInheritedXScale() const { return mInheritedXScale; }
2288 float GetInheritedYScale() const { return mInheritedYScale; }
2289 float GetPresShellResolution() const { return mPresShellResolution; }
2291 MOZ_LAYER_DECL_NAME("ContainerLayer", TYPE_CONTAINER)
2294 * ContainerLayer backends need to override ComputeEffectiveTransforms
2295 * since the decision about whether to use a temporary surface for the
2296 * container is backend-specific. ComputeEffectiveTransforms must also set
2297 * mUseIntermediateSurface.
2299 void ComputeEffectiveTransforms(
2300 const gfx::Matrix4x4& aTransformToSurface) override = 0;
2303 * Call this only after ComputeEffectiveTransforms has been invoked
2304 * on this layer.
2305 * Returns true if this will use an intermediate surface. This is largely
2306 * backend-dependent, but it affects the operation of GetEffectiveOpacity().
2308 bool UseIntermediateSurface() { return mUseIntermediateSurface; }
2311 * Returns the rectangle covered by the intermediate surface,
2312 * in this layer's coordinate system.
2314 * NOTE: Since this layer has an intermediate surface it follows
2315 * that LayerPixel == RenderTargetPixel
2317 RenderTargetIntRect GetIntermediateSurfaceRect();
2320 * Returns true if this container has more than one non-empty child
2322 bool HasMultipleChildren();
2325 * Returns true if this container supports children with component alpha.
2326 * Should only be called while painting a child of this layer.
2328 bool SupportsComponentAlphaChildren() {
2329 return mSupportsComponentAlphaChildren;
2333 * Returns true if aLayer or any layer in its parent chain has the opaque
2334 * content flag set.
2336 static bool HasOpaqueAncestorLayer(Layer* aLayer);
2338 void SetChildrenChanged(bool aVal) { mChildrenChanged = aVal; }
2340 // If |aRect| is null, the entire layer should be considered invalid for
2341 // compositing.
2342 virtual void SetInvalidCompositeRect(const gfx::IntRect* aRect) {}
2344 protected:
2345 friend class ReadbackProcessor;
2347 // Note that this is not virtual, and is based on the implementation of
2348 // ContainerLayer::RemoveChild, so it should only be called where you would
2349 // want to explicitly call the base class implementation of RemoveChild;
2350 // e.g., while (mFirstChild) ContainerLayer::RemoveChild(mFirstChild);
2351 void RemoveAllChildren();
2353 void DidInsertChild(Layer* aLayer);
2354 void DidRemoveChild(Layer* aLayer);
2356 bool AnyAncestorOrThisIs3DContextLeaf();
2358 void Collect3DContextLeaves(nsTArray<Layer*>& aToSort);
2360 // Collects child layers that do not extend 3D context. For ContainerLayers
2361 // that do extend 3D context, the 3D context leaves are collected.
2362 nsTArray<Layer*> CollectChildren() {
2363 nsTArray<Layer*> children;
2365 for (Layer* layer = GetFirstChild(); layer;
2366 layer = layer->GetNextSibling()) {
2367 ContainerLayer* container = layer->AsContainerLayer();
2369 if (container && container->Extend3DContext() &&
2370 !container->UseIntermediateSurface()) {
2371 container->Collect3DContextLeaves(children);
2372 } else {
2373 children.AppendElement(layer);
2377 return children;
2380 ContainerLayer(LayerManager* aManager, void* aImplData);
2383 * A default implementation of ComputeEffectiveTransforms for use by OpenGL
2384 * and D3D.
2386 void DefaultComputeEffectiveTransforms(
2387 const gfx::Matrix4x4& aTransformToSurface);
2390 * A default implementation to compute and set the value for
2391 * SupportsComponentAlphaChildren().
2393 * If aNeedsSurfaceCopy is provided, then it is set to true if the caller
2394 * needs to copy the background up into the intermediate surface created,
2395 * false otherwise.
2397 void DefaultComputeSupportsComponentAlphaChildren(
2398 bool* aNeedsSurfaceCopy = nullptr);
2401 * Loops over the children calling ComputeEffectiveTransforms on them.
2403 void ComputeEffectiveTransformsForChildren(
2404 const gfx::Matrix4x4& aTransformToSurface);
2406 virtual void PrintInfo(std::stringstream& aStream,
2407 const char* aPrefix) override;
2409 virtual void DumpPacket(layerscope::LayersPacket* aPacket,
2410 const void* aParent) override;
2413 * True for if the container start a new 3D context extended by one
2414 * or more children.
2416 bool Creates3DContextWithExtendingChildren();
2418 Layer* mFirstChild;
2419 Layer* mLastChild;
2420 float mPreXScale;
2421 float mPreYScale;
2422 // The resolution scale inherited from the parent layer. This will already
2423 // be part of mTransform.
2424 float mInheritedXScale;
2425 float mInheritedYScale;
2426 // For layers corresponding to an nsDisplayResolution, the resolution of the
2427 // associated pres shell; for other layers, 1.0.
2428 float mPresShellResolution;
2429 bool mUseIntermediateSurface;
2430 bool mSupportsComponentAlphaChildren;
2431 bool mMayHaveReadbackChild;
2432 // This is updated by ComputeDifferences. This will be true if we need to
2433 // invalidate the intermediate surface.
2434 bool mChildrenChanged;
2438 * A Layer which just renders a solid color in its visible region. It actually
2439 * can fill any area that contains the visible region, so if you need to
2440 * restrict the area filled, set a clip region on this layer.
2442 class ColorLayer : public Layer {
2443 public:
2444 ColorLayer* AsColorLayer() override { return this; }
2447 * CONSTRUCTION PHASE ONLY
2448 * Set the color of the layer.
2450 virtual void SetColor(const gfx::DeviceColor& aColor) {
2451 if (mColor != aColor) {
2452 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Color", this));
2453 mColor = aColor;
2454 Mutated();
2458 void SetBounds(const gfx::IntRect& aBounds) {
2459 if (!mBounds.IsEqualEdges(aBounds)) {
2460 mBounds = aBounds;
2461 Mutated();
2465 const gfx::IntRect& GetBounds() { return mBounds; }
2467 // This getter can be used anytime.
2468 virtual const gfx::DeviceColor& GetColor() { return mColor; }
2470 MOZ_LAYER_DECL_NAME("ColorLayer", TYPE_COLOR)
2472 void ComputeEffectiveTransforms(
2473 const gfx::Matrix4x4& aTransformToSurface) override {
2474 gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface;
2475 mEffectiveTransform = SnapTransformTranslation(idealTransform, nullptr);
2476 ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
2479 protected:
2480 ColorLayer(LayerManager* aManager, void* aImplData)
2481 : Layer(aManager, aImplData), mColor() {}
2483 void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
2485 void DumpPacket(layerscope::LayersPacket* aPacket,
2486 const void* aParent) override;
2488 gfx::IntRect mBounds;
2489 gfx::DeviceColor mColor;
2493 * A Layer for HTML Canvas elements. It's backed by either a
2494 * gfxASurface or a GLContext (for WebGL layers), and has some control
2495 * for intelligent updating from the source if necessary (for example,
2496 * if hardware compositing is not available, for reading from the GL
2497 * buffer into an image surface that we can layer composite.)
2499 * After Initialize is called, the underlying canvas Surface/GLContext
2500 * must not be modified during a layer transaction.
2502 class CanvasLayer : public Layer {
2503 public:
2504 void SetBounds(gfx::IntRect aBounds) { mBounds = aBounds; }
2506 CanvasLayer* AsCanvasLayer() override { return this; }
2509 * Notify this CanvasLayer that the canvas surface contents have
2510 * changed (or will change) before the next transaction.
2512 void Updated() {
2513 mCanvasRenderer->SetDirty();
2514 SetInvalidRectToVisibleRegion();
2518 * Notify this CanvasLayer that the canvas surface contents have
2519 * been painted since the last change.
2521 void Painted() { mCanvasRenderer->ResetDirty(); }
2524 * Returns true if the canvas surface contents have changed since the
2525 * last paint.
2527 bool IsDirty() {
2528 // We can only tell if we are dirty if we're part of the
2529 // widget's retained layer tree.
2530 if (!mManager || !mManager->IsWidgetLayerManager()) {
2531 return true;
2533 return mCanvasRenderer->IsDirty();
2536 const nsIntRect& GetBounds() const { return mBounds; }
2538 CanvasRenderer* CreateOrGetCanvasRenderer();
2540 public:
2542 * CONSTRUCTION PHASE ONLY
2543 * Set the filter used to resample this image (if necessary).
2545 void SetSamplingFilter(gfx::SamplingFilter aSamplingFilter) {
2546 if (mSamplingFilter != aSamplingFilter) {
2547 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Filter", this));
2548 mSamplingFilter = aSamplingFilter;
2549 Mutated();
2552 gfx::SamplingFilter GetSamplingFilter() const { return mSamplingFilter; }
2554 MOZ_LAYER_DECL_NAME("CanvasLayer", TYPE_CANVAS)
2556 void ComputeEffectiveTransforms(
2557 const gfx::Matrix4x4& aTransformToSurface) override {
2558 // Snap our local transform first, and snap the inherited transform as well.
2559 // This makes our snapping equivalent to what would happen if our content
2560 // was drawn into a PaintedLayer (gfxContext would snap using the local
2561 // transform, then we'd snap again when compositing the PaintedLayer).
2562 mEffectiveTransform =
2563 SnapTransform(GetLocalTransform(),
2564 gfxRect(0, 0, mBounds.Width(), mBounds.Height()),
2565 nullptr) *
2566 SnapTransformTranslation(aTransformToSurface, nullptr);
2567 ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
2570 protected:
2571 CanvasLayer(LayerManager* aManager, void* aImplData);
2572 virtual ~CanvasLayer();
2574 void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
2576 void DumpPacket(layerscope::LayersPacket* aPacket,
2577 const void* aParent) override;
2579 virtual CanvasRenderer* CreateCanvasRendererInternal() = 0;
2581 UniquePtr<CanvasRenderer> mCanvasRenderer;
2582 gfx::SamplingFilter mSamplingFilter;
2585 * 0, 0, canvaswidth, canvasheight
2587 gfx::IntRect mBounds;
2591 * ContainerLayer that refers to a "foreign" layer tree, through an
2592 * ID. Usage of RefLayer looks like
2594 * Construction phase:
2595 * allocate ID for layer subtree
2596 * create RefLayer, SetReferentId(ID)
2598 * Composition:
2599 * look up subtree for GetReferentId()
2600 * ConnectReferentLayer(subtree)
2601 * compose
2602 * ClearReferentLayer()
2604 * Clients will usually want to Connect/Clear() on each transaction to
2605 * avoid difficulties managing memory across multiple layer subtrees.
2607 class RefLayer : public ContainerLayer {
2608 friend class LayerManager;
2610 private:
2611 bool InsertAfter(Layer* aChild, Layer* aAfter) override {
2612 MOZ_CRASH("GFX: RefLayer");
2613 return false;
2616 bool RemoveChild(Layer* aChild) override {
2617 MOZ_CRASH("GFX: RefLayer");
2618 return false;
2621 bool RepositionChild(Layer* aChild, Layer* aAfter) override {
2622 MOZ_CRASH("GFX: RefLayer");
2623 return false;
2626 public:
2628 * CONSTRUCTION PHASE ONLY
2629 * Set the ID of the layer's referent.
2631 void SetReferentId(LayersId aId) {
2632 MOZ_ASSERT(aId.IsValid());
2633 if (mId != aId) {
2634 MOZ_LAYERS_LOG_IF_SHADOWABLE(this,
2635 ("Layer::Mutated(%p) ReferentId", this));
2636 mId = aId;
2637 Mutated();
2641 * CONSTRUCTION PHASE ONLY
2642 * Connect this ref layer to its referent, temporarily.
2643 * ClearReferentLayer() must be called after composition.
2645 void ConnectReferentLayer(Layer* aLayer) {
2646 MOZ_ASSERT(!mFirstChild && !mLastChild);
2647 MOZ_ASSERT(!aLayer->GetParent());
2648 if (aLayer->Manager() != Manager()) {
2649 // This can happen when e.g. rendering while dragging tabs
2650 // between windows - aLayer's manager may be the manager for the
2651 // old window's tab. In that case, it will be changed before the
2652 // next render (see SetLayerManager). It is simply easier to
2653 // ignore the rendering here than it is to pause it.
2654 NS_WARNING("ConnectReferentLayer failed - Incorrect LayerManager");
2655 return;
2658 mFirstChild = mLastChild = aLayer;
2659 aLayer->SetParent(this);
2663 * CONSTRUCTION PHASE ONLY
2664 * Set flags that indicate how event regions in the child layer tree need
2665 * to be overridden because of properties of the parent layer tree.
2667 void SetEventRegionsOverride(EventRegionsOverride aVal) {
2668 if (mEventRegionsOverride == aVal) {
2669 return;
2672 MOZ_LAYERS_LOG_IF_SHADOWABLE(
2673 this, ("Layer::Mutated(%p) EventRegionsOverride", this));
2674 mEventRegionsOverride = aVal;
2675 Mutated();
2678 EventRegionsOverride GetEventRegionsOverride() const {
2679 return mEventRegionsOverride;
2683 * CONSTRUCTION PHASE ONLY
2684 * Set remote subdocument iframe size.
2686 void SetRemoteDocumentSize(const LayerIntSize& aRemoteDocumentSize) {
2687 if (mRemoteDocumentSize == aRemoteDocumentSize) {
2688 return;
2690 mRemoteDocumentSize = aRemoteDocumentSize;
2691 Mutated();
2694 const LayerIntSize& GetRemoteDocumentSize() const {
2695 return mRemoteDocumentSize;
2699 * DRAWING PHASE ONLY
2700 * |aLayer| is the same as the argument to ConnectReferentLayer().
2702 void DetachReferentLayer(Layer* aLayer) {
2703 mFirstChild = mLastChild = nullptr;
2704 aLayer->SetParent(nullptr);
2707 // These getters can be used anytime.
2708 RefLayer* AsRefLayer() override { return this; }
2710 virtual LayersId GetReferentId() { return mId; }
2713 * DRAWING PHASE ONLY
2715 void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) override;
2717 MOZ_LAYER_DECL_NAME("RefLayer", TYPE_REF)
2719 protected:
2720 RefLayer(LayerManager* aManager, void* aImplData)
2721 : ContainerLayer(aManager, aImplData),
2722 mId{0},
2723 mEventRegionsOverride(EventRegionsOverride::NoOverride) {}
2725 void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
2727 void DumpPacket(layerscope::LayersPacket* aPacket,
2728 const void* aParent) override;
2730 // 0 is a special value that means "no ID".
2731 LayersId mId;
2732 EventRegionsOverride mEventRegionsOverride;
2733 // The remote documents only need their size because their origin is always
2734 // (0, 0).
2735 LayerIntSize mRemoteDocumentSize;
2738 void SetAntialiasingFlags(Layer* aLayer, gfx::DrawTarget* aTarget);
2740 #ifdef MOZ_DUMP_PAINTING
2741 void WriteSnapshotToDumpFile(Layer* aLayer, gfx::DataSourceSurface* aSurf);
2742 void WriteSnapshotToDumpFile(LayerManager* aManager,
2743 gfx::DataSourceSurface* aSurf);
2744 void WriteSnapshotToDumpFile(Compositor* aCompositor, gfx::DrawTarget* aTarget);
2745 #endif
2747 // A utility function used by different LayerManager implementations.
2748 gfx::IntRect ToOutsideIntRect(const gfxRect& aRect);
2750 void RecordCompositionPayloadsPresented(
2751 const nsTArray<CompositionPayload>& aPayloads);
2753 } // namespace layers
2754 } // namespace mozilla
2756 #endif /* GFX_LAYERS_H */