Bumping manifests a=b2g-bump
[gecko.git] / gfx / layers / Compositor.h
blob5a1b6b15d382468741d84eb7cdd455d9eee5bb21
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/. */
6 #ifndef MOZILLA_GFX_COMPOSITOR_H
7 #define MOZILLA_GFX_COMPOSITOR_H
9 #include "Units.h" // for ScreenPoint
10 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
11 #include "mozilla/RefPtr.h" // for TemporaryRef, RefCounted
12 #include "mozilla/gfx/2D.h" // for DrawTarget
13 #include "mozilla/gfx/Point.h" // for IntSize, Point
14 #include "mozilla/gfx/Rect.h" // for Rect, IntRect
15 #include "mozilla/gfx/Types.h" // for Float
16 #include "mozilla/layers/CompositorTypes.h" // for DiagnosticTypes, etc
17 #include "mozilla/layers/FenceUtils.h" // for FenceHandle
18 #include "mozilla/layers/LayersTypes.h" // for LayersBackend
19 #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
20 #include "nsRegion.h"
21 #include <vector>
22 #include "mozilla/WidgetUtils.h"
24 /**
25 * Different elements of a web pages are rendered into separate "layers" before
26 * they are flattened into the final image that is brought to the screen.
27 * See Layers.h for more informations about layers and why we use retained
28 * structures.
29 * Most of the documentation for layers is directly in the source code in the
30 * form of doc comments. An overview can also be found in the the wiki:
31 * https://wiki.mozilla.org/Gecko:Overview#Graphics
34 * # Main interfaces and abstractions
36 * - Layer, ShadowableLayer and LayerComposite
37 * (see Layers.h and ipc/ShadowLayers.h)
38 * - CompositableClient and CompositableHost
39 * (client/CompositableClient.h composite/CompositableHost.h)
40 * - TextureClient and TextureHost
41 * (client/TextureClient.h composite/TextureHost.h)
42 * - TextureSource
43 * (composite/TextureHost.h)
44 * - Forwarders
45 * (ipc/CompositableForwarder.h ipc/ShadowLayers.h)
46 * - Compositor
47 * (this file)
48 * - IPDL protocols
49 * (.ipdl files under the gfx/layers/ipc directory)
51 * The *Client and Shadowable* classes are always used on the content thread.
52 * Forwarders are always used on the content thread.
53 * The *Host and Shadow* classes are always used on the compositor thread.
54 * Compositors, TextureSource, and Effects are always used on the compositor
55 * thread.
56 * Most enums and constants are declared in LayersTypes.h and CompositorTypes.h.
59 * # Texture transfer
61 * Most layer classes own a Compositable plus some extra information like
62 * transforms and clip rects. They are platform independent.
63 * Compositable classes manipulate Texture objects and are reponsible for
64 * things like tiling, buffer rotation or double buffering. Compositables
65 * are also platform-independent. Examples of compositable classes are:
66 * - ImageClient
67 * - CanvasClient
68 * - ContentHost
69 * - etc.
70 * Texture classes (TextureClient and TextureHost) are thin abstractions over
71 * platform-dependent texture memory. They are maniplulated by compositables
72 * and don't know about buffer rotations and such. The purposes of TextureClient
73 * and TextureHost are to synchronize, serialize and deserialize texture data.
74 * TextureHosts provide access to TextureSources that are views on the
75 * Texture data providing the necessary api for Compositor backend to composite
76 * them.
78 * Compositable and Texture clients and hosts are created using factory methods.
79 * They should only be created by using their constructor in exceptional
80 * circumstances. The factory methods are located:
81 * TextureClient - CompositableClient::CreateTextureClient
82 * TextureHost - TextureHost::CreateTextureHost, which calls a
83 * platform-specific function, e.g., CreateTextureHostOGL
84 * CompositableClient - in the appropriate subclass, e.g.,
85 * CanvasClient::CreateCanvasClient
86 * CompositableHost - CompositableHost::Create
89 * # IPDL
91 * If off-main-thread compositing (OMTC) is enabled, compositing is performed
92 * in a dedicated thread. In some setups compositing happens in a dedicated
93 * process. Documentation may refer to either the compositor thread or the
94 * compositor process.
95 * See explanations in ShadowLayers.h.
98 * # Backend implementations
100 * Compositor backends like OpenGL or flavours of D3D live in their own directory
101 * under gfx/layers/. To add a new backend, implement at least the following
102 * interfaces:
103 * - Compositor (ex. CompositorOGL)
104 * - TextureHost (ex. SurfaceTextureHost)
105 * Depending on the type of data that needs to be serialized, you may need to
106 * add specific TextureClient implementations.
109 class nsIWidget;
110 struct nsIntSize;
111 class nsIntRegion;
113 namespace mozilla {
114 namespace gfx {
115 class Matrix;
116 class Matrix4x4;
117 class DrawTarget;
120 namespace layers {
122 struct Effect;
123 struct EffectChain;
124 class Image;
125 class ISurfaceAllocator;
126 class Layer;
127 class TextureSource;
128 class DataTextureSource;
129 class CompositingRenderTarget;
130 class PCompositorParent;
131 class LayerManagerComposite;
133 enum SurfaceInitMode
135 INIT_MODE_NONE,
136 INIT_MODE_CLEAR
140 * Common interface for compositor backends.
142 * Compositor provides a cross-platform interface to a set of operations for
143 * compositing quads. Compositor knows nothing about the layer tree. It must be
144 * told everything about each composited quad - contents, location, transform,
145 * opacity, etc.
147 * In theory it should be possible for different widgets to use the same
148 * compositor. In practice, we use one compositor per window.
150 * # Usage
152 * For an example of a user of Compositor, see LayerManagerComposite.
154 * Initialization: create a Compositor object, call Initialize().
156 * Destruction: destroy any resources associated with the compositor, call
157 * Destroy(), delete the Compositor object.
159 * Composition:
160 * call BeginFrame,
161 * for each quad to be composited:
162 * call MakeCurrent if necessary (not necessary if no other context has been
163 * made current),
164 * take care of any texture upload required to composite the quad, this step
165 * is backend-dependent,
166 * construct an EffectChain for the quad,
167 * call DrawQuad,
168 * call EndFrame.
169 * If the compositor is usually used for compositing but compositing is
170 * temporarily done without the compositor, call EndFrameForExternalComposition
171 * after compositing each frame so the compositor can remain internally
172 * consistent.
174 * By default, the compositor will render to the screen, to render to a target,
175 * call SetTargetContext or SetRenderTarget, the latter with a target created
176 * by CreateRenderTarget or CreateRenderTargetFromSource.
178 * The target and viewport methods can be called before any DrawQuad call and
179 * affect any subsequent DrawQuad calls.
181 class Compositor
183 protected:
184 virtual ~Compositor() {}
186 public:
187 NS_INLINE_DECL_REFCOUNTING(Compositor)
189 explicit Compositor(PCompositorParent* aParent = nullptr)
190 : mCompositorID(0)
191 , mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
192 , mParent(aParent)
193 , mScreenRotation(ROTATION_0)
197 virtual TemporaryRef<DataTextureSource> CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) = 0;
198 virtual bool Initialize() = 0;
199 virtual void Destroy() = 0;
202 * Return true if the effect type is supported.
204 * By default Compositor implementations should support all effects but in
205 * some rare cases it is not possible to support an effect efficiently.
206 * This is the case for BasicCompositor with EffectYCbCr.
208 virtual bool SupportsEffect(EffectTypes aEffect) { return true; }
211 * Request a texture host identifier that may be used for creating textures
212 * across process or thread boundaries that are compatible with this
213 * compositor.
215 virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() = 0;
218 * Properties of the compositor.
220 virtual bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) = 0;
221 virtual int32_t GetMaxTextureSize() const = 0;
224 * Set the target for rendering. Results will have been written to aTarget by
225 * the time that EndFrame returns.
227 * If this method is not used, or we pass in nullptr, we target the compositor's
228 * usual swap chain and render to the screen.
230 void SetTargetContext(gfx::DrawTarget* aTarget, const nsIntRect& aRect)
232 mTarget = aTarget;
233 mTargetBounds = aRect;
235 void ClearTargetContext()
237 mTarget = nullptr;
240 typedef uint32_t MakeCurrentFlags;
241 static const MakeCurrentFlags ForceMakeCurrent = 0x1;
243 * Make this compositor's rendering context the current context for the
244 * underlying graphics API. This may be a global operation, depending on the
245 * API. Our context will remain the current one until someone else changes it.
247 * Clients of the compositor should call this at the start of the compositing
248 * process, it might be required by texture uploads etc.
250 * If aFlags == ForceMakeCurrent then we will (re-)set our context on the
251 * underlying API even if it is already the current context.
253 virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) = 0;
256 * Creates a Surface that can be used as a rendering target by this
257 * compositor.
259 virtual TemporaryRef<CompositingRenderTarget>
260 CreateRenderTarget(const gfx::IntRect& aRect, SurfaceInitMode aInit) = 0;
263 * Creates a Surface that can be used as a rendering target by this
264 * compositor, and initializes the surface by copying from aSource.
265 * If aSource is null, then the current screen buffer is used as source.
267 * aSourcePoint specifies the point in aSource to copy data from.
269 virtual TemporaryRef<CompositingRenderTarget>
270 CreateRenderTargetFromSource(const gfx::IntRect& aRect,
271 const CompositingRenderTarget* aSource,
272 const gfx::IntPoint& aSourcePoint) = 0;
275 * Sets the given surface as the target for subsequent calls to DrawQuad.
276 * Passing null as aSurface sets the screen as the target.
278 virtual void SetRenderTarget(CompositingRenderTarget* aSurface) = 0;
281 * Returns the current target for rendering. Will return null if we are
282 * rendering to the screen.
284 virtual CompositingRenderTarget* GetCurrentRenderTarget() const = 0;
287 * Mostly the compositor will pull the size from a widget and this method will
288 * be ignored, but compositor implementations are free to use it if they like.
290 virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) = 0;
293 * Declare an offset to use when rendering layers. This will be ignored when
294 * rendering to a target instead of the screen.
296 virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) = 0;
299 * Tell the compositor to draw a quad. What to do draw and how it is
300 * drawn is specified by aEffectChain. aRect is the quad to draw, in user space.
301 * aTransform transforms from user space to screen space. If texture coords are
302 * required, these will be in the primary effect in the effect chain.
304 virtual void DrawQuad(const gfx::Rect& aRect, const gfx::Rect& aClipRect,
305 const EffectChain& aEffectChain,
306 gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform) = 0;
309 * Clear aRect on current render target.
311 virtual void ClearRect(const gfx::Rect& aRect) = 0;
314 * Start a new frame.
316 * aInvalidRect is the invalid region of the screen; it can be ignored for
317 * compositors where the performance for compositing the entire window is
318 * sufficient.
320 * aClipRectIn is the clip rect for the window in window space (optional).
321 * aTransform is the transform from user space to window space.
322 * aRenderBounds bounding rect for rendering, in user space.
324 * If aClipRectIn is null, this method sets *aClipRectOut to the clip rect
325 * actually used for rendering (if aClipRectIn is non-null, we will use that
326 * for the clip rect).
328 * If aRenderBoundsOut is non-null, it will be set to the render bounds
329 * actually used by the compositor in window space. If aRenderBoundsOut
330 * is returned empty, composition should be aborted.
332 virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
333 const gfx::Rect* aClipRectIn,
334 const gfx::Rect& aRenderBounds,
335 gfx::Rect* aClipRectOut = nullptr,
336 gfx::Rect* aRenderBoundsOut = nullptr) = 0;
339 * Flush the current frame to the screen and tidy up.
341 virtual void EndFrame() = 0;
343 virtual void SetFBAcquireFence(Layer* aLayer) {}
345 virtual FenceHandle GetReleaseFence()
347 return FenceHandle();
351 * Post-rendering stuff if the rendering is done outside of this Compositor
352 * e.g., by Composer2D.
353 * aTransform is the transform from user space to window space.
355 virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) = 0;
358 * Setup the viewport and projection matrix for rendering to a target of the
359 * given dimensions. The size and transform here will override those set in
360 * BeginFrame. BeginFrame sets a size and transform for the default render
361 * target, usually the screen. Calling this method prepares the compositor to
362 * render using a different viewport (that is, size and transform), usually
363 * associated with a new render target.
365 virtual void PrepareViewport(const gfx::IntSize& aSize) = 0;
368 * Whether textures created by this compositor can receive partial updates.
370 virtual bool SupportsPartialTextureUpdate() = 0;
372 void SetDiagnosticTypes(DiagnosticTypes aDiagnostics)
374 mDiagnosticTypes = aDiagnostics;
377 DiagnosticTypes GetDiagnosticTypes() const
379 return mDiagnosticTypes;
382 void DrawDiagnostics(DiagnosticFlags aFlags,
383 const gfx::Rect& visibleRect,
384 const gfx::Rect& aClipRect,
385 const gfx::Matrix4x4& transform,
386 uint32_t aFlashCounter = DIAGNOSTIC_FLASH_COUNTER_MAX);
388 void DrawDiagnostics(DiagnosticFlags aFlags,
389 const nsIntRegion& visibleRegion,
390 const gfx::Rect& aClipRect,
391 const gfx::Matrix4x4& transform,
392 uint32_t aFlashCounter = DIAGNOSTIC_FLASH_COUNTER_MAX);
394 #ifdef MOZ_DUMP_PAINTING
395 virtual const char* Name() const = 0;
396 #endif // MOZ_DUMP_PAINTING
398 virtual LayersBackend GetBackendType() const = 0;
401 * Each Compositor has a unique ID.
402 * This ID is used to keep references to each Compositor in a map accessed
403 * from the compositor thread only, so that async compositables can find
404 * the right compositor parent and schedule compositing even if the compositor
405 * changed.
407 uint32_t GetCompositorID() const
409 return mCompositorID;
411 void SetCompositorID(uint32_t aID)
413 MOZ_ASSERT(mCompositorID == 0, "The compositor ID must be set only once.");
414 mCompositorID = aID;
418 * Notify the compositor that composition is being paused. This allows the
419 * compositor to temporarily release any resources.
420 * Between calling Pause and Resume, compositing may fail.
422 virtual void Pause() {}
424 * Notify the compositor that composition is being resumed. The compositor
425 * regain any resources it requires for compositing.
426 * Returns true if succeeded.
428 virtual bool Resume() { return true; }
431 * Call before rendering begins to ensure the compositor is ready to
432 * composite. Returns false if rendering should be aborted.
434 virtual bool Ready() { return true; }
436 // XXX I expect we will want to move mWidget into this class and implement
437 // these methods properly.
438 virtual nsIWidget* GetWidget() const { return nullptr; }
441 * Debug-build assertion that can be called to ensure code is running on the
442 * compositor thread.
444 static void AssertOnCompositorThread();
447 * We enforce that there can only be one Compositor backend type off the main
448 * thread at the same time. The backend type in use can be checked with this
449 * static method. We need this for creating texture clients/hosts etc. when we
450 * don't have a reference to a Compositor.
452 * This can only be used from the compositor thread!
454 static LayersBackend GetBackend();
456 size_t GetFillRatio() {
457 float fillRatio = 0;
458 if (mPixelsFilled > 0 && mPixelsPerFrame > 0) {
459 fillRatio = 100.0f * float(mPixelsFilled) / float(mPixelsPerFrame);
460 if (fillRatio > 999.0f) {
461 fillRatio = 999.0f;
464 return fillRatio;
467 ScreenRotation GetScreenRotation() const {
468 return mScreenRotation;
471 void SetScreenRotation(ScreenRotation aRotation) {
472 mScreenRotation = aRotation;
475 protected:
476 void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
477 const gfx::Rect& aVisibleRect,
478 const gfx::Rect& aClipRect,
479 const gfx::Matrix4x4& transform,
480 uint32_t aFlashCounter);
482 bool ShouldDrawDiagnostics(DiagnosticFlags);
485 * Set the global Compositor backend, checking that one isn't already set.
487 static void SetBackend(LayersBackend backend);
489 uint32_t mCompositorID;
490 DiagnosticTypes mDiagnosticTypes;
491 PCompositorParent* mParent;
494 * We keep track of the total number of pixels filled as we composite the
495 * current frame. This value is an approximation and is not accurate,
496 * especially in the presence of transforms.
498 size_t mPixelsPerFrame;
499 size_t mPixelsFilled;
501 ScreenRotation mScreenRotation;
503 virtual gfx::IntSize GetWidgetSize() const = 0;
505 RefPtr<gfx::DrawTarget> mTarget;
506 nsIntRect mTargetBounds;
508 private:
509 static LayersBackend sBackend;
513 // Returns the number of rects. (Up to 4)
514 typedef gfx::Rect decomposedRectArrayT[4];
515 size_t DecomposeIntoNoRepeatRects(const gfx::Rect& aRect,
516 const gfx::Rect& aTexCoordRect,
517 decomposedRectArrayT* aLayerRects,
518 decomposedRectArrayT* aTextureRects);
520 } // namespace layers
521 } // namespace mozilla
523 #endif /* MOZILLA_GFX_COMPOSITOR_H */