|
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, TemporaryRef, 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 Filter, 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 |
|
21 namespace mozilla { |
|
22 namespace layers { |
|
23 |
|
24 /** |
|
25 * Effects and effect chains are used by the compositor API (see Compositor.h). |
|
26 * An effect chain represents a rendering method, for example some shader and |
|
27 * the data required for that shader to run. An effect is some component of the |
|
28 * chain and its data. |
|
29 * |
|
30 * An effect chain consists of a primary effect - how the 'texture' memory should |
|
31 * be interpreted (RGBA, BGRX, YCBCR, etc.) - and any number of secondary effects |
|
32 * - any way in which rendering can be changed, e.g., applying a mask layer. |
|
33 * |
|
34 * During the rendering process, an effect chain is created by the layer being |
|
35 * rendered and the primary effect is added by the compositable host. Secondary |
|
36 * effects may be added by the layer or compositable. The effect chain is passed |
|
37 * to the compositor by the compositable host as a parameter to DrawQuad. |
|
38 */ |
|
39 |
|
40 struct Effect |
|
41 { |
|
42 NS_INLINE_DECL_REFCOUNTING(Effect) |
|
43 |
|
44 Effect(EffectTypes aType) : mType(aType) {} |
|
45 |
|
46 EffectTypes mType; |
|
47 |
|
48 virtual void PrintInfo(nsACString& aTo, const char* aPrefix) = 0; |
|
49 |
|
50 protected: |
|
51 virtual ~Effect() {} |
|
52 }; |
|
53 |
|
54 // Render from a texture |
|
55 struct TexturedEffect : public Effect |
|
56 { |
|
57 TexturedEffect(EffectTypes aType, |
|
58 TextureSource *aTexture, |
|
59 bool aPremultiplied, |
|
60 gfx::Filter aFilter) |
|
61 : Effect(aType) |
|
62 , mTextureCoords(0, 0, 1.0f, 1.0f) |
|
63 , mTexture(aTexture) |
|
64 , mPremultiplied(aPremultiplied) |
|
65 , mFilter(aFilter) |
|
66 {} |
|
67 |
|
68 virtual const char* Name() = 0; |
|
69 virtual void PrintInfo(nsACString& aTo, const char* aPrefix); |
|
70 |
|
71 gfx::Rect mTextureCoords; |
|
72 TextureSource* mTexture; |
|
73 bool mPremultiplied; |
|
74 gfx::Filter mFilter;; |
|
75 }; |
|
76 |
|
77 // Support an alpha mask. |
|
78 struct EffectMask : public Effect |
|
79 { |
|
80 EffectMask(TextureSource *aMaskTexture, |
|
81 gfx::IntSize aSize, |
|
82 const gfx::Matrix4x4 &aMaskTransform) |
|
83 : Effect(EFFECT_MASK) |
|
84 , mMaskTexture(aMaskTexture) |
|
85 , mIs3D(false) |
|
86 , mSize(aSize) |
|
87 , mMaskTransform(aMaskTransform) |
|
88 {} |
|
89 |
|
90 virtual void PrintInfo(nsACString& aTo, const char* aPrefix); |
|
91 |
|
92 TextureSource* mMaskTexture; |
|
93 bool mIs3D; |
|
94 gfx::IntSize mSize; |
|
95 gfx::Matrix4x4 mMaskTransform; |
|
96 }; |
|
97 |
|
98 // Render to a render target rather than the screen. |
|
99 struct EffectRenderTarget : public TexturedEffect |
|
100 { |
|
101 EffectRenderTarget(CompositingRenderTarget *aRenderTarget) |
|
102 : TexturedEffect(EFFECT_RENDER_TARGET, aRenderTarget, true, gfx::Filter::LINEAR) |
|
103 , mRenderTarget(aRenderTarget) |
|
104 {} |
|
105 |
|
106 virtual const char* Name() { return "EffectRenderTarget"; } |
|
107 virtual void PrintInfo(nsACString& aTo, const char* aPrefix); |
|
108 |
|
109 RefPtr<CompositingRenderTarget> mRenderTarget; |
|
110 }; |
|
111 |
|
112 struct EffectRGB : public TexturedEffect |
|
113 { |
|
114 EffectRGB(TextureSource *aTexture, |
|
115 bool aPremultiplied, |
|
116 gfx::Filter aFilter, |
|
117 bool aFlipped = false) |
|
118 : TexturedEffect(EFFECT_RGB, aTexture, aPremultiplied, aFilter) |
|
119 {} |
|
120 |
|
121 virtual const char* Name() { return "EffectRGB"; } |
|
122 }; |
|
123 |
|
124 struct EffectYCbCr : public TexturedEffect |
|
125 { |
|
126 EffectYCbCr(TextureSource *aSource, gfx::Filter aFilter) |
|
127 : TexturedEffect(EFFECT_YCBCR, aSource, false, aFilter) |
|
128 {} |
|
129 |
|
130 virtual const char* Name() { return "EffectYCbCr"; } |
|
131 }; |
|
132 |
|
133 struct EffectComponentAlpha : public TexturedEffect |
|
134 { |
|
135 EffectComponentAlpha(TextureSource *aOnBlack, |
|
136 TextureSource *aOnWhite, |
|
137 gfx::Filter aFilter) |
|
138 : TexturedEffect(EFFECT_COMPONENT_ALPHA, nullptr, false, aFilter) |
|
139 , mOnBlack(aOnBlack) |
|
140 , mOnWhite(aOnWhite) |
|
141 {} |
|
142 |
|
143 virtual const char* Name() { return "EffectComponentAlpha"; } |
|
144 |
|
145 TextureSource* mOnBlack; |
|
146 TextureSource* mOnWhite; |
|
147 }; |
|
148 |
|
149 struct EffectSolidColor : public Effect |
|
150 { |
|
151 EffectSolidColor(const gfx::Color &aColor) |
|
152 : Effect(EFFECT_SOLID_COLOR) |
|
153 , mColor(aColor) |
|
154 {} |
|
155 |
|
156 virtual void PrintInfo(nsACString& aTo, const char* aPrefix); |
|
157 |
|
158 gfx::Color mColor; |
|
159 }; |
|
160 |
|
161 struct EffectChain |
|
162 { |
|
163 EffectChain() : mLayerRef(nullptr) {} |
|
164 explicit EffectChain(void* aLayerRef) : mLayerRef(aLayerRef) {} |
|
165 |
|
166 RefPtr<Effect> mPrimaryEffect; |
|
167 RefPtr<Effect> mSecondaryEffects[EFFECT_MAX_SECONDARY]; |
|
168 void* mLayerRef; //!< For LayerScope logging |
|
169 }; |
|
170 |
|
171 /** |
|
172 * Create a Textured effect corresponding to aFormat and using |
|
173 * aSource as the (first) texture source. |
|
174 * |
|
175 * Note that aFormat can be different form aSource->GetFormat if, we are |
|
176 * creating an effect that takes several texture sources (like with YCBCR |
|
177 * where aFormat would be FOMRAT_YCBCR and each texture source would be |
|
178 * a one-channel A8 texture) |
|
179 */ |
|
180 inline TemporaryRef<TexturedEffect> |
|
181 CreateTexturedEffect(gfx::SurfaceFormat aFormat, |
|
182 TextureSource* aSource, |
|
183 const gfx::Filter& aFilter) |
|
184 { |
|
185 MOZ_ASSERT(aSource); |
|
186 RefPtr<TexturedEffect> result; |
|
187 switch (aFormat) { |
|
188 case gfx::SurfaceFormat::B8G8R8A8: |
|
189 case gfx::SurfaceFormat::B8G8R8X8: |
|
190 case gfx::SurfaceFormat::R8G8B8X8: |
|
191 case gfx::SurfaceFormat::R5G6B5: |
|
192 case gfx::SurfaceFormat::R8G8B8A8: |
|
193 result = new EffectRGB(aSource, true, aFilter); |
|
194 break; |
|
195 case gfx::SurfaceFormat::YUV: |
|
196 result = new EffectYCbCr(aSource, aFilter); |
|
197 break; |
|
198 default: |
|
199 NS_WARNING("unhandled program type"); |
|
200 break; |
|
201 } |
|
202 |
|
203 return result; |
|
204 } |
|
205 |
|
206 /** |
|
207 * Create a textured effect based on aSource format and the presence of |
|
208 * aSourceOnWhite. |
|
209 * |
|
210 * aSourceOnWhite can be null. |
|
211 */ |
|
212 inline TemporaryRef<TexturedEffect> |
|
213 CreateTexturedEffect(TextureSource* aSource, |
|
214 TextureSource* aSourceOnWhite, |
|
215 const gfx::Filter& aFilter) |
|
216 { |
|
217 MOZ_ASSERT(aSource); |
|
218 if (aSourceOnWhite) { |
|
219 MOZ_ASSERT(aSource->GetFormat() == gfx::SurfaceFormat::R8G8B8X8 || |
|
220 aSourceOnWhite->GetFormat() == gfx::SurfaceFormat::B8G8R8X8); |
|
221 return new EffectComponentAlpha(aSource, aSourceOnWhite, aFilter); |
|
222 } |
|
223 |
|
224 return CreateTexturedEffect(aSource->GetFormat(), aSource, aFilter); |
|
225 } |
|
226 |
|
227 /** |
|
228 * Create a textured effect based on aSource format. |
|
229 * |
|
230 * This version excudes the possibility of component alpha. |
|
231 */ |
|
232 inline TemporaryRef<TexturedEffect> |
|
233 CreateTexturedEffect(TextureSource *aTexture, |
|
234 const gfx::Filter& aFilter) |
|
235 { |
|
236 return CreateTexturedEffect(aTexture, nullptr, aFilter); |
|
237 } |
|
238 |
|
239 |
|
240 } // namespace layers |
|
241 } // namespace mozilla |
|
242 |
|
243 #endif |