Line data Source code
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_LAYERS_EFFECTS_H
7 : #define MOZILLA_LAYERS_EFFECTS_H
8 :
9 : #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
10 : #include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed, etc
11 : #include "mozilla/gfx/Matrix.h" // for Matrix4x4
12 : #include "mozilla/gfx/Point.h" // for IntSize
13 : #include "mozilla/gfx/Rect.h" // for Rect
14 : #include "mozilla/gfx/Types.h" // for SamplingFilter, etc
15 : #include "mozilla/layers/CompositorTypes.h" // for EffectTypes, etc
16 : #include "mozilla/layers/LayersTypes.h"
17 : #include "mozilla/layers/TextureHost.h" // for CompositingRenderTarget, etc
18 : #include "mozilla/mozalloc.h" // for operator delete, etc
19 : #include "nscore.h" // for nsACString
20 : #include "mozilla/EnumeratedArray.h"
21 :
22 : namespace mozilla {
23 : namespace layers {
24 :
25 : /**
26 : * Effects and effect chains are used by the compositor API (see Compositor.h).
27 : * An effect chain represents a rendering method, for example some shader and
28 : * the data required for that shader to run. An effect is some component of the
29 : * chain and its data.
30 : *
31 : * An effect chain consists of a primary effect - how the 'texture' memory should
32 : * be interpreted (RGBA, BGRX, YCBCR, etc.) - and any number of secondary effects
33 : * - any way in which rendering can be changed, e.g., applying a mask layer.
34 : *
35 : * During the rendering process, an effect chain is created by the layer being
36 : * rendered and the primary effect is added by the compositable host. Secondary
37 : * effects may be added by the layer or compositable. The effect chain is passed
38 : * to the compositor by the compositable host as a parameter to DrawQuad.
39 : */
40 :
41 : struct TexturedEffect;
42 :
43 : struct Effect
44 : {
45 272 : NS_INLINE_DECL_REFCOUNTING(Effect)
46 :
47 80 : explicit Effect(EffectTypes aType) : mType(aType) {}
48 :
49 : EffectTypes mType;
50 :
51 0 : virtual TexturedEffect* AsTexturedEffect() { return nullptr; }
52 : virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) = 0;
53 :
54 : protected:
55 80 : virtual ~Effect() {}
56 : };
57 :
58 : // Render from a texture
59 56 : struct TexturedEffect : public Effect
60 : {
61 56 : TexturedEffect(EffectTypes aType,
62 : TextureSource *aTexture,
63 : bool aPremultiplied,
64 : gfx::SamplingFilter aSamplingFilter)
65 56 : : Effect(aType)
66 : , mTextureCoords(0, 0, 1.0f, 1.0f)
67 : , mTexture(aTexture)
68 : , mPremultiplied(aPremultiplied)
69 56 : , mSamplingFilter(aSamplingFilter)
70 56 : {}
71 :
72 0 : virtual TexturedEffect* AsTexturedEffect() { return this; }
73 : virtual const char* Name() = 0;
74 : virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
75 :
76 : gfx::Rect mTextureCoords;
77 : TextureSource* mTexture;
78 : bool mPremultiplied;
79 : gfx::SamplingFilter mSamplingFilter;
80 : };
81 :
82 : // Support an alpha mask.
83 0 : struct EffectMask : public Effect
84 : {
85 0 : EffectMask(TextureSource *aMaskTexture,
86 : gfx::IntSize aSize,
87 : const gfx::Matrix4x4 &aMaskTransform)
88 0 : : Effect(EffectTypes::MASK)
89 : , mMaskTexture(aMaskTexture)
90 : , mSize(aSize)
91 0 : , mMaskTransform(aMaskTransform)
92 0 : {}
93 :
94 : virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
95 :
96 : TextureSource* mMaskTexture;
97 : gfx::IntSize mSize;
98 : gfx::Matrix4x4 mMaskTransform;
99 : };
100 :
101 0 : struct EffectBlendMode : public Effect
102 : {
103 0 : explicit EffectBlendMode(gfx::CompositionOp aBlendMode)
104 0 : : Effect(EffectTypes::BLEND_MODE)
105 0 : , mBlendMode(aBlendMode)
106 0 : { }
107 :
108 0 : virtual const char* Name() { return "EffectBlendMode"; }
109 : virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
110 :
111 : gfx::CompositionOp mBlendMode;
112 : };
113 :
114 : // Render to a render target rather than the screen.
115 0 : struct EffectRenderTarget : public TexturedEffect
116 : {
117 0 : explicit EffectRenderTarget(CompositingRenderTarget *aRenderTarget)
118 0 : : TexturedEffect(EffectTypes::RENDER_TARGET, aRenderTarget, true,
119 : gfx::SamplingFilter::LINEAR)
120 0 : , mRenderTarget(aRenderTarget)
121 0 : {}
122 :
123 0 : virtual const char* Name() { return "EffectRenderTarget"; }
124 : virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
125 :
126 : RefPtr<CompositingRenderTarget> mRenderTarget;
127 :
128 : protected:
129 : EffectRenderTarget(EffectTypes aType, CompositingRenderTarget *aRenderTarget)
130 : : TexturedEffect(aType, aRenderTarget, true, gfx::SamplingFilter::LINEAR)
131 : , mRenderTarget(aRenderTarget)
132 : {}
133 :
134 : };
135 :
136 : // Render to a render target rather than the screen.
137 0 : struct EffectColorMatrix : public Effect
138 : {
139 0 : explicit EffectColorMatrix(gfx::Matrix5x4 aMatrix)
140 0 : : Effect(EffectTypes::COLOR_MATRIX)
141 0 : , mColorMatrix(aMatrix)
142 0 : {}
143 :
144 0 : virtual const char* Name() { return "EffectColorMatrix"; }
145 : virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
146 : const gfx::Matrix5x4 mColorMatrix;
147 : };
148 :
149 :
150 168 : struct EffectRGB : public TexturedEffect
151 : {
152 56 : EffectRGB(TextureSource *aTexture,
153 : bool aPremultiplied,
154 : gfx::SamplingFilter aSamplingFilter,
155 : bool aFlipped = false)
156 56 : : TexturedEffect(EffectTypes::RGB, aTexture, aPremultiplied, aSamplingFilter)
157 56 : {}
158 :
159 0 : virtual const char* Name() { return "EffectRGB"; }
160 : };
161 :
162 0 : struct EffectYCbCr : public TexturedEffect
163 : {
164 0 : EffectYCbCr(TextureSource *aSource, YUVColorSpace aYUVColorSpace, gfx::SamplingFilter aSamplingFilter)
165 0 : : TexturedEffect(EffectTypes::YCBCR, aSource, false, aSamplingFilter)
166 0 : , mYUVColorSpace(aYUVColorSpace)
167 0 : {}
168 :
169 0 : virtual const char* Name() { return "EffectYCbCr"; }
170 :
171 : YUVColorSpace mYUVColorSpace;
172 : };
173 :
174 0 : struct EffectNV12 : public TexturedEffect
175 : {
176 0 : EffectNV12(TextureSource *aSource, gfx::SamplingFilter aSamplingFilter)
177 0 : : TexturedEffect(EffectTypes::NV12, aSource, false, aSamplingFilter)
178 0 : {}
179 :
180 0 : virtual const char* Name() { return "EffectNV12"; }
181 : };
182 :
183 0 : struct EffectComponentAlpha : public TexturedEffect
184 : {
185 0 : EffectComponentAlpha(TextureSource *aOnBlack,
186 : TextureSource *aOnWhite,
187 : gfx::SamplingFilter aSamplingFilter)
188 0 : : TexturedEffect(EffectTypes::COMPONENT_ALPHA, nullptr, false, aSamplingFilter)
189 : , mOnBlack(aOnBlack)
190 0 : , mOnWhite(aOnWhite)
191 0 : {}
192 :
193 0 : virtual const char* Name() { return "EffectComponentAlpha"; }
194 :
195 : TextureSource* mOnBlack;
196 : TextureSource* mOnWhite;
197 : };
198 :
199 72 : struct EffectSolidColor : public Effect
200 : {
201 24 : explicit EffectSolidColor(const gfx::Color &aColor)
202 24 : : Effect(EffectTypes::SOLID_COLOR)
203 24 : , mColor(aColor)
204 24 : {}
205 :
206 : virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
207 :
208 : gfx::Color mColor;
209 : };
210 :
211 80 : struct EffectChain
212 : {
213 0 : EffectChain() : mLayerRef(nullptr) {}
214 80 : explicit EffectChain(void* aLayerRef) : mLayerRef(aLayerRef) {}
215 :
216 : RefPtr<Effect> mPrimaryEffect;
217 : EnumeratedArray<EffectTypes, EffectTypes::MAX_SECONDARY, RefPtr<Effect>>
218 : mSecondaryEffects;
219 : void* mLayerRef; //!< For LayerScope logging
220 : };
221 :
222 : /**
223 : * Create a Textured effect corresponding to aFormat and using
224 : * aSource as the (first) texture source.
225 : *
226 : * Note that aFormat can be different form aSource->GetFormat if, we are
227 : * creating an effect that takes several texture sources (like with YCBCR
228 : * where aFormat would be FOMRAT_YCBCR and each texture source would be
229 : * a one-channel A8 texture)
230 : */
231 : inline already_AddRefed<TexturedEffect>
232 56 : CreateTexturedEffect(gfx::SurfaceFormat aFormat,
233 : TextureSource* aSource,
234 : const gfx::SamplingFilter aSamplingFilter,
235 : bool isAlphaPremultiplied)
236 : {
237 56 : MOZ_ASSERT(aSource);
238 112 : RefPtr<TexturedEffect> result;
239 56 : switch (aFormat) {
240 : case gfx::SurfaceFormat::B8G8R8A8:
241 : case gfx::SurfaceFormat::B8G8R8X8:
242 : case gfx::SurfaceFormat::R8G8B8X8:
243 : case gfx::SurfaceFormat::R5G6B5_UINT16:
244 : case gfx::SurfaceFormat::R8G8B8A8:
245 56 : result = new EffectRGB(aSource, isAlphaPremultiplied, aSamplingFilter);
246 56 : break;
247 : case gfx::SurfaceFormat::NV12:
248 0 : result = new EffectNV12(aSource, aSamplingFilter);
249 0 : break;
250 : case gfx::SurfaceFormat::YUV:
251 0 : MOZ_ASSERT_UNREACHABLE("gfx::SurfaceFormat::YUV is invalid");
252 : break;
253 : default:
254 0 : NS_WARNING("unhandled program type");
255 0 : break;
256 : }
257 :
258 112 : return result.forget();
259 : }
260 :
261 : inline already_AddRefed<TexturedEffect>
262 0 : CreateTexturedEffect(TextureHost* aHost,
263 : TextureSource* aSource,
264 : const gfx::SamplingFilter aSamplingFilter,
265 : bool isAlphaPremultiplied)
266 : {
267 0 : MOZ_ASSERT(aHost);
268 0 : MOZ_ASSERT(aSource);
269 :
270 0 : RefPtr<TexturedEffect> result;
271 0 : if (aHost->GetReadFormat() == gfx::SurfaceFormat::YUV) {
272 0 : MOZ_ASSERT(aHost->GetYUVColorSpace() != YUVColorSpace::UNKNOWN);
273 0 : result = new EffectYCbCr(aSource, aHost->GetYUVColorSpace(), aSamplingFilter);
274 : } else {
275 0 : result = CreateTexturedEffect(aHost->GetReadFormat(),
276 : aSource,
277 : aSamplingFilter,
278 0 : isAlphaPremultiplied);
279 : }
280 0 : return result.forget();
281 : }
282 :
283 : /**
284 : * Create a textured effect based on aSource format and the presence of
285 : * aSourceOnWhite.
286 : *
287 : * aSourceOnWhite can be null.
288 : */
289 : inline already_AddRefed<TexturedEffect>
290 56 : CreateTexturedEffect(TextureSource* aSource,
291 : TextureSource* aSourceOnWhite,
292 : const gfx::SamplingFilter aSamplingFilter,
293 : bool isAlphaPremultiplied)
294 : {
295 56 : MOZ_ASSERT(aSource);
296 56 : if (aSourceOnWhite) {
297 0 : MOZ_ASSERT(aSource->GetFormat() == gfx::SurfaceFormat::R8G8B8X8 ||
298 : aSource->GetFormat() == gfx::SurfaceFormat::B8G8R8X8);
299 0 : MOZ_ASSERT(aSource->GetFormat() == aSourceOnWhite->GetFormat());
300 0 : return MakeAndAddRef<EffectComponentAlpha>(aSource, aSourceOnWhite,
301 0 : aSamplingFilter);
302 : }
303 :
304 56 : return CreateTexturedEffect(aSource->GetFormat(),
305 : aSource,
306 : aSamplingFilter,
307 112 : isAlphaPremultiplied);
308 : }
309 :
310 : /**
311 : * Create a textured effect based on aSource format.
312 : *
313 : * This version excudes the possibility of component alpha.
314 : */
315 : inline already_AddRefed<TexturedEffect>
316 : CreateTexturedEffect(TextureSource *aTexture,
317 : const gfx::SamplingFilter aSamplingFilter)
318 : {
319 : return CreateTexturedEffect(aTexture, nullptr, aSamplingFilter, true);
320 : }
321 :
322 :
323 : } // namespace layers
324 : } // namespace mozilla
325 :
326 : #endif
|