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