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
21 #include "mozilla/WidgetUtils.h"
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
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)
42 * (composite/TextureHost.h)
44 * (ipc/CompositableForwarder.h ipc/ShadowLayers.h)
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
55 * Most enums and constants are declared in LayersTypes.h and CompositorTypes.h.
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:
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
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
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
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
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.
124 class ISurfaceAllocator
;
126 class NewTextureSource
;
127 class DataTextureSource
;
128 class CompositingRenderTarget
;
129 class PCompositorParent
;
130 class LayerManagerComposite
;
139 * A base class for a platform-dependent helper for use by TextureHost.
141 class CompositorBackendSpecificData
143 NS_INLINE_DECL_REFCOUNTING(CompositorBackendSpecificData
)
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,
157 * In theory it should be possible for different widgets to use the same
158 * compositor. In practice, we use one compositor per window.
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.
171 * for each quad to be composited:
172 * call MakeCurrent if necessary (not necessary if no other context has been
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,
179 * If the user has to stop compositing at any point before EndFrame, call
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
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.
196 virtual ~Compositor() {}
199 NS_INLINE_DECL_REFCOUNTING(Compositor
)
201 explicit Compositor(PCompositorParent
* aParent
= nullptr)
203 , mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC
)
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
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
)
245 mTargetBounds
= aRect
;
247 void ClearTargetContext()
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
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;
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
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
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.");
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
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() {
475 if (mPixelsFilled
> 0 && mPixelsPerFrame
> 0) {
476 fillRatio
= 100.0f
* float(mPixelsFilled
) / float(mPixelsPerFrame
);
477 if (fillRatio
> 999.0f
) {
484 virtual CompositorBackendSpecificData
* GetCompositorBackendSpecificData() {
488 ScreenRotation
GetScreenRotation() const {
489 return mScreenRotation
;
492 void SetScreenRotation(ScreenRotation aRotation
) {
493 mScreenRotation
= aRotation
;
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
;
530 static LayersBackend sBackend
;
534 } // namespace layers
535 } // namespace mozilla
537 #endif /* MOZILLA_GFX_COMPOSITOR_H */