|
1 /* -*- Mode: C++; tab-width: 20; 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_LayerManagerComposite_H |
|
7 #define GFX_LayerManagerComposite_H |
|
8 |
|
9 #include <stdint.h> // for int32_t, uint32_t |
|
10 #include "GLDefs.h" // for GLenum |
|
11 #include "Layers.h" |
|
12 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc |
|
13 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE |
|
14 #include "mozilla/RefPtr.h" // for RefPtr, TemporaryRef |
|
15 #include "mozilla/gfx/2D.h" |
|
16 #include "mozilla/gfx/Point.h" // for IntSize |
|
17 #include "mozilla/gfx/Rect.h" // for Rect |
|
18 #include "mozilla/gfx/Types.h" // for SurfaceFormat |
|
19 #include "mozilla/layers/CompositorTypes.h" |
|
20 #include "mozilla/layers/LayersTypes.h" // for LayersBackend, etc |
|
21 #include "mozilla/RefPtr.h" |
|
22 #include "nsAString.h" |
|
23 #include "nsAutoPtr.h" // for nsRefPtr |
|
24 #include "nsCOMPtr.h" // for already_AddRefed |
|
25 #include "nsDebug.h" // for NS_ASSERTION |
|
26 #include "nsISupportsImpl.h" // for Layer::AddRef, etc |
|
27 #include "nsRect.h" // for nsIntRect |
|
28 #include "nsRegion.h" // for nsIntRegion |
|
29 #include "nscore.h" // for nsAString, etc |
|
30 #include "LayerTreeInvalidation.h" |
|
31 |
|
32 class gfxContext; |
|
33 struct nsIntPoint; |
|
34 struct nsIntSize; |
|
35 |
|
36 #ifdef XP_WIN |
|
37 #include <windows.h> |
|
38 #endif |
|
39 |
|
40 namespace mozilla { |
|
41 namespace gfx { |
|
42 class DrawTarget; |
|
43 } |
|
44 |
|
45 namespace gl { |
|
46 class GLContext; |
|
47 class TextureImage; |
|
48 } |
|
49 |
|
50 namespace layers { |
|
51 |
|
52 class CanvasLayerComposite; |
|
53 class ColorLayerComposite; |
|
54 class CompositableHost; |
|
55 class Compositor; |
|
56 class ContainerLayerComposite; |
|
57 class EffectChain; |
|
58 class ImageLayer; |
|
59 class ImageLayerComposite; |
|
60 class LayerComposite; |
|
61 class RefLayerComposite; |
|
62 class SurfaceDescriptor; |
|
63 class ThebesLayerComposite; |
|
64 class TiledLayerComposer; |
|
65 class TextRenderer; |
|
66 struct FPSState; |
|
67 |
|
68 class LayerManagerComposite : public LayerManager |
|
69 { |
|
70 typedef mozilla::gfx::DrawTarget DrawTarget; |
|
71 typedef mozilla::gfx::IntSize IntSize; |
|
72 typedef mozilla::gfx::SurfaceFormat SurfaceFormat; |
|
73 |
|
74 public: |
|
75 LayerManagerComposite(Compositor* aCompositor); |
|
76 ~LayerManagerComposite(); |
|
77 |
|
78 virtual void Destroy() MOZ_OVERRIDE; |
|
79 |
|
80 /** |
|
81 * return True if initialization was succesful, false when it was not. |
|
82 */ |
|
83 bool Initialize(); |
|
84 |
|
85 /** |
|
86 * Sets the clipping region for this layer manager. This is important on |
|
87 * windows because using OGL we no longer have GDI's native clipping. Therefor |
|
88 * widget must tell us what part of the screen is being invalidated, |
|
89 * and we should clip to this. |
|
90 * |
|
91 * \param aClippingRegion Region to clip to. Setting an empty region |
|
92 * will disable clipping. |
|
93 */ |
|
94 void SetClippingRegion(const nsIntRegion& aClippingRegion) |
|
95 { |
|
96 mClippingRegion = aClippingRegion; |
|
97 } |
|
98 |
|
99 /** |
|
100 * LayerManager implementation. |
|
101 */ |
|
102 virtual LayerManagerComposite* AsLayerManagerComposite() MOZ_OVERRIDE |
|
103 { |
|
104 return this; |
|
105 } |
|
106 |
|
107 void UpdateRenderBounds(const nsIntRect& aRect); |
|
108 |
|
109 virtual void BeginTransaction() MOZ_OVERRIDE; |
|
110 virtual void BeginTransactionWithTarget(gfxContext* aTarget) MOZ_OVERRIDE |
|
111 { |
|
112 MOZ_CRASH("Use BeginTransactionWithDrawTarget"); |
|
113 } |
|
114 void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget); |
|
115 |
|
116 virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) MOZ_OVERRIDE; |
|
117 virtual void EndTransaction(DrawThebesLayerCallback aCallback, |
|
118 void* aCallbackData, |
|
119 EndTransactionFlags aFlags = END_DEFAULT) MOZ_OVERRIDE; |
|
120 |
|
121 virtual void SetRoot(Layer* aLayer) MOZ_OVERRIDE { mRoot = aLayer; } |
|
122 |
|
123 // XXX[nrc]: never called, we should move this logic to ClientLayerManager |
|
124 // (bug 946926). |
|
125 virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) MOZ_OVERRIDE; |
|
126 |
|
127 virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE |
|
128 { |
|
129 MOZ_CRASH("Call on compositor, not LayerManagerComposite"); |
|
130 } |
|
131 |
|
132 virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE; |
|
133 |
|
134 virtual already_AddRefed<ThebesLayer> CreateThebesLayer() MOZ_OVERRIDE; |
|
135 virtual already_AddRefed<ContainerLayer> CreateContainerLayer() MOZ_OVERRIDE; |
|
136 virtual already_AddRefed<ImageLayer> CreateImageLayer() MOZ_OVERRIDE; |
|
137 virtual already_AddRefed<ColorLayer> CreateColorLayer() MOZ_OVERRIDE; |
|
138 virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() MOZ_OVERRIDE; |
|
139 already_AddRefed<ThebesLayerComposite> CreateThebesLayerComposite(); |
|
140 already_AddRefed<ContainerLayerComposite> CreateContainerLayerComposite(); |
|
141 already_AddRefed<ImageLayerComposite> CreateImageLayerComposite(); |
|
142 already_AddRefed<ColorLayerComposite> CreateColorLayerComposite(); |
|
143 already_AddRefed<CanvasLayerComposite> CreateCanvasLayerComposite(); |
|
144 already_AddRefed<RefLayerComposite> CreateRefLayerComposite(); |
|
145 |
|
146 virtual LayersBackend GetBackendType() MOZ_OVERRIDE |
|
147 { |
|
148 MOZ_CRASH("Shouldn't be called for composited layer manager"); |
|
149 } |
|
150 virtual void GetBackendName(nsAString& name) MOZ_OVERRIDE |
|
151 { |
|
152 MOZ_CRASH("Shouldn't be called for composited layer manager"); |
|
153 } |
|
154 |
|
155 virtual TemporaryRef<DrawTarget> |
|
156 CreateOptimalMaskDrawTarget(const IntSize &aSize) MOZ_OVERRIDE; |
|
157 |
|
158 virtual const char* Name() const MOZ_OVERRIDE { return ""; } |
|
159 |
|
160 enum WorldTransforPolicy { |
|
161 ApplyWorldTransform, |
|
162 DontApplyWorldTransform |
|
163 }; |
|
164 |
|
165 /** |
|
166 * Setup World transform matrix. |
|
167 * Transform will be ignored if it is not PreservesAxisAlignedRectangles |
|
168 * or has non integer scale |
|
169 */ |
|
170 void SetWorldTransform(const gfx::Matrix& aMatrix); |
|
171 gfx::Matrix& GetWorldTransform(void); |
|
172 |
|
173 /** |
|
174 * RAII helper class to add a mask effect with the compositable from aMaskLayer |
|
175 * to the EffectChain aEffect and notify the compositable when we are done. |
|
176 */ |
|
177 class AutoAddMaskEffect |
|
178 { |
|
179 public: |
|
180 AutoAddMaskEffect(Layer* aMaskLayer, |
|
181 EffectChain& aEffect, |
|
182 bool aIs3D = false); |
|
183 ~AutoAddMaskEffect(); |
|
184 |
|
185 private: |
|
186 CompositableHost* mCompositable; |
|
187 }; |
|
188 |
|
189 /** |
|
190 * Creates a DrawTarget which is optimized for inter-operating with this |
|
191 * layermanager. |
|
192 */ |
|
193 virtual TemporaryRef<mozilla::gfx::DrawTarget> |
|
194 CreateDrawTarget(const mozilla::gfx::IntSize& aSize, |
|
195 mozilla::gfx::SurfaceFormat aFormat) MOZ_OVERRIDE; |
|
196 |
|
197 /** |
|
198 * Calculates the 'completeness' of the rendering that intersected with the |
|
199 * screen on the last render. This is only useful when progressive tile |
|
200 * drawing is enabled, otherwise this will always return 1.0. |
|
201 * This function's expense scales with the size of the layer tree and the |
|
202 * complexity of individual layers' valid regions. |
|
203 */ |
|
204 float ComputeRenderIntegrity(); |
|
205 |
|
206 /** |
|
207 * returns true if PlatformAllocBuffer will return a buffer that supports |
|
208 * direct texturing |
|
209 */ |
|
210 static bool SupportsDirectTexturing(); |
|
211 |
|
212 static void PlatformSyncBeforeReplyUpdate(); |
|
213 |
|
214 void AddInvalidRegion(const nsIntRegion& aRegion) |
|
215 { |
|
216 mInvalidRegion.Or(mInvalidRegion, aRegion); |
|
217 } |
|
218 |
|
219 Compositor* GetCompositor() const |
|
220 { |
|
221 return mCompositor; |
|
222 } |
|
223 |
|
224 /** |
|
225 * LayerManagerComposite provides sophisticated debug overlays |
|
226 * that can request a next frame. |
|
227 */ |
|
228 bool DebugOverlayWantsNextFrame() { return mDebugOverlayWantsNextFrame; } |
|
229 void SetDebugOverlayWantsNextFrame(bool aVal) |
|
230 { mDebugOverlayWantsNextFrame = aVal; } |
|
231 |
|
232 void NotifyShadowTreeTransaction(); |
|
233 |
|
234 TextRenderer* GetTextRenderer() { return mTextRenderer; } |
|
235 |
|
236 private: |
|
237 /** Region we're clipping our current drawing to. */ |
|
238 nsIntRegion mClippingRegion; |
|
239 nsIntRect mRenderBounds; |
|
240 |
|
241 /** Current root layer. */ |
|
242 LayerComposite* RootLayer() const; |
|
243 |
|
244 /** |
|
245 * Recursive helper method for use by ComputeRenderIntegrity. Subtracts |
|
246 * any incomplete rendering on aLayer from aScreenRegion. Any low-precision |
|
247 * rendering is included in aLowPrecisionScreenRegion. aTransform is the |
|
248 * accumulated transform of intermediate surfaces beneath aLayer. |
|
249 */ |
|
250 static void ComputeRenderIntegrityInternal(Layer* aLayer, |
|
251 nsIntRegion& aScreenRegion, |
|
252 nsIntRegion& aLowPrecisionScreenRegion, |
|
253 const gfx3DMatrix& aTransform); |
|
254 |
|
255 /** |
|
256 * Render the current layer tree to the active target. |
|
257 */ |
|
258 void Render(); |
|
259 |
|
260 /** |
|
261 * Render debug overlays such as the FPS/FrameCounter above the frame. |
|
262 */ |
|
263 void RenderDebugOverlay(const gfx::Rect& aBounds); |
|
264 |
|
265 void WorldTransformRect(nsIntRect& aRect); |
|
266 |
|
267 RefPtr<Compositor> mCompositor; |
|
268 nsAutoPtr<LayerProperties> mClonedLayerTreeProperties; |
|
269 |
|
270 /** |
|
271 * Context target, nullptr when drawing directly to our swap chain. |
|
272 */ |
|
273 RefPtr<gfx::DrawTarget> mTarget; |
|
274 |
|
275 gfx::Matrix mWorldMatrix; |
|
276 nsIntRegion mInvalidRegion; |
|
277 nsAutoPtr<FPSState> mFPS; |
|
278 |
|
279 bool mInTransaction; |
|
280 bool mIsCompositorReady; |
|
281 bool mDebugOverlayWantsNextFrame; |
|
282 |
|
283 RefPtr<TextRenderer> mTextRenderer; |
|
284 bool mGeometryChanged; |
|
285 }; |
|
286 |
|
287 /** |
|
288 * Composite layers are for use with OMTC on the compositor thread only. There |
|
289 * must be corresponding Basic layers on the content thread. For composite |
|
290 * layers, the layer manager only maintains the layer tree, all rendering is |
|
291 * done by a Compositor (see Compositor.h). As such, composite layers are |
|
292 * platform-independent and can be used on any platform for which there is a |
|
293 * Compositor implementation. |
|
294 * |
|
295 * The composite layer tree reflects exactly the basic layer tree. To |
|
296 * composite to screen, the layer manager walks the layer tree calling render |
|
297 * methods which in turn call into their CompositableHosts' Composite methods. |
|
298 * These call Compositor::DrawQuad to do the rendering. |
|
299 * |
|
300 * Mostly, layers are updated during the layers transaction. This is done from |
|
301 * CompositableClient to CompositableHost without interacting with the layer. |
|
302 * |
|
303 * A reference to the Compositor is stored in LayerManagerComposite. |
|
304 */ |
|
305 class LayerComposite |
|
306 { |
|
307 public: |
|
308 LayerComposite(LayerManagerComposite* aManager); |
|
309 |
|
310 virtual ~LayerComposite(); |
|
311 |
|
312 virtual LayerComposite* GetFirstChildComposite() |
|
313 { |
|
314 return nullptr; |
|
315 } |
|
316 |
|
317 /* Do NOT call this from the generic LayerComposite destructor. Only from the |
|
318 * concrete class destructor |
|
319 */ |
|
320 virtual void Destroy(); |
|
321 |
|
322 virtual Layer* GetLayer() = 0; |
|
323 |
|
324 virtual void RenderLayer(const nsIntRect& aClipRect) = 0; |
|
325 |
|
326 virtual bool SetCompositableHost(CompositableHost*) |
|
327 { |
|
328 // We must handle this gracefully, see bug 967824 |
|
329 NS_WARNING("called SetCompositableHost for a layer type not accepting a compositable"); |
|
330 return false; |
|
331 } |
|
332 virtual CompositableHost* GetCompositableHost() = 0; |
|
333 |
|
334 virtual void CleanupResources() = 0; |
|
335 |
|
336 virtual TiledLayerComposer* GetTiledLayerComposer() { return nullptr; } |
|
337 |
|
338 |
|
339 virtual void DestroyFrontBuffer() { } |
|
340 |
|
341 /** |
|
342 * The following methods are |
|
343 * |
|
344 * CONSTRUCTION PHASE ONLY |
|
345 * |
|
346 * They are analogous to the Layer interface. |
|
347 */ |
|
348 void SetShadowVisibleRegion(const nsIntRegion& aRegion) |
|
349 { |
|
350 mShadowVisibleRegion = aRegion; |
|
351 } |
|
352 |
|
353 void SetShadowOpacity(float aOpacity) |
|
354 { |
|
355 mShadowOpacity = aOpacity; |
|
356 } |
|
357 |
|
358 void SetShadowClipRect(const nsIntRect* aRect) |
|
359 { |
|
360 mUseShadowClipRect = aRect != nullptr; |
|
361 if (aRect) { |
|
362 mShadowClipRect = *aRect; |
|
363 } |
|
364 } |
|
365 |
|
366 void SetShadowTransform(const gfx::Matrix4x4& aMatrix) |
|
367 { |
|
368 mShadowTransform = aMatrix; |
|
369 } |
|
370 void SetShadowTransformSetByAnimation(bool aSetByAnimation) |
|
371 { |
|
372 mShadowTransformSetByAnimation = aSetByAnimation; |
|
373 } |
|
374 |
|
375 void SetLayerComposited(bool value) |
|
376 { |
|
377 mLayerComposited = value; |
|
378 } |
|
379 |
|
380 void SetClearRect(const nsIntRect& aRect) |
|
381 { |
|
382 mClearRect = aRect; |
|
383 } |
|
384 |
|
385 // These getters can be used anytime. |
|
386 float GetShadowOpacity() { return mShadowOpacity; } |
|
387 const nsIntRect* GetShadowClipRect() { return mUseShadowClipRect ? &mShadowClipRect : nullptr; } |
|
388 const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; } |
|
389 const gfx::Matrix4x4& GetShadowTransform() { return mShadowTransform; } |
|
390 bool GetShadowTransformSetByAnimation() { return mShadowTransformSetByAnimation; } |
|
391 bool HasLayerBeenComposited() { return mLayerComposited; } |
|
392 nsIntRect GetClearRect() { return mClearRect; } |
|
393 |
|
394 protected: |
|
395 gfx::Matrix4x4 mShadowTransform; |
|
396 nsIntRegion mShadowVisibleRegion; |
|
397 nsIntRect mShadowClipRect; |
|
398 LayerManagerComposite* mCompositeManager; |
|
399 RefPtr<Compositor> mCompositor; |
|
400 float mShadowOpacity; |
|
401 bool mUseShadowClipRect; |
|
402 bool mShadowTransformSetByAnimation; |
|
403 bool mDestroyed; |
|
404 bool mLayerComposited; |
|
405 nsIntRect mClearRect; |
|
406 }; |
|
407 |
|
408 |
|
409 } /* layers */ |
|
410 } /* mozilla */ |
|
411 |
|
412 #endif /* GFX_LayerManagerComposite_H */ |