summaryrefslogtreecommitdiffstats
path: root/gfx/layers/Compositor.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/Compositor.h')
-rw-r--r--gfx/layers/Compositor.h726
1 files changed, 726 insertions, 0 deletions
diff --git a/gfx/layers/Compositor.h b/gfx/layers/Compositor.h
new file mode 100644
index 000000000..f7aecb0f1
--- /dev/null
+++ b/gfx/layers/Compositor.h
@@ -0,0 +1,726 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MOZILLA_GFX_COMPOSITOR_H
+#define MOZILLA_GFX_COMPOSITOR_H
+
+#include "Units.h" // for ScreenPoint
+#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
+#include "mozilla/RefPtr.h" // for already_AddRefed, RefCounted
+#include "mozilla/gfx/2D.h" // for DrawTarget
+#include "mozilla/gfx/MatrixFwd.h" // for Matrix4x4
+#include "mozilla/gfx/Point.h" // for IntSize, Point
+#include "mozilla/gfx/Polygon.h" // for Polygon3D
+#include "mozilla/gfx/Rect.h" // for Rect, IntRect
+#include "mozilla/gfx/Types.h" // for Float
+#include "mozilla/gfx/Triangle.h" // for Triangle, TexturedTriangle
+#include "mozilla/layers/CompositorTypes.h" // for DiagnosticTypes, etc
+#include "mozilla/layers/LayersTypes.h" // for LayersBackend
+#include "mozilla/widget/CompositorWidget.h"
+#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
+#include "nsRegion.h"
+#include <vector>
+#include "mozilla/WidgetUtils.h"
+
+/**
+ * Different elements of a web pages are rendered into separate "layers" before
+ * they are flattened into the final image that is brought to the screen.
+ * See Layers.h for more informations about layers and why we use retained
+ * structures.
+ * Most of the documentation for layers is directly in the source code in the
+ * form of doc comments. An overview can also be found in the the wiki:
+ * https://wiki.mozilla.org/Gecko:Overview#Graphics
+ *
+ *
+ * # Main interfaces and abstractions
+ *
+ * - Layer, ShadowableLayer and LayerComposite
+ * (see Layers.h and ipc/ShadowLayers.h)
+ * - CompositableClient and CompositableHost
+ * (client/CompositableClient.h composite/CompositableHost.h)
+ * - TextureClient and TextureHost
+ * (client/TextureClient.h composite/TextureHost.h)
+ * - TextureSource
+ * (composite/TextureHost.h)
+ * - Forwarders
+ * (ipc/CompositableForwarder.h ipc/ShadowLayers.h)
+ * - Compositor
+ * (this file)
+ * - IPDL protocols
+ * (.ipdl files under the gfx/layers/ipc directory)
+ *
+ * The *Client and Shadowable* classes are always used on the content thread.
+ * Forwarders are always used on the content thread.
+ * The *Host and Shadow* classes are always used on the compositor thread.
+ * Compositors, TextureSource, and Effects are always used on the compositor
+ * thread.
+ * Most enums and constants are declared in LayersTypes.h and CompositorTypes.h.
+ *
+ *
+ * # Texture transfer
+ *
+ * Most layer classes own a Compositable plus some extra information like
+ * transforms and clip rects. They are platform independent.
+ * Compositable classes manipulate Texture objects and are reponsible for
+ * things like tiling, buffer rotation or double buffering. Compositables
+ * are also platform-independent. Examples of compositable classes are:
+ * - ImageClient
+ * - CanvasClient
+ * - ContentHost
+ * - etc.
+ * Texture classes (TextureClient and TextureHost) are thin abstractions over
+ * platform-dependent texture memory. They are maniplulated by compositables
+ * and don't know about buffer rotations and such. The purposes of TextureClient
+ * and TextureHost are to synchronize, serialize and deserialize texture data.
+ * TextureHosts provide access to TextureSources that are views on the
+ * Texture data providing the necessary api for Compositor backend to composite
+ * them.
+ *
+ * Compositable and Texture clients and hosts are created using factory methods.
+ * They should only be created by using their constructor in exceptional
+ * circumstances. The factory methods are located:
+ * TextureClient - CompositableClient::CreateTextureClient
+ * TextureHost - TextureHost::CreateTextureHost, which calls a
+ * platform-specific function, e.g., CreateTextureHostOGL
+ * CompositableClient - in the appropriate subclass, e.g.,
+ * CanvasClient::CreateCanvasClient
+ * CompositableHost - CompositableHost::Create
+ *
+ *
+ * # IPDL
+ *
+ * If off-main-thread compositing (OMTC) is enabled, compositing is performed
+ * in a dedicated thread. In some setups compositing happens in a dedicated
+ * process. Documentation may refer to either the compositor thread or the
+ * compositor process.
+ * See explanations in ShadowLayers.h.
+ *
+ *
+ * # Backend implementations
+ *
+ * Compositor backends like OpenGL or flavours of D3D live in their own directory
+ * under gfx/layers/. To add a new backend, implement at least the following
+ * interfaces:
+ * - Compositor (ex. CompositorOGL)
+ * - TextureHost (ex. SurfaceTextureHost)
+ * Depending on the type of data that needs to be serialized, you may need to
+ * add specific TextureClient implementations.
+ */
+
+class nsIWidget;
+
+namespace mozilla {
+namespace gfx {
+class Matrix;
+class DrawTarget;
+class DataSourceSurface;
+} // namespace gfx
+
+namespace layers {
+
+struct Effect;
+struct EffectChain;
+class Image;
+class ImageHostOverlay;
+class Layer;
+class TextureSource;
+class DataTextureSource;
+class CompositingRenderTarget;
+class CompositorBridgeParent;
+class LayerManagerComposite;
+class CompositorOGL;
+class CompositorD3D9;
+class CompositorD3D11;
+class BasicCompositor;
+class TextureHost;
+class TextureReadLock;
+
+enum SurfaceInitMode
+{
+ INIT_MODE_NONE,
+ INIT_MODE_CLEAR
+};
+
+/**
+ * Common interface for compositor backends.
+ *
+ * Compositor provides a cross-platform interface to a set of operations for
+ * compositing quads. Compositor knows nothing about the layer tree. It must be
+ * told everything about each composited quad - contents, location, transform,
+ * opacity, etc.
+ *
+ * In theory it should be possible for different widgets to use the same
+ * compositor. In practice, we use one compositor per window.
+ *
+ * # Usage
+ *
+ * For an example of a user of Compositor, see LayerManagerComposite.
+ *
+ * Initialization: create a Compositor object, call Initialize().
+ *
+ * Destruction: destroy any resources associated with the compositor, call
+ * Destroy(), delete the Compositor object.
+ *
+ * Composition:
+ * call BeginFrame,
+ * for each quad to be composited:
+ * call MakeCurrent if necessary (not necessary if no other context has been
+ * made current),
+ * take care of any texture upload required to composite the quad, this step
+ * is backend-dependent,
+ * construct an EffectChain for the quad,
+ * call DrawQuad,
+ * call EndFrame.
+ * If the compositor is usually used for compositing but compositing is
+ * temporarily done without the compositor, call EndFrameForExternalComposition
+ * after compositing each frame so the compositor can remain internally
+ * consistent.
+ *
+ * By default, the compositor will render to the screen, to render to a target,
+ * call SetTargetContext or SetRenderTarget, the latter with a target created
+ * by CreateRenderTarget or CreateRenderTargetFromSource.
+ *
+ * The target and viewport methods can be called before any DrawQuad call and
+ * affect any subsequent DrawQuad calls.
+ */
+class Compositor
+{
+protected:
+ virtual ~Compositor();
+
+public:
+ NS_INLINE_DECL_REFCOUNTING(Compositor)
+
+ explicit Compositor(widget::CompositorWidget* aWidget,
+ CompositorBridgeParent* aParent = nullptr);
+
+ virtual already_AddRefed<DataTextureSource> CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) = 0;
+
+ virtual already_AddRefed<DataTextureSource>
+ CreateDataTextureSourceAround(gfx::DataSourceSurface* aSurface) { return nullptr; }
+
+ virtual already_AddRefed<DataTextureSource>
+ CreateDataTextureSourceAroundYCbCr(TextureHost* aTexture) { return nullptr; }
+
+ virtual bool Initialize(nsCString* const out_failureReason) = 0;
+ virtual void Destroy();
+ bool IsDestroyed() const { return mIsDestroyed; }
+
+ virtual void DetachWidget() { mWidget = nullptr; }
+
+ /**
+ * Return true if the effect type is supported.
+ *
+ * By default Compositor implementations should support all effects but in
+ * some rare cases it is not possible to support an effect efficiently.
+ * This is the case for BasicCompositor with EffectYCbCr.
+ */
+ virtual bool SupportsEffect(EffectTypes aEffect) { return true; }
+
+ /**
+ * Request a texture host identifier that may be used for creating textures
+ * across process or thread boundaries that are compatible with this
+ * compositor.
+ */
+ virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() = 0;
+
+ /**
+ * Properties of the compositor.
+ */
+ virtual bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) = 0;
+ virtual int32_t GetMaxTextureSize() const = 0;
+
+ /**
+ * Set the target for rendering. Results will have been written to aTarget by
+ * the time that EndFrame returns.
+ *
+ * If this method is not used, or we pass in nullptr, we target the compositor's
+ * usual swap chain and render to the screen.
+ */
+ void SetTargetContext(gfx::DrawTarget* aTarget, const gfx::IntRect& aRect)
+ {
+ mTarget = aTarget;
+ mTargetBounds = aRect;
+ }
+ gfx::DrawTarget* GetTargetContext() const
+ {
+ return mTarget;
+ }
+ void ClearTargetContext()
+ {
+ mTarget = nullptr;
+ }
+
+ typedef uint32_t MakeCurrentFlags;
+ static const MakeCurrentFlags ForceMakeCurrent = 0x1;
+ /**
+ * Make this compositor's rendering context the current context for the
+ * underlying graphics API. This may be a global operation, depending on the
+ * API. Our context will remain the current one until someone else changes it.
+ *
+ * Clients of the compositor should call this at the start of the compositing
+ * process, it might be required by texture uploads etc.
+ *
+ * If aFlags == ForceMakeCurrent then we will (re-)set our context on the
+ * underlying API even if it is already the current context.
+ */
+ virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) = 0;
+
+ /**
+ * Creates a Surface that can be used as a rendering target by this
+ * compositor.
+ */
+ virtual already_AddRefed<CompositingRenderTarget>
+ CreateRenderTarget(const gfx::IntRect& aRect, SurfaceInitMode aInit) = 0;
+
+ /**
+ * Creates a Surface that can be used as a rendering target by this
+ * compositor, and initializes the surface by copying from aSource.
+ * If aSource is null, then the current screen buffer is used as source.
+ *
+ * aSourcePoint specifies the point in aSource to copy data from.
+ */
+ virtual already_AddRefed<CompositingRenderTarget>
+ CreateRenderTargetFromSource(const gfx::IntRect& aRect,
+ const CompositingRenderTarget* aSource,
+ const gfx::IntPoint& aSourcePoint) = 0;
+
+ /**
+ * Sets the given surface as the target for subsequent calls to DrawQuad.
+ * Passing null as aSurface sets the screen as the target.
+ */
+ virtual void SetRenderTarget(CompositingRenderTarget* aSurface) = 0;
+
+ /**
+ * Returns the current target for rendering. Will return null if we are
+ * rendering to the screen.
+ */
+ virtual CompositingRenderTarget* GetCurrentRenderTarget() const = 0;
+
+ /**
+ * Mostly the compositor will pull the size from a widget and this method will
+ * be ignored, but compositor implementations are free to use it if they like.
+ */
+ virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) = 0;
+
+ /**
+ * Declare an offset to use when rendering layers. This will be ignored when
+ * rendering to a target instead of the screen.
+ */
+ virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) = 0;
+
+ void DrawGeometry(const gfx::Rect& aRect,
+ const gfx::IntRect& aClipRect,
+ const EffectChain &aEffectChain,
+ gfx::Float aOpacity,
+ const gfx::Matrix4x4& aTransform,
+ const gfx::Rect& aVisibleRect,
+ const Maybe<gfx::Polygon3D>& aGeometry);
+
+ void DrawGeometry(const gfx::Rect& aRect,
+ const gfx::IntRect& aClipRect,
+ const EffectChain &aEffectChain,
+ gfx::Float aOpacity,
+ const gfx::Matrix4x4& aTransform,
+ const Maybe<gfx::Polygon3D>& aGeometry)
+ {
+ DrawGeometry(aRect, aClipRect, aEffectChain, aOpacity,
+ aTransform, aRect, aGeometry);
+ }
+
+ /**
+ * Tell the compositor to draw a quad. What to do draw and how it is
+ * drawn is specified by aEffectChain. aRect is the quad to draw, in user space.
+ * aTransform transforms from user space to screen space. If texture coords are
+ * required, these will be in the primary effect in the effect chain.
+ * aVisibleRect is used to determine which edges should be antialiased,
+ * without applying the effect to the inner edges of a tiled layer.
+ */
+ virtual void DrawQuad(const gfx::Rect& aRect, const gfx::IntRect& aClipRect,
+ const EffectChain& aEffectChain,
+ gfx::Float aOpacity, const gfx::Matrix4x4& aTransform,
+ const gfx::Rect& aVisibleRect) = 0;
+
+ /**
+ * Overload of DrawQuad, with aVisibleRect defaulted to the value of aRect.
+ * Use this when you are drawing a single quad that is not part of a tiled
+ * layer.
+ */
+ void DrawQuad(const gfx::Rect& aRect, const gfx::IntRect& aClipRect,
+ const EffectChain& aEffectChain,
+ gfx::Float aOpacity, const gfx::Matrix4x4& aTransform) {
+ DrawQuad(aRect, aClipRect, aEffectChain, aOpacity, aTransform, aRect);
+ }
+
+ virtual void DrawTriangle(const gfx::TexturedTriangle& aTriangle,
+ const gfx::IntRect& aClipRect,
+ const EffectChain& aEffectChain,
+ gfx::Float aOpacity,
+ const gfx::Matrix4x4& aTransform,
+ const gfx::Rect& aVisibleRect)
+ {
+ MOZ_CRASH("Compositor::DrawTriangle is not implemented for the current platform!");
+ }
+
+ /**
+ * Draw an unfilled solid color rect. Typically used for debugging overlays.
+ */
+ void SlowDrawRect(const gfx::Rect& aRect, const gfx::Color& color,
+ const gfx::IntRect& aClipRect = gfx::IntRect(),
+ const gfx::Matrix4x4& aTransform = gfx::Matrix4x4(),
+ int aStrokeWidth = 1);
+
+ /**
+ * Draw a solid color filled rect. This is a simple DrawQuad helper.
+ */
+ void FillRect(const gfx::Rect& aRect, const gfx::Color& color,
+ const gfx::IntRect& aClipRect = gfx::IntRect(),
+ const gfx::Matrix4x4& aTransform = gfx::Matrix4x4());
+
+ void SetClearColor(const gfx::Color& aColor) {
+ mClearColor = aColor;
+ }
+
+ void SetDefaultClearColor(const gfx::Color& aColor) {
+ mDefaultClearColor = aColor;
+ }
+
+ void SetClearColorToDefault() {
+ mClearColor = mDefaultClearColor;
+ }
+
+ /*
+ * Clear aRect on current render target.
+ */
+ virtual void ClearRect(const gfx::Rect& aRect) = 0;
+
+ /**
+ * Start a new frame.
+ *
+ * aInvalidRect is the invalid region of the screen; it can be ignored for
+ * compositors where the performance for compositing the entire window is
+ * sufficient.
+ *
+ * aClipRectIn is the clip rect for the window in window space (optional).
+ * aTransform is the transform from user space to window space.
+ * aRenderBounds bounding rect for rendering, in user space.
+ *
+ * If aClipRectIn is null, this method sets *aClipRectOut to the clip rect
+ * actually used for rendering (if aClipRectIn is non-null, we will use that
+ * for the clip rect).
+ *
+ * If aRenderBoundsOut is non-null, it will be set to the render bounds
+ * actually used by the compositor in window space. If aRenderBoundsOut
+ * is returned empty, composition should be aborted.
+ *
+ * If aOpaque is true, then all of aInvalidRegion will be drawn to with
+ * opaque content.
+ */
+ virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
+ const gfx::IntRect* aClipRectIn,
+ const gfx::IntRect& aRenderBounds,
+ const nsIntRegion& aOpaqueRegion,
+ gfx::IntRect* aClipRectOut = nullptr,
+ gfx::IntRect* aRenderBoundsOut = nullptr) = 0;
+
+ /**
+ * Flush the current frame to the screen and tidy up.
+ *
+ * Derived class overriding this should call Compositor::EndFrame.
+ */
+ virtual void EndFrame();
+
+ virtual void SetDispAcquireFence(Layer* aLayer);
+
+ /**
+ * Post-rendering stuff if the rendering is done outside of this Compositor
+ * e.g., by Composer2D.
+ * aTransform is the transform from user space to window space.
+ */
+ virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) = 0;
+
+ /**
+ * Whether textures created by this compositor can receive partial updates.
+ */
+ virtual bool SupportsPartialTextureUpdate() = 0;
+
+ void SetDiagnosticTypes(DiagnosticTypes aDiagnostics)
+ {
+ mDiagnosticTypes = aDiagnostics;
+ }
+
+ DiagnosticTypes GetDiagnosticTypes() const
+ {
+ return mDiagnosticTypes;
+ }
+
+ void DrawDiagnostics(DiagnosticFlags aFlags,
+ const gfx::Rect& visibleRect,
+ const gfx::IntRect& aClipRect,
+ const gfx::Matrix4x4& transform,
+ uint32_t aFlashCounter = DIAGNOSTIC_FLASH_COUNTER_MAX);
+
+ void DrawDiagnostics(DiagnosticFlags aFlags,
+ const nsIntRegion& visibleRegion,
+ const gfx::IntRect& aClipRect,
+ const gfx::Matrix4x4& transform,
+ uint32_t aFlashCounter = DIAGNOSTIC_FLASH_COUNTER_MAX);
+
+#ifdef MOZ_DUMP_PAINTING
+ virtual const char* Name() const = 0;
+#endif // MOZ_DUMP_PAINTING
+
+ virtual LayersBackend GetBackendType() const = 0;
+
+ virtual CompositorOGL* AsCompositorOGL() { return nullptr; }
+ virtual CompositorD3D9* AsCompositorD3D9() { return nullptr; }
+ virtual CompositorD3D11* AsCompositorD3D11() { return nullptr; }
+ virtual BasicCompositor* AsBasicCompositor() { return nullptr; }
+
+ /**
+ * Each Compositor has a unique ID.
+ * This ID is used to keep references to each Compositor in a map accessed
+ * from the compositor thread only, so that async compositables can find
+ * the right compositor parent and schedule compositing even if the compositor
+ * changed.
+ */
+ uint32_t GetCompositorID() const
+ {
+ return mCompositorID;
+ }
+ void SetCompositorID(uint32_t aID)
+ {
+ MOZ_ASSERT(mCompositorID == 0, "The compositor ID must be set only once.");
+ mCompositorID = aID;
+ }
+
+ /**
+ * Notify the compositor that composition is being paused. This allows the
+ * compositor to temporarily release any resources.
+ * Between calling Pause and Resume, compositing may fail.
+ */
+ virtual void Pause() {}
+ /**
+ * Notify the compositor that composition is being resumed. The compositor
+ * regain any resources it requires for compositing.
+ * Returns true if succeeded.
+ */
+ virtual bool Resume() { return true; }
+
+ /**
+ * Call before rendering begins to ensure the compositor is ready to
+ * composite. Returns false if rendering should be aborted.
+ */
+ virtual bool Ready() { return true; }
+
+ virtual void ForcePresent() { }
+
+ virtual bool IsPendingComposite() { return false; }
+
+ virtual void FinishPendingComposite() {}
+
+ widget::CompositorWidget* GetWidget() const { return mWidget; }
+
+ virtual bool HasImageHostOverlays() { return false; }
+
+ virtual void AddImageHostOverlay(ImageHostOverlay* aOverlay) {}
+
+ virtual void RemoveImageHostOverlay(ImageHostOverlay* aOverlay) {}
+
+ /**
+ * Debug-build assertion that can be called to ensure code is running on the
+ * compositor thread.
+ */
+ static void AssertOnCompositorThread();
+
+ size_t GetFillRatio() {
+ float fillRatio = 0;
+ if (mPixelsFilled > 0 && mPixelsPerFrame > 0) {
+ fillRatio = 100.0f * float(mPixelsFilled) / float(mPixelsPerFrame);
+ if (fillRatio > 999.0f) {
+ fillRatio = 999.0f;
+ }
+ }
+ return fillRatio;
+ }
+
+ ScreenRotation GetScreenRotation() const {
+ return mScreenRotation;
+ }
+ void SetScreenRotation(ScreenRotation aRotation) {
+ mScreenRotation = aRotation;
+ }
+
+ TimeStamp GetCompositionTime() const {
+ return mCompositionTime;
+ }
+ void SetCompositionTime(TimeStamp aTimeStamp) {
+ mCompositionTime = aTimeStamp;
+ if (!mCompositionTime.IsNull() && !mCompositeUntilTime.IsNull() &&
+ mCompositionTime >= mCompositeUntilTime) {
+ mCompositeUntilTime = TimeStamp();
+ }
+ }
+
+ void CompositeUntil(TimeStamp aTimeStamp) {
+ if (mCompositeUntilTime.IsNull() ||
+ mCompositeUntilTime < aTimeStamp) {
+ mCompositeUntilTime = aTimeStamp;
+ }
+ }
+ TimeStamp GetCompositeUntilTime() const {
+ return mCompositeUntilTime;
+ }
+
+ // A stale Compositor has no CompositorBridgeParent; it will not process
+ // frames and should not be used.
+ void SetInvalid();
+ bool IsValid() const;
+ CompositorBridgeParent* GetCompositorBridgeParent() const {
+ return mParent;
+ }
+
+ /// Most compositor backends operate asynchronously under the hood. This
+ /// means that when a layer stops using a texture it is often desirable to
+ /// wait for the end of the next composition before releasing the texture's
+ /// ReadLock.
+ /// This function provides a convenient way to do this delayed unlocking, if
+ /// the texture itself requires it.
+ void UnlockAfterComposition(TextureHost* aTexture);
+
+ /// Most compositor backends operate asynchronously under the hood. This
+ /// means that when a layer stops using a texture it is often desirable to
+ /// wait for the end of the next composition before NotifyNotUsed() call.
+ /// This function provides a convenient way to do this delayed NotifyNotUsed()
+ /// call, if the texture itself requires it.
+ /// See bug 1260611 and bug 1252835
+ void NotifyNotUsedAfterComposition(TextureHost* aTextureHost);
+
+ void FlushPendingNotifyNotUsed();
+
+protected:
+ void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
+ const gfx::Rect& aVisibleRect,
+ const gfx::IntRect& aClipRect,
+ const gfx::Matrix4x4& transform,
+ uint32_t aFlashCounter);
+
+ bool ShouldDrawDiagnostics(DiagnosticFlags);
+
+ // Should be called at the end of each composition.
+ void ReadUnlockTextures();
+
+ /**
+ * Given a layer rect, clip, and transform, compute the area of the backdrop that
+ * needs to be copied for mix-blending. The output transform translates from 0..1
+ * space into the backdrop rect space.
+ *
+ * The transformed layer quad is also optionally returned - this is the same as
+ * the result rect, before rounding.
+ */
+ gfx::IntRect ComputeBackdropCopyRect(const gfx::Rect& aRect,
+ const gfx::IntRect& aClipRect,
+ const gfx::Matrix4x4& aTransform,
+ gfx::Matrix4x4* aOutTransform,
+ gfx::Rect* aOutLayerQuad = nullptr);
+
+ gfx::IntRect ComputeBackdropCopyRect(const gfx::Triangle& aTriangle,
+ const gfx::IntRect& aClipRect,
+ const gfx::Matrix4x4& aTransform,
+ gfx::Matrix4x4* aOutTransform,
+ gfx::Rect* aOutLayerQuad = nullptr);
+
+
+ /**
+ * An array of locks that will need to be unlocked after the next composition.
+ */
+ nsTArray<RefPtr<TextureHost>> mUnlockAfterComposition;
+
+ /**
+ * An array of TextureHosts that will need to call NotifyNotUsed() after the next composition.
+ */
+ nsTArray<RefPtr<TextureHost>> mNotifyNotUsedAfterComposition;
+
+ /**
+ * Last Composition end time.
+ */
+ TimeStamp mLastCompositionEndTime;
+
+ /**
+ * Render time for the current composition.
+ */
+ TimeStamp mCompositionTime;
+ /**
+ * When nonnull, during rendering, some compositable indicated that it will
+ * change its rendering at this time. In order not to miss it, we composite
+ * on every vsync until this time occurs (this is the latest such time).
+ */
+ TimeStamp mCompositeUntilTime;
+
+ uint32_t mCompositorID;
+ DiagnosticTypes mDiagnosticTypes;
+ CompositorBridgeParent* mParent;
+
+ /**
+ * We keep track of the total number of pixels filled as we composite the
+ * current frame. This value is an approximation and is not accurate,
+ * especially in the presence of transforms.
+ */
+ size_t mPixelsPerFrame;
+ size_t mPixelsFilled;
+
+ ScreenRotation mScreenRotation;
+
+ RefPtr<gfx::DrawTarget> mTarget;
+ gfx::IntRect mTargetBounds;
+
+ widget::CompositorWidget* mWidget;
+
+ bool mIsDestroyed;
+
+ gfx::Color mClearColor;
+ gfx::Color mDefaultClearColor;
+
+private:
+ static LayersBackend sBackend;
+
+};
+
+// Returns the number of rects. (Up to 4)
+typedef gfx::Rect decomposedRectArrayT[4];
+size_t DecomposeIntoNoRepeatRects(const gfx::Rect& aRect,
+ const gfx::Rect& aTexCoordRect,
+ decomposedRectArrayT* aLayerRects,
+ decomposedRectArrayT* aTextureRects);
+
+static inline bool
+BlendOpIsMixBlendMode(gfx::CompositionOp aOp)
+{
+ switch (aOp) {
+ case gfx::CompositionOp::OP_MULTIPLY:
+ case gfx::CompositionOp::OP_SCREEN:
+ case gfx::CompositionOp::OP_OVERLAY:
+ case gfx::CompositionOp::OP_DARKEN:
+ case gfx::CompositionOp::OP_LIGHTEN:
+ case gfx::CompositionOp::OP_COLOR_DODGE:
+ case gfx::CompositionOp::OP_COLOR_BURN:
+ case gfx::CompositionOp::OP_HARD_LIGHT:
+ case gfx::CompositionOp::OP_SOFT_LIGHT:
+ case gfx::CompositionOp::OP_DIFFERENCE:
+ case gfx::CompositionOp::OP_EXCLUSION:
+ case gfx::CompositionOp::OP_HUE:
+ case gfx::CompositionOp::OP_SATURATION:
+ case gfx::CompositionOp::OP_COLOR:
+ case gfx::CompositionOp::OP_LUMINOSITY:
+ return true;
+ default:
+ return false;
+ }
+}
+
+} // namespace layers
+} // namespace mozilla
+
+#endif /* MOZILLA_GFX_COMPOSITOR_H */