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