gfx/layers/Layers.h

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:f2abde823365
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 <stdint.h> // for uint32_t, uint64_t, uint8_t
10 #include <stdio.h> // for FILE
11 #include <sys/types.h> // for int32_t, int64_t
12 #include "FrameMetrics.h" // for FrameMetrics
13 #include "Units.h" // for LayerMargin, LayerPoint
14 #include "gfxContext.h" // for GraphicsOperator
15 #include "gfxTypes.h"
16 #include "gfxColor.h" // for gfxRGBA
17 #include "gfxMatrix.h" // for gfxMatrix
18 #include "GraphicsFilter.h" // for GraphicsFilter
19 #include "gfxPoint.h" // for gfxPoint
20 #include "gfxRect.h" // for gfxRect
21 #include "gfx2DGlue.h"
22 #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2, etc
23 #include "mozilla/DebugOnly.h" // for DebugOnly
24 #include "mozilla/EventForwards.h" // for nsPaintEvent
25 #include "mozilla/RefPtr.h" // for TemporaryRef
26 #include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
27 #include "mozilla/gfx/BaseMargin.h" // for BaseMargin
28 #include "mozilla/gfx/BasePoint.h" // for BasePoint
29 #include "mozilla/gfx/Point.h" // for IntSize
30 #include "mozilla/gfx/Types.h" // for SurfaceFormat
31 #include "mozilla/gfx/UserData.h" // for UserData, etc
32 #include "mozilla/layers/LayersTypes.h"
33 #include "mozilla/mozalloc.h" // for operator delete, etc
34 #include "nsAutoPtr.h" // for nsAutoPtr, nsRefPtr, etc
35 #include "nsCOMPtr.h" // for already_AddRefed
36 #include "nsCSSProperty.h" // for nsCSSProperty
37 #include "nsDebug.h" // for NS_ASSERTION
38 #include "nsISupportsImpl.h" // for Layer::Release, etc
39 #include "nsRect.h" // for nsIntRect
40 #include "nsRegion.h" // for nsIntRegion
41 #include "nsSize.h" // for nsIntSize
42 #include "nsString.h" // for nsCString
43 #include "nsStyleAnimation.h" // for nsStyleAnimation::Value, etc
44 #include "nsTArray.h" // for nsTArray
45 #include "nsTArrayForwardDeclare.h" // for InfallibleTArray
46 #include "nscore.h" // for nsACString, nsAString
47 #include "prlog.h" // for PRLogModuleInfo
48 #include "gfx2DGlue.h"
49
50 class gfxContext;
51
52 extern uint8_t gLayerManagerLayerBuilder;
53
54 namespace mozilla {
55
56 class FrameLayerBuilder;
57 class WebGLContext;
58
59 namespace gl {
60 class GLContext;
61 }
62
63 namespace gfx {
64 class DrawTarget;
65 class SurfaceStream;
66 }
67
68 namespace css {
69 class ComputedTimingFunction;
70 }
71
72 namespace layers {
73
74 class Animation;
75 class AnimationData;
76 class AsyncPanZoomController;
77 class CommonLayerAttributes;
78 class Layer;
79 class ThebesLayer;
80 class ContainerLayer;
81 class ImageLayer;
82 class ColorLayer;
83 class ImageContainer;
84 class CanvasLayer;
85 class ReadbackLayer;
86 class ReadbackProcessor;
87 class RefLayer;
88 class LayerComposite;
89 class ShadowableLayer;
90 class ShadowLayerForwarder;
91 class LayerManagerComposite;
92 class SpecificLayerAttributes;
93 class SurfaceDescriptor;
94 class Compositor;
95 struct TextureFactoryIdentifier;
96 struct EffectMask;
97
98 #define MOZ_LAYER_DECL_NAME(n, e) \
99 virtual const char* Name() const { return n; } \
100 virtual LayerType GetType() const { return e; }
101
102 /**
103 * Base class for userdata objects attached to layers and layer managers.
104 */
105 class LayerUserData {
106 public:
107 virtual ~LayerUserData() {}
108 };
109
110 /*
111 * Motivation: For truly smooth animation and video playback, we need to
112 * be able to compose frames and render them on a dedicated thread (i.e.
113 * off the main thread where DOM manipulation, script execution and layout
114 * induce difficult-to-bound latency). This requires Gecko to construct
115 * some kind of persistent scene structure (graph or tree) that can be
116 * safely transmitted across threads. We have other scenarios (e.g. mobile
117 * browsing) where retaining some rendered data between paints is desired
118 * for performance, so again we need a retained scene structure.
119 *
120 * Our retained scene structure is a layer tree. Each layer represents
121 * content which can be composited onto a destination surface; the root
122 * layer is usually composited into a window, and non-root layers are
123 * composited into their parent layers. Layers have attributes (e.g.
124 * opacity and clipping) that influence their compositing.
125 *
126 * We want to support a variety of layer implementations, including
127 * a simple "immediate mode" implementation that doesn't retain any
128 * rendered data between paints (i.e. uses cairo in just the way that
129 * Gecko used it before layers were introduced). But we also don't want
130 * to have bifurcated "layers"/"non-layers" rendering paths in Gecko.
131 * Therefore the layers API is carefully designed to permit maximally
132 * efficient implementation in an "immediate mode" style. See the
133 * BasicLayerManager for such an implementation.
134 */
135
136 static void LayerManagerUserDataDestroy(void *data)
137 {
138 delete static_cast<LayerUserData*>(data);
139 }
140
141 /**
142 * A LayerManager controls a tree of layers. All layers in the tree
143 * must use the same LayerManager.
144 *
145 * All modifications to a layer tree must happen inside a transaction.
146 * Only the state of the layer tree at the end of a transaction is
147 * rendered. Transactions cannot be nested
148 *
149 * Each transaction has two phases:
150 * 1) Construction: layers are created, inserted, removed and have
151 * properties set on them in this phase.
152 * BeginTransaction and BeginTransactionWithTarget start a transaction in
153 * the Construction phase. When the client has finished constructing the layer
154 * tree, it should call EndConstruction() to enter the drawing phase.
155 * 2) Drawing: ThebesLayers are rendered into in this phase, in tree
156 * order. When the client has finished drawing into the ThebesLayers, it should
157 * call EndTransaction to complete the transaction.
158 *
159 * All layer API calls happen on the main thread.
160 *
161 * Layers are refcounted. The layer manager holds a reference to the
162 * root layer, and each container layer holds a reference to its children.
163 */
164 class LayerManager {
165 NS_INLINE_DECL_REFCOUNTING(LayerManager)
166
167 protected:
168 typedef mozilla::gfx::DrawTarget DrawTarget;
169 typedef mozilla::gfx::IntSize IntSize;
170 typedef mozilla::gfx::SurfaceFormat SurfaceFormat;
171
172 public:
173 LayerManager()
174 : mDestroyed(false)
175 , mSnapEffectiveTransforms(true)
176 , mId(0)
177 , mInTransaction(false)
178 {
179 InitLog();
180 }
181
182 /**
183 * Release layers and resources held by this layer manager, and mark
184 * it as destroyed. Should do any cleanup necessary in preparation
185 * for its widget going away. After this call, only user data calls
186 * are valid on the layer manager.
187 */
188 virtual void Destroy()
189 {
190 mDestroyed = true;
191 mUserData.Destroy();
192 mRoot = nullptr;
193 }
194 bool IsDestroyed() { return mDestroyed; }
195
196 virtual ShadowLayerForwarder* AsShadowForwarder()
197 { return nullptr; }
198
199 virtual LayerManagerComposite* AsLayerManagerComposite()
200 { return nullptr; }
201
202 /**
203 * Returns true if this LayerManager is owned by an nsIWidget,
204 * and is used for drawing into the widget.
205 */
206 virtual bool IsWidgetLayerManager() { return true; }
207
208 /**
209 * Start a new transaction. Nested transactions are not allowed so
210 * there must be no transaction currently in progress.
211 * This transaction will update the state of the window from which
212 * this LayerManager was obtained.
213 */
214 virtual void BeginTransaction() = 0;
215 /**
216 * Start a new transaction. Nested transactions are not allowed so
217 * there must be no transaction currently in progress.
218 * This transaction will render the contents of the layer tree to
219 * the given target context. The rendering will be complete when
220 * EndTransaction returns.
221 */
222 virtual void BeginTransactionWithTarget(gfxContext* aTarget) = 0;
223
224 enum EndTransactionFlags {
225 END_DEFAULT = 0,
226 END_NO_IMMEDIATE_REDRAW = 1 << 0, // Do not perform the drawing phase
227 END_NO_COMPOSITE = 1 << 1, // Do not composite after drawing thebes layer contents.
228 END_NO_REMOTE_COMPOSITE = 1 << 2 // Do not schedule a composition with a remote Compositor, if one exists.
229 };
230
231 FrameLayerBuilder* GetLayerBuilder() {
232 return reinterpret_cast<FrameLayerBuilder*>(GetUserData(&gLayerManagerLayerBuilder));
233 }
234
235 /**
236 * Attempts to end an "empty transaction". There must have been no
237 * changes to the layer tree since the BeginTransaction().
238 * It's possible for this to fail; ThebesLayers may need to be updated
239 * due to VRAM data being lost, for example. In such cases this method
240 * returns false, and the caller must proceed with a normal layer tree
241 * update and EndTransaction.
242 */
243 virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) = 0;
244
245 /**
246 * Function called to draw the contents of each ThebesLayer.
247 * aRegionToDraw contains the region that needs to be drawn.
248 * This would normally be a subregion of the visible region.
249 * The callee must draw all of aRegionToDraw. Drawing outside
250 * aRegionToDraw will be clipped out or ignored.
251 * The callee must draw all of aRegionToDraw.
252 * This region is relative to 0,0 in the ThebesLayer.
253 *
254 * aRegionToInvalidate contains a region whose contents have been
255 * changed by the layer manager and which must therefore be invalidated.
256 * For example, this could be non-empty if a retained layer internally
257 * switches from RGBA to RGB or back ... we might want to repaint it to
258 * consistently use subpixel-AA or not.
259 * This region is relative to 0,0 in the ThebesLayer.
260 * aRegionToInvalidate may contain areas that are outside
261 * aRegionToDraw; the callee must ensure that these areas are repainted
262 * in the current layer manager transaction or in a later layer
263 * manager transaction.
264 *
265 * aContext must not be used after the call has returned.
266 * We guarantee that buffered contents in the visible
267 * region are valid once drawing is complete.
268 *
269 * The origin of aContext is 0,0 in the ThebesLayer.
270 */
271 typedef void (* DrawThebesLayerCallback)(ThebesLayer* aLayer,
272 gfxContext* aContext,
273 const nsIntRegion& aRegionToDraw,
274 DrawRegionClip aClip,
275 const nsIntRegion& aRegionToInvalidate,
276 void* aCallbackData);
277
278 /**
279 * Finish the construction phase of the transaction, perform the
280 * drawing phase, and end the transaction.
281 * During the drawing phase, all ThebesLayers in the tree are
282 * drawn in tree order, exactly once each, except for those layers
283 * where it is known that the visible region is empty.
284 */
285 virtual void EndTransaction(DrawThebesLayerCallback aCallback,
286 void* aCallbackData,
287 EndTransactionFlags aFlags = END_DEFAULT) = 0;
288
289 /**
290 * Schedule a composition with the remote Compositor, if one exists
291 * for this LayerManager. Useful in conjunction with the END_NO_REMOTE_COMPOSITE
292 * flag to EndTransaction.
293 */
294 virtual void Composite() {}
295
296 virtual bool HasShadowManagerInternal() const { return false; }
297 bool HasShadowManager() const { return HasShadowManagerInternal(); }
298
299 bool IsSnappingEffectiveTransforms() { return mSnapEffectiveTransforms; }
300
301 /**
302 * Returns true if this LayerManager can properly support layers with
303 * SurfaceMode::SURFACE_COMPONENT_ALPHA. This can include disabling component
304 * alpha if required.
305 */
306 virtual bool AreComponentAlphaLayersEnabled() { return true; }
307
308 /**
309 * CONSTRUCTION PHASE ONLY
310 * Set the root layer. The root layer is initially null. If there is
311 * no root layer, EndTransaction won't draw anything.
312 */
313 virtual void SetRoot(Layer* aLayer) = 0;
314 /**
315 * Can be called anytime
316 */
317 Layer* GetRoot() { return mRoot; }
318
319 /**
320 * Does a breadth-first search from the root layer to find the first
321 * scrollable layer.
322 * Can be called any time.
323 */
324 Layer* GetPrimaryScrollableLayer();
325
326 /**
327 * Returns a list of all descendant layers for which
328 * GetFrameMetrics().IsScrollable() is true.
329 */
330 void GetScrollableLayers(nsTArray<Layer*>& aArray);
331
332 /**
333 * CONSTRUCTION PHASE ONLY
334 * Called when a managee has mutated.
335 * Subclasses overriding this method must first call their
336 * superclass's impl
337 */
338 #ifdef DEBUG
339 // In debug builds, we check some properties of |aLayer|.
340 virtual void Mutated(Layer* aLayer);
341 #else
342 virtual void Mutated(Layer* aLayer) { }
343 #endif
344
345 /**
346 * Hints that can be used during Thebes layer creation to influence the type
347 * or properties of the layer created.
348 *
349 * NONE: No hint.
350 * SCROLLABLE: This layer may represent scrollable content.
351 */
352 enum ThebesLayerCreationHint {
353 NONE, SCROLLABLE
354 };
355
356 /**
357 * CONSTRUCTION PHASE ONLY
358 * Create a ThebesLayer for this manager's layer tree.
359 */
360 virtual already_AddRefed<ThebesLayer> CreateThebesLayer() = 0;
361 /**
362 * CONSTRUCTION PHASE ONLY
363 * Create a ThebesLayer for this manager's layer tree, with a creation hint
364 * parameter to help optimise the type of layer created.
365 */
366 virtual already_AddRefed<ThebesLayer> CreateThebesLayerWithHint(ThebesLayerCreationHint) {
367 return CreateThebesLayer();
368 }
369 /**
370 * CONSTRUCTION PHASE ONLY
371 * Create a ContainerLayer for this manager's layer tree.
372 */
373 virtual already_AddRefed<ContainerLayer> CreateContainerLayer() = 0;
374 /**
375 * CONSTRUCTION PHASE ONLY
376 * Create an ImageLayer for this manager's layer tree.
377 */
378 virtual already_AddRefed<ImageLayer> CreateImageLayer() = 0;
379 /**
380 * CONSTRUCTION PHASE ONLY
381 * Create a ColorLayer for this manager's layer tree.
382 */
383 virtual already_AddRefed<ColorLayer> CreateColorLayer() = 0;
384 /**
385 * CONSTRUCTION PHASE ONLY
386 * Create a CanvasLayer for this manager's layer tree.
387 */
388 virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() = 0;
389 /**
390 * CONSTRUCTION PHASE ONLY
391 * Create a ReadbackLayer for this manager's layer tree.
392 */
393 virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer() { return nullptr; }
394 /**
395 * CONSTRUCTION PHASE ONLY
396 * Create a RefLayer for this manager's layer tree.
397 */
398 virtual already_AddRefed<RefLayer> CreateRefLayer() { return nullptr; }
399
400
401 /**
402 * Can be called anytime, from any thread.
403 *
404 * Creates an Image container which forwards its images to the compositor within
405 * layer transactions on the main thread.
406 */
407 static already_AddRefed<ImageContainer> CreateImageContainer();
408
409 /**
410 * Can be called anytime, from any thread.
411 *
412 * Tries to create an Image container which forwards its images to the compositor
413 * asynchronously using the ImageBridge IPDL protocol. If the protocol is not
414 * available, the returned ImageContainer will forward images within layer
415 * transactions, just like if it was created with CreateImageContainer().
416 */
417 static already_AddRefed<ImageContainer> CreateAsynchronousImageContainer();
418
419 /**
420 * Type of layer manager his is. This is to be used sparsely in order to
421 * avoid a lot of Layers backend specific code. It should be used only when
422 * Layers backend specific functionality is necessary.
423 */
424 virtual LayersBackend GetBackendType() = 0;
425
426 /**
427 * Type of layers backend that will be used to composite this layer tree.
428 * When compositing is done remotely, then this returns the layers type
429 * of the compositor.
430 */
431 virtual LayersBackend GetCompositorBackendType() { return GetBackendType(); }
432
433 /**
434 * Creates a DrawTarget which is optimized for inter-operating with this
435 * layer manager.
436 */
437 virtual TemporaryRef<DrawTarget>
438 CreateOptimalDrawTarget(const IntSize &aSize,
439 SurfaceFormat imageFormat);
440
441 /**
442 * Creates a DrawTarget for alpha masks which is optimized for inter-
443 * operating with this layer manager. In contrast to CreateOptimalDrawTarget,
444 * this surface is optimised for drawing alpha only and we assume that
445 * drawing the mask is fairly simple.
446 */
447 virtual TemporaryRef<DrawTarget>
448 CreateOptimalMaskDrawTarget(const IntSize &aSize);
449
450 /**
451 * Creates a DrawTarget for use with canvas which is optimized for
452 * inter-operating with this layermanager.
453 */
454 virtual TemporaryRef<mozilla::gfx::DrawTarget>
455 CreateDrawTarget(const mozilla::gfx::IntSize &aSize,
456 mozilla::gfx::SurfaceFormat aFormat);
457
458 virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) { return true; }
459
460 /**
461 * returns the maximum texture size on this layer backend, or INT32_MAX
462 * if there is no maximum
463 */
464 virtual int32_t GetMaxTextureSize() const = 0;
465
466 /**
467 * Return the name of the layer manager's backend.
468 */
469 virtual void GetBackendName(nsAString& aName) = 0;
470
471 /**
472 * This setter can be used anytime. The user data for all keys is
473 * initially null. Ownership pases to the layer manager.
474 */
475 void SetUserData(void* aKey, LayerUserData* aData)
476 {
477 mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerManagerUserDataDestroy);
478 }
479 /**
480 * This can be used anytime. Ownership passes to the caller!
481 */
482 nsAutoPtr<LayerUserData> RemoveUserData(void* aKey)
483 {
484 nsAutoPtr<LayerUserData> d(static_cast<LayerUserData*>(mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey))));
485 return d;
486 }
487 /**
488 * This getter can be used anytime.
489 */
490 bool HasUserData(void* aKey)
491 {
492 return mUserData.Has(static_cast<gfx::UserDataKey*>(aKey));
493 }
494 /**
495 * This getter can be used anytime. Ownership is retained by the layer
496 * manager.
497 */
498 LayerUserData* GetUserData(void* aKey) const
499 {
500 return static_cast<LayerUserData*>(mUserData.Get(static_cast<gfx::UserDataKey*>(aKey)));
501 }
502
503 /**
504 * Must be called outside of a layers transaction.
505 *
506 * For the subtree rooted at |aSubtree|, this attempts to free up
507 * any free-able resources like retained buffers, but may do nothing
508 * at all. After this call, the layer tree is left in an undefined
509 * state; the layers in |aSubtree|'s subtree may no longer have
510 * buffers with valid content and may no longer be able to draw
511 * their visible and valid regions.
512 *
513 * In general, a painting or forwarding transaction on |this| must
514 * complete on the tree before it returns to a valid state.
515 *
516 * Resource freeing begins from |aSubtree| or |mRoot| if |aSubtree|
517 * is null. |aSubtree|'s manager must be this.
518 */
519 virtual void ClearCachedResources(Layer* aSubtree = nullptr) {}
520
521 /**
522 * Flag the next paint as the first for a document.
523 */
524 virtual void SetIsFirstPaint() {}
525
526 /**
527 * Make sure that the previous transaction has been entirely
528 * completed.
529 *
530 * Note: This may sychronously wait on a remote compositor
531 * to complete rendering.
532 */
533 virtual void FlushRendering() { }
534
535 /**
536 * Checks if we need to invalidate the OS widget to trigger
537 * painting when updating this layer manager.
538 */
539 virtual bool NeedsWidgetInvalidation() { return true; }
540
541 virtual const char* Name() const { return "???"; }
542
543 /**
544 * Dump information about this layer manager and its managed tree to
545 * aFile, which defaults to stderr.
546 */
547 void Dump(FILE* aFile=nullptr, const char* aPrefix="", bool aDumpHtml=false);
548 /**
549 * Dump information about just this layer manager itself to aFile,
550 * which defaults to stderr.
551 */
552 void DumpSelf(FILE* aFile=nullptr, const char* aPrefix="");
553
554 /**
555 * Log information about this layer manager and its managed tree to
556 * the NSPR log (if enabled for "Layers").
557 */
558 void Log(const char* aPrefix="");
559 /**
560 * Log information about just this layer manager itself to the NSPR
561 * log (if enabled for "Layers").
562 */
563 void LogSelf(const char* aPrefix="");
564
565 /**
566 * Record (and return) frame-intervals and paint-times for frames which were presented
567 * between calling StartFrameTimeRecording and StopFrameTimeRecording.
568 *
569 * - Uses a cyclic buffer and serves concurrent consumers, so if Stop is called too late
570 * (elements were overwritten since Start), result is considered invalid and hence empty.
571 * - Buffer is capable of holding 10 seconds @ 60fps (or more if frames were less frequent).
572 * Can be changed (up to 1 hour) via pref: toolkit.framesRecording.bufferSize.
573 * - Note: the first frame-interval may be longer than expected because last frame
574 * might have been presented some time before calling StartFrameTimeRecording.
575 */
576
577 /**
578 * Returns a handle which represents current recording start position.
579 */
580 virtual uint32_t StartFrameTimeRecording(int32_t aBufferSize);
581
582 /**
583 * Clears, then populates aFrameIntervals with the recorded frame timing
584 * data. The array will be empty if data was overwritten since
585 * aStartIndex was obtained.
586 */
587 virtual void StopFrameTimeRecording(uint32_t aStartIndex,
588 nsTArray<float>& aFrameIntervals);
589
590 void RecordFrame();
591 void PostPresent();
592
593 void BeginTabSwitch();
594
595 static bool IsLogEnabled();
596 static PRLogModuleInfo* GetLog() { return sLog; }
597
598 bool IsCompositingCheap(LayersBackend aBackend)
599 {
600 // LayersBackend::LAYERS_NONE is an error state, but in that case we should try to
601 // avoid loading the compositor!
602 return LayersBackend::LAYERS_BASIC != aBackend && LayersBackend::LAYERS_NONE != aBackend;
603 }
604
605 virtual bool IsCompositingCheap() { return true; }
606
607 bool IsInTransaction() const { return mInTransaction; }
608
609 virtual void SetRegionToClear(const nsIntRegion& aRegion)
610 {
611 mRegionToClear = aRegion;
612 }
613
614 protected:
615 nsRefPtr<Layer> mRoot;
616 gfx::UserData mUserData;
617 bool mDestroyed;
618 bool mSnapEffectiveTransforms;
619
620 nsIntRegion mRegionToClear;
621
622 // Protected destructor, to discourage deletion outside of Release():
623 virtual ~LayerManager() {}
624
625 // Print interesting information about this into aTo. Internally
626 // used to implement Dump*() and Log*().
627 virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
628
629 static void InitLog();
630 static PRLogModuleInfo* sLog;
631 uint64_t mId;
632 bool mInTransaction;
633 private:
634 struct FramesTimingRecording
635 {
636 // Stores state and data for frame intervals and paint times recording.
637 // see LayerManager::StartFrameTimeRecording() at Layers.cpp for more details.
638 FramesTimingRecording()
639 : mIsPaused(true)
640 , mNextIndex(0)
641 {}
642 bool mIsPaused;
643 uint32_t mNextIndex;
644 TimeStamp mLastFrameTime;
645 nsTArray<float> mIntervals;
646 uint32_t mLatestStartIndex;
647 uint32_t mCurrentRunStartIndex;
648 };
649 FramesTimingRecording mRecording;
650
651 TimeStamp mTabSwitchStart;
652 };
653
654 typedef InfallibleTArray<Animation> AnimationArray;
655
656 struct AnimData {
657 InfallibleTArray<nsStyleAnimation::Value> mStartValues;
658 InfallibleTArray<nsStyleAnimation::Value> mEndValues;
659 InfallibleTArray<nsAutoPtr<mozilla::css::ComputedTimingFunction> > mFunctions;
660 };
661
662 /**
663 * A Layer represents anything that can be rendered onto a destination
664 * surface.
665 */
666 class Layer {
667 NS_INLINE_DECL_REFCOUNTING(Layer)
668
669 public:
670 // Keep these in alphabetical order
671 enum LayerType {
672 TYPE_CANVAS,
673 TYPE_COLOR,
674 TYPE_CONTAINER,
675 TYPE_IMAGE,
676 TYPE_READBACK,
677 TYPE_REF,
678 TYPE_SHADOW,
679 TYPE_THEBES
680 };
681
682 /**
683 * Returns the LayerManager this Layer belongs to. Note that the layer
684 * manager might be in a destroyed state, at which point it's only
685 * valid to set/get user data from it.
686 */
687 LayerManager* Manager() { return mManager; }
688
689 enum {
690 /**
691 * If this is set, the caller is promising that by the end of this
692 * transaction the entire visible region (as specified by
693 * SetVisibleRegion) will be filled with opaque content.
694 */
695 CONTENT_OPAQUE = 0x01,
696 /**
697 * If this is set, the caller is notifying that the contents of this layer
698 * require per-component alpha for optimal fidelity. However, there is no
699 * guarantee that component alpha will be supported for this layer at
700 * paint time.
701 * This should never be set at the same time as CONTENT_OPAQUE.
702 */
703 CONTENT_COMPONENT_ALPHA = 0x02,
704
705 /**
706 * If this is set then this layer is part of a preserve-3d group, and should
707 * be sorted with sibling layers that are also part of the same group.
708 */
709 CONTENT_PRESERVE_3D = 0x04,
710 /**
711 * This indicates that the transform may be changed on during an empty
712 * transaction where there is no possibility of redrawing the content, so the
713 * implementation should be ready for that.
714 */
715 CONTENT_MAY_CHANGE_TRANSFORM = 0x08,
716
717 /**
718 * Disable subpixel AA for this layer. This is used if the display isn't suited
719 * for subpixel AA like hidpi or rotated content.
720 */
721 CONTENT_DISABLE_SUBPIXEL_AA = 0x10
722 };
723 /**
724 * CONSTRUCTION PHASE ONLY
725 * This lets layout make some promises about what will be drawn into the
726 * visible region of the ThebesLayer. This enables internal quality
727 * and performance optimizations.
728 */
729 void SetContentFlags(uint32_t aFlags)
730 {
731 NS_ASSERTION((aFlags & (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA)) !=
732 (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA),
733 "Can't be opaque and require component alpha");
734 if (mContentFlags != aFlags) {
735 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ContentFlags", this));
736 mContentFlags = aFlags;
737 Mutated();
738 }
739 }
740 /**
741 * CONSTRUCTION PHASE ONLY
742 * Tell this layer which region will be visible. The visible region
743 * is a region which contains all the contents of the layer that can
744 * actually affect the rendering of the window. It can exclude areas
745 * that are covered by opaque contents of other layers, and it can
746 * exclude areas where this layer simply contains no content at all.
747 * (This can be an overapproximation to the "true" visible region.)
748 *
749 * There is no general guarantee that drawing outside the bounds of the
750 * visible region will be ignored. So if a layer draws outside the bounds
751 * of its visible region, it needs to ensure that what it draws is valid.
752 */
753 virtual void SetVisibleRegion(const nsIntRegion& aRegion)
754 {
755 if (!mVisibleRegion.IsEqual(aRegion)) {
756 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) VisibleRegion was %s is %s", this,
757 mVisibleRegion.ToString().get(), aRegion.ToString().get()));
758 mVisibleRegion = aRegion;
759 Mutated();
760 }
761 }
762
763 /*
764 * Compositor event handling
765 * =========================
766 * When a touch-start event (or similar) is sent to the AsyncPanZoomController,
767 * it needs to decide whether the event should be sent to the main thread.
768 * Each layer has a list of event handling regions. When the compositor needs
769 * to determine how to handle a touch event, it scans the layer tree from top
770 * to bottom in z-order (traversing children before their parents). Points
771 * outside the clip region for a layer cause that layer (and its subtree)
772 * to be ignored. If a layer has a mask layer, and that mask layer's alpha
773 * value is zero at the event point, then the layer and its subtree should
774 * be ignored.
775 * For each layer, if the point is outside its hit region, we ignore the layer
776 * and move onto the next. If the point is inside its hit region but
777 * outside the dispatch-to-content region, we can initiate a gesture without
778 * consulting the content thread. Otherwise we must dispatch the event to
779 * content.
780 */
781 /**
782 * CONSTRUCTION PHASE ONLY
783 * Set the event handling region.
784 */
785 void SetEventRegions(const EventRegions& aRegions)
786 {
787 if (mEventRegions != aRegions) {
788 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) eventregions were %s, now %s", this,
789 mEventRegions.ToString().get(), aRegions.ToString().get()));
790 mEventRegions = aRegions;
791 Mutated();
792 }
793 }
794
795 /**
796 * CONSTRUCTION PHASE ONLY
797 * Set the opacity which will be applied to this layer as it
798 * is composited to the destination.
799 */
800 void SetOpacity(float aOpacity)
801 {
802 if (mOpacity != aOpacity) {
803 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Opacity", this));
804 mOpacity = aOpacity;
805 Mutated();
806 }
807 }
808
809 void SetMixBlendMode(gfx::CompositionOp aMixBlendMode)
810 {
811 if (mMixBlendMode != aMixBlendMode) {
812 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) MixBlendMode", this));
813 mMixBlendMode = aMixBlendMode;
814 Mutated();
815 }
816 }
817
818 void DeprecatedSetMixBlendMode(gfxContext::GraphicsOperator aMixBlendMode)
819 {
820 SetMixBlendMode(gfx::CompositionOpForOp(aMixBlendMode));
821 }
822
823 void SetForceIsolatedGroup(bool aForceIsolatedGroup)
824 {
825 if(mForceIsolatedGroup != aForceIsolatedGroup) {
826 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ForceIsolatedGroup", this));
827 mForceIsolatedGroup = aForceIsolatedGroup;
828 Mutated();
829 }
830 }
831
832 bool GetForceIsolatedGroup() const
833 {
834 return mForceIsolatedGroup;
835 }
836
837 /**
838 * CONSTRUCTION PHASE ONLY
839 * Set a clip rect which will be applied to this layer as it is
840 * composited to the destination. The coordinates are relative to
841 * the parent layer (i.e. the contents of this layer
842 * are transformed before this clip rect is applied).
843 * For the root layer, the coordinates are relative to the widget,
844 * in device pixels.
845 * If aRect is null no clipping will be performed.
846 */
847 void SetClipRect(const nsIntRect* aRect)
848 {
849 if (mUseClipRect) {
850 if (!aRect) {
851 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ClipRect was %d,%d,%d,%d is <none>", this,
852 mClipRect.x, mClipRect.y, mClipRect.width, mClipRect.height));
853 mUseClipRect = false;
854 Mutated();
855 } else {
856 if (!aRect->IsEqualEdges(mClipRect)) {
857 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ClipRect was %d,%d,%d,%d is %d,%d,%d,%d", this,
858 mClipRect.x, mClipRect.y, mClipRect.width, mClipRect.height,
859 aRect->x, aRect->y, aRect->width, aRect->height));
860 mClipRect = *aRect;
861 Mutated();
862 }
863 }
864 } else {
865 if (aRect) {
866 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ClipRect was <none> is %d,%d,%d,%d", this,
867 aRect->x, aRect->y, aRect->width, aRect->height));
868 mUseClipRect = true;
869 mClipRect = *aRect;
870 Mutated();
871 }
872 }
873 }
874
875 /**
876 * CONSTRUCTION PHASE ONLY
877 * Set a layer to mask this layer.
878 *
879 * The mask layer should be applied using its effective transform (after it
880 * is calculated by ComputeEffectiveTransformForMaskLayer), this should use
881 * this layer's parent's transform and the mask layer's transform, but not
882 * this layer's. That is, the mask layer is specified relative to this layer's
883 * position in it's parent layer's coord space.
884 * Currently, only 2D translations are supported for the mask layer transform.
885 *
886 * Ownership of aMaskLayer passes to this.
887 * Typical use would be an ImageLayer with an alpha image used for masking.
888 * See also ContainerState::BuildMaskLayer in FrameLayerBuilder.cpp.
889 */
890 void SetMaskLayer(Layer* aMaskLayer)
891 {
892 #ifdef DEBUG
893 if (aMaskLayer) {
894 bool maskIs2D = aMaskLayer->GetTransform().CanDraw2D();
895 NS_ASSERTION(maskIs2D, "Mask layer has invalid transform.");
896 }
897 #endif
898
899 if (mMaskLayer != aMaskLayer) {
900 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) MaskLayer", this));
901 mMaskLayer = aMaskLayer;
902 Mutated();
903 }
904 }
905
906 /**
907 * CONSTRUCTION PHASE ONLY
908 * Tell this layer what its transform should be. The transformation
909 * is applied when compositing the layer into its parent container.
910 */
911 void SetBaseTransform(const gfx::Matrix4x4& aMatrix)
912 {
913 NS_ASSERTION(!aMatrix.IsSingular(),
914 "Shouldn't be trying to draw with a singular matrix!");
915 mPendingTransform = nullptr;
916 if (mTransform == aMatrix) {
917 return;
918 }
919 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) BaseTransform", this));
920 mTransform = aMatrix;
921 Mutated();
922 }
923
924 /**
925 * Can be called at any time.
926 *
927 * Like SetBaseTransform(), but can be called before the next
928 * transform (i.e. outside an open transaction). Semantically, this
929 * method enqueues a new transform value to be set immediately after
930 * the next transaction is opened.
931 */
932 void SetBaseTransformForNextTransaction(const gfx::Matrix4x4& aMatrix)
933 {
934 mPendingTransform = new gfx::Matrix4x4(aMatrix);
935 }
936
937 void SetPostScale(float aXScale, float aYScale)
938 {
939 if (mPostXScale == aXScale && mPostYScale == aYScale) {
940 return;
941 }
942 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PostScale", this));
943 mPostXScale = aXScale;
944 mPostYScale = aYScale;
945 Mutated();
946 }
947
948 /**
949 * CONSTRUCTION PHASE ONLY
950 * A layer is "fixed position" when it draws content from a content
951 * (not chrome) document, the topmost content document has a root scrollframe
952 * with a displayport, but the layer does not move when that displayport scrolls.
953 */
954 void SetIsFixedPosition(bool aFixedPosition)
955 {
956 if (mIsFixedPosition != aFixedPosition) {
957 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) IsFixedPosition", this));
958 mIsFixedPosition = aFixedPosition;
959 Mutated();
960 }
961 }
962
963 // Call AddAnimation to add a new animation to this layer from layout code.
964 // Caller must fill in all the properties of the returned animation.
965 Animation* AddAnimation();
966 // ClearAnimations clears animations on this layer.
967 void ClearAnimations();
968 // This is only called when the layer tree is updated. Do not call this from
969 // layout code. To add an animation to this layer, use AddAnimation.
970 void SetAnimations(const AnimationArray& aAnimations);
971
972 // These are a parallel to AddAnimation and clearAnimations, except
973 // they add pending animations that apply only when the next
974 // transaction is begun. (See also
975 // SetBaseTransformForNextTransaction.)
976 Animation* AddAnimationForNextTransaction();
977 void ClearAnimationsForNextTransaction();
978
979 /**
980 * CONSTRUCTION PHASE ONLY
981 * If a layer is "fixed position", this determines which point on the layer
982 * is considered the "anchor" point, that is, the point which remains in the
983 * same position when compositing the layer tree with a transformation
984 * (such as when asynchronously scrolling and zooming).
985 */
986 void SetFixedPositionAnchor(const LayerPoint& aAnchor)
987 {
988 if (mAnchor != aAnchor) {
989 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FixedPositionAnchor", this));
990 mAnchor = aAnchor;
991 Mutated();
992 }
993 }
994
995 /**
996 * CONSTRUCTION PHASE ONLY
997 * If a layer represents a fixed position element or elements that are on
998 * a document that has had fixed position element margins set on it, these
999 * will be mirrored here. This allows for asynchronous animation of the
1000 * margins by reconciling the difference between this value and a value that
1001 * is updated more frequently.
1002 * If the left or top margins are negative, it means that the elements this
1003 * layer represents are auto-positioned, and so fixed position margins should
1004 * not have an effect on the corresponding axis.
1005 */
1006 void SetFixedPositionMargins(const LayerMargin& aMargins)
1007 {
1008 if (mMargins != aMargins) {
1009 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FixedPositionMargins", this));
1010 mMargins = aMargins;
1011 Mutated();
1012 }
1013 }
1014
1015 /**
1016 * CONSTRUCTION PHASE ONLY
1017 * If a layer is "sticky position", |aScrollId| holds the scroll identifier
1018 * of the scrollable content that contains it. The difference between the two
1019 * rectangles |aOuter| and |aInner| is treated as two intervals in each
1020 * dimension, with the current scroll position at the origin. For each
1021 * dimension, while that component of the scroll position lies within either
1022 * interval, the layer should not move relative to its scrolling container.
1023 */
1024 void SetStickyPositionData(FrameMetrics::ViewID aScrollId, LayerRect aOuter,
1025 LayerRect aInner)
1026 {
1027 if (!mStickyPositionData ||
1028 !mStickyPositionData->mOuter.IsEqualEdges(aOuter) ||
1029 !mStickyPositionData->mInner.IsEqualEdges(aInner)) {
1030 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) StickyPositionData", this));
1031 if (!mStickyPositionData) {
1032 mStickyPositionData = new StickyPositionData;
1033 }
1034 mStickyPositionData->mScrollId = aScrollId;
1035 mStickyPositionData->mOuter = aOuter;
1036 mStickyPositionData->mInner = aInner;
1037 Mutated();
1038 }
1039 }
1040
1041 enum ScrollDirection {
1042 NONE,
1043 VERTICAL,
1044 HORIZONTAL
1045 };
1046
1047 /**
1048 * CONSTRUCTION PHASE ONLY
1049 * If a layer is a scrollbar layer, |aScrollId| holds the scroll identifier
1050 * of the scrollable content that the scrollbar is for.
1051 */
1052 void SetScrollbarData(FrameMetrics::ViewID aScrollId, ScrollDirection aDir)
1053 {
1054 if (mScrollbarTargetId != aScrollId ||
1055 mScrollbarDirection != aDir) {
1056 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrollbarData", this));
1057 mScrollbarTargetId = aScrollId;
1058 mScrollbarDirection = aDir;
1059 Mutated();
1060 }
1061 }
1062
1063 // These getters can be used anytime.
1064 float GetOpacity() { return mOpacity; }
1065 gfx::CompositionOp GetMixBlendMode() const { return mMixBlendMode; }
1066 const nsIntRect* GetClipRect() { return mUseClipRect ? &mClipRect : nullptr; }
1067 uint32_t GetContentFlags() { return mContentFlags; }
1068 const nsIntRegion& GetVisibleRegion() { return mVisibleRegion; }
1069 const EventRegions& GetEventRegions() const { return mEventRegions; }
1070 ContainerLayer* GetParent() { return mParent; }
1071 Layer* GetNextSibling() { return mNextSibling; }
1072 const Layer* GetNextSibling() const { return mNextSibling; }
1073 Layer* GetPrevSibling() { return mPrevSibling; }
1074 const Layer* GetPrevSibling() const { return mPrevSibling; }
1075 virtual Layer* GetFirstChild() const { return nullptr; }
1076 virtual Layer* GetLastChild() const { return nullptr; }
1077 const gfx::Matrix4x4 GetTransform() const;
1078 const gfx::Matrix4x4& GetBaseTransform() const { return mTransform; }
1079 float GetPostXScale() const { return mPostXScale; }
1080 float GetPostYScale() const { return mPostYScale; }
1081 bool GetIsFixedPosition() { return mIsFixedPosition; }
1082 bool GetIsStickyPosition() { return mStickyPositionData; }
1083 LayerPoint GetFixedPositionAnchor() { return mAnchor; }
1084 const LayerMargin& GetFixedPositionMargins() { return mMargins; }
1085 FrameMetrics::ViewID GetStickyScrollContainerId() { return mStickyPositionData->mScrollId; }
1086 const LayerRect& GetStickyScrollRangeOuter() { return mStickyPositionData->mOuter; }
1087 const LayerRect& GetStickyScrollRangeInner() { return mStickyPositionData->mInner; }
1088 FrameMetrics::ViewID GetScrollbarTargetContainerId() { return mScrollbarTargetId; }
1089 ScrollDirection GetScrollbarDirection() { return mScrollbarDirection; }
1090 Layer* GetMaskLayer() const { return mMaskLayer; }
1091
1092 // Note that all lengths in animation data are either in CSS pixels or app
1093 // units and must be converted to device pixels by the compositor.
1094 AnimationArray& GetAnimations() { return mAnimations; }
1095 InfallibleTArray<AnimData>& GetAnimationData() { return mAnimationData; }
1096
1097 uint64_t GetAnimationGeneration() { return mAnimationGeneration; }
1098 void SetAnimationGeneration(uint64_t aCount) { mAnimationGeneration = aCount; }
1099
1100 /**
1101 * Returns the local transform for this layer: either mTransform or,
1102 * for shadow layers, GetShadowTransform()
1103 */
1104 const gfx::Matrix4x4 GetLocalTransform();
1105
1106 /**
1107 * Returns the local opacity for this layer: either mOpacity or,
1108 * for shadow layers, GetShadowOpacity()
1109 */
1110 const float GetLocalOpacity();
1111
1112 /**
1113 * DRAWING PHASE ONLY
1114 *
1115 * Apply pending changes to layers before drawing them, if those
1116 * pending changes haven't been overridden by later changes.
1117 */
1118 void ApplyPendingUpdatesToSubtree();
1119
1120 /**
1121 * DRAWING PHASE ONLY
1122 *
1123 * Write layer-subtype-specific attributes into aAttrs. Used to
1124 * synchronize layer attributes to their shadows'.
1125 */
1126 virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) { }
1127
1128 // Returns true if it's OK to save the contents of aLayer in an
1129 // opaque surface (a surface without an alpha channel).
1130 // If we can use a surface without an alpha channel, we should, because
1131 // it will often make painting of antialiased text faster and higher
1132 // quality.
1133 bool CanUseOpaqueSurface();
1134
1135 SurfaceMode GetSurfaceMode()
1136 {
1137 if (CanUseOpaqueSurface())
1138 return SurfaceMode::SURFACE_OPAQUE;
1139 if (mContentFlags & CONTENT_COMPONENT_ALPHA)
1140 return SurfaceMode::SURFACE_COMPONENT_ALPHA;
1141 return SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
1142 }
1143
1144 /**
1145 * This setter can be used anytime. The user data for all keys is
1146 * initially null. Ownership pases to the layer manager.
1147 */
1148 void SetUserData(void* aKey, LayerUserData* aData)
1149 {
1150 mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerManagerUserDataDestroy);
1151 }
1152 /**
1153 * This can be used anytime. Ownership passes to the caller!
1154 */
1155 nsAutoPtr<LayerUserData> RemoveUserData(void* aKey)
1156 {
1157 nsAutoPtr<LayerUserData> d(static_cast<LayerUserData*>(mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey))));
1158 return d;
1159 }
1160 /**
1161 * This getter can be used anytime.
1162 */
1163 bool HasUserData(void* aKey)
1164 {
1165 return mUserData.Has(static_cast<gfx::UserDataKey*>(aKey));
1166 }
1167 /**
1168 * This getter can be used anytime. Ownership is retained by the layer
1169 * manager.
1170 */
1171 LayerUserData* GetUserData(void* aKey) const
1172 {
1173 return static_cast<LayerUserData*>(mUserData.Get(static_cast<gfx::UserDataKey*>(aKey)));
1174 }
1175
1176 /**
1177 * |Disconnect()| is used by layers hooked up over IPC. It may be
1178 * called at any time, and may not be called at all. Using an
1179 * IPC-enabled layer after Destroy() (drawing etc.) results in a
1180 * safe no-op; no crashy or uaf etc.
1181 *
1182 * XXX: this interface is essentially LayerManager::Destroy, but at
1183 * Layer granularity. It might be beneficial to unify them.
1184 */
1185 virtual void Disconnect() {}
1186
1187 /**
1188 * Dynamic downcast to a Thebes layer. Returns null if this is not
1189 * a ThebesLayer.
1190 */
1191 virtual ThebesLayer* AsThebesLayer() { return nullptr; }
1192
1193 /**
1194 * Dynamic cast to a ContainerLayer. Returns null if this is not
1195 * a ContainerLayer.
1196 */
1197 virtual ContainerLayer* AsContainerLayer() { return nullptr; }
1198 virtual const ContainerLayer* AsContainerLayer() const { return nullptr; }
1199
1200 /**
1201 * Dynamic cast to a RefLayer. Returns null if this is not a
1202 * RefLayer.
1203 */
1204 virtual RefLayer* AsRefLayer() { return nullptr; }
1205
1206 /**
1207 * Dynamic cast to a Color. Returns null if this is not a
1208 * ColorLayer.
1209 */
1210 virtual ColorLayer* AsColorLayer() { return nullptr; }
1211
1212 /**
1213 * Dynamic cast to a LayerComposite. Return null if this is not a
1214 * LayerComposite. Can be used anytime.
1215 */
1216 virtual LayerComposite* AsLayerComposite() { return nullptr; }
1217
1218 /**
1219 * Dynamic cast to a ShadowableLayer. Return null if this is not a
1220 * ShadowableLayer. Can be used anytime.
1221 */
1222 virtual ShadowableLayer* AsShadowableLayer() { return nullptr; }
1223
1224 // These getters can be used anytime. They return the effective
1225 // values that should be used when drawing this layer to screen,
1226 // accounting for this layer possibly being a shadow.
1227 const nsIntRect* GetEffectiveClipRect();
1228 const nsIntRegion& GetEffectiveVisibleRegion();
1229
1230 /**
1231 * Returns the product of the opacities of this layer and all ancestors up
1232 * to and excluding the nearest ancestor that has UseIntermediateSurface() set.
1233 */
1234 float GetEffectiveOpacity();
1235
1236 /**
1237 * Returns the blendmode of this layer.
1238 */
1239 gfx::CompositionOp GetEffectiveMixBlendMode();
1240 gfxContext::GraphicsOperator DeprecatedGetEffectiveMixBlendMode();
1241
1242 /**
1243 * This returns the effective transform computed by
1244 * ComputeEffectiveTransforms. Typically this is a transform that transforms
1245 * this layer all the way to some intermediate surface or destination
1246 * surface. For non-BasicLayers this will be a transform to the nearest
1247 * ancestor with UseIntermediateSurface() (or to the root, if there is no
1248 * such ancestor), but for BasicLayers it's different.
1249 */
1250 const gfx::Matrix4x4& GetEffectiveTransform() const { return mEffectiveTransform; }
1251
1252 /**
1253 * @param aTransformToSurface the composition of the transforms
1254 * from the parent layer (if any) to the destination pixel grid.
1255 *
1256 * Computes mEffectiveTransform for this layer and all its descendants.
1257 * mEffectiveTransform transforms this layer up to the destination
1258 * pixel grid (whatever aTransformToSurface is relative to).
1259 *
1260 * We promise that when this is called on a layer, all ancestor layers
1261 * have already had ComputeEffectiveTransforms called.
1262 */
1263 virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) = 0;
1264
1265 /**
1266 * computes the effective transform for a mask layer, if this layer has one
1267 */
1268 void ComputeEffectiveTransformForMaskLayer(const gfx::Matrix4x4& aTransformToSurface);
1269
1270 /**
1271 * Calculate the scissor rect required when rendering this layer.
1272 * Returns a rectangle relative to the intermediate surface belonging to the
1273 * nearest ancestor that has an intermediate surface, or relative to the root
1274 * viewport if no ancestor has an intermediate surface, corresponding to the
1275 * clip rect for this layer intersected with aCurrentScissorRect.
1276 * If no ancestor has an intermediate surface, the clip rect is transformed
1277 * by aWorldTransform before being combined with aCurrentScissorRect, if
1278 * aWorldTransform is non-null.
1279 */
1280 nsIntRect CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
1281 const gfx::Matrix* aWorldTransform);
1282
1283 virtual const char* Name() const =0;
1284 virtual LayerType GetType() const =0;
1285
1286 /**
1287 * Only the implementation should call this. This is per-implementation
1288 * private data. Normally, all layers with a given layer manager
1289 * use the same type of ImplData.
1290 */
1291 void* ImplData() { return mImplData; }
1292
1293 /**
1294 * Only the implementation should use these methods.
1295 */
1296 void SetParent(ContainerLayer* aParent) { mParent = aParent; }
1297 void SetNextSibling(Layer* aSibling) { mNextSibling = aSibling; }
1298 void SetPrevSibling(Layer* aSibling) { mPrevSibling = aSibling; }
1299
1300 /**
1301 * Dump information about this layer manager and its managed tree to
1302 * aFile, which defaults to stderr.
1303 */
1304 void Dump(FILE* aFile=nullptr, const char* aPrefix="", bool aDumpHtml=false);
1305 /**
1306 * Dump information about just this layer manager itself to aFile,
1307 * which defaults to stderr.
1308 */
1309 void DumpSelf(FILE* aFile=nullptr, const char* aPrefix="");
1310
1311 /**
1312 * Log information about this layer manager and its managed tree to
1313 * the NSPR log (if enabled for "Layers").
1314 */
1315 void Log(const char* aPrefix="");
1316 /**
1317 * Log information about just this layer manager itself to the NSPR
1318 * log (if enabled for "Layers").
1319 */
1320 void LogSelf(const char* aPrefix="");
1321
1322 // Print interesting information about this into aTo. Internally
1323 // used to implement Dump*() and Log*(). If subclasses have
1324 // additional interesting properties, they should override this with
1325 // an implementation that first calls the base implementation then
1326 // appends additional info to aTo.
1327 virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
1328
1329 static bool IsLogEnabled() { return LayerManager::IsLogEnabled(); }
1330
1331 /**
1332 * Returns the current area of the layer (in layer-space coordinates)
1333 * marked as needed to be recomposited.
1334 */
1335 const nsIntRegion& GetInvalidRegion() { return mInvalidRegion; }
1336 const void SetInvalidRegion(const nsIntRegion& aRect) { mInvalidRegion = aRect; }
1337
1338 /**
1339 * Mark the entirety of the layer's visible region as being invalid.
1340 */
1341 void SetInvalidRectToVisibleRegion() { mInvalidRegion = GetVisibleRegion(); }
1342
1343 /**
1344 * Adds to the current invalid rect.
1345 */
1346 void AddInvalidRect(const nsIntRect& aRect) { mInvalidRegion.Or(mInvalidRegion, aRect); }
1347
1348 /**
1349 * Clear the invalid rect, marking the layer as being identical to what is currently
1350 * composited.
1351 */
1352 void ClearInvalidRect() { mInvalidRegion.SetEmpty(); }
1353
1354 void ApplyPendingUpdatesForThisTransaction();
1355
1356 #ifdef DEBUG
1357 void SetDebugColorIndex(uint32_t aIndex) { mDebugColorIndex = aIndex; }
1358 uint32_t GetDebugColorIndex() { return mDebugColorIndex; }
1359 #endif
1360
1361 virtual LayerRenderState GetRenderState() { return LayerRenderState(); }
1362
1363
1364 void Mutated()
1365 {
1366 mManager->Mutated(this);
1367 }
1368
1369 protected:
1370 Layer(LayerManager* aManager, void* aImplData);
1371
1372 // Protected destructor, to discourage deletion outside of Release():
1373 virtual ~Layer();
1374
1375 /**
1376 * We can snap layer transforms for two reasons:
1377 * 1) To avoid unnecessary resampling when a transform is a translation
1378 * by a non-integer number of pixels.
1379 * Snapping the translation to an integer number of pixels avoids
1380 * blurring the layer and can be faster to composite.
1381 * 2) When a layer is used to render a rectangular object, we need to
1382 * emulate the rendering of rectangular inactive content and snap the
1383 * edges of the rectangle to pixel boundaries. This is both to ensure
1384 * layer rendering is consistent with inactive content rendering, and to
1385 * avoid seams.
1386 * This function implements type 1 snapping. If aTransform is a 2D
1387 * translation, and this layer's layer manager has enabled snapping
1388 * (which is the default), return aTransform with the translation snapped
1389 * to nearest pixels. Otherwise just return aTransform. Call this when the
1390 * layer does not correspond to a single rectangular content object.
1391 * This function does not try to snap if aTransform has a scale, because in
1392 * that case resampling is inevitable and there's no point in trying to
1393 * avoid it. In fact snapping can cause problems because pixel edges in the
1394 * layer's content can be rendered unpredictably (jiggling) as the scale
1395 * interacts with the snapping of the translation, especially with animated
1396 * transforms.
1397 * @param aResidualTransform a transform to apply before the result transform
1398 * in order to get the results to completely match aTransform.
1399 */
1400 gfx::Matrix4x4 SnapTransformTranslation(const gfx::Matrix4x4& aTransform,
1401 gfx::Matrix* aResidualTransform);
1402 /**
1403 * See comment for SnapTransformTranslation.
1404 * This function implements type 2 snapping. If aTransform is a translation
1405 * and/or scale, transform aSnapRect by aTransform, snap to pixel boundaries,
1406 * and return the transform that maps aSnapRect to that rect. Otherwise
1407 * just return aTransform.
1408 * @param aSnapRect a rectangle whose edges should be snapped to pixel
1409 * boundaries in the destination surface.
1410 * @param aResidualTransform a transform to apply before the result transform
1411 * in order to get the results to completely match aTransform.
1412 */
1413 gfx::Matrix4x4 SnapTransform(const gfx::Matrix4x4& aTransform,
1414 const gfxRect& aSnapRect,
1415 gfx::Matrix* aResidualTransform);
1416
1417 /**
1418 * Returns true if this layer's effective transform is not just
1419 * a translation by integers, or if this layer or some ancestor layer
1420 * is marked as having a transform that may change without a full layer
1421 * transaction.
1422 */
1423 bool MayResample();
1424
1425 LayerManager* mManager;
1426 ContainerLayer* mParent;
1427 Layer* mNextSibling;
1428 Layer* mPrevSibling;
1429 void* mImplData;
1430 nsRefPtr<Layer> mMaskLayer;
1431 gfx::UserData mUserData;
1432 nsIntRegion mVisibleRegion;
1433 EventRegions mEventRegions;
1434 gfx::Matrix4x4 mTransform;
1435 // A mutation of |mTransform| that we've queued to be applied at the
1436 // end of the next transaction (if nothing else overrides it in the
1437 // meantime).
1438 nsAutoPtr<gfx::Matrix4x4> mPendingTransform;
1439 float mPostXScale;
1440 float mPostYScale;
1441 gfx::Matrix4x4 mEffectiveTransform;
1442 AnimationArray mAnimations;
1443 // See mPendingTransform above.
1444 nsAutoPtr<AnimationArray> mPendingAnimations;
1445 InfallibleTArray<AnimData> mAnimationData;
1446 float mOpacity;
1447 gfx::CompositionOp mMixBlendMode;
1448 bool mForceIsolatedGroup;
1449 nsIntRect mClipRect;
1450 nsIntRect mTileSourceRect;
1451 nsIntRegion mInvalidRegion;
1452 uint32_t mContentFlags;
1453 bool mUseClipRect;
1454 bool mUseTileSourceRect;
1455 bool mIsFixedPosition;
1456 LayerPoint mAnchor;
1457 LayerMargin mMargins;
1458 struct StickyPositionData {
1459 FrameMetrics::ViewID mScrollId;
1460 LayerRect mOuter;
1461 LayerRect mInner;
1462 };
1463 nsAutoPtr<StickyPositionData> mStickyPositionData;
1464 FrameMetrics::ViewID mScrollbarTargetId;
1465 ScrollDirection mScrollbarDirection;
1466 DebugOnly<uint32_t> mDebugColorIndex;
1467 // If this layer is used for OMTA, then this counter is used to ensure we
1468 // stay in sync with the animation manager
1469 uint64_t mAnimationGeneration;
1470 };
1471
1472 /**
1473 * A Layer which we can draw into using Thebes. It is a conceptually
1474 * infinite surface, but each ThebesLayer has an associated "valid region"
1475 * of contents that it is currently storing, which is finite. ThebesLayer
1476 * implementations can store content between paints.
1477 *
1478 * ThebesLayers are rendered into during the drawing phase of a transaction.
1479 *
1480 * Currently the contents of a ThebesLayer are in the device output color
1481 * space.
1482 */
1483 class ThebesLayer : public Layer {
1484 public:
1485 /**
1486 * CONSTRUCTION PHASE ONLY
1487 * Tell this layer that the content in some region has changed and
1488 * will need to be repainted. This area is removed from the valid
1489 * region.
1490 */
1491 virtual void InvalidateRegion(const nsIntRegion& aRegion) = 0;
1492 /**
1493 * CONSTRUCTION PHASE ONLY
1494 * Set whether ComputeEffectiveTransforms should compute the
1495 * "residual translation" --- the translation that should be applied *before*
1496 * mEffectiveTransform to get the ideal transform for this ThebesLayer.
1497 * When this is true, ComputeEffectiveTransforms will compute the residual
1498 * and ensure that the layer is invalidated whenever the residual changes.
1499 * When it's false, a change in the residual will not trigger invalidation
1500 * and GetResidualTranslation will return 0,0.
1501 * So when the residual is to be ignored, set this to false for better
1502 * performance.
1503 */
1504 void SetAllowResidualTranslation(bool aAllow) { mAllowResidualTranslation = aAllow; }
1505
1506 /**
1507 * Can be used anytime
1508 */
1509 const nsIntRegion& GetValidRegion() const { return mValidRegion; }
1510
1511 virtual ThebesLayer* AsThebesLayer() { return this; }
1512
1513 MOZ_LAYER_DECL_NAME("ThebesLayer", TYPE_THEBES)
1514
1515 virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface)
1516 {
1517 gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface;
1518 gfx::Matrix residual;
1519 mEffectiveTransform = SnapTransformTranslation(idealTransform,
1520 mAllowResidualTranslation ? &residual : nullptr);
1521 // The residual can only be a translation because SnapTransformTranslation
1522 // only changes the transform if it's a translation
1523 NS_ASSERTION(residual.IsTranslation(),
1524 "Residual transform can only be a translation");
1525 if (!gfx::ThebesPoint(residual.GetTranslation()).WithinEpsilonOf(mResidualTranslation, 1e-3f)) {
1526 mResidualTranslation = gfx::ThebesPoint(residual.GetTranslation());
1527 NS_ASSERTION(-0.5 <= mResidualTranslation.x && mResidualTranslation.x < 0.5 &&
1528 -0.5 <= mResidualTranslation.y && mResidualTranslation.y < 0.5,
1529 "Residual translation out of range");
1530 mValidRegion.SetEmpty();
1531 }
1532 ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
1533 }
1534
1535 bool UsedForReadback() { return mUsedForReadback; }
1536 void SetUsedForReadback(bool aUsed) { mUsedForReadback = aUsed; }
1537 /**
1538 * Returns the residual translation. Apply this translation when drawing
1539 * into the ThebesLayer so that when mEffectiveTransform is applied afterwards
1540 * by layer compositing, the results exactly match the "ideal transform"
1541 * (the product of the transform of this layer and its ancestors).
1542 * Returns 0,0 unless SetAllowResidualTranslation(true) has been called.
1543 * The residual translation components are always in the range [-0.5, 0.5).
1544 */
1545 gfxPoint GetResidualTranslation() const { return mResidualTranslation; }
1546
1547 protected:
1548 ThebesLayer(LayerManager* aManager, void* aImplData)
1549 : Layer(aManager, aImplData)
1550 , mValidRegion()
1551 , mUsedForReadback(false)
1552 , mAllowResidualTranslation(false)
1553 {
1554 mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT
1555 }
1556
1557 virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
1558
1559 /**
1560 * ComputeEffectiveTransforms snaps the ideal transform to get mEffectiveTransform.
1561 * mResidualTranslation is the translation that should be applied *before*
1562 * mEffectiveTransform to get the ideal transform.
1563 */
1564 gfxPoint mResidualTranslation;
1565 nsIntRegion mValidRegion;
1566 /**
1567 * Set when this ThebesLayer is participating in readback, i.e. some
1568 * ReadbackLayer (may) be getting its background from this layer.
1569 */
1570 bool mUsedForReadback;
1571 /**
1572 * True when
1573 */
1574 bool mAllowResidualTranslation;
1575 };
1576
1577 /**
1578 * A Layer which other layers render into. It holds references to its
1579 * children.
1580 */
1581 class ContainerLayer : public Layer {
1582 public:
1583
1584 ~ContainerLayer();
1585
1586 /**
1587 * CONSTRUCTION PHASE ONLY
1588 * Insert aChild into the child list of this container. aChild must
1589 * not be currently in any child list or the root for the layer manager.
1590 * If aAfter is non-null, it must be a child of this container and
1591 * we insert after that layer. If it's null we insert at the start.
1592 */
1593 virtual bool InsertAfter(Layer* aChild, Layer* aAfter);
1594 /**
1595 * CONSTRUCTION PHASE ONLY
1596 * Remove aChild from the child list of this container. aChild must
1597 * be a child of this container.
1598 */
1599 virtual bool RemoveChild(Layer* aChild);
1600 /**
1601 * CONSTRUCTION PHASE ONLY
1602 * Reposition aChild from the child list of this container. aChild must
1603 * be a child of this container.
1604 * If aAfter is non-null, it must be a child of this container and we
1605 * reposition after that layer. If it's null, we reposition at the start.
1606 */
1607 virtual bool RepositionChild(Layer* aChild, Layer* aAfter);
1608
1609 /**
1610 * CONSTRUCTION PHASE ONLY
1611 * Set the (sub)document metrics used to render the Layer subtree
1612 * rooted at this.
1613 */
1614 void SetFrameMetrics(const FrameMetrics& aFrameMetrics)
1615 {
1616 if (mFrameMetrics != aFrameMetrics) {
1617 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FrameMetrics", this));
1618 mFrameMetrics = aFrameMetrics;
1619 Mutated();
1620 }
1621 }
1622
1623 // These functions allow attaching an AsyncPanZoomController to this layer,
1624 // and can be used anytime.
1625 // A container layer has an APZC only-if GetFrameMetrics().IsScrollable()
1626 void SetAsyncPanZoomController(AsyncPanZoomController *controller);
1627 AsyncPanZoomController* GetAsyncPanZoomController() const;
1628
1629 /**
1630 * CONSTRUCTION PHASE ONLY
1631 * Set the ViewID of the ContainerLayer to which overscroll should be handed
1632 * off. A value of NULL_SCROLL_ID means that the default handoff-parent-finding
1633 * behaviour should be used (i.e. walk up the layer tree to find the next
1634 * scrollable ancestor layer).
1635 */
1636 void SetScrollHandoffParentId(FrameMetrics::ViewID aScrollParentId)
1637 {
1638 if (mScrollHandoffParentId != aScrollParentId) {
1639 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrollHandoffParentId", this));
1640 mScrollHandoffParentId = aScrollParentId;
1641 Mutated();
1642 }
1643 }
1644
1645 void SetPreScale(float aXScale, float aYScale)
1646 {
1647 if (mPreXScale == aXScale && mPreYScale == aYScale) {
1648 return;
1649 }
1650
1651 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PreScale", this));
1652 mPreXScale = aXScale;
1653 mPreYScale = aYScale;
1654 Mutated();
1655 }
1656
1657 void SetInheritedScale(float aXScale, float aYScale)
1658 {
1659 if (mInheritedXScale == aXScale && mInheritedYScale == aYScale) {
1660 return;
1661 }
1662
1663 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) InheritedScale", this));
1664 mInheritedXScale = aXScale;
1665 mInheritedYScale = aYScale;
1666 Mutated();
1667 }
1668
1669 virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs);
1670
1671 void SortChildrenBy3DZOrder(nsTArray<Layer*>& aArray);
1672
1673 // These getters can be used anytime.
1674
1675 virtual ContainerLayer* AsContainerLayer() { return this; }
1676 virtual const ContainerLayer* AsContainerLayer() const { return this; }
1677
1678 virtual Layer* GetFirstChild() const { return mFirstChild; }
1679 virtual Layer* GetLastChild() const { return mLastChild; }
1680 const FrameMetrics& GetFrameMetrics() const { return mFrameMetrics; }
1681 FrameMetrics::ViewID GetScrollHandoffParentId() const { return mScrollHandoffParentId; }
1682 float GetPreXScale() const { return mPreXScale; }
1683 float GetPreYScale() const { return mPreYScale; }
1684 float GetInheritedXScale() const { return mInheritedXScale; }
1685 float GetInheritedYScale() const { return mInheritedYScale; }
1686
1687 MOZ_LAYER_DECL_NAME("ContainerLayer", TYPE_CONTAINER)
1688
1689 /**
1690 * ContainerLayer backends need to override ComputeEffectiveTransforms
1691 * since the decision about whether to use a temporary surface for the
1692 * container is backend-specific. ComputeEffectiveTransforms must also set
1693 * mUseIntermediateSurface.
1694 */
1695 virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) = 0;
1696
1697 /**
1698 * Call this only after ComputeEffectiveTransforms has been invoked
1699 * on this layer.
1700 * Returns true if this will use an intermediate surface. This is largely
1701 * backend-dependent, but it affects the operation of GetEffectiveOpacity().
1702 */
1703 bool UseIntermediateSurface() { return mUseIntermediateSurface; }
1704
1705 /**
1706 * Returns the rectangle covered by the intermediate surface,
1707 * in this layer's coordinate system
1708 */
1709 nsIntRect GetIntermediateSurfaceRect()
1710 {
1711 NS_ASSERTION(mUseIntermediateSurface, "Must have intermediate surface");
1712 return mVisibleRegion.GetBounds();
1713 }
1714
1715 /**
1716 * Returns true if this container has more than one non-empty child
1717 */
1718 bool HasMultipleChildren();
1719
1720 /**
1721 * Returns true if this container supports children with component alpha.
1722 * Should only be called while painting a child of this layer.
1723 */
1724 bool SupportsComponentAlphaChildren() { return mSupportsComponentAlphaChildren; }
1725
1726 /**
1727 * Returns true if aLayer or any layer in its parent chain has the opaque
1728 * content flag set.
1729 */
1730 static bool HasOpaqueAncestorLayer(Layer* aLayer);
1731
1732 protected:
1733 friend class ReadbackProcessor;
1734
1735 void DidInsertChild(Layer* aLayer);
1736 void DidRemoveChild(Layer* aLayer);
1737
1738 ContainerLayer(LayerManager* aManager, void* aImplData);
1739
1740 /**
1741 * A default implementation of ComputeEffectiveTransforms for use by OpenGL
1742 * and D3D.
1743 */
1744 void DefaultComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface);
1745
1746 /**
1747 * Loops over the children calling ComputeEffectiveTransforms on them.
1748 */
1749 void ComputeEffectiveTransformsForChildren(const gfx::Matrix4x4& aTransformToSurface);
1750
1751 virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
1752
1753 Layer* mFirstChild;
1754 Layer* mLastChild;
1755 FrameMetrics mFrameMetrics;
1756 nsRefPtr<AsyncPanZoomController> mAPZC;
1757 FrameMetrics::ViewID mScrollHandoffParentId;
1758 float mPreXScale;
1759 float mPreYScale;
1760 // The resolution scale inherited from the parent layer. This will already
1761 // be part of mTransform.
1762 float mInheritedXScale;
1763 float mInheritedYScale;
1764 bool mUseIntermediateSurface;
1765 bool mSupportsComponentAlphaChildren;
1766 bool mMayHaveReadbackChild;
1767 };
1768
1769 /**
1770 * A Layer which just renders a solid color in its visible region. It actually
1771 * can fill any area that contains the visible region, so if you need to
1772 * restrict the area filled, set a clip region on this layer.
1773 */
1774 class ColorLayer : public Layer {
1775 public:
1776 virtual ColorLayer* AsColorLayer() { return this; }
1777
1778 /**
1779 * CONSTRUCTION PHASE ONLY
1780 * Set the color of the layer.
1781 */
1782 virtual void SetColor(const gfxRGBA& aColor)
1783 {
1784 if (mColor != aColor) {
1785 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Color", this));
1786 mColor = aColor;
1787 Mutated();
1788 }
1789 }
1790
1791 void SetBounds(const nsIntRect& aBounds)
1792 {
1793 if (!mBounds.IsEqualEdges(aBounds)) {
1794 mBounds = aBounds;
1795 Mutated();
1796 }
1797 }
1798
1799 const nsIntRect& GetBounds()
1800 {
1801 return mBounds;
1802 }
1803
1804 // This getter can be used anytime.
1805 virtual const gfxRGBA& GetColor() { return mColor; }
1806
1807 MOZ_LAYER_DECL_NAME("ColorLayer", TYPE_COLOR)
1808
1809 virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface)
1810 {
1811 gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface;
1812 mEffectiveTransform = SnapTransformTranslation(idealTransform, nullptr);
1813 ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
1814 }
1815
1816 protected:
1817 ColorLayer(LayerManager* aManager, void* aImplData)
1818 : Layer(aManager, aImplData),
1819 mColor(0.0, 0.0, 0.0, 0.0)
1820 {}
1821
1822 virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
1823
1824 nsIntRect mBounds;
1825 gfxRGBA mColor;
1826 };
1827
1828 /**
1829 * A Layer for HTML Canvas elements. It's backed by either a
1830 * gfxASurface or a GLContext (for WebGL layers), and has some control
1831 * for intelligent updating from the source if necessary (for example,
1832 * if hardware compositing is not available, for reading from the GL
1833 * buffer into an image surface that we can layer composite.)
1834 *
1835 * After Initialize is called, the underlying canvas Surface/GLContext
1836 * must not be modified during a layer transaction.
1837 */
1838 class CanvasLayer : public Layer {
1839 public:
1840 struct Data {
1841 Data()
1842 : mDrawTarget(nullptr)
1843 , mGLContext(nullptr)
1844 , mStream(nullptr)
1845 , mTexID(0)
1846 , mSize(0,0)
1847 , mIsGLAlphaPremult(false)
1848 { }
1849
1850 // One of these two must be specified for Canvas2D, but never both
1851 mozilla::gfx::DrawTarget *mDrawTarget; // a DrawTarget for the canvas contents
1852 mozilla::gl::GLContext* mGLContext; // or this, for GL.
1853
1854 // Canvas/SkiaGL uses this
1855 mozilla::gfx::SurfaceStream* mStream;
1856
1857 // ID of the texture backing the canvas layer (defaults to 0)
1858 uint32_t mTexID;
1859
1860 // The size of the canvas content
1861 nsIntSize mSize;
1862
1863 // Whether mGLContext contains data that is alpha-premultiplied.
1864 bool mIsGLAlphaPremult;
1865 };
1866
1867 /**
1868 * CONSTRUCTION PHASE ONLY
1869 * Initialize this CanvasLayer with the given data. The data must
1870 * have either mSurface or mGLContext initialized (but not both), as
1871 * well as mSize.
1872 *
1873 * This must only be called once.
1874 */
1875 virtual void Initialize(const Data& aData) = 0;
1876
1877 /**
1878 * Check the data is owned by this layer is still valid for rendering
1879 */
1880 virtual bool IsDataValid(const Data& aData) { return true; }
1881
1882 /**
1883 * Notify this CanvasLayer that the canvas surface contents have
1884 * changed (or will change) before the next transaction.
1885 */
1886 void Updated() { mDirty = true; SetInvalidRectToVisibleRegion(); }
1887
1888 /**
1889 * Notify this CanvasLayer that the canvas surface contents have
1890 * been painted since the last change.
1891 */
1892 void Painted() { mDirty = false; }
1893
1894 /**
1895 * Returns true if the canvas surface contents have changed since the
1896 * last paint.
1897 */
1898 bool IsDirty()
1899 {
1900 // We can only tell if we are dirty if we're part of the
1901 // widget's retained layer tree.
1902 if (!mManager || !mManager->IsWidgetLayerManager()) {
1903 return true;
1904 }
1905 return mDirty;
1906 }
1907
1908 /**
1909 * Register a callback to be called at the start of each transaction.
1910 */
1911 typedef void PreTransactionCallback(void* closureData);
1912 void SetPreTransactionCallback(PreTransactionCallback* callback, void* closureData)
1913 {
1914 mPreTransCallback = callback;
1915 mPreTransCallbackData = closureData;
1916 }
1917
1918 protected:
1919 void FirePreTransactionCallback()
1920 {
1921 if (mPreTransCallback) {
1922 mPreTransCallback(mPreTransCallbackData);
1923 }
1924 }
1925
1926 public:
1927 /**
1928 * Register a callback to be called at the end of each transaction.
1929 */
1930 typedef void (* DidTransactionCallback)(void* aClosureData);
1931 void SetDidTransactionCallback(DidTransactionCallback aCallback, void* aClosureData)
1932 {
1933 mPostTransCallback = aCallback;
1934 mPostTransCallbackData = aClosureData;
1935 }
1936
1937 /**
1938 * CONSTRUCTION PHASE ONLY
1939 * Set the filter used to resample this image (if necessary).
1940 */
1941 void SetFilter(GraphicsFilter aFilter)
1942 {
1943 if (mFilter != aFilter) {
1944 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Filter", this));
1945 mFilter = aFilter;
1946 Mutated();
1947 }
1948 }
1949 GraphicsFilter GetFilter() const { return mFilter; }
1950
1951 MOZ_LAYER_DECL_NAME("CanvasLayer", TYPE_CANVAS)
1952
1953 virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface)
1954 {
1955 // Snap our local transform first, and snap the inherited transform as well.
1956 // This makes our snapping equivalent to what would happen if our content
1957 // was drawn into a ThebesLayer (gfxContext would snap using the local
1958 // transform, then we'd snap again when compositing the ThebesLayer).
1959 mEffectiveTransform =
1960 SnapTransform(GetLocalTransform(), gfxRect(0, 0, mBounds.width, mBounds.height),
1961 nullptr)*
1962 SnapTransformTranslation(aTransformToSurface, nullptr);
1963 ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
1964 }
1965
1966 protected:
1967 CanvasLayer(LayerManager* aManager, void* aImplData)
1968 : Layer(aManager, aImplData)
1969 , mPreTransCallback(nullptr)
1970 , mPreTransCallbackData(nullptr)
1971 , mPostTransCallback(nullptr)
1972 , mPostTransCallbackData(nullptr)
1973 , mFilter(GraphicsFilter::FILTER_GOOD)
1974 , mDirty(false)
1975 {}
1976
1977 virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
1978
1979 void FireDidTransactionCallback()
1980 {
1981 if (mPostTransCallback) {
1982 mPostTransCallback(mPostTransCallbackData);
1983 }
1984 }
1985
1986 /**
1987 * 0, 0, canvaswidth, canvasheight
1988 */
1989 nsIntRect mBounds;
1990 PreTransactionCallback* mPreTransCallback;
1991 void* mPreTransCallbackData;
1992 DidTransactionCallback mPostTransCallback;
1993 void* mPostTransCallbackData;
1994 GraphicsFilter mFilter;
1995
1996 private:
1997 /**
1998 * Set to true in Updated(), cleared during a transaction.
1999 */
2000 bool mDirty;
2001 };
2002
2003 /**
2004 * ContainerLayer that refers to a "foreign" layer tree, through an
2005 * ID. Usage of RefLayer looks like
2006 *
2007 * Construction phase:
2008 * allocate ID for layer subtree
2009 * create RefLayer, SetReferentId(ID)
2010 *
2011 * Composition:
2012 * look up subtree for GetReferentId()
2013 * ConnectReferentLayer(subtree)
2014 * compose
2015 * ClearReferentLayer()
2016 *
2017 * Clients will usually want to Connect/Clear() on each transaction to
2018 * avoid difficulties managing memory across multiple layer subtrees.
2019 */
2020 class RefLayer : public ContainerLayer {
2021 friend class LayerManager;
2022
2023 private:
2024 virtual bool InsertAfter(Layer* aChild, Layer* aAfter) MOZ_OVERRIDE
2025 { MOZ_CRASH(); return false; }
2026
2027 virtual bool RemoveChild(Layer* aChild)
2028 { MOZ_CRASH(); return false; }
2029
2030 virtual bool RepositionChild(Layer* aChild, Layer* aAfter)
2031 { MOZ_CRASH(); return false; }
2032
2033 using ContainerLayer::SetFrameMetrics;
2034
2035 public:
2036 /**
2037 * CONSTRUCTION PHASE ONLY
2038 * Set the ID of the layer's referent.
2039 */
2040 void SetReferentId(uint64_t aId)
2041 {
2042 MOZ_ASSERT(aId != 0);
2043 if (mId != aId) {
2044 MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ReferentId", this));
2045 mId = aId;
2046 Mutated();
2047 }
2048 }
2049 /**
2050 * CONSTRUCTION PHASE ONLY
2051 * Connect this ref layer to its referent, temporarily.
2052 * ClearReferentLayer() must be called after composition.
2053 */
2054 void ConnectReferentLayer(Layer* aLayer)
2055 {
2056 MOZ_ASSERT(!mFirstChild && !mLastChild);
2057 MOZ_ASSERT(!aLayer->GetParent());
2058 MOZ_ASSERT(aLayer->Manager() == Manager());
2059
2060 mFirstChild = mLastChild = aLayer;
2061 aLayer->SetParent(this);
2062 }
2063
2064 /**
2065 * DRAWING PHASE ONLY
2066 * |aLayer| is the same as the argument to ConnectReferentLayer().
2067 */
2068 void DetachReferentLayer(Layer* aLayer)
2069 {
2070 MOZ_ASSERT(aLayer == mFirstChild && mFirstChild == mLastChild);
2071 MOZ_ASSERT(aLayer->GetParent() == this);
2072
2073 mFirstChild = mLastChild = nullptr;
2074 aLayer->SetParent(nullptr);
2075 }
2076
2077 // These getters can be used anytime.
2078 virtual RefLayer* AsRefLayer() { return this; }
2079
2080 virtual int64_t GetReferentId() { return mId; }
2081
2082 /**
2083 * DRAWING PHASE ONLY
2084 */
2085 virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs);
2086
2087 MOZ_LAYER_DECL_NAME("RefLayer", TYPE_REF)
2088
2089 protected:
2090 RefLayer(LayerManager* aManager, void* aImplData)
2091 : ContainerLayer(aManager, aImplData) , mId(0)
2092 {}
2093
2094 virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
2095
2096 Layer* mTempReferent;
2097 // 0 is a special value that means "no ID".
2098 uint64_t mId;
2099 };
2100
2101 void SetAntialiasingFlags(Layer* aLayer, gfxContext* aTarget);
2102 void SetAntialiasingFlags(Layer* aLayer, gfx::DrawTarget* aTarget);
2103
2104 #ifdef MOZ_DUMP_PAINTING
2105 void WriteSnapshotToDumpFile(Layer* aLayer, gfx::DataSourceSurface* aSurf);
2106 void WriteSnapshotToDumpFile(LayerManager* aManager, gfx::DataSourceSurface* aSurf);
2107 void WriteSnapshotToDumpFile(Compositor* aCompositor, gfx::DrawTarget* aTarget);
2108 #endif
2109
2110 }
2111 }
2112
2113 #endif /* GFX_LAYERS_H */

mercurial