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/. */
7 #ifndef MOZILLA_LAYERS_EFFECTS_H
8 #define MOZILLA_LAYERS_EFFECTS_H
10 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
11 #include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed, etc
12 #include "mozilla/gfx/Matrix.h" // for Matrix4x4
13 #include "mozilla/gfx/Point.h" // for IntSize
14 #include "mozilla/gfx/Rect.h" // for Rect
15 #include "mozilla/gfx/Types.h" // for SamplingFilter, etc
16 #include "mozilla/layers/CompositorTypes.h" // for EffectTypes, etc
17 #include "mozilla/layers/LayersTypes.h"
18 #include "mozilla/layers/TextureHost.h" // for CompositingRenderTarget, etc
19 #include "mozilla/mozalloc.h" // for operator delete, etc
20 #include "nscore.h" // for nsACString
21 #include "mozilla/EnumeratedArray.h"
27 * Effects and effect chains are used by the compositor API (see Compositor.h).
28 * An effect chain represents a rendering method, for example some shader and
29 * the data required for that shader to run. An effect is some component of the
32 * An effect chain consists of a primary effect - how the 'texture' memory
33 * should be interpreted (RGBA, BGRX, YCBCR, etc.) - and any number of secondary
35 * - any way in which rendering can be changed, e.g., applying a mask layer.
37 * During the rendering process, an effect chain is created by the layer being
38 * rendered and the primary effect is added by the compositable host. Secondary
39 * effects may be added by the layer or compositable. The effect chain is passed
40 * to the compositor by the compositable host as a parameter to DrawQuad.
43 struct TexturedEffect
;
46 NS_INLINE_DECL_REFCOUNTING(Effect
)
48 explicit Effect(EffectTypes aType
) : mType(aType
) {}
52 virtual TexturedEffect
* AsTexturedEffect() { return nullptr; }
53 virtual void PrintInfo(std::stringstream
& aStream
, const char* aPrefix
) = 0;
56 virtual ~Effect() = default;
59 // Render from a texture
60 struct TexturedEffect
: public Effect
{
61 TexturedEffect(EffectTypes aType
, TextureSource
* aTexture
,
62 bool aPremultiplied
, gfx::SamplingFilter aSamplingFilter
)
64 mTextureCoords(0, 0, 1.0f
, 1.0f
),
66 mPremultiplied(aPremultiplied
),
67 mSamplingFilter(aSamplingFilter
) {}
69 TexturedEffect
* AsTexturedEffect() override
{ return this; }
70 virtual const char* Name() = 0;
71 void PrintInfo(std::stringstream
& aStream
, const char* aPrefix
) override
;
73 gfx::Rect mTextureCoords
;
74 TextureSource
* mTexture
;
76 gfx::SamplingFilter mSamplingFilter
;
79 // Support an alpha mask.
80 struct EffectMask
: public Effect
{
81 EffectMask(TextureSource
* aMaskTexture
, gfx::IntSize aSize
,
82 const gfx::Matrix4x4
& aMaskTransform
)
83 : Effect(EffectTypes::MASK
),
84 mMaskTexture(aMaskTexture
),
86 mMaskTransform(aMaskTransform
) {}
88 void PrintInfo(std::stringstream
& aStream
, const char* aPrefix
) override
;
90 TextureSource
* mMaskTexture
;
92 gfx::Matrix4x4 mMaskTransform
;
95 struct EffectBlendMode
: public Effect
{
96 explicit EffectBlendMode(gfx::CompositionOp aBlendMode
)
97 : Effect(EffectTypes::BLEND_MODE
), mBlendMode(aBlendMode
) {}
99 virtual const char* Name() { return "EffectBlendMode"; }
100 void PrintInfo(std::stringstream
& aStream
, const char* aPrefix
) override
;
102 gfx::CompositionOp mBlendMode
;
105 // Render to a render target rather than the screen.
106 struct EffectRenderTarget
: public TexturedEffect
{
107 explicit EffectRenderTarget(CompositingRenderTarget
* aRenderTarget
)
108 : TexturedEffect(EffectTypes::RENDER_TARGET
, aRenderTarget
, true,
109 gfx::SamplingFilter::LINEAR
),
110 mRenderTarget(aRenderTarget
) {}
112 const char* Name() override
{ return "EffectRenderTarget"; }
113 void PrintInfo(std::stringstream
& aStream
, const char* aPrefix
) override
;
115 RefPtr
<CompositingRenderTarget
> mRenderTarget
;
118 EffectRenderTarget(EffectTypes aType
, CompositingRenderTarget
* aRenderTarget
)
119 : TexturedEffect(aType
, aRenderTarget
, true, gfx::SamplingFilter::LINEAR
),
120 mRenderTarget(aRenderTarget
) {}
123 // Render to a render target rather than the screen.
124 struct EffectColorMatrix
: public Effect
{
125 explicit EffectColorMatrix(gfx::Matrix5x4 aMatrix
)
126 : Effect(EffectTypes::COLOR_MATRIX
), mColorMatrix(aMatrix
) {}
128 void PrintInfo(std::stringstream
& aStream
, const char* aPrefix
) override
;
129 const gfx::Matrix5x4 mColorMatrix
;
132 struct EffectRGB
: public TexturedEffect
{
133 EffectRGB(TextureSource
* aTexture
, bool aPremultiplied
,
134 gfx::SamplingFilter aSamplingFilter
, bool aFlipped
= false)
135 : TexturedEffect(EffectTypes::RGB
, aTexture
, aPremultiplied
,
138 const char* Name() override
{ return "EffectRGB"; }
141 struct EffectYCbCr
: public TexturedEffect
{
142 EffectYCbCr(TextureSource
* aSource
, gfx::YUVColorSpace aYUVColorSpace
,
143 gfx::ColorRange aColorRange
, gfx::ColorDepth aColorDepth
,
144 gfx::SamplingFilter aSamplingFilter
)
145 : TexturedEffect(EffectTypes::YCBCR
, aSource
, false, aSamplingFilter
),
146 mYUVColorSpace(aYUVColorSpace
),
147 mColorRange(aColorRange
),
148 mColorDepth(aColorDepth
) {}
150 const char* Name() override
{ return "EffectYCbCr"; }
152 gfx::YUVColorSpace mYUVColorSpace
;
153 gfx::ColorRange mColorRange
;
154 gfx::ColorDepth mColorDepth
;
157 struct EffectNV12
: public EffectYCbCr
{
158 EffectNV12(TextureSource
* aSource
, gfx::YUVColorSpace aYUVColorSpace
,
159 gfx::ColorRange aColorRange
, gfx::ColorDepth aColorDepth
,
160 gfx::SamplingFilter aSamplingFilter
)
161 : EffectYCbCr(aSource
, aYUVColorSpace
, aColorRange
, aColorDepth
,
163 mType
= EffectTypes::NV12
;
166 const char* Name() override
{ return "EffectNV12"; }
169 struct EffectComponentAlpha
: public TexturedEffect
{
170 EffectComponentAlpha(TextureSource
* aOnBlack
, TextureSource
* aOnWhite
,
171 gfx::SamplingFilter aSamplingFilter
)
172 : TexturedEffect(EffectTypes::COMPONENT_ALPHA
, nullptr, false,
175 mOnWhite(aOnWhite
) {}
177 const char* Name() override
{ return "EffectComponentAlpha"; }
179 TextureSource
* mOnBlack
;
180 TextureSource
* mOnWhite
;
183 struct EffectSolidColor
: public Effect
{
184 explicit EffectSolidColor(const gfx::Color
& aColor
)
185 : Effect(EffectTypes::SOLID_COLOR
), mColor(aColor
) {}
187 void PrintInfo(std::stringstream
& aStream
, const char* aPrefix
) override
;
193 EffectChain() : mLayerRef(nullptr) {}
194 explicit EffectChain(void* aLayerRef
) : mLayerRef(aLayerRef
) {}
196 RefPtr
<Effect
> mPrimaryEffect
;
197 EnumeratedArray
<EffectTypes
, EffectTypes::MAX_SECONDARY
, RefPtr
<Effect
>>
199 void* mLayerRef
; //!< For LayerScope logging
203 * Create a Textured effect corresponding to aFormat and using
204 * aSource as the (first) texture source.
206 * Note that aFormat can be different form aSource->GetFormat if, we are
207 * creating an effect that takes several texture sources (like with YCBCR
208 * where aFormat would be FORMAT_YCBCR and each texture source would be
209 * a one-channel A8 texture)
211 inline already_AddRefed
<TexturedEffect
> CreateTexturedEffect(
212 gfx::SurfaceFormat aFormat
, TextureSource
* aSource
,
213 const gfx::SamplingFilter aSamplingFilter
, bool isAlphaPremultiplied
) {
215 RefPtr
<TexturedEffect
> result
;
217 case gfx::SurfaceFormat::B8G8R8A8
:
218 case gfx::SurfaceFormat::B8G8R8X8
:
219 case gfx::SurfaceFormat::R8G8B8X8
:
220 case gfx::SurfaceFormat::R5G6B5_UINT16
:
221 case gfx::SurfaceFormat::R8G8B8A8
:
222 result
= new EffectRGB(aSource
, isAlphaPremultiplied
, aSamplingFilter
);
224 case gfx::SurfaceFormat::YUV
:
225 case gfx::SurfaceFormat::NV12
:
226 case gfx::SurfaceFormat::P010
:
227 case gfx::SurfaceFormat::P016
:
228 MOZ_ASSERT_UNREACHABLE(
229 "gfx::SurfaceFormat::YUV/NV12/P010/P016 is invalid");
232 NS_WARNING("unhandled program type");
236 return result
.forget();
239 inline already_AddRefed
<TexturedEffect
> CreateTexturedEffect(
240 TextureHost
* aHost
, TextureSource
* aSource
,
241 const gfx::SamplingFilter aSamplingFilter
, bool isAlphaPremultiplied
) {
245 RefPtr
<TexturedEffect
> result
;
247 switch (aHost
->GetReadFormat()) {
248 case gfx::SurfaceFormat::YUV
:
249 MOZ_ASSERT(aHost
->GetYUVColorSpace() != gfx::YUVColorSpace::UNKNOWN
);
250 result
= new EffectYCbCr(aSource
, aHost
->GetYUVColorSpace(),
251 aHost
->GetColorRange(), aHost
->GetColorDepth(),
254 case gfx::SurfaceFormat::NV12
:
255 case gfx::SurfaceFormat::P010
:
256 case gfx::SurfaceFormat::P016
:
257 result
= new EffectNV12(aSource
, aHost
->GetYUVColorSpace(),
258 aHost
->GetColorRange(), aHost
->GetColorDepth(),
262 result
= CreateTexturedEffect(aHost
->GetReadFormat(), aSource
,
263 aSamplingFilter
, isAlphaPremultiplied
);
266 return result
.forget();
270 * Create a textured effect based on aSource format and the presence of
273 * aSourceOnWhite can be null.
275 inline already_AddRefed
<TexturedEffect
> CreateTexturedEffect(
276 TextureSource
* aSource
, TextureSource
* aSourceOnWhite
,
277 const gfx::SamplingFilter aSamplingFilter
, bool isAlphaPremultiplied
) {
279 if (aSourceOnWhite
) {
280 MOZ_ASSERT(aSource
->GetFormat() == gfx::SurfaceFormat::R8G8B8X8
||
281 aSource
->GetFormat() == gfx::SurfaceFormat::B8G8R8X8
);
282 MOZ_ASSERT(aSource
->GetFormat() == aSourceOnWhite
->GetFormat());
283 return MakeAndAddRef
<EffectComponentAlpha
>(aSource
, aSourceOnWhite
,
287 return CreateTexturedEffect(aSource
->GetFormat(), aSource
, aSamplingFilter
,
288 isAlphaPremultiplied
);
292 * Create a textured effect based on aSource format.
294 * This version excudes the possibility of component alpha.
296 inline already_AddRefed
<TexturedEffect
> CreateTexturedEffect(
297 TextureSource
* aTexture
, const gfx::SamplingFilter aSamplingFilter
) {
298 return CreateTexturedEffect(aTexture
, nullptr, aSamplingFilter
, true);
301 } // namespace layers
302 } // namespace mozilla