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