Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
michael@0 | 2 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef MOZILLA_GFX_COMPOSITOR_H |
michael@0 | 7 | #define MOZILLA_GFX_COMPOSITOR_H |
michael@0 | 8 | |
michael@0 | 9 | #include "Units.h" // for ScreenPoint |
michael@0 | 10 | #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc |
michael@0 | 11 | #include "mozilla/RefPtr.h" // for TemporaryRef, RefCounted |
michael@0 | 12 | #include "mozilla/gfx/Point.h" // for IntSize, Point |
michael@0 | 13 | #include "mozilla/gfx/Rect.h" // for Rect, IntRect |
michael@0 | 14 | #include "mozilla/gfx/Types.h" // for Float |
michael@0 | 15 | #include "mozilla/layers/CompositorTypes.h" // for DiagnosticTypes, etc |
michael@0 | 16 | #include "mozilla/layers/LayersTypes.h" // for LayersBackend |
michael@0 | 17 | #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc |
michael@0 | 18 | #include "nsRegion.h" |
michael@0 | 19 | #include <vector> |
michael@0 | 20 | #include "mozilla/WidgetUtils.h" |
michael@0 | 21 | |
michael@0 | 22 | /** |
michael@0 | 23 | * Different elements of a web pages are rendered into separate "layers" before |
michael@0 | 24 | * they are flattened into the final image that is brought to the screen. |
michael@0 | 25 | * See Layers.h for more informations about layers and why we use retained |
michael@0 | 26 | * structures. |
michael@0 | 27 | * Most of the documentation for layers is directly in the source code in the |
michael@0 | 28 | * form of doc comments. An overview can also be found in the the wiki: |
michael@0 | 29 | * https://wiki.mozilla.org/Gecko:Overview#Graphics |
michael@0 | 30 | * |
michael@0 | 31 | * |
michael@0 | 32 | * # Main interfaces and abstractions |
michael@0 | 33 | * |
michael@0 | 34 | * - Layer, ShadowableLayer and LayerComposite |
michael@0 | 35 | * (see Layers.h and ipc/ShadowLayers.h) |
michael@0 | 36 | * - CompositableClient and CompositableHost |
michael@0 | 37 | * (client/CompositableClient.h composite/CompositableHost.h) |
michael@0 | 38 | * - TextureClient and TextureHost |
michael@0 | 39 | * (client/TextureClient.h composite/TextureHost.h) |
michael@0 | 40 | * - TextureSource |
michael@0 | 41 | * (composite/TextureHost.h) |
michael@0 | 42 | * - Forwarders |
michael@0 | 43 | * (ipc/CompositableForwarder.h ipc/ShadowLayers.h) |
michael@0 | 44 | * - Compositor |
michael@0 | 45 | * (this file) |
michael@0 | 46 | * - IPDL protocols |
michael@0 | 47 | * (.ipdl files under the gfx/layers/ipc directory) |
michael@0 | 48 | * |
michael@0 | 49 | * The *Client and Shadowable* classes are always used on the content thread. |
michael@0 | 50 | * Forwarders are always used on the content thread. |
michael@0 | 51 | * The *Host and Shadow* classes are always used on the compositor thread. |
michael@0 | 52 | * Compositors, TextureSource, and Effects are always used on the compositor |
michael@0 | 53 | * thread. |
michael@0 | 54 | * Most enums and constants are declared in LayersTypes.h and CompositorTypes.h. |
michael@0 | 55 | * |
michael@0 | 56 | * |
michael@0 | 57 | * # Texture transfer |
michael@0 | 58 | * |
michael@0 | 59 | * Most layer classes own a Compositable plus some extra information like |
michael@0 | 60 | * transforms and clip rects. They are platform independent. |
michael@0 | 61 | * Compositable classes manipulate Texture objects and are reponsible for |
michael@0 | 62 | * things like tiling, buffer rotation or double buffering. Compositables |
michael@0 | 63 | * are also platform-independent. Examples of compositable classes are: |
michael@0 | 64 | * - ImageClient |
michael@0 | 65 | * - CanvasClient |
michael@0 | 66 | * - ContentHost |
michael@0 | 67 | * - etc. |
michael@0 | 68 | * Texture classes (TextureClient and TextureHost) are thin abstractions over |
michael@0 | 69 | * platform-dependent texture memory. They are maniplulated by compositables |
michael@0 | 70 | * and don't know about buffer rotations and such. The purposes of TextureClient |
michael@0 | 71 | * and TextureHost are to synchronize, serialize and deserialize texture data. |
michael@0 | 72 | * TextureHosts provide access to TextureSources that are views on the |
michael@0 | 73 | * Texture data providing the necessary api for Compositor backend to composite |
michael@0 | 74 | * them. |
michael@0 | 75 | * |
michael@0 | 76 | * Compositable and Texture clients and hosts are created using factory methods. |
michael@0 | 77 | * They should only be created by using their constructor in exceptional |
michael@0 | 78 | * circumstances. The factory methods are located: |
michael@0 | 79 | * TextureClient - CompositableClient::CreateTextureClient |
michael@0 | 80 | * TextureHost - TextureHost::CreateTextureHost, which calls a |
michael@0 | 81 | * platform-specific function, e.g., CreateTextureHostOGL |
michael@0 | 82 | * CompositableClient - in the appropriate subclass, e.g., |
michael@0 | 83 | * CanvasClient::CreateCanvasClient |
michael@0 | 84 | * CompositableHost - CompositableHost::Create |
michael@0 | 85 | * |
michael@0 | 86 | * |
michael@0 | 87 | * # IPDL |
michael@0 | 88 | * |
michael@0 | 89 | * If off-main-thread compositing (OMTC) is enabled, compositing is performed |
michael@0 | 90 | * in a dedicated thread. In some setups compositing happens in a dedicated |
michael@0 | 91 | * process. Documentation may refer to either the compositor thread or the |
michael@0 | 92 | * compositor process. |
michael@0 | 93 | * See explanations in ShadowLayers.h. |
michael@0 | 94 | * |
michael@0 | 95 | * |
michael@0 | 96 | * # Backend implementations |
michael@0 | 97 | * |
michael@0 | 98 | * Compositor backends like OpenGL or flavours of D3D live in their own directory |
michael@0 | 99 | * under gfx/layers/. To add a new backend, implement at least the following |
michael@0 | 100 | * interfaces: |
michael@0 | 101 | * - Compositor (ex. CompositorOGL) |
michael@0 | 102 | * - TextureHost (ex. SharedTextureHostOGL) |
michael@0 | 103 | * Depending on the type of data that needs to be serialized, you may need to |
michael@0 | 104 | * add specific TextureClient implementations. |
michael@0 | 105 | */ |
michael@0 | 106 | |
michael@0 | 107 | class nsIWidget; |
michael@0 | 108 | struct nsIntSize; |
michael@0 | 109 | class nsIntRegion; |
michael@0 | 110 | |
michael@0 | 111 | namespace mozilla { |
michael@0 | 112 | namespace gfx { |
michael@0 | 113 | class Matrix; |
michael@0 | 114 | class Matrix4x4; |
michael@0 | 115 | class DrawTarget; |
michael@0 | 116 | } |
michael@0 | 117 | |
michael@0 | 118 | namespace layers { |
michael@0 | 119 | |
michael@0 | 120 | struct Effect; |
michael@0 | 121 | struct EffectChain; |
michael@0 | 122 | class Image; |
michael@0 | 123 | class ISurfaceAllocator; |
michael@0 | 124 | class Layer; |
michael@0 | 125 | class NewTextureSource; |
michael@0 | 126 | class DataTextureSource; |
michael@0 | 127 | class CompositingRenderTarget; |
michael@0 | 128 | class PCompositorParent; |
michael@0 | 129 | class LayerManagerComposite; |
michael@0 | 130 | |
michael@0 | 131 | enum SurfaceInitMode |
michael@0 | 132 | { |
michael@0 | 133 | INIT_MODE_NONE, |
michael@0 | 134 | INIT_MODE_CLEAR |
michael@0 | 135 | }; |
michael@0 | 136 | |
michael@0 | 137 | /** |
michael@0 | 138 | * A base class for a platform-dependent helper for use by TextureHost. |
michael@0 | 139 | */ |
michael@0 | 140 | class CompositorBackendSpecificData |
michael@0 | 141 | { |
michael@0 | 142 | NS_INLINE_DECL_REFCOUNTING(CompositorBackendSpecificData) |
michael@0 | 143 | |
michael@0 | 144 | protected: |
michael@0 | 145 | virtual ~CompositorBackendSpecificData() {} |
michael@0 | 146 | }; |
michael@0 | 147 | |
michael@0 | 148 | /** |
michael@0 | 149 | * Common interface for compositor backends. |
michael@0 | 150 | * |
michael@0 | 151 | * Compositor provides a cross-platform interface to a set of operations for |
michael@0 | 152 | * compositing quads. Compositor knows nothing about the layer tree. It must be |
michael@0 | 153 | * told everything about each composited quad - contents, location, transform, |
michael@0 | 154 | * opacity, etc. |
michael@0 | 155 | * |
michael@0 | 156 | * In theory it should be possible for different widgets to use the same |
michael@0 | 157 | * compositor. In practice, we use one compositor per window. |
michael@0 | 158 | * |
michael@0 | 159 | * # Usage |
michael@0 | 160 | * |
michael@0 | 161 | * For an example of a user of Compositor, see LayerManagerComposite. |
michael@0 | 162 | * |
michael@0 | 163 | * Initialization: create a Compositor object, call Initialize(). |
michael@0 | 164 | * |
michael@0 | 165 | * Destruction: destroy any resources associated with the compositor, call |
michael@0 | 166 | * Destroy(), delete the Compositor object. |
michael@0 | 167 | * |
michael@0 | 168 | * Composition: |
michael@0 | 169 | * call BeginFrame, |
michael@0 | 170 | * for each quad to be composited: |
michael@0 | 171 | * call MakeCurrent if necessary (not necessary if no other context has been |
michael@0 | 172 | * made current), |
michael@0 | 173 | * take care of any texture upload required to composite the quad, this step |
michael@0 | 174 | * is backend-dependent, |
michael@0 | 175 | * construct an EffectChain for the quad, |
michael@0 | 176 | * call DrawQuad, |
michael@0 | 177 | * call EndFrame. |
michael@0 | 178 | * If the user has to stop compositing at any point before EndFrame, call |
michael@0 | 179 | * AbortFrame. |
michael@0 | 180 | * If the compositor is usually used for compositing but compositing is |
michael@0 | 181 | * temporarily done without the compositor, call EndFrameForExternalComposition |
michael@0 | 182 | * after compositing each frame so the compositor can remain internally |
michael@0 | 183 | * consistent. |
michael@0 | 184 | * |
michael@0 | 185 | * By default, the compositor will render to the screen, to render to a target, |
michael@0 | 186 | * call SetTargetContext or SetRenderTarget, the latter with a target created |
michael@0 | 187 | * by CreateRenderTarget or CreateRenderTargetFromSource. |
michael@0 | 188 | * |
michael@0 | 189 | * The target and viewport methods can be called before any DrawQuad call and |
michael@0 | 190 | * affect any subsequent DrawQuad calls. |
michael@0 | 191 | */ |
michael@0 | 192 | class Compositor |
michael@0 | 193 | { |
michael@0 | 194 | protected: |
michael@0 | 195 | virtual ~Compositor() {} |
michael@0 | 196 | |
michael@0 | 197 | public: |
michael@0 | 198 | NS_INLINE_DECL_REFCOUNTING(Compositor) |
michael@0 | 199 | |
michael@0 | 200 | Compositor(PCompositorParent* aParent = nullptr) |
michael@0 | 201 | : mCompositorID(0) |
michael@0 | 202 | , mDiagnosticTypes(DIAGNOSTIC_NONE) |
michael@0 | 203 | , mParent(aParent) |
michael@0 | 204 | , mScreenRotation(ROTATION_0) |
michael@0 | 205 | { |
michael@0 | 206 | } |
michael@0 | 207 | |
michael@0 | 208 | virtual TemporaryRef<DataTextureSource> CreateDataTextureSource(TextureFlags aFlags = 0) = 0; |
michael@0 | 209 | virtual bool Initialize() = 0; |
michael@0 | 210 | virtual void Destroy() = 0; |
michael@0 | 211 | |
michael@0 | 212 | /** |
michael@0 | 213 | * Return true if the effect type is supported. |
michael@0 | 214 | * |
michael@0 | 215 | * By default Compositor implementations should support all effects but in |
michael@0 | 216 | * some rare cases it is not possible to support an effect efficiently. |
michael@0 | 217 | * This is the case for BasicCompositor with EffectYCbCr. |
michael@0 | 218 | */ |
michael@0 | 219 | virtual bool SupportsEffect(EffectTypes aEffect) { return true; } |
michael@0 | 220 | |
michael@0 | 221 | /** |
michael@0 | 222 | * Request a texture host identifier that may be used for creating textures |
michael@0 | 223 | * across process or thread boundaries that are compatible with this |
michael@0 | 224 | * compositor. |
michael@0 | 225 | */ |
michael@0 | 226 | virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() = 0; |
michael@0 | 227 | |
michael@0 | 228 | /** |
michael@0 | 229 | * Properties of the compositor. |
michael@0 | 230 | */ |
michael@0 | 231 | virtual bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) = 0; |
michael@0 | 232 | virtual int32_t GetMaxTextureSize() const = 0; |
michael@0 | 233 | |
michael@0 | 234 | /** |
michael@0 | 235 | * Set the target for rendering. Results will have been written to aTarget by |
michael@0 | 236 | * the time that EndFrame returns. |
michael@0 | 237 | * |
michael@0 | 238 | * If this method is not used, or we pass in nullptr, we target the compositor's |
michael@0 | 239 | * usual swap chain and render to the screen. |
michael@0 | 240 | */ |
michael@0 | 241 | virtual void SetTargetContext(gfx::DrawTarget* aTarget) = 0; |
michael@0 | 242 | |
michael@0 | 243 | typedef uint32_t MakeCurrentFlags; |
michael@0 | 244 | static const MakeCurrentFlags ForceMakeCurrent = 0x1; |
michael@0 | 245 | /** |
michael@0 | 246 | * Make this compositor's rendering context the current context for the |
michael@0 | 247 | * underlying graphics API. This may be a global operation, depending on the |
michael@0 | 248 | * API. Our context will remain the current one until someone else changes it. |
michael@0 | 249 | * |
michael@0 | 250 | * Clients of the compositor should call this at the start of the compositing |
michael@0 | 251 | * process, it might be required by texture uploads etc. |
michael@0 | 252 | * |
michael@0 | 253 | * If aFlags == ForceMakeCurrent then we will (re-)set our context on the |
michael@0 | 254 | * underlying API even if it is already the current context. |
michael@0 | 255 | */ |
michael@0 | 256 | virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) = 0; |
michael@0 | 257 | |
michael@0 | 258 | /** |
michael@0 | 259 | * Creates a Surface that can be used as a rendering target by this |
michael@0 | 260 | * compositor. |
michael@0 | 261 | */ |
michael@0 | 262 | virtual TemporaryRef<CompositingRenderTarget> |
michael@0 | 263 | CreateRenderTarget(const gfx::IntRect& aRect, SurfaceInitMode aInit) = 0; |
michael@0 | 264 | |
michael@0 | 265 | /** |
michael@0 | 266 | * Creates a Surface that can be used as a rendering target by this |
michael@0 | 267 | * compositor, and initializes the surface by copying from aSource. |
michael@0 | 268 | * If aSource is null, then the current screen buffer is used as source. |
michael@0 | 269 | * |
michael@0 | 270 | * aSourcePoint specifies the point in aSource to copy data from. |
michael@0 | 271 | */ |
michael@0 | 272 | virtual TemporaryRef<CompositingRenderTarget> |
michael@0 | 273 | CreateRenderTargetFromSource(const gfx::IntRect& aRect, |
michael@0 | 274 | const CompositingRenderTarget* aSource, |
michael@0 | 275 | const gfx::IntPoint& aSourcePoint) = 0; |
michael@0 | 276 | |
michael@0 | 277 | /** |
michael@0 | 278 | * Sets the given surface as the target for subsequent calls to DrawQuad. |
michael@0 | 279 | * Passing null as aSurface sets the screen as the target. |
michael@0 | 280 | */ |
michael@0 | 281 | virtual void SetRenderTarget(CompositingRenderTarget* aSurface) = 0; |
michael@0 | 282 | |
michael@0 | 283 | /** |
michael@0 | 284 | * Returns the current target for rendering. Will return null if we are |
michael@0 | 285 | * rendering to the screen. |
michael@0 | 286 | */ |
michael@0 | 287 | virtual CompositingRenderTarget* GetCurrentRenderTarget() const = 0; |
michael@0 | 288 | |
michael@0 | 289 | /** |
michael@0 | 290 | * Mostly the compositor will pull the size from a widget and this method will |
michael@0 | 291 | * be ignored, but compositor implementations are free to use it if they like. |
michael@0 | 292 | */ |
michael@0 | 293 | virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) = 0; |
michael@0 | 294 | |
michael@0 | 295 | /** |
michael@0 | 296 | * Declare an offset to use when rendering layers. This will be ignored when |
michael@0 | 297 | * rendering to a target instead of the screen. |
michael@0 | 298 | */ |
michael@0 | 299 | virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) = 0; |
michael@0 | 300 | |
michael@0 | 301 | /** |
michael@0 | 302 | * Tell the compositor to draw a quad. What to do draw and how it is |
michael@0 | 303 | * drawn is specified by aEffectChain. aRect is the quad to draw, in user space. |
michael@0 | 304 | * aTransform transforms from user space to screen space. If texture coords are |
michael@0 | 305 | * required, these will be in the primary effect in the effect chain. |
michael@0 | 306 | */ |
michael@0 | 307 | virtual void DrawQuad(const gfx::Rect& aRect, const gfx::Rect& aClipRect, |
michael@0 | 308 | const EffectChain& aEffectChain, |
michael@0 | 309 | gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform) = 0; |
michael@0 | 310 | |
michael@0 | 311 | /** |
michael@0 | 312 | * Tell the compositor to draw lines connecting the points. Behaves like |
michael@0 | 313 | * DrawQuad. |
michael@0 | 314 | */ |
michael@0 | 315 | virtual void DrawLines(const std::vector<gfx::Point>& aLines, const gfx::Rect& aClipRect, |
michael@0 | 316 | const gfx::Color& aColor, |
michael@0 | 317 | gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform) |
michael@0 | 318 | { /* Should turn into pure virtual once implemented in D3D */ } |
michael@0 | 319 | |
michael@0 | 320 | /* |
michael@0 | 321 | * Clear aRect on current render target. |
michael@0 | 322 | */ |
michael@0 | 323 | virtual void ClearRect(const gfx::Rect& aRect) { } |
michael@0 | 324 | |
michael@0 | 325 | /** |
michael@0 | 326 | * Start a new frame. |
michael@0 | 327 | * |
michael@0 | 328 | * aInvalidRect is the invalid region of the screen; it can be ignored for |
michael@0 | 329 | * compositors where the performance for compositing the entire window is |
michael@0 | 330 | * sufficient. |
michael@0 | 331 | * |
michael@0 | 332 | * aClipRectIn is the clip rect for the window in window space (optional). |
michael@0 | 333 | * aTransform is the transform from user space to window space. |
michael@0 | 334 | * aRenderBounds bounding rect for rendering, in user space. |
michael@0 | 335 | * |
michael@0 | 336 | * If aClipRectIn is null, this method sets *aClipRectOut to the clip rect |
michael@0 | 337 | * actually used for rendering (if aClipRectIn is non-null, we will use that |
michael@0 | 338 | * for the clip rect). |
michael@0 | 339 | * |
michael@0 | 340 | * If aRenderBoundsOut is non-null, it will be set to the render bounds |
michael@0 | 341 | * actually used by the compositor in window space. If aRenderBoundsOut |
michael@0 | 342 | * is returned empty, composition should be aborted. |
michael@0 | 343 | */ |
michael@0 | 344 | virtual void BeginFrame(const nsIntRegion& aInvalidRegion, |
michael@0 | 345 | const gfx::Rect* aClipRectIn, |
michael@0 | 346 | const gfx::Matrix& aTransform, |
michael@0 | 347 | const gfx::Rect& aRenderBounds, |
michael@0 | 348 | gfx::Rect* aClipRectOut = nullptr, |
michael@0 | 349 | gfx::Rect* aRenderBoundsOut = nullptr) = 0; |
michael@0 | 350 | |
michael@0 | 351 | /** |
michael@0 | 352 | * Flush the current frame to the screen and tidy up. |
michael@0 | 353 | */ |
michael@0 | 354 | virtual void EndFrame() = 0; |
michael@0 | 355 | |
michael@0 | 356 | virtual void SetFBAcquireFence(Layer* aLayer) {} |
michael@0 | 357 | |
michael@0 | 358 | /** |
michael@0 | 359 | * Post-rendering stuff if the rendering is done outside of this Compositor |
michael@0 | 360 | * e.g., by Composer2D. |
michael@0 | 361 | * aTransform is the transform from user space to window space. |
michael@0 | 362 | */ |
michael@0 | 363 | virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) = 0; |
michael@0 | 364 | |
michael@0 | 365 | /** |
michael@0 | 366 | * Tidy up if BeginFrame has been called, but EndFrame won't be. |
michael@0 | 367 | */ |
michael@0 | 368 | virtual void AbortFrame() = 0; |
michael@0 | 369 | |
michael@0 | 370 | /** |
michael@0 | 371 | * Setup the viewport and projection matrix for rendering to a target of the |
michael@0 | 372 | * given dimensions. The size and transform here will override those set in |
michael@0 | 373 | * BeginFrame. BeginFrame sets a size and transform for the default render |
michael@0 | 374 | * target, usually the screen. Calling this method prepares the compositor to |
michael@0 | 375 | * render using a different viewport (that is, size and transform), usually |
michael@0 | 376 | * associated with a new render target. |
michael@0 | 377 | * aWorldTransform is the transform from user space to the new viewport's |
michael@0 | 378 | * coordinate space. |
michael@0 | 379 | */ |
michael@0 | 380 | virtual void PrepareViewport(const gfx::IntSize& aSize, |
michael@0 | 381 | const gfx::Matrix& aWorldTransform) = 0; |
michael@0 | 382 | |
michael@0 | 383 | /** |
michael@0 | 384 | * Whether textures created by this compositor can receive partial updates. |
michael@0 | 385 | */ |
michael@0 | 386 | virtual bool SupportsPartialTextureUpdate() = 0; |
michael@0 | 387 | |
michael@0 | 388 | void SetDiagnosticTypes(DiagnosticTypes aDiagnostics) |
michael@0 | 389 | { |
michael@0 | 390 | mDiagnosticTypes = aDiagnostics; |
michael@0 | 391 | } |
michael@0 | 392 | |
michael@0 | 393 | DiagnosticTypes GetDiagnosticTypes() const |
michael@0 | 394 | { |
michael@0 | 395 | return mDiagnosticTypes; |
michael@0 | 396 | } |
michael@0 | 397 | |
michael@0 | 398 | void DrawDiagnostics(DiagnosticFlags aFlags, |
michael@0 | 399 | const gfx::Rect& visibleRect, |
michael@0 | 400 | const gfx::Rect& aClipRect, |
michael@0 | 401 | const gfx::Matrix4x4& transform, |
michael@0 | 402 | uint32_t aFlashCounter = DIAGNOSTIC_FLASH_COUNTER_MAX); |
michael@0 | 403 | |
michael@0 | 404 | void DrawDiagnostics(DiagnosticFlags aFlags, |
michael@0 | 405 | const nsIntRegion& visibleRegion, |
michael@0 | 406 | const gfx::Rect& aClipRect, |
michael@0 | 407 | const gfx::Matrix4x4& transform, |
michael@0 | 408 | uint32_t aFlashCounter = DIAGNOSTIC_FLASH_COUNTER_MAX); |
michael@0 | 409 | |
michael@0 | 410 | #ifdef MOZ_DUMP_PAINTING |
michael@0 | 411 | virtual const char* Name() const = 0; |
michael@0 | 412 | #endif // MOZ_DUMP_PAINTING |
michael@0 | 413 | |
michael@0 | 414 | virtual LayersBackend GetBackendType() const = 0; |
michael@0 | 415 | |
michael@0 | 416 | /** |
michael@0 | 417 | * Each Compositor has a unique ID. |
michael@0 | 418 | * This ID is used to keep references to each Compositor in a map accessed |
michael@0 | 419 | * from the compositor thread only, so that async compositables can find |
michael@0 | 420 | * the right compositor parent and schedule compositing even if the compositor |
michael@0 | 421 | * changed. |
michael@0 | 422 | */ |
michael@0 | 423 | uint32_t GetCompositorID() const |
michael@0 | 424 | { |
michael@0 | 425 | return mCompositorID; |
michael@0 | 426 | } |
michael@0 | 427 | void SetCompositorID(uint32_t aID) |
michael@0 | 428 | { |
michael@0 | 429 | MOZ_ASSERT(mCompositorID == 0, "The compositor ID must be set only once."); |
michael@0 | 430 | mCompositorID = aID; |
michael@0 | 431 | } |
michael@0 | 432 | |
michael@0 | 433 | /** |
michael@0 | 434 | * Notify the compositor that composition is being paused. This allows the |
michael@0 | 435 | * compositor to temporarily release any resources. |
michael@0 | 436 | * Between calling Pause and Resume, compositing may fail. |
michael@0 | 437 | */ |
michael@0 | 438 | virtual void Pause() {} |
michael@0 | 439 | /** |
michael@0 | 440 | * Notify the compositor that composition is being resumed. The compositor |
michael@0 | 441 | * regain any resources it requires for compositing. |
michael@0 | 442 | * Returns true if succeeded. |
michael@0 | 443 | */ |
michael@0 | 444 | virtual bool Resume() { return true; } |
michael@0 | 445 | |
michael@0 | 446 | /** |
michael@0 | 447 | * Call before rendering begins to ensure the compositor is ready to |
michael@0 | 448 | * composite. Returns false if rendering should be aborted. |
michael@0 | 449 | */ |
michael@0 | 450 | virtual bool Ready() { return true; } |
michael@0 | 451 | |
michael@0 | 452 | // XXX I expect we will want to move mWidget into this class and implement |
michael@0 | 453 | // these methods properly. |
michael@0 | 454 | virtual nsIWidget* GetWidget() const { return nullptr; } |
michael@0 | 455 | |
michael@0 | 456 | /** |
michael@0 | 457 | * Debug-build assertion that can be called to ensure code is running on the |
michael@0 | 458 | * compositor thread. |
michael@0 | 459 | */ |
michael@0 | 460 | static void AssertOnCompositorThread(); |
michael@0 | 461 | |
michael@0 | 462 | /** |
michael@0 | 463 | * We enforce that there can only be one Compositor backend type off the main |
michael@0 | 464 | * thread at the same time. The backend type in use can be checked with this |
michael@0 | 465 | * static method. We need this for creating texture clients/hosts etc. when we |
michael@0 | 466 | * don't have a reference to a Compositor. |
michael@0 | 467 | * |
michael@0 | 468 | * This can only be used from the compositor thread! |
michael@0 | 469 | */ |
michael@0 | 470 | static LayersBackend GetBackend(); |
michael@0 | 471 | |
michael@0 | 472 | size_t GetFillRatio() { |
michael@0 | 473 | float fillRatio = 0; |
michael@0 | 474 | if (mPixelsFilled > 0 && mPixelsPerFrame > 0) { |
michael@0 | 475 | fillRatio = 100.0f * float(mPixelsFilled) / float(mPixelsPerFrame); |
michael@0 | 476 | if (fillRatio > 999.0f) { |
michael@0 | 477 | fillRatio = 999.0f; |
michael@0 | 478 | } |
michael@0 | 479 | } |
michael@0 | 480 | return fillRatio; |
michael@0 | 481 | } |
michael@0 | 482 | |
michael@0 | 483 | virtual CompositorBackendSpecificData* GetCompositorBackendSpecificData() { |
michael@0 | 484 | return nullptr; |
michael@0 | 485 | } |
michael@0 | 486 | |
michael@0 | 487 | ScreenRotation GetScreenRotation() const { |
michael@0 | 488 | return mScreenRotation; |
michael@0 | 489 | } |
michael@0 | 490 | |
michael@0 | 491 | void SetScreenRotation(ScreenRotation aRotation) { |
michael@0 | 492 | mScreenRotation = aRotation; |
michael@0 | 493 | } |
michael@0 | 494 | |
michael@0 | 495 | // On b2g the clip rect is in the coordinate space of the physical screen |
michael@0 | 496 | // independently of its rotation, while the coordinate space of the layers, |
michael@0 | 497 | // on the other hand, depends on the screen orientation. |
michael@0 | 498 | // This only applies to b2g as with other platforms, orientation is handled |
michael@0 | 499 | // at the OS level rather than in Gecko. |
michael@0 | 500 | // In addition, the clip rect needs to be offset by the rendering origin. |
michael@0 | 501 | // This becomes important if intermediate surfaces are used. |
michael@0 | 502 | gfx::Rect ClipRectInLayersCoordinates(gfx::Rect aClip) const; |
michael@0 | 503 | |
michael@0 | 504 | protected: |
michael@0 | 505 | void DrawDiagnosticsInternal(DiagnosticFlags aFlags, |
michael@0 | 506 | const gfx::Rect& aVisibleRect, |
michael@0 | 507 | const gfx::Rect& aClipRect, |
michael@0 | 508 | const gfx::Matrix4x4& transform, |
michael@0 | 509 | uint32_t aFlashCounter); |
michael@0 | 510 | |
michael@0 | 511 | bool ShouldDrawDiagnostics(DiagnosticFlags); |
michael@0 | 512 | |
michael@0 | 513 | /** |
michael@0 | 514 | * Set the global Compositor backend, checking that one isn't already set. |
michael@0 | 515 | */ |
michael@0 | 516 | static void SetBackend(LayersBackend backend); |
michael@0 | 517 | |
michael@0 | 518 | uint32_t mCompositorID; |
michael@0 | 519 | DiagnosticTypes mDiagnosticTypes; |
michael@0 | 520 | PCompositorParent* mParent; |
michael@0 | 521 | |
michael@0 | 522 | /** |
michael@0 | 523 | * We keep track of the total number of pixels filled as we composite the |
michael@0 | 524 | * current frame. This value is an approximation and is not accurate, |
michael@0 | 525 | * especially in the presence of transforms. |
michael@0 | 526 | */ |
michael@0 | 527 | size_t mPixelsPerFrame; |
michael@0 | 528 | size_t mPixelsFilled; |
michael@0 | 529 | |
michael@0 | 530 | ScreenRotation mScreenRotation; |
michael@0 | 531 | |
michael@0 | 532 | virtual gfx::IntSize GetWidgetSize() const = 0; |
michael@0 | 533 | |
michael@0 | 534 | private: |
michael@0 | 535 | static LayersBackend sBackend; |
michael@0 | 536 | |
michael@0 | 537 | }; |
michael@0 | 538 | |
michael@0 | 539 | } // namespace layers |
michael@0 | 540 | } // namespace mozilla |
michael@0 | 541 | |
michael@0 | 542 | #endif /* MOZILLA_GFX_COMPOSITOR_H */ |