1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Corporation code.
16 : *
17 : * The Initial Developer of the Original Code is Mozilla Foundation.
18 : * Portions created by the Initial Developer are Copyright (C) 2009
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Robert O'Callahan <robert@ocallahan.org>
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either the GNU General Public License Version 2 or later (the "GPL"), or
26 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #ifndef GFX_LAYERS_H
39 : #define GFX_LAYERS_H
40 :
41 : #include "gfxTypes.h"
42 : #include "gfxASurface.h"
43 : #include "nsRegion.h"
44 : #include "nsPoint.h"
45 : #include "nsRect.h"
46 : #include "nsISupportsImpl.h"
47 : #include "nsAutoPtr.h"
48 : #include "gfx3DMatrix.h"
49 : #include "gfxColor.h"
50 : #include "gfxPattern.h"
51 : #include "nsTArray.h"
52 : #include "nsThreadUtils.h"
53 :
54 : #include "mozilla/gfx/2D.h"
55 : #include "mozilla/TimeStamp.h"
56 :
57 : #if defined(DEBUG) || defined(PR_LOGGING)
58 : # include <stdio.h> // FILE
59 : # include "prlog.h"
60 : # define MOZ_LAYERS_HAVE_LOG
61 : # define MOZ_LAYERS_LOG(_args) \
62 : PR_LOG(LayerManager::GetLog(), PR_LOG_DEBUG, _args)
63 : #else
64 : struct PRLogModuleInfo;
65 : # define MOZ_LAYERS_LOG(_args)
66 : #endif // if defined(DEBUG) || defined(PR_LOGGING)
67 :
68 : class gfxContext;
69 : class nsPaintEvent;
70 :
71 : namespace mozilla {
72 : namespace gl {
73 : class GLContext;
74 : }
75 :
76 : namespace layers {
77 :
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 ShadowLayer;
88 : class ShadowLayerForwarder;
89 : class ShadowLayerManager;
90 : class SpecificLayerAttributes;
91 :
92 : /**
93 : * The viewport and displayport metrics for the painted frame at the
94 : * time of a layer-tree transaction. These metrics are especially
95 : * useful for shadow layers, because the metrics values are updated
96 : * atomically with new pixels.
97 : */
98 0 : struct THEBES_API FrameMetrics {
99 : public:
100 : // We use IDs to identify frames across processes.
101 : typedef PRUint64 ViewID;
102 : static const ViewID NULL_SCROLL_ID; // This container layer does not scroll.
103 : static const ViewID ROOT_SCROLL_ID; // This is the root scroll frame.
104 : static const ViewID START_SCROLL_ID; // This is the ID that scrolling subframes
105 : // will begin at.
106 :
107 0 : FrameMetrics()
108 : : mViewport(0, 0, 0, 0)
109 : , mContentSize(0, 0)
110 : , mViewportScrollOffset(0, 0)
111 0 : , mScrollId(NULL_SCROLL_ID)
112 0 : {}
113 :
114 : // Default copy ctor and operator= are fine
115 :
116 0 : bool operator==(const FrameMetrics& aOther) const
117 : {
118 0 : return (mViewport.IsEqualEdges(aOther.mViewport) &&
119 0 : mViewportScrollOffset == aOther.mViewportScrollOffset &&
120 0 : mDisplayPort.IsEqualEdges(aOther.mDisplayPort) &&
121 0 : mScrollId == aOther.mScrollId);
122 : }
123 : bool operator!=(const FrameMetrics& aOther) const
124 : {
125 : return !operator==(aOther);
126 : }
127 :
128 : bool IsDefault() const
129 : {
130 : return (FrameMetrics() == *this);
131 : }
132 :
133 0 : bool IsRootScrollable() const
134 : {
135 0 : return mScrollId == ROOT_SCROLL_ID;
136 : }
137 :
138 0 : bool IsScrollable() const
139 : {
140 0 : return mScrollId != NULL_SCROLL_ID;
141 : }
142 :
143 : // These are all in layer coordinate space.
144 : nsIntRect mViewport;
145 : nsIntSize mContentSize;
146 : nsIntPoint mViewportScrollOffset;
147 : nsIntRect mDisplayPort;
148 : ViewID mScrollId;
149 : };
150 :
151 : #define MOZ_LAYER_DECL_NAME(n, e) \
152 : virtual const char* Name() const { return n; } \
153 : virtual LayerType GetType() const { return e; }
154 :
155 : /**
156 : * Base class for userdata objects attached to layers and layer managers.
157 : */
158 0 : class THEBES_API LayerUserData {
159 : public:
160 0 : virtual ~LayerUserData() {}
161 : };
162 :
163 : /*
164 : * Motivation: For truly smooth animation and video playback, we need to
165 : * be able to compose frames and render them on a dedicated thread (i.e.
166 : * off the main thread where DOM manipulation, script execution and layout
167 : * induce difficult-to-bound latency). This requires Gecko to construct
168 : * some kind of persistent scene structure (graph or tree) that can be
169 : * safely transmitted across threads. We have other scenarios (e.g. mobile
170 : * browsing) where retaining some rendered data between paints is desired
171 : * for performance, so again we need a retained scene structure.
172 : *
173 : * Our retained scene structure is a layer tree. Each layer represents
174 : * content which can be composited onto a destination surface; the root
175 : * layer is usually composited into a window, and non-root layers are
176 : * composited into their parent layers. Layers have attributes (e.g.
177 : * opacity and clipping) that influence their compositing.
178 : *
179 : * We want to support a variety of layer implementations, including
180 : * a simple "immediate mode" implementation that doesn't retain any
181 : * rendered data between paints (i.e. uses cairo in just the way that
182 : * Gecko used it before layers were introduced). But we also don't want
183 : * to have bifurcated "layers"/"non-layers" rendering paths in Gecko.
184 : * Therefore the layers API is carefully designed to permit maximally
185 : * efficient implementation in an "immediate mode" style. See the
186 : * BasicLayerManager for such an implementation.
187 : */
188 :
189 : /**
190 : * Helper class to manage user data for layers and LayerManagers.
191 : */
192 : class THEBES_API LayerUserDataSet {
193 : public:
194 : LayerUserDataSet() : mKey(nsnull) {}
195 :
196 0 : void Set(void* aKey, LayerUserData* aValue)
197 : {
198 0 : NS_ASSERTION(!mKey || mKey == aKey,
199 : "Multiple LayerUserData objects not supported");
200 0 : mKey = aKey;
201 0 : mValue = aValue;
202 0 : }
203 : /**
204 : * This can be used anytime. Ownership passes to the caller!
205 : */
206 0 : LayerUserData* Remove(void* aKey)
207 : {
208 0 : if (mKey == aKey) {
209 0 : mKey = nsnull;
210 0 : LayerUserData* d = mValue.forget();
211 0 : return d;
212 : }
213 0 : return nsnull;
214 : }
215 : /**
216 : * This getter can be used anytime.
217 : */
218 0 : bool Has(void* aKey)
219 : {
220 0 : return mKey == aKey;
221 : }
222 : /**
223 : * This getter can be used anytime. Ownership is retained by this object.
224 : */
225 0 : LayerUserData* Get(void* aKey)
226 : {
227 0 : return mKey == aKey ? mValue.get() : nsnull;
228 : }
229 :
230 : /**
231 : * Clear out current user data.
232 : */
233 : void Clear()
234 : {
235 : mKey = nsnull;
236 : mValue = nsnull;
237 : }
238 :
239 : private:
240 : void* mKey;
241 : nsAutoPtr<LayerUserData> mValue;
242 : };
243 :
244 : /**
245 : * A LayerManager controls a tree of layers. All layers in the tree
246 : * must use the same LayerManager.
247 : *
248 : * All modifications to a layer tree must happen inside a transaction.
249 : * Only the state of the layer tree at the end of a transaction is
250 : * rendered. Transactions cannot be nested
251 : *
252 : * Each transaction has two phases:
253 : * 1) Construction: layers are created, inserted, removed and have
254 : * properties set on them in this phase.
255 : * BeginTransaction and BeginTransactionWithTarget start a transaction in
256 : * the Construction phase. When the client has finished constructing the layer
257 : * tree, it should call EndConstruction() to enter the drawing phase.
258 : * 2) Drawing: ThebesLayers are rendered into in this phase, in tree
259 : * order. When the client has finished drawing into the ThebesLayers, it should
260 : * call EndTransaction to complete the transaction.
261 : *
262 : * All layer API calls happen on the main thread.
263 : *
264 : * Layers are refcounted. The layer manager holds a reference to the
265 : * root layer, and each container layer holds a reference to its children.
266 : */
267 : class THEBES_API LayerManager {
268 0 : NS_INLINE_DECL_REFCOUNTING(LayerManager)
269 :
270 : public:
271 : enum LayersBackend {
272 : LAYERS_NONE = 0,
273 : LAYERS_BASIC,
274 : LAYERS_OPENGL,
275 : LAYERS_D3D9,
276 : LAYERS_D3D10,
277 : LAYERS_LAST
278 : };
279 :
280 : LayerManager() : mDestroyed(false), mSnapEffectiveTransforms(true)
281 : {
282 : InitLog();
283 : }
284 : virtual ~LayerManager() {}
285 :
286 : /**
287 : * Release layers and resources held by this layer manager, and mark
288 : * it as destroyed. Should do any cleanup necessary in preparation
289 : * for its widget going away. After this call, only user data calls
290 : * are valid on the layer manager.
291 : */
292 : virtual void Destroy() { mDestroyed = true; mUserData.Clear(); }
293 : bool IsDestroyed() { return mDestroyed; }
294 :
295 : virtual ShadowLayerForwarder* AsShadowForwarder()
296 : { return nsnull; }
297 :
298 : virtual ShadowLayerManager* AsShadowManager()
299 : { return nsnull; }
300 :
301 : /**
302 : * Start a new transaction. Nested transactions are not allowed so
303 : * there must be no transaction currently in progress.
304 : * This transaction will update the state of the window from which
305 : * this LayerManager was obtained.
306 : */
307 : virtual void BeginTransaction() = 0;
308 : /**
309 : * Start a new transaction. Nested transactions are not allowed so
310 : * there must be no transaction currently in progress.
311 : * This transaction will render the contents of the layer tree to
312 : * the given target context. The rendering will be complete when
313 : * EndTransaction returns.
314 : */
315 : virtual void BeginTransactionWithTarget(gfxContext* aTarget) = 0;
316 : /**
317 : * Attempts to end an "empty transaction". There must have been no
318 : * changes to the layer tree since the BeginTransaction().
319 : * It's possible for this to fail; ThebesLayers may need to be updated
320 : * due to VRAM data being lost, for example. In such cases this method
321 : * returns false, and the caller must proceed with a normal layer tree
322 : * update and EndTransaction.
323 : */
324 : virtual bool EndEmptyTransaction() = 0;
325 :
326 : /**
327 : * Function called to draw the contents of each ThebesLayer.
328 : * aRegionToDraw contains the region that needs to be drawn.
329 : * This would normally be a subregion of the visible region.
330 : * The callee must draw all of aRegionToDraw. Drawing outside
331 : * aRegionToDraw will be clipped out or ignored.
332 : * The callee must draw all of aRegionToDraw.
333 : * This region is relative to 0,0 in the ThebesLayer.
334 : *
335 : * aRegionToInvalidate contains a region whose contents have been
336 : * changed by the layer manager and which must therefore be invalidated.
337 : * For example, this could be non-empty if a retained layer internally
338 : * switches from RGBA to RGB or back ... we might want to repaint it to
339 : * consistently use subpixel-AA or not.
340 : * This region is relative to 0,0 in the ThebesLayer.
341 : * aRegionToInvalidate may contain areas that are outside
342 : * aRegionToDraw; the callee must ensure that these areas are repainted
343 : * in the current layer manager transaction or in a later layer
344 : * manager transaction.
345 : *
346 : * aContext must not be used after the call has returned.
347 : * We guarantee that buffered contents in the visible
348 : * region are valid once drawing is complete.
349 : *
350 : * The origin of aContext is 0,0 in the ThebesLayer.
351 : */
352 : typedef void (* DrawThebesLayerCallback)(ThebesLayer* aLayer,
353 : gfxContext* aContext,
354 : const nsIntRegion& aRegionToDraw,
355 : const nsIntRegion& aRegionToInvalidate,
356 : void* aCallbackData);
357 :
358 : enum EndTransactionFlags {
359 : END_DEFAULT = 0,
360 : END_NO_IMMEDIATE_REDRAW = 1 << 0 // Do not perform the drawing phase
361 : };
362 :
363 : /**
364 : * Finish the construction phase of the transaction, perform the
365 : * drawing phase, and end the transaction.
366 : * During the drawing phase, all ThebesLayers in the tree are
367 : * drawn in tree order, exactly once each, except for those layers
368 : * where it is known that the visible region is empty.
369 : */
370 : virtual void EndTransaction(DrawThebesLayerCallback aCallback,
371 : void* aCallbackData,
372 : EndTransactionFlags aFlags = END_DEFAULT) = 0;
373 :
374 : bool IsSnappingEffectiveTransforms() { return mSnapEffectiveTransforms; }
375 :
376 : /**
377 : * CONSTRUCTION PHASE ONLY
378 : * Set the root layer. The root layer is initially null. If there is
379 : * no root layer, EndTransaction won't draw anything.
380 : */
381 : virtual void SetRoot(Layer* aLayer) = 0;
382 : /**
383 : * Can be called anytime
384 : */
385 0 : Layer* GetRoot() { return mRoot; }
386 :
387 : /**
388 : * CONSTRUCTION PHASE ONLY
389 : * Called when a managee has mutated.
390 : * Subclasses overriding this method must first call their
391 : * superclass's impl
392 : */
393 : #ifdef DEBUG
394 : // In debug builds, we check some properties of |aLayer|.
395 : virtual void Mutated(Layer* aLayer);
396 : #else
397 : virtual void Mutated(Layer* aLayer) { }
398 : #endif
399 :
400 : /**
401 : * CONSTRUCTION PHASE ONLY
402 : * Create a ThebesLayer for this manager's layer tree.
403 : */
404 : virtual already_AddRefed<ThebesLayer> CreateThebesLayer() = 0;
405 : /**
406 : * CONSTRUCTION PHASE ONLY
407 : * Create a ContainerLayer for this manager's layer tree.
408 : */
409 : virtual already_AddRefed<ContainerLayer> CreateContainerLayer() = 0;
410 : /**
411 : * CONSTRUCTION PHASE ONLY
412 : * Create an ImageLayer for this manager's layer tree.
413 : */
414 : virtual already_AddRefed<ImageLayer> CreateImageLayer() = 0;
415 : /**
416 : * CONSTRUCTION PHASE ONLY
417 : * Create a ColorLayer for this manager's layer tree.
418 : */
419 : virtual already_AddRefed<ColorLayer> CreateColorLayer() = 0;
420 : /**
421 : * CONSTRUCTION PHASE ONLY
422 : * Create a CanvasLayer for this manager's layer tree.
423 : */
424 : virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() = 0;
425 : /**
426 : * CONSTRUCTION PHASE ONLY
427 : * Create a ReadbackLayer for this manager's layer tree.
428 : */
429 : virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer() { return nsnull; }
430 :
431 : /**
432 : * Can be called anytime, from any thread.
433 : */
434 : static already_AddRefed<ImageContainer> CreateImageContainer();
435 :
436 : /**
437 : * Type of layer manager his is. This is to be used sparsely in order to
438 : * avoid a lot of Layers backend specific code. It should be used only when
439 : * Layers backend specific functionality is necessary.
440 : */
441 : virtual LayersBackend GetBackendType() = 0;
442 :
443 : /**
444 : * Creates a layer which is optimized for inter-operating with this layer
445 : * manager.
446 : */
447 : virtual already_AddRefed<gfxASurface>
448 : CreateOptimalSurface(const gfxIntSize &aSize,
449 : gfxASurface::gfxImageFormat imageFormat);
450 :
451 : /**
452 : * Creates a DrawTarget which is optimized for inter-operating with this
453 : * layermanager.
454 : */
455 : virtual TemporaryRef<mozilla::gfx::DrawTarget>
456 : CreateDrawTarget(const mozilla::gfx::IntSize &aSize,
457 : mozilla::gfx::SurfaceFormat aFormat);
458 :
459 : virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) { return true; }
460 :
461 : /**
462 : * Return the name of the layer manager's backend.
463 : */
464 : virtual void GetBackendName(nsAString& aName) = 0;
465 :
466 : /**
467 : * This setter can be used anytime. The user data for all keys is
468 : * initially null. Ownership pases to the layer manager.
469 : */
470 0 : void SetUserData(void* aKey, LayerUserData* aData)
471 0 : { mUserData.Set(aKey, aData); }
472 : /**
473 : * This can be used anytime. Ownership passes to the caller!
474 : */
475 0 : nsAutoPtr<LayerUserData> RemoveUserData(void* aKey)
476 0 : { nsAutoPtr<LayerUserData> d(mUserData.Remove(aKey)); return d; }
477 : /**
478 : * This getter can be used anytime.
479 : */
480 : bool HasUserData(void* aKey)
481 : { return mUserData.Has(aKey); }
482 : /**
483 : * This getter can be used anytime. Ownership is retained by the layer
484 : * manager.
485 : */
486 0 : LayerUserData* GetUserData(void* aKey)
487 0 : { return mUserData.Get(aKey); }
488 :
489 : // We always declare the following logging symbols, because it's
490 : // extremely tricky to conditionally declare them. However, for
491 : // ifndef MOZ_LAYERS_HAVE_LOG builds, they only have trivial
492 : // definitions in Layers.cpp.
493 : virtual const char* Name() const { return "???"; }
494 :
495 : /**
496 : * Dump information about this layer manager and its managed tree to
497 : * aFile, which defaults to stderr.
498 : */
499 : void Dump(FILE* aFile=NULL, const char* aPrefix="");
500 : /**
501 : * Dump information about just this layer manager itself to aFile,
502 : * which defaults to stderr.
503 : */
504 : void DumpSelf(FILE* aFile=NULL, const char* aPrefix="");
505 :
506 : /**
507 : * Log information about this layer manager and its managed tree to
508 : * the NSPR log (if enabled for "Layers").
509 : */
510 : void Log(const char* aPrefix="");
511 : /**
512 : * Log information about just this layer manager itself to the NSPR
513 : * log (if enabled for "Layers").
514 : */
515 : void LogSelf(const char* aPrefix="");
516 :
517 : void StartFrameTimeRecording();
518 : nsTArray<float> StopFrameTimeRecording();
519 :
520 : void PostPresent();
521 :
522 : static bool IsLogEnabled();
523 : static PRLogModuleInfo* GetLog() { return sLog; }
524 :
525 : bool IsCompositingCheap(LayerManager::LayersBackend aBackend)
526 : { return LAYERS_BASIC != aBackend; }
527 :
528 : virtual bool IsCompositingCheap() { return true; }
529 :
530 : protected:
531 : nsRefPtr<Layer> mRoot;
532 : LayerUserDataSet mUserData;
533 : bool mDestroyed;
534 : bool mSnapEffectiveTransforms;
535 :
536 : // Print interesting information about this into aTo. Internally
537 : // used to implement Dump*() and Log*().
538 : virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
539 :
540 : static void InitLog();
541 : static PRLogModuleInfo* sLog;
542 : private:
543 : TimeStamp mLastFrameTime;
544 : nsTArray<float> mFrameTimes;
545 : };
546 :
547 : class ThebesLayer;
548 :
549 : /**
550 : * A Layer represents anything that can be rendered onto a destination
551 : * surface.
552 : */
553 : class THEBES_API Layer {
554 0 : NS_INLINE_DECL_REFCOUNTING(Layer)
555 :
556 : public:
557 : // Keep these in alphabetical order
558 : enum LayerType {
559 : TYPE_CANVAS,
560 : TYPE_COLOR,
561 : TYPE_CONTAINER,
562 : TYPE_IMAGE,
563 : TYPE_READBACK,
564 : TYPE_SHADOW,
565 : TYPE_THEBES
566 : };
567 :
568 : virtual ~Layer() {}
569 :
570 : /**
571 : * Returns the LayerManager this Layer belongs to. Note that the layer
572 : * manager might be in a destroyed state, at which point it's only
573 : * valid to set/get user data from it.
574 : */
575 0 : LayerManager* Manager() { return mManager; }
576 :
577 : enum {
578 : /**
579 : * If this is set, the caller is promising that by the end of this
580 : * transaction the entire visible region (as specified by
581 : * SetVisibleRegion) will be filled with opaque content.
582 : */
583 : CONTENT_OPAQUE = 0x01,
584 : /**
585 : * If this is set, the caller is notifying that the contents of this layer
586 : * require per-component alpha for optimal fidelity. However, there is no
587 : * guarantee that component alpha will be supported for this layer at
588 : * paint time.
589 : * This should never be set at the same time as CONTENT_OPAQUE.
590 : */
591 : CONTENT_COMPONENT_ALPHA = 0x02,
592 :
593 : /**
594 : * If this is set then this layer is part of a preserve-3d group, and should
595 : * be sorted with sibling layers that are also part of the same group.
596 : */
597 : CONTENT_PRESERVE_3D = 0x04
598 : };
599 : /**
600 : * CONSTRUCTION PHASE ONLY
601 : * This lets layout make some promises about what will be drawn into the
602 : * visible region of the ThebesLayer. This enables internal quality
603 : * and performance optimizations.
604 : */
605 0 : void SetContentFlags(PRUint32 aFlags)
606 : {
607 0 : NS_ASSERTION((aFlags & (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA)) !=
608 : (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA),
609 : "Can't be opaque and require component alpha");
610 0 : mContentFlags = aFlags;
611 0 : Mutated();
612 0 : }
613 : /**
614 : * CONSTRUCTION PHASE ONLY
615 : * Tell this layer which region will be visible. The visible region
616 : * is a region which contains all the contents of the layer that can
617 : * actually affect the rendering of the window. It can exclude areas
618 : * that are covered by opaque contents of other layers, and it can
619 : * exclude areas where this layer simply contains no content at all.
620 : * (This can be an overapproximation to the "true" visible region.)
621 : *
622 : * There is no general guarantee that drawing outside the bounds of the
623 : * visible region will be ignored. So if a layer draws outside the bounds
624 : * of its visible region, it needs to ensure that what it draws is valid.
625 : */
626 : virtual void SetVisibleRegion(const nsIntRegion& aRegion)
627 : {
628 : mVisibleRegion = aRegion;
629 : Mutated();
630 : }
631 :
632 : /**
633 : * CONSTRUCTION PHASE ONLY
634 : * Set the opacity which will be applied to this layer as it
635 : * is composited to the destination.
636 : */
637 0 : void SetOpacity(float aOpacity)
638 : {
639 0 : mOpacity = aOpacity;
640 0 : Mutated();
641 0 : }
642 :
643 : /**
644 : * CONSTRUCTION PHASE ONLY
645 : * Set a clip rect which will be applied to this layer as it is
646 : * composited to the destination. The coordinates are relative to
647 : * the parent layer (i.e. the contents of this layer
648 : * are transformed before this clip rect is applied).
649 : * For the root layer, the coordinates are relative to the widget,
650 : * in device pixels.
651 : * If aRect is null no clipping will be performed.
652 : */
653 0 : void SetClipRect(const nsIntRect* aRect)
654 : {
655 0 : mUseClipRect = aRect != nsnull;
656 0 : if (aRect) {
657 0 : mClipRect = *aRect;
658 : }
659 0 : Mutated();
660 0 : }
661 :
662 : /**
663 : * CONSTRUCTION PHASE ONLY
664 : * Set a clip rect which will be applied to this layer as it is
665 : * composited to the destination. The coordinates are relative to
666 : * the parent layer (i.e. the contents of this layer
667 : * are transformed before this clip rect is applied).
668 : * For the root layer, the coordinates are relative to the widget,
669 : * in device pixels.
670 : * The provided rect is intersected with any existing clip rect.
671 : */
672 0 : void IntersectClipRect(const nsIntRect& aRect)
673 : {
674 0 : if (mUseClipRect) {
675 0 : mClipRect.IntersectRect(mClipRect, aRect);
676 : } else {
677 0 : mUseClipRect = true;
678 0 : mClipRect = aRect;
679 : }
680 0 : Mutated();
681 0 : }
682 :
683 : /**
684 : * CONSTRUCTION PHASE ONLY
685 : * Tell this layer what its transform should be. The transformation
686 : * is applied when compositing the layer into its parent container.
687 : * XXX Currently only transformations corresponding to 2D affine transforms
688 : * are supported.
689 : */
690 0 : void SetTransform(const gfx3DMatrix& aMatrix)
691 : {
692 0 : mTransform = aMatrix;
693 0 : Mutated();
694 0 : }
695 :
696 : /**
697 : * CONSTRUCTION PHASE ONLY
698 : *
699 : * Define a subrect of this layer that will be used as the source
700 : * image for tiling this layer's visible region. The coordinates
701 : * are in the un-transformed space of this layer (i.e. the visible
702 : * region of this this layer is tiled before being transformed).
703 : * The visible region is tiled "outwards" from the source rect; that
704 : * is, the source rect is drawn "in place", then repeated to cover
705 : * the layer's visible region.
706 : *
707 : * The interpretation of the source rect varies depending on
708 : * underlying layer type. For ImageLayers and CanvasLayers, it
709 : * doesn't make sense to set a source rect not fully contained by
710 : * the bounds of their underlying images. For ThebesLayers, thebes
711 : * content may need to be rendered to fill the source rect. For
712 : * ColorLayers, a source rect for tiling doesn't make sense at all.
713 : *
714 : * If aRect is null no tiling will be performed.
715 : *
716 : * NB: this interface is only implemented for BasicImageLayers, and
717 : * then only for source rects the same size as the layers'
718 : * underlying images.
719 : */
720 : void SetTileSourceRect(const nsIntRect* aRect)
721 : {
722 : mUseTileSourceRect = aRect != nsnull;
723 : if (aRect) {
724 : mTileSourceRect = *aRect;
725 : }
726 : Mutated();
727 : }
728 :
729 0 : void SetIsFixedPosition(bool aFixedPosition) { mIsFixedPosition = aFixedPosition; }
730 :
731 : // These getters can be used anytime.
732 : float GetOpacity() { return mOpacity; }
733 0 : const nsIntRect* GetClipRect() { return mUseClipRect ? &mClipRect : nsnull; }
734 0 : PRUint32 GetContentFlags() { return mContentFlags; }
735 0 : const nsIntRegion& GetVisibleRegion() { return mVisibleRegion; }
736 0 : ContainerLayer* GetParent() { return mParent; }
737 0 : Layer* GetNextSibling() { return mNextSibling; }
738 : Layer* GetPrevSibling() { return mPrevSibling; }
739 : virtual Layer* GetFirstChild() { return nsnull; }
740 : virtual Layer* GetLastChild() { return nsnull; }
741 0 : const gfx3DMatrix& GetTransform() { return mTransform; }
742 : const nsIntRect* GetTileSourceRect() { return mUseTileSourceRect ? &mTileSourceRect : nsnull; }
743 0 : bool GetIsFixedPosition() { return mIsFixedPosition; }
744 :
745 : /**
746 : * DRAWING PHASE ONLY
747 : *
748 : * Write layer-subtype-specific attributes into aAttrs. Used to
749 : * synchronize layer attributes to their shadows'.
750 : */
751 : virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) { }
752 :
753 : // Returns true if it's OK to save the contents of aLayer in an
754 : // opaque surface (a surface without an alpha channel).
755 : // If we can use a surface without an alpha channel, we should, because
756 : // it will often make painting of antialiased text faster and higher
757 : // quality.
758 : bool CanUseOpaqueSurface();
759 :
760 : enum SurfaceMode {
761 : SURFACE_OPAQUE,
762 : SURFACE_SINGLE_CHANNEL_ALPHA,
763 : SURFACE_COMPONENT_ALPHA
764 : };
765 : SurfaceMode GetSurfaceMode()
766 : {
767 : if (CanUseOpaqueSurface())
768 : return SURFACE_OPAQUE;
769 : if (mContentFlags & CONTENT_COMPONENT_ALPHA)
770 : return SURFACE_COMPONENT_ALPHA;
771 : return SURFACE_SINGLE_CHANNEL_ALPHA;
772 : }
773 :
774 : /**
775 : * This setter can be used anytime. The user data for all keys is
776 : * initially null. Ownership pases to the layer manager.
777 : */
778 0 : void SetUserData(void* aKey, LayerUserData* aData)
779 0 : { mUserData.Set(aKey, aData); }
780 : /**
781 : * This can be used anytime. Ownership passes to the caller!
782 : */
783 : nsAutoPtr<LayerUserData> RemoveUserData(void* aKey)
784 : { nsAutoPtr<LayerUserData> d(mUserData.Remove(aKey)); return d; }
785 : /**
786 : * This getter can be used anytime.
787 : */
788 0 : bool HasUserData(void* aKey)
789 0 : { return mUserData.Has(aKey); }
790 : /**
791 : * This getter can be used anytime. Ownership is retained by the layer
792 : * manager.
793 : */
794 0 : LayerUserData* GetUserData(void* aKey)
795 0 : { return mUserData.Get(aKey); }
796 :
797 : /**
798 : * |Disconnect()| is used by layers hooked up over IPC. It may be
799 : * called at any time, and may not be called at all. Using an
800 : * IPC-enabled layer after Destroy() (drawing etc.) results in a
801 : * safe no-op; no crashy or uaf etc.
802 : *
803 : * XXX: this interface is essentially LayerManager::Destroy, but at
804 : * Layer granularity. It might be beneficial to unify them.
805 : */
806 : virtual void Disconnect() {}
807 :
808 : /**
809 : * Dynamic downcast to a Thebes layer. Returns null if this is not
810 : * a ThebesLayer.
811 : */
812 : virtual ThebesLayer* AsThebesLayer() { return nsnull; }
813 :
814 : /**
815 : * Dynamic cast to a ContainerLayer. Returns null if this is not
816 : * a ContainerLayer.
817 : */
818 : virtual ContainerLayer* AsContainerLayer() { return nsnull; }
819 :
820 : /**
821 : * Dynamic cast to a ShadowLayer. Return null if this is not a
822 : * ShadowLayer. Can be used anytime.
823 : */
824 : virtual ShadowLayer* AsShadowLayer() { return nsnull; }
825 :
826 : // These getters can be used anytime. They return the effective
827 : // values that should be used when drawing this layer to screen,
828 : // accounting for this layer possibly being a shadow.
829 : const nsIntRect* GetEffectiveClipRect();
830 : const nsIntRegion& GetEffectiveVisibleRegion();
831 : /**
832 : * Returns the product of the opacities of this layer and all ancestors up
833 : * to and excluding the nearest ancestor that has UseIntermediateSurface() set.
834 : */
835 : float GetEffectiveOpacity();
836 : /**
837 : * This returns the effective transform computed by
838 : * ComputeEffectiveTransforms. Typically this is a transform that transforms
839 : * this layer all the way to some intermediate surface or destination
840 : * surface. For non-BasicLayers this will be a transform to the nearest
841 : * ancestor with UseIntermediateSurface() (or to the root, if there is no
842 : * such ancestor), but for BasicLayers it's different.
843 : */
844 : const gfx3DMatrix& GetEffectiveTransform() const { return mEffectiveTransform; }
845 :
846 : /**
847 : * @param aTransformToSurface the composition of the transforms
848 : * from the parent layer (if any) to the destination pixel grid.
849 : *
850 : * Computes mEffectiveTransform for this layer and all its descendants.
851 : * mEffectiveTransform transforms this layer up to the destination
852 : * pixel grid (whatever aTransformToSurface is relative to).
853 : *
854 : * We promise that when this is called on a layer, all ancestor layers
855 : * have already had ComputeEffectiveTransforms called.
856 : */
857 : virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) = 0;
858 :
859 : /**
860 : * Calculate the scissor rect required when rendering this layer.
861 : * Returns a rectangle relative to the intermediate surface belonging to the
862 : * nearest ancestor that has an intermediate surface, or relative to the root
863 : * viewport if no ancestor has an intermediate surface, corresponding to the
864 : * clip rect for this layer intersected with aCurrentScissorRect.
865 : * If no ancestor has an intermediate surface, the clip rect is transformed
866 : * by aWorldTransform before being combined with aCurrentScissorRect, if
867 : * aWorldTransform is non-null.
868 : */
869 : nsIntRect CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
870 : const gfxMatrix* aWorldTransform);
871 :
872 : virtual const char* Name() const =0;
873 : virtual LayerType GetType() const =0;
874 :
875 : /**
876 : * Only the implementation should call this. This is per-implementation
877 : * private data. Normally, all layers with a given layer manager
878 : * use the same type of ImplData.
879 : */
880 : void* ImplData() { return mImplData; }
881 :
882 : /**
883 : * Only the implementation should use these methods.
884 : */
885 : void SetParent(ContainerLayer* aParent) { mParent = aParent; }
886 : void SetNextSibling(Layer* aSibling) { mNextSibling = aSibling; }
887 : void SetPrevSibling(Layer* aSibling) { mPrevSibling = aSibling; }
888 :
889 : /**
890 : * Dump information about this layer manager and its managed tree to
891 : * aFile, which defaults to stderr.
892 : */
893 : void Dump(FILE* aFile=NULL, const char* aPrefix="");
894 : /**
895 : * Dump information about just this layer manager itself to aFile,
896 : * which defaults to stderr.
897 : */
898 : void DumpSelf(FILE* aFile=NULL, const char* aPrefix="");
899 :
900 : /**
901 : * Log information about this layer manager and its managed tree to
902 : * the NSPR log (if enabled for "Layers").
903 : */
904 : void Log(const char* aPrefix="");
905 : /**
906 : * Log information about just this layer manager itself to the NSPR
907 : * log (if enabled for "Layers").
908 : */
909 : void LogSelf(const char* aPrefix="");
910 :
911 : static bool IsLogEnabled() { return LayerManager::IsLogEnabled(); }
912 :
913 : protected:
914 : Layer(LayerManager* aManager, void* aImplData) :
915 : mManager(aManager),
916 : mParent(nsnull),
917 : mNextSibling(nsnull),
918 : mPrevSibling(nsnull),
919 : mImplData(aImplData),
920 : mOpacity(1.0),
921 : mContentFlags(0),
922 : mUseClipRect(false),
923 : mUseTileSourceRect(false),
924 : mIsFixedPosition(false)
925 : {}
926 :
927 0 : void Mutated() { mManager->Mutated(this); }
928 :
929 : // Print interesting information about this into aTo. Internally
930 : // used to implement Dump*() and Log*(). If subclasses have
931 : // additional interesting properties, they should override this with
932 : // an implementation that first calls the base implementation then
933 : // appends additional info to aTo.
934 : virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
935 :
936 : /**
937 : * Returns the local transform for this layer: either mTransform or,
938 : * for shadow layers, GetShadowTransform()
939 : */
940 : const gfx3DMatrix& GetLocalTransform();
941 :
942 : /**
943 : * Computes a tweaked version of aTransform that snaps a point or a rectangle
944 : * to pixel boundaries. Snapping is only performed if this layer's
945 : * layer manager has enabled snapping (which is the default).
946 : * @param aSnapRect a rectangle whose edges should be snapped to pixel
947 : * boundaries in the destination surface. If the rectangle is empty,
948 : * then the snapping process should preserve the scale factors of the
949 : * transform matrix
950 : * @param aResidualTransform a transform to apply before mEffectiveTransform
951 : * in order to get the results to completely match aTransform
952 : */
953 : gfx3DMatrix SnapTransform(const gfx3DMatrix& aTransform,
954 : const gfxRect& aSnapRect,
955 : gfxMatrix* aResidualTransform);
956 :
957 : LayerManager* mManager;
958 : ContainerLayer* mParent;
959 : Layer* mNextSibling;
960 : Layer* mPrevSibling;
961 : void* mImplData;
962 : LayerUserDataSet mUserData;
963 : nsIntRegion mVisibleRegion;
964 : gfx3DMatrix mTransform;
965 : gfx3DMatrix mEffectiveTransform;
966 : float mOpacity;
967 : nsIntRect mClipRect;
968 : nsIntRect mTileSourceRect;
969 : PRUint32 mContentFlags;
970 : bool mUseClipRect;
971 : bool mUseTileSourceRect;
972 : bool mIsFixedPosition;
973 : };
974 :
975 : /**
976 : * A Layer which we can draw into using Thebes. It is a conceptually
977 : * infinite surface, but each ThebesLayer has an associated "valid region"
978 : * of contents that it is currently storing, which is finite. ThebesLayer
979 : * implementations can store content between paints.
980 : *
981 : * ThebesLayers are rendered into during the drawing phase of a transaction.
982 : *
983 : * Currently the contents of a ThebesLayer are in the device output color
984 : * space.
985 : */
986 : class THEBES_API ThebesLayer : public Layer {
987 : public:
988 : /**
989 : * CONSTRUCTION PHASE ONLY
990 : * Tell this layer that the content in some region has changed and
991 : * will need to be repainted. This area is removed from the valid
992 : * region.
993 : */
994 : virtual void InvalidateRegion(const nsIntRegion& aRegion) = 0;
995 : /**
996 : * CONSTRUCTION PHASE ONLY
997 : * Set whether ComputeEffectiveTransforms should compute the
998 : * "residual translation" --- the translation that should be applied *before*
999 : * mEffectiveTransform to get the ideal transform for this ThebesLayer.
1000 : * When this is true, ComputeEffectiveTransforms will compute the residual
1001 : * and ensure that the layer is invalidated whenever the residual changes.
1002 : * When it's false, a change in the residual will not trigger invalidation
1003 : * and GetResidualTranslation will return 0,0.
1004 : * So when the residual is to be ignored, set this to false for better
1005 : * performance.
1006 : */
1007 0 : void SetAllowResidualTranslation(bool aAllow) { mAllowResidualTranslation = aAllow; }
1008 :
1009 : /**
1010 : * Can be used anytime
1011 : */
1012 0 : const nsIntRegion& GetValidRegion() const { return mValidRegion; }
1013 :
1014 : virtual ThebesLayer* AsThebesLayer() { return this; }
1015 :
1016 : MOZ_LAYER_DECL_NAME("ThebesLayer", TYPE_THEBES)
1017 :
1018 : virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
1019 : {
1020 : // The default implementation just snaps 0,0 to pixels.
1021 : gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
1022 : gfxMatrix residual;
1023 : mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0),
1024 : mAllowResidualTranslation ? &residual : nsnull);
1025 : // The residual can only be a translation because ThebesLayer snapping
1026 : // only aligns a single point with the pixel grid; scale factors are always
1027 : // preserved exactly
1028 : NS_ASSERTION(!residual.HasNonTranslation(),
1029 : "Residual transform can only be a translation");
1030 : if (residual.GetTranslation() != mResidualTranslation) {
1031 : mResidualTranslation = residual.GetTranslation();
1032 : NS_ASSERTION(-0.5 <= mResidualTranslation.x && mResidualTranslation.x < 0.5 &&
1033 : -0.5 <= mResidualTranslation.y && mResidualTranslation.y < 0.5,
1034 : "Residual translation out of range");
1035 : mValidRegion.SetEmpty();
1036 : }
1037 : }
1038 :
1039 : bool UsedForReadback() { return mUsedForReadback; }
1040 : void SetUsedForReadback(bool aUsed) { mUsedForReadback = aUsed; }
1041 : /**
1042 : * Returns the residual translation. Apply this translation when drawing
1043 : * into the ThebesLayer so that when mEffectiveTransform is applied afterwards
1044 : * by layer compositing, the results exactly match the "ideal transform"
1045 : * (the product of the transform of this layer and its ancestors).
1046 : * Returns 0,0 unless SetAllowResidualTranslation(true) has been called.
1047 : * The residual translation components are always in the range [-0.5, 0.5).
1048 : */
1049 0 : gfxPoint GetResidualTranslation() const { return mResidualTranslation; }
1050 :
1051 : protected:
1052 : ThebesLayer(LayerManager* aManager, void* aImplData)
1053 : : Layer(aManager, aImplData)
1054 : , mValidRegion()
1055 : , mUsedForReadback(false)
1056 : , mAllowResidualTranslation(false)
1057 : {
1058 : mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT
1059 : }
1060 :
1061 : virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
1062 :
1063 : /**
1064 : * ComputeEffectiveTransforms snaps the ideal transform to get mEffectiveTransform.
1065 : * mResidualTranslation is the translation that should be applied *before*
1066 : * mEffectiveTransform to get the ideal transform.
1067 : */
1068 : gfxPoint mResidualTranslation;
1069 : nsIntRegion mValidRegion;
1070 : /**
1071 : * Set when this ThebesLayer is participating in readback, i.e. some
1072 : * ReadbackLayer (may) be getting its background from this layer.
1073 : */
1074 : bool mUsedForReadback;
1075 : /**
1076 : * True when
1077 : */
1078 : bool mAllowResidualTranslation;
1079 : };
1080 :
1081 : /**
1082 : * A Layer which other layers render into. It holds references to its
1083 : * children.
1084 : */
1085 : class THEBES_API ContainerLayer : public Layer {
1086 : public:
1087 : /**
1088 : * CONSTRUCTION PHASE ONLY
1089 : * Insert aChild into the child list of this container. aChild must
1090 : * not be currently in any child list or the root for the layer manager.
1091 : * If aAfter is non-null, it must be a child of this container and
1092 : * we insert after that layer. If it's null we insert at the start.
1093 : */
1094 : virtual void InsertAfter(Layer* aChild, Layer* aAfter) = 0;
1095 : /**
1096 : * CONSTRUCTION PHASE ONLY
1097 : * Remove aChild from the child list of this container. aChild must
1098 : * be a child of this container.
1099 : */
1100 : virtual void RemoveChild(Layer* aChild) = 0;
1101 :
1102 : /**
1103 : * CONSTRUCTION PHASE ONLY
1104 : * Set the (sub)document metrics used to render the Layer subtree
1105 : * rooted at this.
1106 : */
1107 0 : void SetFrameMetrics(const FrameMetrics& aFrameMetrics)
1108 : {
1109 0 : mFrameMetrics = aFrameMetrics;
1110 0 : Mutated();
1111 0 : }
1112 :
1113 : virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs);
1114 :
1115 : void SortChildrenBy3DZOrder(nsTArray<Layer*>& aArray);
1116 :
1117 : // These getters can be used anytime.
1118 :
1119 : virtual ContainerLayer* AsContainerLayer() { return this; }
1120 :
1121 : virtual Layer* GetFirstChild() { return mFirstChild; }
1122 : virtual Layer* GetLastChild() { return mLastChild; }
1123 0 : const FrameMetrics& GetFrameMetrics() { return mFrameMetrics; }
1124 :
1125 : MOZ_LAYER_DECL_NAME("ContainerLayer", TYPE_CONTAINER)
1126 :
1127 : /**
1128 : * ContainerLayer backends need to override ComputeEffectiveTransforms
1129 : * since the decision about whether to use a temporary surface for the
1130 : * container is backend-specific. ComputeEffectiveTransforms must also set
1131 : * mUseIntermediateSurface.
1132 : */
1133 : virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) = 0;
1134 :
1135 : /**
1136 : * Call this only after ComputeEffectiveTransforms has been invoked
1137 : * on this layer.
1138 : * Returns true if this will use an intermediate surface. This is largely
1139 : * backend-dependent, but it affects the operation of GetEffectiveOpacity().
1140 : */
1141 : bool UseIntermediateSurface() { return mUseIntermediateSurface; }
1142 :
1143 : /**
1144 : * Returns the rectangle covered by the intermediate surface,
1145 : * in this layer's coordinate system
1146 : */
1147 : nsIntRect GetIntermediateSurfaceRect()
1148 : {
1149 : NS_ASSERTION(mUseIntermediateSurface, "Must have intermediate surface");
1150 : return mVisibleRegion.GetBounds();
1151 : }
1152 :
1153 : /**
1154 : * Returns true if this container has more than one non-empty child
1155 : */
1156 : bool HasMultipleChildren();
1157 :
1158 : /**
1159 : * Returns true if this container supports children with component alpha.
1160 : * Should only be called while painting a child of this layer.
1161 : */
1162 : bool SupportsComponentAlphaChildren() { return mSupportsComponentAlphaChildren; }
1163 :
1164 : protected:
1165 : friend class ReadbackProcessor;
1166 :
1167 : void DidInsertChild(Layer* aLayer);
1168 : void DidRemoveChild(Layer* aLayer);
1169 :
1170 : ContainerLayer(LayerManager* aManager, void* aImplData)
1171 : : Layer(aManager, aImplData),
1172 : mFirstChild(nsnull),
1173 : mLastChild(nsnull),
1174 : mUseIntermediateSurface(false),
1175 : mSupportsComponentAlphaChildren(false),
1176 : mMayHaveReadbackChild(false)
1177 : {
1178 : mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT
1179 : }
1180 :
1181 : /**
1182 : * A default implementation of ComputeEffectiveTransforms for use by OpenGL
1183 : * and D3D.
1184 : */
1185 : void DefaultComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface);
1186 :
1187 : /**
1188 : * Loops over the children calling ComputeEffectiveTransforms on them.
1189 : */
1190 : void ComputeEffectiveTransformsForChildren(const gfx3DMatrix& aTransformToSurface);
1191 :
1192 : virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
1193 :
1194 : Layer* mFirstChild;
1195 : Layer* mLastChild;
1196 : FrameMetrics mFrameMetrics;
1197 : bool mUseIntermediateSurface;
1198 : bool mSupportsComponentAlphaChildren;
1199 : bool mMayHaveReadbackChild;
1200 : };
1201 :
1202 : /**
1203 : * A Layer which just renders a solid color in its visible region. It actually
1204 : * can fill any area that contains the visible region, so if you need to
1205 : * restrict the area filled, set a clip region on this layer.
1206 : */
1207 : class THEBES_API ColorLayer : public Layer {
1208 : public:
1209 : /**
1210 : * CONSTRUCTION PHASE ONLY
1211 : * Set the color of the layer.
1212 : */
1213 : virtual void SetColor(const gfxRGBA& aColor)
1214 : {
1215 : mColor = aColor;
1216 : }
1217 :
1218 : // This getter can be used anytime.
1219 : virtual const gfxRGBA& GetColor() { return mColor; }
1220 :
1221 : MOZ_LAYER_DECL_NAME("ColorLayer", TYPE_COLOR)
1222 :
1223 : virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
1224 : {
1225 : // Snap 0,0 to pixel boundaries, no extra internal transform.
1226 : gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
1227 : mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0), nsnull);
1228 : }
1229 :
1230 : protected:
1231 : ColorLayer(LayerManager* aManager, void* aImplData)
1232 : : Layer(aManager, aImplData),
1233 : mColor(0.0, 0.0, 0.0, 0.0)
1234 : {}
1235 :
1236 : virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
1237 :
1238 : gfxRGBA mColor;
1239 : };
1240 :
1241 : /**
1242 : * A Layer for HTML Canvas elements. It's backed by either a
1243 : * gfxASurface or a GLContext (for WebGL layers), and has some control
1244 : * for intelligent updating from the source if necessary (for example,
1245 : * if hardware compositing is not available, for reading from the GL
1246 : * buffer into an image surface that we can layer composite.)
1247 : *
1248 : * After Initialize is called, the underlying canvas Surface/GLContext
1249 : * must not be modified during a layer transaction.
1250 : */
1251 : class THEBES_API CanvasLayer : public Layer {
1252 : public:
1253 : struct Data {
1254 0 : Data()
1255 : : mSurface(nsnull), mGLContext(nsnull)
1256 0 : , mDrawTarget(nsnull), mGLBufferIsPremultiplied(false)
1257 0 : { }
1258 :
1259 : /* One of these two must be specified, but never both */
1260 : gfxASurface* mSurface; // a gfx Surface for the canvas contents
1261 : mozilla::gl::GLContext* mGLContext; // a GL PBuffer Context
1262 : mozilla::gfx::DrawTarget *mDrawTarget; // a DrawTarget for the canvas contents
1263 :
1264 : /* The size of the canvas content */
1265 : nsIntSize mSize;
1266 :
1267 : /* Whether the GLContext contains premultiplied alpha
1268 : * values in the framebuffer or not. Defaults to FALSE.
1269 : */
1270 : bool mGLBufferIsPremultiplied;
1271 : };
1272 :
1273 : /**
1274 : * CONSTRUCTION PHASE ONLY
1275 : * Initialize this CanvasLayer with the given data. The data must
1276 : * have either mSurface or mGLContext initialized (but not both), as
1277 : * well as mSize.
1278 : *
1279 : * This must only be called once.
1280 : */
1281 : virtual void Initialize(const Data& aData) = 0;
1282 :
1283 : /**
1284 : * Notify this CanvasLayer that the canvas surface contents have
1285 : * changed (or will change) before the next transaction.
1286 : */
1287 0 : void Updated() { mDirty = true; }
1288 :
1289 : /**
1290 : * Register a callback to be called at the end of each transaction.
1291 : */
1292 : typedef void (* DidTransactionCallback)(void* aClosureData);
1293 0 : void SetDidTransactionCallback(DidTransactionCallback aCallback, void* aClosureData)
1294 : {
1295 0 : mCallback = aCallback;
1296 0 : mCallbackData = aClosureData;
1297 0 : }
1298 :
1299 : /**
1300 : * CONSTRUCTION PHASE ONLY
1301 : * Set the filter used to resample this image (if necessary).
1302 : */
1303 0 : void SetFilter(gfxPattern::GraphicsFilter aFilter) { mFilter = aFilter; }
1304 : gfxPattern::GraphicsFilter GetFilter() const { return mFilter; }
1305 :
1306 : MOZ_LAYER_DECL_NAME("CanvasLayer", TYPE_CANVAS)
1307 :
1308 : virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
1309 : {
1310 : // Snap our local transform first, and snap the inherited transform as well.
1311 : // This makes our snapping equivalent to what would happen if our content
1312 : // was drawn into a ThebesLayer (gfxContext would snap using the local
1313 : // transform, then we'd snap again when compositing the ThebesLayer).
1314 : mEffectiveTransform =
1315 : SnapTransform(GetLocalTransform(), gfxRect(0, 0, mBounds.width, mBounds.height),
1316 : nsnull)*
1317 : SnapTransform(aTransformToSurface, gfxRect(0, 0, 0, 0), nsnull);
1318 : }
1319 :
1320 : protected:
1321 : CanvasLayer(LayerManager* aManager, void* aImplData)
1322 : : Layer(aManager, aImplData),
1323 : mCallback(nsnull), mCallbackData(nsnull), mFilter(gfxPattern::FILTER_GOOD),
1324 : mDirty(false) {}
1325 :
1326 : virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
1327 :
1328 : void FireDidTransactionCallback()
1329 : {
1330 : if (mCallback) {
1331 : mCallback(mCallbackData);
1332 : }
1333 : }
1334 :
1335 : /**
1336 : * 0, 0, canvaswidth, canvasheight
1337 : */
1338 : nsIntRect mBounds;
1339 : DidTransactionCallback mCallback;
1340 : void* mCallbackData;
1341 : gfxPattern::GraphicsFilter mFilter;
1342 : /**
1343 : * Set to true in Updated(), cleared during a transaction.
1344 : */
1345 : bool mDirty;
1346 : };
1347 :
1348 : #ifdef MOZ_DUMP_PAINTING
1349 : void WriteSnapshotToDumpFile(Layer* aLayer, gfxASurface* aSurf);
1350 : void WriteSnapshotToDumpFile(LayerManager* aManager, gfxASurface* aSurf);
1351 : #endif
1352 :
1353 : }
1354 : }
1355 :
1356 : #endif /* GFX_LAYERS_H */
|