/src/mozilla-central/gfx/layers/opengl/OGLShaderProgram.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 GFX_OGLSHADERPROGRAM_H |
8 | | #define GFX_OGLSHADERPROGRAM_H |
9 | | |
10 | | #include "GLContext.h" // for fast inlines of glUniform* |
11 | | #include "gfxTypes.h" |
12 | | #include "ImageTypes.h" |
13 | | #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc |
14 | | #include "mozilla/Pair.h" // for Pair |
15 | | #include "mozilla/RefPtr.h" // for RefPtr |
16 | | #include "mozilla/gfx/Matrix.h" // for Matrix4x4 |
17 | | #include "mozilla/gfx/Rect.h" // for Rect |
18 | | #include "mozilla/gfx/Types.h" |
19 | | #include "nsDebug.h" // for NS_ASSERTION |
20 | | #include "nsPoint.h" // for nsIntPoint |
21 | | #include "nsTArray.h" // for nsTArray |
22 | | #include "mozilla/layers/CompositorTypes.h" |
23 | | |
24 | | #include <string> |
25 | | |
26 | | namespace mozilla { |
27 | | namespace layers { |
28 | | |
29 | | class Layer; |
30 | | |
31 | | enum ShaderFeatures { |
32 | | ENABLE_RENDER_COLOR=0x01, |
33 | | ENABLE_TEXTURE_RECT=0x02, |
34 | | ENABLE_TEXTURE_EXTERNAL=0x04, |
35 | | ENABLE_TEXTURE_YCBCR=0x08, |
36 | | ENABLE_TEXTURE_NV12=0x10, |
37 | | ENABLE_TEXTURE_COMPONENT_ALPHA=0x20, |
38 | | ENABLE_TEXTURE_NO_ALPHA=0x40, |
39 | | ENABLE_TEXTURE_RB_SWAP=0x80, |
40 | | ENABLE_OPACITY=0x100, |
41 | | ENABLE_BLUR=0x200, |
42 | | ENABLE_COLOR_MATRIX=0x400, |
43 | | ENABLE_MASK=0x800, |
44 | | ENABLE_NO_PREMUL_ALPHA=0x1000, |
45 | | ENABLE_DEAA=0x2000, |
46 | | ENABLE_DYNAMIC_GEOMETRY=0x4000, |
47 | | ENABLE_MASK_TEXTURE_RECT=0x8000, |
48 | | }; |
49 | | |
50 | | class KnownUniform { |
51 | | public: |
52 | | // this needs to be kept in sync with strings in 'AddUniforms' |
53 | | enum KnownUniformName { |
54 | | NotAKnownUniform = -1, |
55 | | |
56 | | LayerTransform = 0, |
57 | | LayerTransformInverse, |
58 | | MaskTransform, |
59 | | BackdropTransform, |
60 | | LayerRects, |
61 | | MatrixProj, |
62 | | TextureTransform, |
63 | | TextureRects, |
64 | | RenderTargetOffset, |
65 | | LayerOpacity, |
66 | | Texture, |
67 | | YTexture, |
68 | | CbTexture, |
69 | | CrTexture, |
70 | | BlackTexture, |
71 | | WhiteTexture, |
72 | | MaskTexture, |
73 | | BackdropTexture, |
74 | | RenderColor, |
75 | | TexCoordMultiplier, |
76 | | CbCrTexCoordMultiplier, |
77 | | MaskCoordMultiplier, |
78 | | TexturePass2, |
79 | | ColorMatrix, |
80 | | ColorMatrixVector, |
81 | | BlurRadius, |
82 | | BlurOffset, |
83 | | BlurAlpha, |
84 | | BlurGaussianKernel, |
85 | | SSEdges, |
86 | | ViewportSize, |
87 | | VisibleCenter, |
88 | | YuvColorMatrix, |
89 | | |
90 | | KnownUniformCount |
91 | | }; |
92 | | |
93 | | KnownUniform() |
94 | 0 | { |
95 | 0 | mName = NotAKnownUniform; |
96 | 0 | mNameString = nullptr; |
97 | 0 | mLocation = -1; |
98 | 0 | memset(&mValue, 0, sizeof(mValue)); |
99 | 0 | } |
100 | | |
101 | 0 | bool UpdateUniform(int32_t i1) { |
102 | 0 | if (mLocation == -1) return false; |
103 | 0 | if (mValue.i1 != i1) { |
104 | 0 | mValue.i1 = i1; |
105 | 0 | return true; |
106 | 0 | } |
107 | 0 | return false; |
108 | 0 | } |
109 | | |
110 | 0 | bool UpdateUniform(float f1) { |
111 | 0 | if (mLocation == -1) return false; |
112 | 0 | if (mValue.f1 != f1) { |
113 | 0 | mValue.f1 = f1; |
114 | 0 | return true; |
115 | 0 | } |
116 | 0 | return false; |
117 | 0 | } |
118 | | |
119 | | bool UpdateUniform(float f1, float f2) { |
120 | | if (mLocation == -1) return false; |
121 | | if (mValue.f16v[0] != f1 || |
122 | | mValue.f16v[1] != f2) |
123 | | { |
124 | | mValue.f16v[0] = f1; |
125 | | mValue.f16v[1] = f2; |
126 | | return true; |
127 | | } |
128 | | return false; |
129 | | } |
130 | | |
131 | 0 | bool UpdateUniform(float f1, float f2, float f3, float f4) { |
132 | 0 | if (mLocation == -1) return false; |
133 | 0 | if (mValue.f16v[0] != f1 || |
134 | 0 | mValue.f16v[1] != f2 || |
135 | 0 | mValue.f16v[2] != f3 || |
136 | 0 | mValue.f16v[3] != f4) |
137 | 0 | { |
138 | 0 | mValue.f16v[0] = f1; |
139 | 0 | mValue.f16v[1] = f2; |
140 | 0 | mValue.f16v[2] = f3; |
141 | 0 | mValue.f16v[3] = f4; |
142 | 0 | return true; |
143 | 0 | } |
144 | 0 | return false; |
145 | 0 | } |
146 | | |
147 | 0 | bool UpdateUniform(int cnt, const float *fp) { |
148 | 0 | if (mLocation == -1) return false; |
149 | 0 | switch (cnt) { |
150 | 0 | case 1: |
151 | 0 | case 2: |
152 | 0 | case 3: |
153 | 0 | case 4: |
154 | 0 | case 9: |
155 | 0 | case 16: |
156 | 0 | if (memcmp(mValue.f16v, fp, sizeof(float) * cnt) != 0) { |
157 | 0 | memcpy(mValue.f16v, fp, sizeof(float) * cnt); |
158 | 0 | return true; |
159 | 0 | } |
160 | 0 | return false; |
161 | 0 | } |
162 | 0 | |
163 | 0 | MOZ_ASSERT_UNREACHABLE("cnt must be 1 2 3 4 9 or 16"); |
164 | 0 | return false; |
165 | 0 | } |
166 | | |
167 | 0 | bool UpdateArrayUniform(int cnt, const float *fp) { |
168 | 0 | if (mLocation == -1) return false; |
169 | 0 | if (cnt > 16) { |
170 | 0 | return false; |
171 | 0 | } |
172 | 0 | |
173 | 0 | if (memcmp(mValue.f16v, fp, sizeof(float) * cnt) != 0) { |
174 | 0 | memcpy(mValue.f16v, fp, sizeof(float) * cnt); |
175 | 0 | return true; |
176 | 0 | } |
177 | 0 | return false; |
178 | 0 | } |
179 | | |
180 | 0 | bool UpdateArrayUniform(int cnt, const gfx::Point3D* points) { |
181 | 0 | if (mLocation == -1) return false; |
182 | 0 | if (cnt > 4) { |
183 | 0 | return false; |
184 | 0 | } |
185 | 0 | |
186 | 0 | float fp[12]; |
187 | 0 | float *d = fp; |
188 | 0 | for(int i=0; i < cnt; i++) { |
189 | 0 | // Note: Do not want to make assumptions about .x, .y, .z member packing. |
190 | 0 | // If gfx::Point3D is updated to make this guarantee, SIMD optimizations |
191 | 0 | // may be possible |
192 | 0 | *d++ = points[i].x; |
193 | 0 | *d++ = points[i].y; |
194 | 0 | *d++ = points[i].z; |
195 | 0 | } |
196 | 0 |
|
197 | 0 | if (memcmp(mValue.f16v, fp, sizeof(float) * cnt * 3) != 0) { |
198 | 0 | memcpy(mValue.f16v, fp, sizeof(float) * cnt * 3); |
199 | 0 | return true; |
200 | 0 | } |
201 | 0 | return false; |
202 | 0 | } |
203 | | |
204 | | KnownUniformName mName; |
205 | | const char *mNameString; |
206 | | int32_t mLocation; |
207 | | |
208 | | union { |
209 | | int i1; |
210 | | float f1; |
211 | | float f16v[16]; |
212 | | } mValue; |
213 | | }; |
214 | | |
215 | | class ShaderConfigOGL |
216 | | { |
217 | | public: |
218 | | ShaderConfigOGL() |
219 | | : mFeatures(0) |
220 | | , mMultiplier(1) |
221 | | , mCompositionOp(gfx::CompositionOp::OP_OVER) |
222 | | { |
223 | | } |
224 | | |
225 | | void SetRenderColor(bool aEnabled); |
226 | | void SetTextureTarget(GLenum aTarget); |
227 | | void SetMaskTextureTarget(GLenum aTarget); |
228 | | void SetRBSwap(bool aEnabled); |
229 | | void SetNoAlpha(bool aEnabled); |
230 | | void SetOpacity(bool aEnabled); |
231 | | void SetYCbCr(bool aEnabled); |
232 | | void SetNV12(bool aEnabled); |
233 | | void SetComponentAlpha(bool aEnabled); |
234 | | void SetColorMatrix(bool aEnabled); |
235 | | void SetBlur(bool aEnabled); |
236 | | void SetMask(bool aEnabled); |
237 | | void SetDEAA(bool aEnabled); |
238 | | void SetCompositionOp(gfx::CompositionOp aOp); |
239 | | void SetNoPremultipliedAlpha(); |
240 | | void SetDynamicGeometry(bool aEnabled); |
241 | | void SetColorMultiplier(uint32_t aMultiplier); |
242 | | |
243 | | bool operator< (const ShaderConfigOGL& other) const |
244 | 0 | { |
245 | 0 | return mFeatures < other.mFeatures || |
246 | 0 | (mFeatures == other.mFeatures && |
247 | 0 | (int)mCompositionOp < (int)other.mCompositionOp) || |
248 | 0 | (mFeatures == other.mFeatures && |
249 | 0 | (int)mCompositionOp == (int)other.mCompositionOp && |
250 | 0 | mMultiplier < other.mMultiplier); |
251 | 0 | } |
252 | | |
253 | | public: |
254 | | void SetFeature(int aBitmask, bool aState) |
255 | 0 | { |
256 | 0 | if (aState) |
257 | 0 | mFeatures |= aBitmask; |
258 | 0 | else |
259 | 0 | mFeatures &= (~aBitmask); |
260 | 0 | } |
261 | | |
262 | | int mFeatures; |
263 | | uint32_t mMultiplier; |
264 | | gfx::CompositionOp mCompositionOp; |
265 | | }; |
266 | | |
267 | | static inline ShaderConfigOGL |
268 | | ShaderConfigFromTargetAndFormat(GLenum aTarget, |
269 | | gfx::SurfaceFormat aFormat) |
270 | 0 | { |
271 | 0 | ShaderConfigOGL config; |
272 | 0 | config.SetTextureTarget(aTarget); |
273 | 0 | config.SetRBSwap(aFormat == gfx::SurfaceFormat::B8G8R8A8 || |
274 | 0 | aFormat == gfx::SurfaceFormat::B8G8R8X8); |
275 | 0 | config.SetNoAlpha(aFormat == gfx::SurfaceFormat::B8G8R8X8 || |
276 | 0 | aFormat == gfx::SurfaceFormat::R8G8B8X8 || |
277 | 0 | aFormat == gfx::SurfaceFormat::R5G6B5_UINT16); |
278 | 0 | return config; |
279 | 0 | } |
280 | | |
281 | | /** |
282 | | * This struct represents the shaders that make up a program and the uniform |
283 | | * and attribute parmeters that those shaders take. |
284 | | * It is used by ShaderProgramOGL. |
285 | | * Use the factory method GetProfileFor to create instances. |
286 | | */ |
287 | | struct ProgramProfileOGL |
288 | | { |
289 | | /** |
290 | | * Factory method; creates an instance of this class for the given |
291 | | * ShaderConfigOGL |
292 | | */ |
293 | | static ProgramProfileOGL GetProfileFor(ShaderConfigOGL aConfig); |
294 | | |
295 | | // the source code for the program's shaders |
296 | | std::string mVertexShaderString; |
297 | | std::string mFragmentShaderString; |
298 | | |
299 | | // the vertex attributes |
300 | | nsTArray<Pair<nsCString, GLuint>> mAttributes; |
301 | | |
302 | | KnownUniform mUniforms[KnownUniform::KnownUniformCount]; |
303 | | nsTArray<const char *> mDefines; |
304 | | size_t mTextureCount; |
305 | | |
306 | | ProgramProfileOGL() : |
307 | | mTextureCount(0) |
308 | 0 | {} |
309 | | |
310 | | private: |
311 | | static void BuildMixBlender(const ShaderConfigOGL& aConfig, std::ostringstream& fs); |
312 | | }; |
313 | | |
314 | | |
315 | | #if defined(DEBUG) |
316 | | #define CHECK_CURRENT_PROGRAM 1 |
317 | | #define ASSERT_THIS_PROGRAM \ |
318 | | do { \ |
319 | | GLuint currentProgram; \ |
320 | | mGL->GetUIntegerv(LOCAL_GL_CURRENT_PROGRAM, ¤tProgram); \ |
321 | | MOZ_ASSERT(currentProgram == mProgram, \ |
322 | | "SetUniform with wrong program active!"); \ |
323 | | } while (0) |
324 | | #else |
325 | | #define ASSERT_THIS_PROGRAM \ |
326 | 0 | do { } while (0) |
327 | | #endif |
328 | | |
329 | | /** |
330 | | * Represents an OGL shader program. The details of a program are represented |
331 | | * by a ProgramProfileOGL |
332 | | */ |
333 | | class ShaderProgramOGL |
334 | | { |
335 | | public: |
336 | | typedef mozilla::gl::GLContext GLContext; |
337 | | |
338 | | ShaderProgramOGL(GLContext* aGL, const ProgramProfileOGL& aProfile); |
339 | | |
340 | | ~ShaderProgramOGL(); |
341 | | |
342 | | bool HasInitialized() { |
343 | | NS_ASSERTION(mProgramState != STATE_OK || mProgram > 0, "Inconsistent program state"); |
344 | | return mProgramState == STATE_OK; |
345 | | } |
346 | | |
347 | | GLuint GetProgram(); |
348 | | |
349 | | bool Initialize(); |
350 | | |
351 | | GLint CreateShader(GLenum aShaderType, const char *aShaderSource); |
352 | | |
353 | | /** |
354 | | * Creates a program and stores its id. |
355 | | */ |
356 | | bool CreateProgram(const char *aVertexShaderString, |
357 | | const char *aFragmentShaderString); |
358 | | |
359 | | /** |
360 | | * The following set of methods set a uniform argument to the shader program. |
361 | | * Not all uniforms may be set for all programs, and such uses will throw |
362 | | * an assertion. |
363 | | */ |
364 | 0 | void SetLayerTransform(const gfx::Matrix4x4& aMatrix) { |
365 | 0 | SetMatrixUniform(KnownUniform::LayerTransform, aMatrix); |
366 | 0 | } |
367 | | |
368 | 0 | void SetLayerTransformInverse(const gfx::Matrix4x4& aMatrix) { |
369 | 0 | SetMatrixUniform(KnownUniform::LayerTransformInverse, aMatrix); |
370 | 0 | } |
371 | | |
372 | 0 | void SetMaskLayerTransform(const gfx::Matrix4x4& aMatrix) { |
373 | 0 | SetMatrixUniform(KnownUniform::MaskTransform, aMatrix); |
374 | 0 | } |
375 | | |
376 | 0 | void SetBackdropTransform(const gfx::Matrix4x4& aMatrix) { |
377 | 0 | SetMatrixUniform(KnownUniform::BackdropTransform, aMatrix); |
378 | 0 | } |
379 | | |
380 | 0 | void SetDEAAEdges(const gfx::Point3D* aEdges) { |
381 | 0 | SetArrayUniform(KnownUniform::SSEdges, 4, aEdges); |
382 | 0 | } |
383 | | |
384 | 0 | void SetViewportSize(const gfx::IntSize& aSize) { |
385 | 0 | float vals[2] = { (float)aSize.width, (float)aSize.height }; |
386 | 0 | SetUniform(KnownUniform::ViewportSize, 2, vals); |
387 | 0 | } |
388 | | |
389 | 0 | void SetVisibleCenter(const gfx::Point& aVisibleCenter) { |
390 | 0 | float vals[2] = { aVisibleCenter.x, aVisibleCenter.y }; |
391 | 0 | SetUniform(KnownUniform::VisibleCenter, 2, vals); |
392 | 0 | } |
393 | | |
394 | 0 | void SetLayerRects(const gfx::Rect* aRects) { |
395 | 0 | float vals[16] = { aRects[0].X(), aRects[0].Y(), aRects[0].Width(), aRects[0].Height(), |
396 | 0 | aRects[1].X(), aRects[1].Y(), aRects[1].Width(), aRects[1].Height(), |
397 | 0 | aRects[2].X(), aRects[2].Y(), aRects[2].Width(), aRects[2].Height(), |
398 | 0 | aRects[3].X(), aRects[3].Y(), aRects[3].Width(), aRects[3].Height() }; |
399 | 0 | SetUniform(KnownUniform::LayerRects, 16, vals); |
400 | 0 | } |
401 | | |
402 | 0 | void SetProjectionMatrix(const gfx::Matrix4x4& aMatrix) { |
403 | 0 | SetMatrixUniform(KnownUniform::MatrixProj, aMatrix); |
404 | 0 | } |
405 | | |
406 | | // sets this program's texture transform, if it uses one |
407 | 0 | void SetTextureTransform(const gfx::Matrix4x4& aMatrix) { |
408 | 0 | SetMatrixUniform(KnownUniform::TextureTransform, aMatrix); |
409 | 0 | } |
410 | | |
411 | 0 | void SetTextureRects(const gfx::Rect* aRects) { |
412 | 0 | float vals[16] = { aRects[0].X(), aRects[0].Y(), aRects[0].Width(), aRects[0].Height(), |
413 | 0 | aRects[1].X(), aRects[1].Y(), aRects[1].Width(), aRects[1].Height(), |
414 | 0 | aRects[2].X(), aRects[2].Y(), aRects[2].Width(), aRects[2].Height(), |
415 | 0 | aRects[3].X(), aRects[3].Y(), aRects[3].Width(), aRects[3].Height() }; |
416 | 0 | SetUniform(KnownUniform::TextureRects, 16, vals); |
417 | 0 | } |
418 | | |
419 | | void SetRenderOffset(const nsIntPoint& aOffset) { |
420 | | float vals[4] = { float(aOffset.x), float(aOffset.y) }; |
421 | | SetUniform(KnownUniform::RenderTargetOffset, 2, vals); |
422 | | } |
423 | | |
424 | 0 | void SetRenderOffset(float aX, float aY) { |
425 | 0 | float vals[2] = { aX, aY }; |
426 | 0 | SetUniform(KnownUniform::RenderTargetOffset, 2, vals); |
427 | 0 | } |
428 | | |
429 | 0 | void SetLayerOpacity(float aOpacity) { |
430 | 0 | SetUniform(KnownUniform::LayerOpacity, aOpacity); |
431 | 0 | } |
432 | | |
433 | 0 | void SetTextureUnit(GLint aUnit) { |
434 | 0 | SetUniform(KnownUniform::Texture, aUnit); |
435 | 0 | } |
436 | | void SetYTextureUnit(GLint aUnit) { |
437 | | SetUniform(KnownUniform::YTexture, aUnit); |
438 | | } |
439 | | |
440 | | void SetCbTextureUnit(GLint aUnit) { |
441 | | SetUniform(KnownUniform::CbTexture, aUnit); |
442 | | } |
443 | | |
444 | | void SetCrTextureUnit(GLint aUnit) { |
445 | | SetUniform(KnownUniform::CrTexture, aUnit); |
446 | | } |
447 | | |
448 | 0 | void SetYCbCrTextureUnits(GLint aYUnit, GLint aCbUnit, GLint aCrUnit) { |
449 | 0 | SetUniform(KnownUniform::YTexture, aYUnit); |
450 | 0 | SetUniform(KnownUniform::CbTexture, aCbUnit); |
451 | 0 | SetUniform(KnownUniform::CrTexture, aCrUnit); |
452 | 0 | } |
453 | | |
454 | 0 | void SetNV12TextureUnits(GLint aYUnit, GLint aCbCrUnit) { |
455 | 0 | SetUniform(KnownUniform::YTexture, aYUnit); |
456 | 0 | SetUniform(KnownUniform::CbTexture, aCbCrUnit); |
457 | 0 | } |
458 | | |
459 | 0 | void SetBlackTextureUnit(GLint aUnit) { |
460 | 0 | SetUniform(KnownUniform::BlackTexture, aUnit); |
461 | 0 | } |
462 | | |
463 | 0 | void SetWhiteTextureUnit(GLint aUnit) { |
464 | 0 | SetUniform(KnownUniform::WhiteTexture, aUnit); |
465 | 0 | } |
466 | | |
467 | 0 | void SetMaskTextureUnit(GLint aUnit) { |
468 | 0 | SetUniform(KnownUniform::MaskTexture, aUnit); |
469 | 0 | } |
470 | | |
471 | 0 | void SetBackdropTextureUnit(GLint aUnit) { |
472 | 0 | SetUniform(KnownUniform::BackdropTexture, aUnit); |
473 | 0 | } |
474 | | |
475 | 0 | void SetRenderColor(const gfx::Color& aColor) { |
476 | 0 | SetUniform(KnownUniform::RenderColor, aColor); |
477 | 0 | } |
478 | | |
479 | | void SetColorMatrix(const gfx::Matrix5x4& aColorMatrix) |
480 | 0 | { |
481 | 0 | SetMatrixUniform(KnownUniform::ColorMatrix, &aColorMatrix._11); |
482 | 0 | SetUniform(KnownUniform::ColorMatrixVector, 4, &aColorMatrix._51); |
483 | 0 | } |
484 | | |
485 | 0 | void SetTexCoordMultiplier(float aWidth, float aHeight) { |
486 | 0 | float f[] = {aWidth, aHeight}; |
487 | 0 | SetUniform(KnownUniform::TexCoordMultiplier, 2, f); |
488 | 0 | } |
489 | | |
490 | 0 | void SetCbCrTexCoordMultiplier(float aWidth, float aHeight) { |
491 | 0 | float f[] = {aWidth, aHeight}; |
492 | 0 | SetUniform(KnownUniform::CbCrTexCoordMultiplier, 2, f); |
493 | 0 | } |
494 | | |
495 | 0 | void SetMaskCoordMultiplier(float aWidth, float aHeight) { |
496 | 0 | float f[] = {aWidth, aHeight}; |
497 | 0 | SetUniform(KnownUniform::MaskCoordMultiplier, 2, f); |
498 | 0 | } |
499 | | |
500 | | void SetYUVColorSpace(YUVColorSpace aYUVColorSpace); |
501 | | |
502 | | // Set whether we want the component alpha shader to return the color |
503 | | // vector (pass 1, false) or the alpha vector (pass2, true). With support |
504 | | // for multiple render targets we wouldn't need two passes here. |
505 | 0 | void SetTexturePass2(bool aFlag) { |
506 | 0 | SetUniform(KnownUniform::TexturePass2, aFlag ? 1 : 0); |
507 | 0 | } |
508 | | |
509 | | void SetBlurRadius(float aRX, float aRY); |
510 | | |
511 | | void SetBlurAlpha(float aAlpha) { |
512 | | SetUniform(KnownUniform::BlurAlpha, aAlpha); |
513 | | } |
514 | | |
515 | | void SetBlurOffset(float aOffsetX, float aOffsetY) { |
516 | | float f[] = {aOffsetX, aOffsetY}; |
517 | | SetUniform(KnownUniform::BlurOffset, 2, f); |
518 | | } |
519 | | |
520 | 0 | size_t GetTextureCount() const { |
521 | 0 | return mProfile.mTextureCount; |
522 | 0 | } |
523 | | |
524 | | protected: |
525 | | RefPtr<GLContext> mGL; |
526 | | // the OpenGL id of the program |
527 | | GLuint mProgram; |
528 | | ProgramProfileOGL mProfile; |
529 | | enum { |
530 | | STATE_NEW, |
531 | | STATE_OK, |
532 | | STATE_ERROR |
533 | | } mProgramState; |
534 | | |
535 | | #ifdef CHECK_CURRENT_PROGRAM |
536 | | static int sCurrentProgramKey; |
537 | | #endif |
538 | | |
539 | | void SetUniform(KnownUniform::KnownUniformName aKnownUniform, float aFloatValue) |
540 | 0 | { |
541 | 0 | ASSERT_THIS_PROGRAM; |
542 | 0 | NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform"); |
543 | 0 |
|
544 | 0 | KnownUniform& ku(mProfile.mUniforms[aKnownUniform]); |
545 | 0 | if (ku.UpdateUniform(aFloatValue)) { |
546 | 0 | mGL->fUniform1f(ku.mLocation, aFloatValue); |
547 | 0 | } |
548 | 0 | } |
549 | | |
550 | 0 | void SetUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx::Color& aColor) { |
551 | 0 | ASSERT_THIS_PROGRAM; |
552 | 0 | NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform"); |
553 | 0 |
|
554 | 0 | KnownUniform& ku(mProfile.mUniforms[aKnownUniform]); |
555 | 0 | if (ku.UpdateUniform(aColor.r, aColor.g, aColor.b, aColor.a)) { |
556 | 0 | mGL->fUniform4fv(ku.mLocation, 1, ku.mValue.f16v); |
557 | 0 | } |
558 | 0 | } |
559 | | |
560 | | void SetUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, const float *aFloatValues) |
561 | 0 | { |
562 | 0 | ASSERT_THIS_PROGRAM; |
563 | 0 | NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform"); |
564 | 0 |
|
565 | 0 | KnownUniform& ku(mProfile.mUniforms[aKnownUniform]); |
566 | 0 | if (ku.UpdateUniform(aLength, aFloatValues)) { |
567 | 0 | switch (aLength) { |
568 | 0 | case 1: mGL->fUniform1fv(ku.mLocation, 1, ku.mValue.f16v); break; |
569 | 0 | case 2: mGL->fUniform2fv(ku.mLocation, 1, ku.mValue.f16v); break; |
570 | 0 | case 3: mGL->fUniform3fv(ku.mLocation, 1, ku.mValue.f16v); break; |
571 | 0 | case 4: mGL->fUniform4fv(ku.mLocation, 1, ku.mValue.f16v); break; |
572 | 0 | case 16: mGL->fUniform4fv(ku.mLocation, 4, ku.mValue.f16v); break; |
573 | 0 | default: |
574 | 0 | MOZ_ASSERT_UNREACHABLE("Bogus aLength param"); |
575 | 0 | } |
576 | 0 | } |
577 | 0 | } |
578 | | |
579 | | void SetArrayUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, float *aFloatValues) |
580 | 0 | { |
581 | 0 | ASSERT_THIS_PROGRAM; |
582 | 0 | NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform"); |
583 | 0 |
|
584 | 0 | KnownUniform& ku(mProfile.mUniforms[aKnownUniform]); |
585 | 0 | if (ku.UpdateArrayUniform(aLength, aFloatValues)) { |
586 | 0 | mGL->fUniform1fv(ku.mLocation, aLength, ku.mValue.f16v); |
587 | 0 | } |
588 | 0 | } |
589 | | |
590 | | void SetArrayUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, const gfx::Point3D *aPointValues) |
591 | 0 | { |
592 | 0 | ASSERT_THIS_PROGRAM; |
593 | 0 | NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform"); |
594 | 0 |
|
595 | 0 | KnownUniform& ku(mProfile.mUniforms[aKnownUniform]); |
596 | 0 | if (ku.UpdateArrayUniform(aLength, aPointValues)) { |
597 | 0 | mGL->fUniform3fv(ku.mLocation, aLength, ku.mValue.f16v); |
598 | 0 | } |
599 | 0 | } |
600 | | |
601 | 0 | void SetUniform(KnownUniform::KnownUniformName aKnownUniform, GLint aIntValue) { |
602 | 0 | ASSERT_THIS_PROGRAM; |
603 | 0 | NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform"); |
604 | 0 |
|
605 | 0 | KnownUniform& ku(mProfile.mUniforms[aKnownUniform]); |
606 | 0 | if (ku.UpdateUniform(aIntValue)) { |
607 | 0 | mGL->fUniform1i(ku.mLocation, aIntValue); |
608 | 0 | } |
609 | 0 | } |
610 | | |
611 | 0 | void SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const float *aFloatValues) { |
612 | 0 | ASSERT_THIS_PROGRAM; |
613 | 0 | NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform"); |
614 | 0 |
|
615 | 0 | KnownUniform& ku(mProfile.mUniforms[aKnownUniform]); |
616 | 0 | if (ku.UpdateUniform(16, aFloatValues)) { |
617 | 0 | mGL->fUniformMatrix4fv(ku.mLocation, 1, false, ku.mValue.f16v); |
618 | 0 | } |
619 | 0 | } |
620 | | |
621 | 0 | void SetMatrix3fvUniform(KnownUniform::KnownUniformName aKnownUniform, const float *aFloatValues) { |
622 | 0 | ASSERT_THIS_PROGRAM; |
623 | 0 | NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform"); |
624 | 0 |
|
625 | 0 | KnownUniform& ku(mProfile.mUniforms[aKnownUniform]); |
626 | 0 | if (ku.UpdateUniform(9, aFloatValues)) { |
627 | 0 | mGL->fUniformMatrix3fv(ku.mLocation, 1, false, ku.mValue.f16v); |
628 | 0 | } |
629 | 0 | } |
630 | | |
631 | 0 | void SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx::Matrix4x4& aMatrix) { |
632 | 0 | SetMatrixUniform(aKnownUniform, &aMatrix._11); |
633 | 0 | } |
634 | | }; |
635 | | |
636 | | } // namespace layers |
637 | | } // namespace mozilla |
638 | | |
639 | | #endif /* GFX_OGLSHADERPROGRAM_H */ |