|
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 */ |