Source code

Revision control

Other Tools

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