/src/mozilla-central/gfx/layers/Compositor.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef MOZILLA_GFX_COMPOSITOR_H |
8 | | #define MOZILLA_GFX_COMPOSITOR_H |
9 | | |
10 | | #include "Units.h" // for ScreenPoint |
11 | | #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc |
12 | | #include "mozilla/RefPtr.h" // for already_AddRefed, RefCounted |
13 | | #include "mozilla/gfx/2D.h" // for DrawTarget |
14 | | #include "mozilla/gfx/MatrixFwd.h" // for Matrix, Matrix4x4 |
15 | | #include "mozilla/gfx/Point.h" // for IntSize, Point |
16 | | #include "mozilla/gfx/Polygon.h" // for Polygon |
17 | | #include "mozilla/gfx/Rect.h" // for Rect, IntRect |
18 | | #include "mozilla/gfx/Types.h" // for Float |
19 | | #include "mozilla/gfx/Triangle.h" // for Triangle, TexturedTriangle |
20 | | #include "mozilla/layers/CompositorTypes.h" // for DiagnosticTypes, etc |
21 | | #include "mozilla/layers/LayersTypes.h" // for LayersBackend |
22 | | #include "mozilla/layers/TextureSourceProvider.h" |
23 | | #include "mozilla/widget/CompositorWidget.h" |
24 | | #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc |
25 | | #include "nsRegion.h" |
26 | | #include <vector> |
27 | | #include "mozilla/WidgetUtils.h" |
28 | | |
29 | | /** |
30 | | * Different elements of a web pages are rendered into separate "layers" before |
31 | | * they are flattened into the final image that is brought to the screen. |
32 | | * See Layers.h for more informations about layers and why we use retained |
33 | | * structures. |
34 | | * Most of the documentation for layers is directly in the source code in the |
35 | | * form of doc comments. An overview can also be found in the the wiki: |
36 | | * https://wiki.mozilla.org/Gecko:Overview#Graphics |
37 | | * |
38 | | * |
39 | | * # Main interfaces and abstractions |
40 | | * |
41 | | * - Layer, ShadowableLayer and LayerComposite |
42 | | * (see Layers.h and ipc/ShadowLayers.h) |
43 | | * - CompositableClient and CompositableHost |
44 | | * (client/CompositableClient.h composite/CompositableHost.h) |
45 | | * - TextureClient and TextureHost |
46 | | * (client/TextureClient.h composite/TextureHost.h) |
47 | | * - TextureSource |
48 | | * (composite/TextureHost.h) |
49 | | * - Forwarders |
50 | | * (ipc/CompositableForwarder.h ipc/ShadowLayers.h) |
51 | | * - Compositor |
52 | | * (this file) |
53 | | * - IPDL protocols |
54 | | * (.ipdl files under the gfx/layers/ipc directory) |
55 | | * |
56 | | * The *Client and Shadowable* classes are always used on the content thread. |
57 | | * Forwarders are always used on the content thread. |
58 | | * The *Host and Shadow* classes are always used on the compositor thread. |
59 | | * Compositors, TextureSource, and Effects are always used on the compositor |
60 | | * thread. |
61 | | * Most enums and constants are declared in LayersTypes.h and CompositorTypes.h. |
62 | | * |
63 | | * |
64 | | * # Texture transfer |
65 | | * |
66 | | * Most layer classes own a Compositable plus some extra information like |
67 | | * transforms and clip rects. They are platform independent. |
68 | | * Compositable classes manipulate Texture objects and are reponsible for |
69 | | * things like tiling, buffer rotation or double buffering. Compositables |
70 | | * are also platform-independent. Examples of compositable classes are: |
71 | | * - ImageClient |
72 | | * - CanvasClient |
73 | | * - ContentHost |
74 | | * - etc. |
75 | | * Texture classes (TextureClient and TextureHost) are thin abstractions over |
76 | | * platform-dependent texture memory. They are maniplulated by compositables |
77 | | * and don't know about buffer rotations and such. The purposes of TextureClient |
78 | | * and TextureHost are to synchronize, serialize and deserialize texture data. |
79 | | * TextureHosts provide access to TextureSources that are views on the |
80 | | * Texture data providing the necessary api for Compositor backend to composite |
81 | | * them. |
82 | | * |
83 | | * Compositable and Texture clients and hosts are created using factory methods. |
84 | | * They should only be created by using their constructor in exceptional |
85 | | * circumstances. The factory methods are located: |
86 | | * TextureClient - CompositableClient::CreateTextureClient |
87 | | * TextureHost - TextureHost::CreateTextureHost, which calls a |
88 | | * platform-specific function, e.g., CreateTextureHostOGL |
89 | | * CompositableClient - in the appropriate subclass, e.g., |
90 | | * CanvasClient::CreateCanvasClient |
91 | | * CompositableHost - CompositableHost::Create |
92 | | * |
93 | | * |
94 | | * # IPDL |
95 | | * |
96 | | * If off-main-thread compositing (OMTC) is enabled, compositing is performed |
97 | | * in a dedicated thread. In some setups compositing happens in a dedicated |
98 | | * process. Documentation may refer to either the compositor thread or the |
99 | | * compositor process. |
100 | | * See explanations in ShadowLayers.h. |
101 | | * |
102 | | * |
103 | | * # Backend implementations |
104 | | * |
105 | | * Compositor backends like OpenGL or flavours of D3D live in their own directory |
106 | | * under gfx/layers/. To add a new backend, implement at least the following |
107 | | * interfaces: |
108 | | * - Compositor (ex. CompositorOGL) |
109 | | * - TextureHost (ex. SurfaceTextureHost) |
110 | | * Depending on the type of data that needs to be serialized, you may need to |
111 | | * add specific TextureClient implementations. |
112 | | */ |
113 | | |
114 | | class nsIWidget; |
115 | | |
116 | | namespace mozilla { |
117 | | namespace gfx { |
118 | | class DrawTarget; |
119 | | class DataSourceSurface; |
120 | | } // namespace gfx |
121 | | |
122 | | namespace layers { |
123 | | |
124 | | struct Effect; |
125 | | struct EffectChain; |
126 | | class Image; |
127 | | class Layer; |
128 | | class TextureSource; |
129 | | class DataTextureSource; |
130 | | class CompositingRenderTarget; |
131 | | class CompositorBridgeParent; |
132 | | class LayerManagerComposite; |
133 | | class CompositorOGL; |
134 | | class CompositorD3D11; |
135 | | class BasicCompositor; |
136 | | class TextureReadLock; |
137 | | struct GPUStats; |
138 | | class AsyncReadbackBuffer; |
139 | | |
140 | | enum SurfaceInitMode |
141 | | { |
142 | | INIT_MODE_NONE, |
143 | | INIT_MODE_CLEAR |
144 | | }; |
145 | | |
146 | | /** |
147 | | * Common interface for compositor backends. |
148 | | * |
149 | | * Compositor provides a cross-platform interface to a set of operations for |
150 | | * compositing quads. Compositor knows nothing about the layer tree. It must be |
151 | | * told everything about each composited quad - contents, location, transform, |
152 | | * opacity, etc. |
153 | | * |
154 | | * In theory it should be possible for different widgets to use the same |
155 | | * compositor. In practice, we use one compositor per window. |
156 | | * |
157 | | * # Usage |
158 | | * |
159 | | * For an example of a user of Compositor, see LayerManagerComposite. |
160 | | * |
161 | | * Initialization: create a Compositor object, call Initialize(). |
162 | | * |
163 | | * Destruction: destroy any resources associated with the compositor, call |
164 | | * Destroy(), delete the Compositor object. |
165 | | * |
166 | | * Composition: |
167 | | * call BeginFrame, |
168 | | * for each quad to be composited: |
169 | | * call MakeCurrent if necessary (not necessary if no other context has been |
170 | | * made current), |
171 | | * take care of any texture upload required to composite the quad, this step |
172 | | * is backend-dependent, |
173 | | * construct an EffectChain for the quad, |
174 | | * call DrawQuad, |
175 | | * call EndFrame. |
176 | | * |
177 | | * By default, the compositor will render to the screen, to render to a target, |
178 | | * call SetTargetContext or SetRenderTarget, the latter with a target created |
179 | | * by CreateRenderTarget or CreateRenderTargetFromSource. |
180 | | * |
181 | | * The target and viewport methods can be called before any DrawQuad call and |
182 | | * affect any subsequent DrawQuad calls. |
183 | | */ |
184 | | class Compositor : public TextureSourceProvider |
185 | | { |
186 | | protected: |
187 | | virtual ~Compositor(); |
188 | | |
189 | | public: |
190 | | explicit Compositor(widget::CompositorWidget* aWidget, |
191 | | CompositorBridgeParent* aParent = nullptr); |
192 | | |
193 | | virtual bool Initialize(nsCString* const out_failureReason) = 0; |
194 | | virtual void Destroy() override; |
195 | | bool IsDestroyed() const { return mIsDestroyed; } |
196 | | |
197 | | virtual void DetachWidget() { mWidget = nullptr; } |
198 | | |
199 | | /** |
200 | | * Request a texture host identifier that may be used for creating textures |
201 | | * across process or thread boundaries that are compatible with this |
202 | | * compositor. |
203 | | */ |
204 | | virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() = 0; |
205 | | |
206 | | /** |
207 | | * Properties of the compositor. |
208 | | */ |
209 | | virtual bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) = 0; |
210 | | |
211 | | /** |
212 | | * Set the target for rendering. Results will have been written to aTarget by |
213 | | * the time that EndFrame returns. |
214 | | * |
215 | | * If this method is not used, or we pass in nullptr, we target the compositor's |
216 | | * usual swap chain and render to the screen. |
217 | | */ |
218 | | void SetTargetContext(gfx::DrawTarget* aTarget, const gfx::IntRect& aRect) |
219 | | { |
220 | | mTarget = aTarget; |
221 | | mTargetBounds = aRect; |
222 | | } |
223 | | gfx::DrawTarget* GetTargetContext() const |
224 | | { |
225 | | return mTarget; |
226 | | } |
227 | | void ClearTargetContext() |
228 | | { |
229 | | mTarget = nullptr; |
230 | | } |
231 | | |
232 | | typedef uint32_t MakeCurrentFlags; |
233 | | static const MakeCurrentFlags ForceMakeCurrent = 0x1; |
234 | | /** |
235 | | * Make this compositor's rendering context the current context for the |
236 | | * underlying graphics API. This may be a global operation, depending on the |
237 | | * API. Our context will remain the current one until someone else changes it. |
238 | | * |
239 | | * Clients of the compositor should call this at the start of the compositing |
240 | | * process, it might be required by texture uploads etc. |
241 | | * |
242 | | * If aFlags == ForceMakeCurrent then we will (re-)set our context on the |
243 | | * underlying API even if it is already the current context. |
244 | | */ |
245 | | virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) = 0; |
246 | | |
247 | | /** |
248 | | * Creates a Surface that can be used as a rendering target by this |
249 | | * compositor. |
250 | | */ |
251 | | virtual already_AddRefed<CompositingRenderTarget> |
252 | | CreateRenderTarget(const gfx::IntRect& aRect, SurfaceInitMode aInit) = 0; |
253 | | |
254 | | /** |
255 | | * Creates a Surface that can be used as a rendering target by this |
256 | | * compositor, and initializes the surface by copying from aSource. |
257 | | * If aSource is null, then the current screen buffer is used as source. |
258 | | * |
259 | | * aSourcePoint specifies the point in aSource to copy data from. |
260 | | */ |
261 | | virtual already_AddRefed<CompositingRenderTarget> |
262 | | CreateRenderTargetFromSource(const gfx::IntRect& aRect, |
263 | | const CompositingRenderTarget* aSource, |
264 | | const gfx::IntPoint& aSourcePoint) = 0; |
265 | | |
266 | | /** |
267 | | * Grab a snapshot of aSource and store it in aDest, so that the pixels can |
268 | | * be read on the CPU by mapping aDest at some point in the future. |
269 | | * aSource and aDest must have the same size. |
270 | | * If this is a GPU compositor, this call must not block on the GPU. |
271 | | * Returns whether the operation was successful. |
272 | | */ |
273 | | virtual bool |
274 | | ReadbackRenderTarget(CompositingRenderTarget* aSource, |
275 | | AsyncReadbackBuffer* aDest) { return false; } |
276 | | |
277 | | /** |
278 | | * Create an AsyncReadbackBuffer of the specified size. Can return null. |
279 | | */ |
280 | | virtual already_AddRefed<AsyncReadbackBuffer> |
281 | | CreateAsyncReadbackBuffer(const gfx::IntSize& aSize) { return nullptr; } |
282 | | |
283 | | /** |
284 | | * Draw a part of aSource into the current render target. |
285 | | * Scaling is done with linear filtering. |
286 | | * Returns whether the operation was successful. |
287 | | */ |
288 | | virtual bool |
289 | | BlitRenderTarget(CompositingRenderTarget* aSource, |
290 | | const gfx::IntSize& aSourceSize, |
291 | | const gfx::IntSize& aDestSize) { return false; } |
292 | | |
293 | | /** |
294 | | * Sets the given surface as the target for subsequent calls to DrawQuad. |
295 | | * Passing null as aSurface sets the screen as the target. |
296 | | */ |
297 | | virtual void SetRenderTarget(CompositingRenderTarget* aSurface) = 0; |
298 | | |
299 | | /** |
300 | | * Returns the current target for rendering. Will return null if we are |
301 | | * rendering to the screen. |
302 | | */ |
303 | | virtual CompositingRenderTarget* GetCurrentRenderTarget() const = 0; |
304 | | |
305 | | /** |
306 | | * Returns a render target which contains the entire window's drawing. |
307 | | * On platforms where no such render target is used during compositing (e.g. |
308 | | * with buffered BasicCompositor, where only the invalid area is drawn to a |
309 | | * render target), this will return null. |
310 | | */ |
311 | | virtual CompositingRenderTarget* GetWindowRenderTarget() const { return nullptr; } |
312 | | |
313 | | /** |
314 | | * Mostly the compositor will pull the size from a widget and this method will |
315 | | * be ignored, but compositor implementations are free to use it if they like. |
316 | | */ |
317 | | virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) = 0; |
318 | | |
319 | | /** |
320 | | * Declare an offset to use when rendering layers. This will be ignored when |
321 | | * rendering to a target instead of the screen. |
322 | | */ |
323 | | virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) = 0; |
324 | | |
325 | | void DrawGeometry(const gfx::Rect& aRect, |
326 | | const gfx::IntRect& aClipRect, |
327 | | const EffectChain &aEffectChain, |
328 | | gfx::Float aOpacity, |
329 | | const gfx::Matrix4x4& aTransform, |
330 | | const gfx::Rect& aVisibleRect, |
331 | | const Maybe<gfx::Polygon>& aGeometry); |
332 | | |
333 | | void DrawGeometry(const gfx::Rect& aRect, |
334 | | const gfx::IntRect& aClipRect, |
335 | | const EffectChain &aEffectChain, |
336 | | gfx::Float aOpacity, |
337 | | const gfx::Matrix4x4& aTransform, |
338 | | const Maybe<gfx::Polygon>& aGeometry) |
339 | | { |
340 | | DrawGeometry(aRect, aClipRect, aEffectChain, aOpacity, |
341 | | aTransform, aRect, aGeometry); |
342 | | } |
343 | | |
344 | | /** |
345 | | * Tell the compositor to draw a quad. What to do draw and how it is |
346 | | * drawn is specified by aEffectChain. aRect is the quad to draw, in user space. |
347 | | * aTransform transforms from user space to screen space. If texture coords are |
348 | | * required, these will be in the primary effect in the effect chain. |
349 | | * aVisibleRect is used to determine which edges should be antialiased, |
350 | | * without applying the effect to the inner edges of a tiled layer. |
351 | | */ |
352 | | virtual void DrawQuad(const gfx::Rect& aRect, const gfx::IntRect& aClipRect, |
353 | | const EffectChain& aEffectChain, |
354 | | gfx::Float aOpacity, const gfx::Matrix4x4& aTransform, |
355 | | const gfx::Rect& aVisibleRect) = 0; |
356 | | |
357 | | /** |
358 | | * Overload of DrawQuad, with aVisibleRect defaulted to the value of aRect. |
359 | | * Use this when you are drawing a single quad that is not part of a tiled |
360 | | * layer. |
361 | | */ |
362 | | void DrawQuad(const gfx::Rect& aRect, const gfx::IntRect& aClipRect, |
363 | | const EffectChain& aEffectChain, |
364 | | gfx::Float aOpacity, const gfx::Matrix4x4& aTransform) { |
365 | | DrawQuad(aRect, aClipRect, aEffectChain, aOpacity, aTransform, aRect); |
366 | | } |
367 | | |
368 | | virtual void DrawTriangle(const gfx::TexturedTriangle& aTriangle, |
369 | | const gfx::IntRect& aClipRect, |
370 | | const EffectChain& aEffectChain, |
371 | | gfx::Float aOpacity, |
372 | | const gfx::Matrix4x4& aTransform, |
373 | | const gfx::Rect& aVisibleRect) |
374 | | { |
375 | | MOZ_CRASH("Compositor::DrawTriangle is not implemented for the current platform!"); |
376 | | } |
377 | | |
378 | | virtual bool SupportsLayerGeometry() const |
379 | | { |
380 | | return false; |
381 | | } |
382 | | |
383 | | /** |
384 | | * Draw an unfilled solid color rect. Typically used for debugging overlays. |
385 | | */ |
386 | | void SlowDrawRect(const gfx::Rect& aRect, const gfx::Color& color, |
387 | | const gfx::IntRect& aClipRect = gfx::IntRect(), |
388 | | const gfx::Matrix4x4& aTransform = gfx::Matrix4x4(), |
389 | | int aStrokeWidth = 1); |
390 | | |
391 | | /** |
392 | | * Draw a solid color filled rect. This is a simple DrawQuad helper. |
393 | | */ |
394 | | void FillRect(const gfx::Rect& aRect, const gfx::Color& color, |
395 | | const gfx::IntRect& aClipRect = gfx::IntRect(), |
396 | | const gfx::Matrix4x4& aTransform = gfx::Matrix4x4()); |
397 | | |
398 | | void SetClearColor(const gfx::Color& aColor) { |
399 | | mClearColor = aColor; |
400 | | } |
401 | | |
402 | | void SetDefaultClearColor(const gfx::Color& aColor) { |
403 | | mDefaultClearColor = aColor; |
404 | | } |
405 | | |
406 | | void SetClearColorToDefault() { |
407 | | mClearColor = mDefaultClearColor; |
408 | | } |
409 | | |
410 | | /* |
411 | | * Clear aRect on current render target. |
412 | | */ |
413 | | virtual void ClearRect(const gfx::Rect& aRect) = 0; |
414 | | |
415 | | /** |
416 | | * Start a new frame. |
417 | | * |
418 | | * aInvalidRect is the invalid region of the screen; it can be ignored for |
419 | | * compositors where the performance for compositing the entire window is |
420 | | * sufficient. |
421 | | * |
422 | | * aClipRectIn is the clip rect for the window in window space (optional). |
423 | | * aTransform is the transform from user space to window space. |
424 | | * aRenderBounds bounding rect for rendering, in user space. |
425 | | * |
426 | | * If aClipRectIn is null, this method sets *aClipRectOut to the clip rect |
427 | | * actually used for rendering (if aClipRectIn is non-null, we will use that |
428 | | * for the clip rect). |
429 | | * |
430 | | * If aRenderBoundsOut is non-null, it will be set to the render bounds |
431 | | * actually used by the compositor in window space. If aRenderBoundsOut |
432 | | * is returned empty, composition should be aborted. |
433 | | * |
434 | | * If aOpaque is true, then all of aInvalidRegion will be drawn to with |
435 | | * opaque content. |
436 | | */ |
437 | | virtual void BeginFrame(const nsIntRegion& aInvalidRegion, |
438 | | const gfx::IntRect* aClipRectIn, |
439 | | const gfx::IntRect& aRenderBounds, |
440 | | const nsIntRegion& aOpaqueRegion, |
441 | | gfx::IntRect* aClipRectOut = nullptr, |
442 | | gfx::IntRect* aRenderBoundsOut = nullptr) = 0; |
443 | | |
444 | | /** |
445 | | * Notification that we've finished issuing draw commands for normal |
446 | | * layers (as opposed to the diagnostic overlay which comes after). |
447 | | */ |
448 | | virtual void NormalDrawingDone() {} |
449 | | |
450 | | /** |
451 | | * Flush the current frame to the screen and tidy up. |
452 | | * |
453 | | * Derived class overriding this should call Compositor::EndFrame. |
454 | | */ |
455 | | virtual void EndFrame(); |
456 | | |
457 | | virtual void CancelFrame(bool aNeedFlush = true) { ReadUnlockTextures(); } |
458 | | |
459 | | /** |
460 | | * Whether textures created by this compositor can receive partial updates. |
461 | | */ |
462 | | virtual bool SupportsPartialTextureUpdate() = 0; |
463 | | |
464 | | void SetDiagnosticTypes(DiagnosticTypes aDiagnostics) |
465 | | { |
466 | | mDiagnosticTypes = aDiagnostics; |
467 | | } |
468 | | |
469 | | DiagnosticTypes GetDiagnosticTypes() const |
470 | | { |
471 | | return mDiagnosticTypes; |
472 | | } |
473 | | |
474 | | void DrawDiagnostics(DiagnosticFlags aFlags, |
475 | | const gfx::Rect& visibleRect, |
476 | | const gfx::IntRect& aClipRect, |
477 | | const gfx::Matrix4x4& transform, |
478 | | uint32_t aFlashCounter = DIAGNOSTIC_FLASH_COUNTER_MAX); |
479 | | |
480 | | void DrawDiagnostics(DiagnosticFlags aFlags, |
481 | | const nsIntRegion& visibleRegion, |
482 | | const gfx::IntRect& aClipRect, |
483 | | const gfx::Matrix4x4& transform, |
484 | | uint32_t aFlashCounter = DIAGNOSTIC_FLASH_COUNTER_MAX); |
485 | | |
486 | | #ifdef MOZ_DUMP_PAINTING |
487 | | virtual const char* Name() const = 0; |
488 | | #endif // MOZ_DUMP_PAINTING |
489 | | |
490 | | virtual LayersBackend GetBackendType() const = 0; |
491 | | |
492 | | virtual CompositorOGL* AsCompositorOGL() { return nullptr; } |
493 | | virtual CompositorD3D11* AsCompositorD3D11() { return nullptr; } |
494 | | virtual BasicCompositor* AsBasicCompositor() { return nullptr; } |
495 | | |
496 | | virtual Compositor* AsCompositor() override { |
497 | | return this; |
498 | | } |
499 | | |
500 | | TimeStamp GetLastCompositionEndTime() const override { |
501 | | return mLastCompositionEndTime; |
502 | | } |
503 | | |
504 | | void UnlockAfterComposition(TextureHost* aTexture) override; |
505 | | bool NotifyNotUsedAfterComposition(TextureHost* aTextureHost) override; |
506 | | |
507 | | /** |
508 | | * Notify the compositor that composition is being paused. This allows the |
509 | | * compositor to temporarily release any resources. |
510 | | * Between calling Pause and Resume, compositing may fail. |
511 | | */ |
512 | | virtual void Pause() {} |
513 | | /** |
514 | | * Notify the compositor that composition is being resumed. The compositor |
515 | | * regain any resources it requires for compositing. |
516 | | * Returns true if succeeded. |
517 | | */ |
518 | | virtual bool Resume() { return true; } |
519 | | |
520 | | /** |
521 | | * Call before rendering begins to ensure the compositor is ready to |
522 | | * composite. Returns false if rendering should be aborted. |
523 | | */ |
524 | | virtual bool Ready() { return true; } |
525 | | |
526 | | virtual void ForcePresent() { } |
527 | | |
528 | | virtual bool IsPendingComposite() { return false; } |
529 | | |
530 | | virtual void FinishPendingComposite() {} |
531 | | |
532 | | widget::CompositorWidget* GetWidget() const { return mWidget; } |
533 | | |
534 | | // Return statistics for the most recent frame we computed statistics for. |
535 | | virtual void GetFrameStats(GPUStats* aStats); |
536 | | |
537 | | ScreenRotation GetScreenRotation() const { |
538 | | return mScreenRotation; |
539 | | } |
540 | | void SetScreenRotation(ScreenRotation aRotation) { |
541 | | mScreenRotation = aRotation; |
542 | | } |
543 | | |
544 | | // A stale Compositor has no CompositorBridgeParent; it will not process |
545 | | // frames and should not be used. |
546 | | void SetInvalid(); |
547 | | virtual bool IsValid() const override; |
548 | | CompositorBridgeParent* GetCompositorBridgeParent() const { |
549 | | return mParent; |
550 | | } |
551 | | |
552 | | protected: |
553 | | void DrawDiagnosticsInternal(DiagnosticFlags aFlags, |
554 | | const gfx::Rect& aVisibleRect, |
555 | | const gfx::IntRect& aClipRect, |
556 | | const gfx::Matrix4x4& transform, |
557 | | uint32_t aFlashCounter); |
558 | | |
559 | | bool ShouldDrawDiagnostics(DiagnosticFlags); |
560 | | |
561 | | /** |
562 | | * Given a layer rect, clip, and transform, compute the area of the backdrop that |
563 | | * needs to be copied for mix-blending. The output transform translates from 0..1 |
564 | | * space into the backdrop rect space. |
565 | | * |
566 | | * The transformed layer quad is also optionally returned - this is the same as |
567 | | * the result rect, before rounding. |
568 | | */ |
569 | | gfx::IntRect ComputeBackdropCopyRect(const gfx::Rect& aRect, |
570 | | const gfx::IntRect& aClipRect, |
571 | | const gfx::Matrix4x4& aTransform, |
572 | | gfx::Matrix4x4* aOutTransform, |
573 | | gfx::Rect* aOutLayerQuad = nullptr); |
574 | | |
575 | | gfx::IntRect ComputeBackdropCopyRect(const gfx::Triangle& aTriangle, |
576 | | const gfx::IntRect& aClipRect, |
577 | | const gfx::Matrix4x4& aTransform, |
578 | | gfx::Matrix4x4* aOutTransform, |
579 | | gfx::Rect* aOutLayerQuad = nullptr); |
580 | | |
581 | | virtual void DrawTriangles(const nsTArray<gfx::TexturedTriangle>& aTriangles, |
582 | | const gfx::Rect& aRect, |
583 | | const gfx::IntRect& aClipRect, |
584 | | const EffectChain& aEffectChain, |
585 | | gfx::Float aOpacity, |
586 | | const gfx::Matrix4x4& aTransform, |
587 | | const gfx::Rect& aVisibleRect); |
588 | | |
589 | | virtual void DrawPolygon(const gfx::Polygon& aPolygon, |
590 | | const gfx::Rect& aRect, |
591 | | const gfx::IntRect& aClipRect, |
592 | | const EffectChain& aEffectChain, |
593 | | gfx::Float aOpacity, |
594 | | const gfx::Matrix4x4& aTransform, |
595 | | const gfx::Rect& aVisibleRect); |
596 | | |
597 | | /** |
598 | | * Last Composition end time. |
599 | | */ |
600 | | TimeStamp mLastCompositionEndTime; |
601 | | |
602 | | DiagnosticTypes mDiagnosticTypes; |
603 | | CompositorBridgeParent* mParent; |
604 | | |
605 | | /** |
606 | | * We keep track of the total number of pixels filled as we composite the |
607 | | * current frame. This value is an approximation and is not accurate, |
608 | | * especially in the presence of transforms. |
609 | | */ |
610 | | size_t mPixelsPerFrame; |
611 | | size_t mPixelsFilled; |
612 | | |
613 | | ScreenRotation mScreenRotation; |
614 | | |
615 | | RefPtr<gfx::DrawTarget> mTarget; |
616 | | gfx::IntRect mTargetBounds; |
617 | | |
618 | | widget::CompositorWidget* mWidget; |
619 | | |
620 | | bool mIsDestroyed; |
621 | | |
622 | | gfx::Color mClearColor; |
623 | | gfx::Color mDefaultClearColor; |
624 | | |
625 | | private: |
626 | | static LayersBackend sBackend; |
627 | | |
628 | | }; |
629 | | |
630 | | // Returns the number of rects. (Up to 4) |
631 | | typedef gfx::Rect decomposedRectArrayT[4]; |
632 | | size_t DecomposeIntoNoRepeatRects(const gfx::Rect& aRect, |
633 | | const gfx::Rect& aTexCoordRect, |
634 | | decomposedRectArrayT* aLayerRects, |
635 | | decomposedRectArrayT* aTextureRects); |
636 | | |
637 | | static inline bool |
638 | | BlendOpIsMixBlendMode(gfx::CompositionOp aOp) |
639 | 0 | { |
640 | 0 | switch (aOp) { |
641 | 0 | case gfx::CompositionOp::OP_MULTIPLY: |
642 | 0 | case gfx::CompositionOp::OP_SCREEN: |
643 | 0 | case gfx::CompositionOp::OP_OVERLAY: |
644 | 0 | case gfx::CompositionOp::OP_DARKEN: |
645 | 0 | case gfx::CompositionOp::OP_LIGHTEN: |
646 | 0 | case gfx::CompositionOp::OP_COLOR_DODGE: |
647 | 0 | case gfx::CompositionOp::OP_COLOR_BURN: |
648 | 0 | case gfx::CompositionOp::OP_HARD_LIGHT: |
649 | 0 | case gfx::CompositionOp::OP_SOFT_LIGHT: |
650 | 0 | case gfx::CompositionOp::OP_DIFFERENCE: |
651 | 0 | case gfx::CompositionOp::OP_EXCLUSION: |
652 | 0 | case gfx::CompositionOp::OP_HUE: |
653 | 0 | case gfx::CompositionOp::OP_SATURATION: |
654 | 0 | case gfx::CompositionOp::OP_COLOR: |
655 | 0 | case gfx::CompositionOp::OP_LUMINOSITY: |
656 | 0 | return true; |
657 | 0 | default: |
658 | 0 | return false; |
659 | 0 | } |
660 | 0 | } |
661 | | |
662 | | class AsyncReadbackBuffer |
663 | | { |
664 | | public: |
665 | | NS_INLINE_DECL_REFCOUNTING(AsyncReadbackBuffer) |
666 | | |
667 | | gfx::IntSize GetSize() const { return mSize; } |
668 | | virtual bool MapAndCopyInto(gfx::DataSourceSurface* aSurface, |
669 | | const gfx::IntSize& aReadSize) const=0; |
670 | | |
671 | | protected: |
672 | | explicit AsyncReadbackBuffer(const gfx::IntSize& aSize) : mSize(aSize) {} |
673 | | virtual ~AsyncReadbackBuffer() {} |
674 | | |
675 | | gfx::IntSize mSize; |
676 | | }; |
677 | | |
678 | | struct TexturedVertex |
679 | | { |
680 | | float position[2]; |
681 | | float texCoords[2]; |
682 | | }; |
683 | | |
684 | | nsTArray<TexturedVertex> |
685 | | TexturedTrianglesToVertexArray(const nsTArray<gfx::TexturedTriangle>& aTriangles); |
686 | | |
687 | | } // namespace layers |
688 | | } // namespace mozilla |
689 | | |
690 | | #endif /* MOZILLA_GFX_COMPOSITOR_H */ |