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_BASICLAYERS_H
39 : #define GFX_BASICLAYERS_H
40 :
41 : #include "Layers.h"
42 :
43 : #include "gfxContext.h"
44 : #include "gfxCachedTempSurface.h"
45 : #include "nsAutoRef.h"
46 : #include "nsThreadUtils.h"
47 :
48 : #include "mozilla/layers/ShadowLayers.h"
49 :
50 : class nsIWidget;
51 :
52 : namespace mozilla {
53 : namespace layers {
54 :
55 : class BasicShadowableLayer;
56 : class ShadowThebesLayer;
57 : class ShadowContainerLayer;
58 : class ShadowImageLayer;
59 : class ShadowCanvasLayer;
60 : class ShadowColorLayer;
61 : class ReadbackProcessor;
62 :
63 : /**
64 : * This is a cairo/Thebes-only, main-thread-only implementation of layers.
65 : *
66 : * In each transaction, the client sets up the layer tree and then during
67 : * the drawing phase, each ThebesLayer is painted directly into the target
68 : * context (with appropriate clipping and Push/PopGroups performed
69 : * between layers).
70 : */
71 : class THEBES_API BasicLayerManager :
72 : public ShadowLayerManager
73 : {
74 : public:
75 : /**
76 : * Construct a BasicLayerManager which will have no default
77 : * target context. SetDefaultTarget or BeginTransactionWithTarget
78 : * must be called for any rendering to happen. ThebesLayers will not
79 : * be retained.
80 : */
81 : BasicLayerManager();
82 : /**
83 : * Construct a BasicLayerManager which will have no default
84 : * target context. SetDefaultTarget or BeginTransactionWithTarget
85 : * must be called for any rendering to happen. ThebesLayers will be
86 : * retained; that is, we will try to retain the visible contents of
87 : * ThebesLayers as cairo surfaces. We create ThebesLayer buffers by
88 : * creating similar surfaces to the default target context, or to
89 : * aWidget's GetThebesSurface if there is no default target context, or
90 : * to the passed-in context if there is no widget and no default
91 : * target context.
92 : *
93 : * This does not keep a strong reference to the widget, so the caller
94 : * must ensure that the widget outlives the layer manager or call
95 : * ClearWidget before the widget dies.
96 : */
97 : BasicLayerManager(nsIWidget* aWidget);
98 : virtual ~BasicLayerManager();
99 :
100 : /**
101 : * Set the default target context that will be used when BeginTransaction
102 : * is called. This can only be called outside a transaction.
103 : *
104 : * aDoubleBuffering can request double-buffering for drawing to the
105 : * default target. When BUFFERED, the layer manager avoids blitting
106 : * temporary results to aContext and then overpainting them with final
107 : * results, by using a temporary buffer when necessary. In BUFFERED
108 : * mode we always completely overwrite the contents of aContext's
109 : * destination surface (within the clip region) using OPERATOR_SOURCE.
110 : */
111 : enum BufferMode {
112 : BUFFER_NONE,
113 : BUFFER_BUFFERED
114 : };
115 : void SetDefaultTarget(gfxContext* aContext, BufferMode aDoubleBuffering);
116 : gfxContext* GetDefaultTarget() { return mDefaultTarget; }
117 :
118 0 : nsIWidget* GetRetainerWidget() { return mWidget; }
119 0 : void ClearRetainerWidget() { mWidget = nsnull; }
120 :
121 : virtual void BeginTransaction();
122 : virtual void BeginTransactionWithTarget(gfxContext* aTarget);
123 : virtual bool EndEmptyTransaction();
124 : virtual void EndTransaction(DrawThebesLayerCallback aCallback,
125 : void* aCallbackData,
126 : EndTransactionFlags aFlags = END_DEFAULT);
127 :
128 : virtual void SetRoot(Layer* aLayer);
129 :
130 : virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
131 : virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
132 : virtual already_AddRefed<ImageLayer> CreateImageLayer();
133 : virtual already_AddRefed<CanvasLayer> CreateCanvasLayer();
134 : virtual already_AddRefed<ColorLayer> CreateColorLayer();
135 : virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer();
136 : virtual ImageFactory *GetImageFactory();
137 :
138 : virtual already_AddRefed<ShadowThebesLayer> CreateShadowThebesLayer()
139 : { return nsnull; }
140 : virtual already_AddRefed<ShadowContainerLayer> CreateShadowContainerLayer()
141 : { return nsnull; }
142 : virtual already_AddRefed<ShadowImageLayer> CreateShadowImageLayer()
143 : { return nsnull; }
144 : virtual already_AddRefed<ShadowColorLayer> CreateShadowColorLayer()
145 : { return nsnull; }
146 : virtual already_AddRefed<ShadowCanvasLayer> CreateShadowCanvasLayer()
147 : { return nsnull; }
148 :
149 : virtual LayersBackend GetBackendType() { return LAYERS_BASIC; }
150 : virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Basic"); }
151 :
152 : #ifdef DEBUG
153 : bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; }
154 : bool InDrawing() { return mPhase == PHASE_DRAWING; }
155 : bool InForward() { return mPhase == PHASE_FORWARD; }
156 : bool InTransaction() { return mPhase != PHASE_NONE; }
157 : #endif
158 : gfxContext* GetTarget() { return mTarget; }
159 0 : bool IsRetained() { return mWidget != nsnull; }
160 :
161 : #ifdef MOZ_LAYERS_HAVE_LOG
162 : virtual const char* Name() const { return "Basic"; }
163 : #endif // MOZ_LAYERS_HAVE_LOG
164 :
165 : // Clear the cached contents of this layer.
166 : void ClearCachedResources();
167 :
168 : void SetTransactionIncomplete() { mTransactionIncomplete = true; }
169 : bool IsTransactionIncomplete() { return mTransactionIncomplete; }
170 :
171 : already_AddRefed<gfxContext> PushGroupForLayer(gfxContext* aContext, Layer* aLayer,
172 : const nsIntRegion& aRegion,
173 : bool* aNeedsClipToVisibleRegion);
174 : already_AddRefed<gfxContext> PushGroupWithCachedSurface(gfxContext *aTarget,
175 : gfxASurface::gfxContentType aContent);
176 : void PopGroupToSourceWithCachedSurface(gfxContext *aTarget, gfxContext *aPushed);
177 :
178 : virtual bool IsCompositingCheap() { return false; }
179 : virtual bool HasShadowManagerInternal() const { return false; }
180 : bool HasShadowManager() const { return HasShadowManagerInternal(); }
181 :
182 : protected:
183 : #ifdef DEBUG
184 : enum TransactionPhase {
185 : PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD
186 : };
187 : TransactionPhase mPhase;
188 : #endif
189 :
190 : // Paints aLayer to mTarget.
191 : void PaintLayer(gfxContext* aTarget,
192 : Layer* aLayer,
193 : DrawThebesLayerCallback aCallback,
194 : void* aCallbackData,
195 : ReadbackProcessor* aReadback);
196 :
197 : // Clear the contents of a layer
198 : void ClearLayer(Layer* aLayer);
199 :
200 : bool EndTransactionInternal(DrawThebesLayerCallback aCallback,
201 : void* aCallbackData,
202 : EndTransactionFlags aFlags = END_DEFAULT);
203 :
204 : // Widget whose surface should be used as the basis for ThebesLayer
205 : // buffers.
206 : nsIWidget* mWidget;
207 : // The default context for BeginTransaction.
208 : nsRefPtr<gfxContext> mDefaultTarget;
209 : // The context to draw into.
210 : nsRefPtr<gfxContext> mTarget;
211 : // Image factory we use.
212 : nsRefPtr<ImageFactory> mFactory;
213 :
214 : // Cached surface for double buffering
215 : gfxCachedTempSurface mCachedSurface;
216 :
217 : BufferMode mDoubleBuffering;
218 : bool mUsingDefaultTarget;
219 : bool mCachedSurfaceInUse;
220 : bool mTransactionIncomplete;
221 : };
222 :
223 :
224 : class BasicShadowLayerManager : public BasicLayerManager,
225 : public ShadowLayerForwarder
226 : {
227 : typedef nsTArray<nsRefPtr<Layer> > LayerRefArray;
228 :
229 : public:
230 : BasicShadowLayerManager(nsIWidget* aWidget);
231 : virtual ~BasicShadowLayerManager();
232 :
233 : virtual ShadowLayerForwarder* AsShadowForwarder()
234 : {
235 : return this;
236 : }
237 : virtual ShadowLayerManager* AsShadowManager()
238 : {
239 : return this;
240 : }
241 :
242 : virtual void BeginTransactionWithTarget(gfxContext* aTarget);
243 : virtual bool EndEmptyTransaction();
244 : virtual void EndTransaction(DrawThebesLayerCallback aCallback,
245 : void* aCallbackData,
246 : EndTransactionFlags aFlags = END_DEFAULT);
247 :
248 : virtual void SetRoot(Layer* aLayer);
249 :
250 : virtual void Mutated(Layer* aLayer);
251 :
252 : virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
253 : virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
254 : virtual already_AddRefed<ImageLayer> CreateImageLayer();
255 : virtual already_AddRefed<CanvasLayer> CreateCanvasLayer();
256 : virtual already_AddRefed<ColorLayer> CreateColorLayer();
257 : virtual already_AddRefed<ShadowThebesLayer> CreateShadowThebesLayer();
258 : virtual already_AddRefed<ShadowContainerLayer> CreateShadowContainerLayer();
259 : virtual already_AddRefed<ShadowImageLayer> CreateShadowImageLayer();
260 : virtual already_AddRefed<ShadowColorLayer> CreateShadowColorLayer();
261 : virtual already_AddRefed<ShadowCanvasLayer> CreateShadowCanvasLayer();
262 :
263 : ShadowableLayer* Hold(Layer* aLayer);
264 :
265 : bool HasShadowManager() const { return ShadowLayerForwarder::HasShadowManager(); }
266 :
267 : virtual bool IsCompositingCheap();
268 : virtual bool HasShadowManagerInternal() const { return HasShadowManager(); }
269 :
270 : private:
271 : /**
272 : * Forward transaction results to the parent context.
273 : */
274 : void ForwardTransaction();
275 :
276 : LayerRefArray mKeepAlive;
277 : };
278 :
279 : }
280 : }
281 :
282 : #endif /* GFX_BASICLAYERS_H */
|