backout 29799f914cab, Bug 917642 - [Helix] Please update the helix blobs
[gecko.git] / gfx / layers / Compositor.h
blob7f148973f125c156f63e81d08652e95627034080
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/LayersTypes.h" // for LayersBackend
17 #include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
19 /**
20 * Different elements of a web pages are rendered into separate "layers" before
21 * they are flattened into the final image that is brought to the screen.
22 * See Layers.h for more informations about layers and why we use retained
23 * structures.
24 * Most of the documentation for layers is directly in the source code in the
25 * form of doc comments. An overview can also be found in the the wiki:
26 * https://wiki.mozilla.org/Gecko:Overview#Graphics
29 * # Main interfaces and abstractions
31 * - Layer, ShadowableLayer and LayerComposite
32 * (see Layers.h and ipc/ShadowLayers.h)
33 * - CompositableClient and CompositableHost
34 * (client/CompositableClient.h composite/CompositableHost.h)
35 * - TextureClient and TextureHost
36 * (client/TextureClient.h composite/TextureHost.h)
37 * - TextureSource
38 * (composite/TextureHost.h)
39 * - Forwarders
40 * (ipc/CompositableForwarder.h ipc/ShadowLayers.h)
41 * - Compositor
42 * (this file)
43 * - IPDL protocols
44 * (.ipdl files under the gfx/layers/ipc directory)
46 * The *Client and Shadowable* classes are always used on the content thread.
47 * Forwarders are always used on the content thread.
48 * The *Host and Shadow* classes are always used on the compositor thread.
49 * Compositors, TextureSource, and Effects are always used on the compositor
50 * thread.
51 * Most enums and constants are declared in LayersTypes.h and CompositorTypes.h.
54 * # Texture transfer
56 * Most layer classes own a Compositable plus some extra information like
57 * transforms and clip rects. They are platform independent.
58 * Compositable classes manipulate Texture objects and are reponsible for
59 * things like tiling, buffer rotation or double buffering. Compositables
60 * are also platform-independent. Examples of compositable classes are:
61 * - ImageClient
62 * - CanvasClient
63 * - ContentHost
64 * - etc.
65 * Texture classes (TextureClient and TextureHost) are thin abstractions over
66 * platform-dependent texture memory. They are maniplulated by compositables
67 * and don't know about buffer rotations and such. The purposes of TextureClient
68 * and TextureHost are to synchronize, serialize and deserialize texture data.
69 * TextureHosts provide access to TextureSources that are views on the
70 * Texture data providing the necessary api for Compositor backend to composite
71 * them.
73 * Compositable and Texture clients and hosts are created using factory methods.
74 * They should only be created by using their constructor in exceptional
75 * circumstances. The factory methods are located:
76 * TextureClient - CompositableClient::CreateTextureClient
77 * TextureHost - TextureHost::CreateTextureHost, which calls a
78 * platform-specific function, e.g., CreateTextureHostOGL
79 * CompositableClient - in the appropriate subclass, e.g.,
80 * CanvasClient::CreateCanvasClient
81 * CompositableHost - CompositableHost::Create
84 * # IPDL
86 * If off-main-thread compositing (OMTC) is enabled, compositing is performed
87 * in a dedicated thread. In some setups compositing happens in a dedicated
88 * process. Documentation may refer to either the compositor thread or the
89 * compositor process.
90 * See explanations in ShadowLayers.h.
93 * # Backend implementations
95 * Compositor backends like OpenGL or flavours of D3D live in their own directory
96 * under gfx/layers/. To add a new backend, implement at least the following
97 * interfaces:
98 * - Compositor (ex. CompositorOGL)
99 * - TextureHost (ex. SharedTextureHostOGL)
100 * Depending on the type of data that needs to be serialized, you may need to
101 * add specific TextureClient implementations.
104 class nsIWidget;
105 struct gfxMatrix;
106 struct nsIntSize;
107 class nsIntRegion;
109 namespace mozilla {
110 namespace gfx {
111 class Matrix4x4;
112 class DrawTarget;
115 namespace layers {
117 struct Effect;
118 struct EffectChain;
119 class Image;
120 class ISurfaceAllocator;
121 class NewTextureSource;
122 class DataTextureSource;
123 class CompositingRenderTarget;
125 enum SurfaceInitMode
127 INIT_MODE_NONE,
128 INIT_MODE_CLEAR,
129 INIT_MODE_COPY
133 * Common interface for compositor backends.
135 * Compositor provides a cross-platform interface to a set of operations for
136 * compositing quads. Compositor knows nothing about the layer tree. It must be
137 * told everything about each composited quad - contents, location, transform,
138 * opacity, etc.
140 * In theory it should be possible for different widgets to use the same
141 * compositor. In practice, we use one compositor per window.
143 * # Usage
145 * For an example of a user of Compositor, see LayerManagerComposite.
147 * Initialization: create a Compositor object, call Initialize().
149 * Destruction: destroy any resources associated with the compositor, call
150 * Destroy(), delete the Compositor object.
152 * Composition:
153 * call BeginFrame,
154 * for each quad to be composited:
155 * call MakeCurrent if necessary (not necessary if no other context has been
156 * made current),
157 * take care of any texture upload required to composite the quad, this step
158 * is backend-dependent,
159 * construct an EffectChain for the quad,
160 * call DrawQuad,
161 * call EndFrame.
162 * If the user has to stop compositing at any point before EndFrame, call
163 * AbortFrame.
164 * If the compositor is usually used for compositing but compositing is
165 * temporarily done without the compositor, call EndFrameForExternalComposition
166 * after compositing each frame so the compositor can remain internally
167 * consistent.
169 * By default, the compositor will render to the screen, to render to a target,
170 * call SetTargetContext or SetRenderTarget, the latter with a target created
171 * by CreateRenderTarget or CreateRenderTargetFromSource.
173 * The target and viewport methods can be called before any DrawQuad call and
174 * affect any subsequent DrawQuad calls.
176 class Compositor : public RefCounted<Compositor>
178 public:
179 Compositor()
180 : mCompositorID(0)
181 , mDiagnosticTypes(DIAGNOSTIC_NONE)
183 MOZ_COUNT_CTOR(Compositor);
185 virtual ~Compositor()
187 MOZ_COUNT_DTOR(Compositor);
190 virtual TemporaryRef<DataTextureSource> CreateDataTextureSource(TextureFlags aFlags = 0) = 0;
191 virtual bool Initialize() = 0;
192 virtual void Destroy() = 0;
195 * Return true if the effect type is supported.
197 * By default Compositor implementations should support all effects but in
198 * some rare cases it is not possible to support an effect efficiently.
199 * This is the case for BasicCompositor with EffectYCbCr.
201 virtual bool SupportsEffect(EffectTypes aEffect) { return true; }
204 * Request a texture host identifier that may be used for creating textures
205 * across process or thread boundaries that are compatible with this
206 * compositor.
208 virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() = 0;
211 * Properties of the compositor.
213 virtual bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) = 0;
214 virtual int32_t GetMaxTextureSize() const = 0;
217 * Set the target for rendering. Results will have been written to aTarget by
218 * the time that EndFrame returns.
220 * If this method is not used, or we pass in nullptr, we target the compositor's
221 * usual swap chain and render to the screen.
223 virtual void SetTargetContext(gfx::DrawTarget* aTarget) = 0;
225 typedef uint32_t MakeCurrentFlags;
226 static const MakeCurrentFlags ForceMakeCurrent = 0x1;
228 * Make this compositor's rendering context the current context for the
229 * underlying graphics API. This may be a global operation, depending on the
230 * API. Our context will remain the current one until someone else changes it.
232 * Clients of the compositor should call this at the start of the compositing
233 * process, it might be required by texture uploads etc.
235 * If aFlags == ForceMakeCurrent then we will (re-)set our context on the
236 * underlying API even if it is already the current context.
238 virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) = 0;
241 * Creates a Surface that can be used as a rendering target by this
242 * compositor.
244 virtual TemporaryRef<CompositingRenderTarget>
245 CreateRenderTarget(const gfx::IntRect& aRect, SurfaceInitMode aInit) = 0;
248 * Creates a Surface that can be used as a rendering target by this
249 * compositor, and initializes the surface by copying from aSource.
250 * If aSource is null, then the current screen buffer is used as source.
252 virtual TemporaryRef<CompositingRenderTarget>
253 CreateRenderTargetFromSource(const gfx::IntRect& aRect,
254 const CompositingRenderTarget* aSource) = 0;
257 * Sets the given surface as the target for subsequent calls to DrawQuad.
258 * Passing null as aSurface sets the screen as the target.
260 virtual void SetRenderTarget(CompositingRenderTarget* aSurface) = 0;
263 * Returns the current target for rendering. Will return null if we are
264 * rendering to the screen.
266 virtual CompositingRenderTarget* GetCurrentRenderTarget() = 0;
269 * Mostly the compositor will pull the size from a widget and this method will
270 * be ignored, but compositor implementations are free to use it if they like.
272 virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) = 0;
275 * Declare an offset to use when rendering layers. This will be ignored when
276 * rendering to a target instead of the screen.
278 virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) = 0;
281 * Tell the compositor to actually draw a quad. What to do draw and how it is
282 * drawn is specified by aEffectChain. aRect is the quad to draw, in user space.
283 * aTransform transforms from user space to screen space. aOffset is the
284 * offset of the render target from 0,0 of the screen. If texture coords are
285 * required, these will be in the primary effect in the effect chain.
287 virtual void DrawQuad(const gfx::Rect& aRect, const gfx::Rect& aClipRect,
288 const EffectChain& aEffectChain,
289 gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform,
290 const gfx::Point& aOffset) = 0;
293 * Start a new frame.
294 * aClipRectIn is the clip rect for the window in window space (optional).
295 * aTransform is the transform from user space to window space.
296 * aRenderBounds bounding rect for rendering, in user space.
297 * If aClipRectIn is null, this method sets *aClipRectOut to the clip rect
298 * actually used for rendering (if aClipRectIn is non-null, we will use that
299 * for the clip rect).
300 * If aRenderBoundsOut is non-null, it will be set to the render bounds
301 * actually used by the compositor in window space.
303 virtual void BeginFrame(const gfx::Rect* aClipRectIn,
304 const gfxMatrix& aTransform,
305 const gfx::Rect& aRenderBounds,
306 gfx::Rect* aClipRectOut = nullptr,
307 gfx::Rect* aRenderBoundsOut = nullptr) = 0;
310 * Flush the current frame to the screen and tidy up.
312 virtual void EndFrame() = 0;
315 * Post-rendering stuff if the rendering is done outside of this Compositor
316 * e.g., by Composer2D.
317 * aTransform is the transform from user space to window space.
319 virtual void EndFrameForExternalComposition(const gfxMatrix& aTransform) = 0;
322 * Tidy up if BeginFrame has been called, but EndFrame won't be.
324 virtual void AbortFrame() = 0;
327 * Setup the viewport and projection matrix for rendering to a target of the
328 * given dimensions. The size and transform here will override those set in
329 * BeginFrame. BeginFrame sets a size and transform for the default render
330 * target, usually the screen. Calling this method prepares the compositor to
331 * render using a different viewport (that is, size and transform), usually
332 * associated with a new render target.
333 * aWorldTransform is the transform from user space to the new viewport's
334 * coordinate space.
336 virtual void PrepareViewport(const gfx::IntSize& aSize,
337 const gfxMatrix& aWorldTransform) = 0;
340 * Whether textures created by this compositor can receive partial updates.
342 virtual bool SupportsPartialTextureUpdate() = 0;
344 void SetDiagnosticTypes(DiagnosticTypes aDiagnostics)
346 mDiagnosticTypes = aDiagnostics;
349 void DrawDiagnostics(DiagnosticFlags aFlags,
350 const gfx::Rect& visibleRect,
351 const gfx::Rect& aClipRect,
352 const gfx::Matrix4x4& transform,
353 const gfx::Point& aOffset);
355 void DrawDiagnostics(DiagnosticFlags aFlags,
356 const nsIntRegion& visibleRegion,
357 const gfx::Rect& aClipRect,
358 const gfx::Matrix4x4& transform,
359 const gfx::Point& aOffset);
362 #ifdef MOZ_DUMP_PAINTING
363 virtual const char* Name() const = 0;
364 #endif // MOZ_DUMP_PAINTING
368 * Each Compositor has a unique ID.
369 * This ID is used to keep references to each Compositor in a map accessed
370 * from the compositor thread only, so that async compositables can find
371 * the right compositor parent and schedule compositing even if the compositor
372 * changed.
374 uint32_t GetCompositorID() const
376 return mCompositorID;
378 void SetCompositorID(uint32_t aID)
380 MOZ_ASSERT(mCompositorID == 0, "The compositor ID must be set only once.");
381 mCompositorID = aID;
385 * Notify the compositor that a layers transaction has occured. This is only
386 * used for FPS information at the moment.
387 * XXX: surely there is a better way to do this?
389 virtual void NotifyLayersTransaction() = 0;
392 * Notify the compositor that composition is being paused. This allows the
393 * compositor to temporarily release any resources.
394 * Between calling Pause and Resume, compositing may fail.
396 virtual void Pause() {}
398 * Notify the compositor that composition is being resumed. The compositor
399 * regain any resources it requires for compositing.
400 * Returns true if succeeded.
402 virtual bool Resume() { return true; }
404 // XXX I expect we will want to move mWidget into this class and implement
405 // these methods properly.
406 virtual nsIWidget* GetWidget() const { return nullptr; }
407 virtual const nsIntSize& GetWidgetSize() = 0;
409 // Call before and after any rendering not done by this compositor but which
410 // might affect the compositor's internal state or the state of any APIs it
411 // uses. For example, internal GL state.
412 virtual void SaveState() {}
413 virtual void RestoreState() {}
416 * Debug-build assertion that can be called to ensure code is running on the
417 * compositor thread.
419 static void AssertOnCompositorThread();
422 * We enforce that there can only be one Compositor backend type off the main
423 * thread at the same time. The backend type in use can be checked with this
424 * static method. We need this for creating texture clients/hosts etc. when we
425 * don't have a reference to a Compositor.
427 * This can only be used from the compositor thread!
429 static LayersBackend GetBackend();
431 protected:
432 void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
433 const gfx::Rect& aVisibleRect,
434 const gfx::Rect& aClipRect,
435 const gfx::Matrix4x4& transform,
436 const gfx::Point& aOffset);
438 bool ShouldDrawDiagnostics(DiagnosticFlags);
440 uint32_t mCompositorID;
441 static LayersBackend sBackend;
442 DiagnosticTypes mDiagnosticTypes;
445 * We keep track of the total number of pixels filled as we composite the
446 * current frame. This value is an approximation and is not accurate,
447 * especially in the presence of transforms.
449 size_t mPixelsPerFrame;
450 size_t mPixelsFilled;
453 } // namespace layers
454 } // namespace mozilla
456 #endif /* MOZILLA_GFX_COMPOSITOR_H */