Bumping manifests a=b2g-bump
[gecko.git] / gfx / layers / Compositor.h
blob32ded4dcfd060861efc45f7ee2880e78920c95ad
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/Point.h" // for IntSize, Point
13 #include "mozilla/gfx/Rect.h" // for Rect, IntRect
14 #include "mozilla/gfx/Types.h" // for Float
15 #include "mozilla/layers/CompositorTypes.h" // for DiagnosticTypes, etc
16 #include "mozilla/layers/FenceUtils.h" // for FenceHandle
17 #include "mozilla/layers/LayersTypes.h" // for LayersBackend
18 #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
19 #include "nsRegion.h"
20 #include <vector>
21 #include "mozilla/WidgetUtils.h"
23 /**
24 * Different elements of a web pages are rendered into separate "layers" before
25 * they are flattened into the final image that is brought to the screen.
26 * See Layers.h for more informations about layers and why we use retained
27 * structures.
28 * Most of the documentation for layers is directly in the source code in the
29 * form of doc comments. An overview can also be found in the the wiki:
30 * https://wiki.mozilla.org/Gecko:Overview#Graphics
33 * # Main interfaces and abstractions
35 * - Layer, ShadowableLayer and LayerComposite
36 * (see Layers.h and ipc/ShadowLayers.h)
37 * - CompositableClient and CompositableHost
38 * (client/CompositableClient.h composite/CompositableHost.h)
39 * - TextureClient and TextureHost
40 * (client/TextureClient.h composite/TextureHost.h)
41 * - TextureSource
42 * (composite/TextureHost.h)
43 * - Forwarders
44 * (ipc/CompositableForwarder.h ipc/ShadowLayers.h)
45 * - Compositor
46 * (this file)
47 * - IPDL protocols
48 * (.ipdl files under the gfx/layers/ipc directory)
50 * The *Client and Shadowable* classes are always used on the content thread.
51 * Forwarders are always used on the content thread.
52 * The *Host and Shadow* classes are always used on the compositor thread.
53 * Compositors, TextureSource, and Effects are always used on the compositor
54 * thread.
55 * Most enums and constants are declared in LayersTypes.h and CompositorTypes.h.
58 * # Texture transfer
60 * Most layer classes own a Compositable plus some extra information like
61 * transforms and clip rects. They are platform independent.
62 * Compositable classes manipulate Texture objects and are reponsible for
63 * things like tiling, buffer rotation or double buffering. Compositables
64 * are also platform-independent. Examples of compositable classes are:
65 * - ImageClient
66 * - CanvasClient
67 * - ContentHost
68 * - etc.
69 * Texture classes (TextureClient and TextureHost) are thin abstractions over
70 * platform-dependent texture memory. They are maniplulated by compositables
71 * and don't know about buffer rotations and such. The purposes of TextureClient
72 * and TextureHost are to synchronize, serialize and deserialize texture data.
73 * TextureHosts provide access to TextureSources that are views on the
74 * Texture data providing the necessary api for Compositor backend to composite
75 * them.
77 * Compositable and Texture clients and hosts are created using factory methods.
78 * They should only be created by using their constructor in exceptional
79 * circumstances. The factory methods are located:
80 * TextureClient - CompositableClient::CreateTextureClient
81 * TextureHost - TextureHost::CreateTextureHost, which calls a
82 * platform-specific function, e.g., CreateTextureHostOGL
83 * CompositableClient - in the appropriate subclass, e.g.,
84 * CanvasClient::CreateCanvasClient
85 * CompositableHost - CompositableHost::Create
88 * # IPDL
90 * If off-main-thread compositing (OMTC) is enabled, compositing is performed
91 * in a dedicated thread. In some setups compositing happens in a dedicated
92 * process. Documentation may refer to either the compositor thread or the
93 * compositor process.
94 * See explanations in ShadowLayers.h.
97 * # Backend implementations
99 * Compositor backends like OpenGL or flavours of D3D live in their own directory
100 * under gfx/layers/. To add a new backend, implement at least the following
101 * interfaces:
102 * - Compositor (ex. CompositorOGL)
103 * - TextureHost (ex. SurfaceTextureHost)
104 * Depending on the type of data that needs to be serialized, you may need to
105 * add specific TextureClient implementations.
108 class nsIWidget;
109 struct nsIntSize;
110 class nsIntRegion;
112 namespace mozilla {
113 namespace gfx {
114 class Matrix;
115 class Matrix4x4;
116 class DrawTarget;
119 namespace layers {
121 struct Effect;
122 struct EffectChain;
123 class Image;
124 class ISurfaceAllocator;
125 class Layer;
126 class NewTextureSource;
127 class DataTextureSource;
128 class CompositingRenderTarget;
129 class PCompositorParent;
130 class LayerManagerComposite;
132 enum SurfaceInitMode
134 INIT_MODE_NONE,
135 INIT_MODE_CLEAR
139 * A base class for a platform-dependent helper for use by TextureHost.
141 class CompositorBackendSpecificData
143 NS_INLINE_DECL_REFCOUNTING(CompositorBackendSpecificData)
145 protected:
146 virtual ~CompositorBackendSpecificData() {}
150 * Common interface for compositor backends.
152 * Compositor provides a cross-platform interface to a set of operations for
153 * compositing quads. Compositor knows nothing about the layer tree. It must be
154 * told everything about each composited quad - contents, location, transform,
155 * opacity, etc.
157 * In theory it should be possible for different widgets to use the same
158 * compositor. In practice, we use one compositor per window.
160 * # Usage
162 * For an example of a user of Compositor, see LayerManagerComposite.
164 * Initialization: create a Compositor object, call Initialize().
166 * Destruction: destroy any resources associated with the compositor, call
167 * Destroy(), delete the Compositor object.
169 * Composition:
170 * call BeginFrame,
171 * for each quad to be composited:
172 * call MakeCurrent if necessary (not necessary if no other context has been
173 * made current),
174 * take care of any texture upload required to composite the quad, this step
175 * is backend-dependent,
176 * construct an EffectChain for the quad,
177 * call DrawQuad,
178 * call EndFrame.
179 * If the user has to stop compositing at any point before EndFrame, call
180 * AbortFrame.
181 * If the compositor is usually used for compositing but compositing is
182 * temporarily done without the compositor, call EndFrameForExternalComposition
183 * after compositing each frame so the compositor can remain internally
184 * consistent.
186 * By default, the compositor will render to the screen, to render to a target,
187 * call SetTargetContext or SetRenderTarget, the latter with a target created
188 * by CreateRenderTarget or CreateRenderTargetFromSource.
190 * The target and viewport methods can be called before any DrawQuad call and
191 * affect any subsequent DrawQuad calls.
193 class Compositor
195 protected:
196 virtual ~Compositor() {}
198 public:
199 NS_INLINE_DECL_REFCOUNTING(Compositor)
201 explicit Compositor(PCompositorParent* aParent = nullptr)
202 : mCompositorID(0)
203 , mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
204 , mParent(aParent)
205 , mScreenRotation(ROTATION_0)
209 virtual TemporaryRef<DataTextureSource> CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) = 0;
210 virtual bool Initialize() = 0;
211 virtual void Destroy() = 0;
214 * Return true if the effect type is supported.
216 * By default Compositor implementations should support all effects but in
217 * some rare cases it is not possible to support an effect efficiently.
218 * This is the case for BasicCompositor with EffectYCbCr.
220 virtual bool SupportsEffect(EffectTypes aEffect) { return true; }
223 * Request a texture host identifier that may be used for creating textures
224 * across process or thread boundaries that are compatible with this
225 * compositor.
227 virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() = 0;
230 * Properties of the compositor.
232 virtual bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) = 0;
233 virtual int32_t GetMaxTextureSize() const = 0;
236 * Set the target for rendering. Results will have been written to aTarget by
237 * the time that EndFrame returns.
239 * If this method is not used, or we pass in nullptr, we target the compositor's
240 * usual swap chain and render to the screen.
242 void SetTargetContext(gfx::DrawTarget* aTarget, const nsIntRect& aRect)
244 mTarget = aTarget;
245 mTargetBounds = aRect;
247 void ClearTargetContext()
249 mTarget = nullptr;
252 typedef uint32_t MakeCurrentFlags;
253 static const MakeCurrentFlags ForceMakeCurrent = 0x1;
255 * Make this compositor's rendering context the current context for the
256 * underlying graphics API. This may be a global operation, depending on the
257 * API. Our context will remain the current one until someone else changes it.
259 * Clients of the compositor should call this at the start of the compositing
260 * process, it might be required by texture uploads etc.
262 * If aFlags == ForceMakeCurrent then we will (re-)set our context on the
263 * underlying API even if it is already the current context.
265 virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) = 0;
268 * Creates a Surface that can be used as a rendering target by this
269 * compositor.
271 virtual TemporaryRef<CompositingRenderTarget>
272 CreateRenderTarget(const gfx::IntRect& aRect, SurfaceInitMode aInit) = 0;
275 * Creates a Surface that can be used as a rendering target by this
276 * compositor, and initializes the surface by copying from aSource.
277 * If aSource is null, then the current screen buffer is used as source.
279 * aSourcePoint specifies the point in aSource to copy data from.
281 virtual TemporaryRef<CompositingRenderTarget>
282 CreateRenderTargetFromSource(const gfx::IntRect& aRect,
283 const CompositingRenderTarget* aSource,
284 const gfx::IntPoint& aSourcePoint) = 0;
287 * Sets the given surface as the target for subsequent calls to DrawQuad.
288 * Passing null as aSurface sets the screen as the target.
290 virtual void SetRenderTarget(CompositingRenderTarget* aSurface) = 0;
293 * Returns the current target for rendering. Will return null if we are
294 * rendering to the screen.
296 virtual CompositingRenderTarget* GetCurrentRenderTarget() const = 0;
299 * Mostly the compositor will pull the size from a widget and this method will
300 * be ignored, but compositor implementations are free to use it if they like.
302 virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) = 0;
305 * Declare an offset to use when rendering layers. This will be ignored when
306 * rendering to a target instead of the screen.
308 virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) = 0;
311 * Tell the compositor to draw a quad. What to do draw and how it is
312 * drawn is specified by aEffectChain. aRect is the quad to draw, in user space.
313 * aTransform transforms from user space to screen space. If texture coords are
314 * required, these will be in the primary effect in the effect chain.
316 virtual void DrawQuad(const gfx::Rect& aRect, const gfx::Rect& aClipRect,
317 const EffectChain& aEffectChain,
318 gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform) = 0;
321 * Clear aRect on current render target.
323 virtual void ClearRect(const gfx::Rect& aRect) = 0;
326 * Start a new frame.
328 * aInvalidRect is the invalid region of the screen; it can be ignored for
329 * compositors where the performance for compositing the entire window is
330 * sufficient.
332 * aClipRectIn is the clip rect for the window in window space (optional).
333 * aTransform is the transform from user space to window space.
334 * aRenderBounds bounding rect for rendering, in user space.
336 * If aClipRectIn is null, this method sets *aClipRectOut to the clip rect
337 * actually used for rendering (if aClipRectIn is non-null, we will use that
338 * for the clip rect).
340 * If aRenderBoundsOut is non-null, it will be set to the render bounds
341 * actually used by the compositor in window space. If aRenderBoundsOut
342 * is returned empty, composition should be aborted.
344 virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
345 const gfx::Rect* aClipRectIn,
346 const gfx::Rect& aRenderBounds,
347 gfx::Rect* aClipRectOut = nullptr,
348 gfx::Rect* aRenderBoundsOut = nullptr) = 0;
351 * Flush the current frame to the screen and tidy up.
353 virtual void EndFrame() = 0;
355 virtual void SetFBAcquireFence(Layer* aLayer) {}
357 virtual FenceHandle GetReleaseFence()
359 return FenceHandle();
363 * Post-rendering stuff if the rendering is done outside of this Compositor
364 * e.g., by Composer2D.
365 * aTransform is the transform from user space to window space.
367 virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) = 0;
370 * Tidy up if BeginFrame has been called, but EndFrame won't be.
372 virtual void AbortFrame() = 0;
375 * Setup the viewport and projection matrix for rendering to a target of the
376 * given dimensions. The size and transform here will override those set in
377 * BeginFrame. BeginFrame sets a size and transform for the default render
378 * target, usually the screen. Calling this method prepares the compositor to
379 * render using a different viewport (that is, size and transform), usually
380 * associated with a new render target.
382 virtual void PrepareViewport(const gfx::IntSize& aSize) = 0;
385 * Whether textures created by this compositor can receive partial updates.
387 virtual bool SupportsPartialTextureUpdate() = 0;
389 void SetDiagnosticTypes(DiagnosticTypes aDiagnostics)
391 mDiagnosticTypes = aDiagnostics;
394 DiagnosticTypes GetDiagnosticTypes() const
396 return mDiagnosticTypes;
399 void DrawDiagnostics(DiagnosticFlags aFlags,
400 const gfx::Rect& visibleRect,
401 const gfx::Rect& aClipRect,
402 const gfx::Matrix4x4& transform,
403 uint32_t aFlashCounter = DIAGNOSTIC_FLASH_COUNTER_MAX);
405 void DrawDiagnostics(DiagnosticFlags aFlags,
406 const nsIntRegion& visibleRegion,
407 const gfx::Rect& aClipRect,
408 const gfx::Matrix4x4& transform,
409 uint32_t aFlashCounter = DIAGNOSTIC_FLASH_COUNTER_MAX);
411 #ifdef MOZ_DUMP_PAINTING
412 virtual const char* Name() const = 0;
413 #endif // MOZ_DUMP_PAINTING
415 virtual LayersBackend GetBackendType() const = 0;
418 * Each Compositor has a unique ID.
419 * This ID is used to keep references to each Compositor in a map accessed
420 * from the compositor thread only, so that async compositables can find
421 * the right compositor parent and schedule compositing even if the compositor
422 * changed.
424 uint32_t GetCompositorID() const
426 return mCompositorID;
428 void SetCompositorID(uint32_t aID)
430 MOZ_ASSERT(mCompositorID == 0, "The compositor ID must be set only once.");
431 mCompositorID = aID;
435 * Notify the compositor that composition is being paused. This allows the
436 * compositor to temporarily release any resources.
437 * Between calling Pause and Resume, compositing may fail.
439 virtual void Pause() {}
441 * Notify the compositor that composition is being resumed. The compositor
442 * regain any resources it requires for compositing.
443 * Returns true if succeeded.
445 virtual bool Resume() { return true; }
448 * Call before rendering begins to ensure the compositor is ready to
449 * composite. Returns false if rendering should be aborted.
451 virtual bool Ready() { return true; }
453 // XXX I expect we will want to move mWidget into this class and implement
454 // these methods properly.
455 virtual nsIWidget* GetWidget() const { return nullptr; }
458 * Debug-build assertion that can be called to ensure code is running on the
459 * compositor thread.
461 static void AssertOnCompositorThread();
464 * We enforce that there can only be one Compositor backend type off the main
465 * thread at the same time. The backend type in use can be checked with this
466 * static method. We need this for creating texture clients/hosts etc. when we
467 * don't have a reference to a Compositor.
469 * This can only be used from the compositor thread!
471 static LayersBackend GetBackend();
473 size_t GetFillRatio() {
474 float fillRatio = 0;
475 if (mPixelsFilled > 0 && mPixelsPerFrame > 0) {
476 fillRatio = 100.0f * float(mPixelsFilled) / float(mPixelsPerFrame);
477 if (fillRatio > 999.0f) {
478 fillRatio = 999.0f;
481 return fillRatio;
484 virtual CompositorBackendSpecificData* GetCompositorBackendSpecificData() {
485 return nullptr;
488 ScreenRotation GetScreenRotation() const {
489 return mScreenRotation;
492 void SetScreenRotation(ScreenRotation aRotation) {
493 mScreenRotation = aRotation;
496 protected:
497 void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
498 const gfx::Rect& aVisibleRect,
499 const gfx::Rect& aClipRect,
500 const gfx::Matrix4x4& transform,
501 uint32_t aFlashCounter);
503 bool ShouldDrawDiagnostics(DiagnosticFlags);
506 * Set the global Compositor backend, checking that one isn't already set.
508 static void SetBackend(LayersBackend backend);
510 uint32_t mCompositorID;
511 DiagnosticTypes mDiagnosticTypes;
512 PCompositorParent* mParent;
515 * We keep track of the total number of pixels filled as we composite the
516 * current frame. This value is an approximation and is not accurate,
517 * especially in the presence of transforms.
519 size_t mPixelsPerFrame;
520 size_t mPixelsFilled;
522 ScreenRotation mScreenRotation;
524 virtual gfx::IntSize GetWidgetSize() const = 0;
526 RefPtr<gfx::DrawTarget> mTarget;
527 nsIntRect mTargetBounds;
529 private:
530 static LayersBackend sBackend;
534 } // namespace layers
535 } // namespace mozilla
537 #endif /* MOZILLA_GFX_COMPOSITOR_H */