1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Corporation code.
16 : *
17 : * The Initial Developer of the Original Code is Mozilla Foundation.
18 : * Portions created by the Initial Developer are Copyright (C) 2010
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Vladimir Vukicevic <vladimir@pobox.com>
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either the GNU General Public License Version 2 or later (the "GPL"), or
26 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #ifndef GFX_LAYERMANAGEROGLPROGRAM_H
39 : #define GFX_LAYERMANAGEROGLPROGRAM_H
40 :
41 : #include <string.h>
42 :
43 : #include "prenv.h"
44 :
45 : #include "nsString.h"
46 : #include "GLContext.h"
47 :
48 : namespace mozilla {
49 : namespace layers {
50 :
51 : #if defined(DEBUG)
52 : #define CHECK_CURRENT_PROGRAM 1
53 : #define ASSERT_THIS_PROGRAM \
54 : do { \
55 : NS_ASSERTION(mGL->GetUserData(&sCurrentProgramKey) == this, \
56 : "SetUniform with wrong program active!"); \
57 : } while (0)
58 : #else
59 : #define ASSERT_THIS_PROGRAM
60 : #endif
61 :
62 : class LayerManagerOGLProgram {
63 : protected:
64 : #ifdef CHECK_CURRENT_PROGRAM
65 : static int sCurrentProgramKey;
66 : #endif
67 :
68 : public:
69 : typedef mozilla::gl::GLContext GLContext;
70 :
71 : // common attrib locations
72 : enum {
73 : VertexAttrib = 0,
74 : TexCoordAttrib = 1
75 : };
76 :
77 0 : LayerManagerOGLProgram(GLContext *aGL)
78 0 : : mGL(aGL), mProgram(0)
79 0 : { }
80 :
81 0 : virtual ~LayerManagerOGLProgram() {
82 0 : nsRefPtr<GLContext> ctx = mGL->GetSharedContext();
83 0 : if (!ctx) {
84 0 : ctx = mGL;
85 : }
86 0 : ctx->MakeCurrent();
87 0 : ctx->fDeleteProgram(mProgram);
88 0 : }
89 :
90 0 : void Activate() {
91 0 : NS_ASSERTION(mProgram != 0, "Attempting to activate a program that's not in use!");
92 0 : mGL->fUseProgram(mProgram);
93 : #if CHECK_CURRENT_PROGRAM
94 0 : mGL->SetUserData(&sCurrentProgramKey, this);
95 : #endif
96 0 : }
97 :
98 0 : void SetUniform(GLuint aUniform, float aFloatValue) {
99 0 : ASSERT_THIS_PROGRAM;
100 0 : if (aUniform == GLuint(-1))
101 0 : return;
102 0 : mGL->fUniform1f(aUniform, aFloatValue);
103 : }
104 :
105 0 : void SetUniform(GLuint aUniform, const gfxRGBA& aColor) {
106 0 : ASSERT_THIS_PROGRAM;
107 0 : if (aUniform == GLuint(-1))
108 0 : return;
109 0 : mGL->fUniform4f(aUniform, float(aColor.r), float(aColor.g), float(aColor.b), float(aColor.a));
110 : }
111 :
112 0 : void SetUniform(GLuint aUniform, int aLength, float *aFloatValues) {
113 0 : ASSERT_THIS_PROGRAM;
114 :
115 0 : if (aUniform == GLuint(-1))
116 0 : return;
117 :
118 0 : if (aLength == 1) {
119 0 : mGL->fUniform1fv(aUniform, 1, aFloatValues);
120 0 : } else if (aLength == 2) {
121 0 : mGL->fUniform2fv(aUniform, 1, aFloatValues);
122 0 : } else if (aLength == 3) {
123 0 : mGL->fUniform3fv(aUniform, 1, aFloatValues);
124 0 : } else if (aLength == 4) {
125 0 : mGL->fUniform4fv(aUniform, 1, aFloatValues);
126 : } else {
127 0 : NS_NOTREACHED("Bogus aLength param");
128 : }
129 : }
130 :
131 0 : void SetUniform(GLuint aUniform, GLint aIntValue) {
132 0 : ASSERT_THIS_PROGRAM;
133 0 : if (aUniform == GLuint(-1))
134 0 : return;
135 0 : mGL->fUniform1i(aUniform, aIntValue);
136 : }
137 :
138 0 : void SetMatrixUniform(GLuint aUniform, const float *aFloatValues) {
139 0 : ASSERT_THIS_PROGRAM;
140 0 : if (aUniform == GLuint(-1))
141 0 : return;
142 0 : mGL->fUniformMatrix4fv(aUniform, 1, false, aFloatValues);
143 : }
144 :
145 : protected:
146 : nsRefPtr<GLContext> mGL;
147 :
148 : GLuint mProgram;
149 :
150 0 : GLint CreateShader(GLenum aShaderType,
151 : const char *aShaderSource)
152 : {
153 0 : GLint success, len = 0;
154 :
155 0 : GLint sh = mGL->fCreateShader(aShaderType);
156 0 : mGL->fShaderSource(sh, 1, (const GLchar**)&aShaderSource, NULL);
157 0 : mGL->fCompileShader(sh);
158 0 : mGL->fGetShaderiv(sh, LOCAL_GL_COMPILE_STATUS, &success);
159 0 : mGL->fGetShaderiv(sh, LOCAL_GL_INFO_LOG_LENGTH, (GLint*) &len);
160 : /* Even if compiling is successful, there may still be warnings. Print them
161 : * in a debug build. The > 10 is to catch silly compilers that might put
162 : * some whitespace in the log but otherwise leave it empty.
163 : */
164 0 : if (!success
165 : #ifdef DEBUG
166 0 : || (len > 10 && PR_GetEnv("MOZ_DEBUG_SHADERS"))
167 : #endif
168 : )
169 : {
170 0 : nsCAutoString log;
171 0 : log.SetCapacity(len);
172 0 : mGL->fGetShaderInfoLog(sh, len, (GLint*) &len, (char*) log.BeginWriting());
173 0 : log.SetLength(len);
174 :
175 0 : if (!success) {
176 0 : printf_stderr("=== SHADER COMPILATION FAILED ===\n");
177 : } else {
178 0 : printf_stderr("=== SHADER COMPILATION WARNINGS ===\n");
179 : }
180 :
181 0 : printf_stderr("=== Source:\n%s\n", aShaderSource);
182 0 : printf_stderr("=== Log:\n%s\n", log.get());
183 0 : printf_stderr("============\n");
184 :
185 0 : if (!success) {
186 0 : mGL->fDeleteShader(sh);
187 0 : return 0;
188 : }
189 : }
190 :
191 0 : return sh;
192 : }
193 :
194 0 : bool CreateProgram(const char *aVertexShaderString,
195 : const char *aFragmentShaderString)
196 : {
197 0 : GLuint vertexShader = CreateShader(LOCAL_GL_VERTEX_SHADER, aVertexShaderString);
198 0 : GLuint fragmentShader = CreateShader(LOCAL_GL_FRAGMENT_SHADER, aFragmentShaderString);
199 :
200 0 : if (!vertexShader || !fragmentShader)
201 0 : return false;
202 :
203 0 : mProgram = mGL->fCreateProgram();
204 0 : mGL->fAttachShader(mProgram, vertexShader);
205 0 : mGL->fAttachShader(mProgram, fragmentShader);
206 :
207 : // bind common attribs to consistent indices
208 0 : mGL->fBindAttribLocation(mProgram, VertexAttrib, "aVertexCoord");
209 0 : mGL->fBindAttribLocation(mProgram, TexCoordAttrib, "aTexCoord");
210 :
211 0 : mGL->fLinkProgram(mProgram);
212 :
213 : GLint success, len;
214 0 : mGL->fGetProgramiv(mProgram, LOCAL_GL_LINK_STATUS, &success);
215 0 : mGL->fGetProgramiv(mProgram, LOCAL_GL_INFO_LOG_LENGTH, (GLint*) &len);
216 : /* Even if linking is successful, there may still be warnings. Print them
217 : * in a debug build. The > 10 is to catch silly compilers that might put
218 : * some whitespace in the log but otherwise leave it empty.
219 : */
220 0 : if (!success
221 : #ifdef DEBUG
222 0 : || (len > 10 && PR_GetEnv("MOZ_DEBUG_SHADERS"))
223 : #endif
224 : )
225 : {
226 0 : nsCAutoString log;
227 0 : log.SetCapacity(len);
228 0 : mGL->fGetProgramInfoLog(mProgram, len, (GLint*) &len, (char*) log.BeginWriting());
229 0 : log.SetLength(len);
230 :
231 0 : if (!success) {
232 0 : printf_stderr("=== PROGRAM LINKING FAILED ===\n");
233 : } else {
234 0 : printf_stderr("=== PROGRAM LINKING WARNINGS ===\n");
235 : }
236 0 : printf_stderr("=== Log:\n%s\n", log.get());
237 0 : printf_stderr("============\n");
238 : }
239 :
240 : // We can mark the shaders for deletion; they're attached to the program
241 : // and will remain attached.
242 0 : mGL->fDeleteShader(vertexShader);
243 0 : mGL->fDeleteShader(fragmentShader);
244 :
245 0 : if (!success) {
246 0 : mGL->fDeleteProgram(mProgram);
247 0 : mProgram = 0;
248 0 : return false;
249 : }
250 :
251 0 : return true;
252 : }
253 :
254 0 : void GetAttribLocations(const char **aAttribNames,
255 : GLint *aAttribLocations)
256 : {
257 0 : NS_ASSERTION(mProgram != 0, "GetAttribLocations called with no program!");
258 :
259 0 : for (int i = 0; aAttribNames[i] != nsnull; ++i) {
260 0 : aAttribLocations[i] = mGL->fGetAttribLocation(mProgram, aAttribNames[i]);
261 : }
262 0 : }
263 :
264 0 : void GetUniformLocations(const char **aUniformNames,
265 : GLint *aUniformLocations)
266 : {
267 0 : NS_ASSERTION(mProgram != 0, "GetUniformLocations called with no program!");
268 :
269 0 : for (int i = 0; aUniformNames[i] != nsnull; ++i) {
270 0 : aUniformLocations[i] = mGL->fGetUniformLocation(mProgram, aUniformNames[i]);
271 : }
272 0 : }
273 : };
274 :
275 : /*
276 : * A LayerProgram is the base of all further LayerPrograms.
277 : *
278 : * It has a number of attributes and uniforms common to all layer programs.
279 : *
280 : * Attribute inputs:
281 : * aVertexCoord - vertex coordinate
282 : *
283 : * Uniforms:
284 : * uLayerTransform - a transform matrix
285 : * uLayerQuadTransform
286 : * uMatrixProj - projection matrix
287 : * uRenderTargetOffset - a vec4 offset to apply to the transformed coordinates
288 : * uLayerOpacity - a float, the layer opacity (final colors will be multiplied by this)
289 : */
290 :
291 : class LayerProgram :
292 : public LayerManagerOGLProgram
293 0 : {
294 : public:
295 : enum {
296 : TransformMatrixUniform = 0,
297 : QuadTransformUniform,
298 : ProjectionMatrixUniform,
299 : OffsetUniform,
300 : LayerOpacityUniform,
301 : NumLayerUniforms
302 : };
303 :
304 : enum {
305 : VertexCoordAttrib = 0,
306 : NumLayerAttribs
307 : };
308 :
309 0 : LayerProgram(GLContext *aGL)
310 0 : : LayerManagerOGLProgram(aGL)
311 0 : { }
312 :
313 0 : bool Initialize(const char *aVertexShaderString,
314 : const char *aFragmentShaderString)
315 : {
316 0 : if (!CreateProgram(aVertexShaderString, aFragmentShaderString))
317 0 : return false;
318 :
319 : const char *uniformNames[] = {
320 : "uLayerTransform",
321 : "uLayerQuadTransform",
322 : "uMatrixProj",
323 : "uRenderTargetOffset",
324 : "uLayerOpacity",
325 : NULL
326 0 : };
327 :
328 0 : mUniformLocations.SetLength(NumLayerUniforms);
329 0 : GetUniformLocations(uniformNames, &mUniformLocations[0]);
330 :
331 : const char *attribNames[] = {
332 : "aVertexCoord",
333 : NULL
334 0 : };
335 :
336 0 : mAttribLocations.SetLength(NumLayerAttribs);
337 0 : GetAttribLocations(attribNames, &mAttribLocations[0]);
338 :
339 0 : return true;
340 : }
341 :
342 0 : GLint AttribLocation(int aWhich) {
343 0 : if (aWhich < 0 || aWhich >= int(mAttribLocations.Length()))
344 0 : return -1;
345 0 : return mAttribLocations[aWhich];
346 : }
347 :
348 0 : void SetLayerTransform(const gfx3DMatrix& aMatrix) {
349 0 : SetLayerTransform(&aMatrix._11);
350 0 : }
351 :
352 0 : void SetLayerTransform(const float *aMatrix) {
353 0 : SetMatrixUniform(mUniformLocations[TransformMatrixUniform], aMatrix);
354 0 : }
355 :
356 0 : void SetLayerQuadRect(const nsIntRect& aRect) {
357 0 : gfx3DMatrix m;
358 0 : m._11 = float(aRect.width);
359 0 : m._22 = float(aRect.height);
360 0 : m._41 = float(aRect.x);
361 0 : m._42 = float(aRect.y);
362 0 : SetMatrixUniform(mUniformLocations[QuadTransformUniform], &m._11);
363 0 : }
364 :
365 0 : void SetProjectionMatrix(const gfx3DMatrix& aMatrix) {
366 0 : SetProjectionMatrix(&aMatrix._11);
367 0 : }
368 :
369 0 : void SetProjectionMatrix(const float *aMatrix) {
370 0 : SetMatrixUniform(mUniformLocations[ProjectionMatrixUniform], aMatrix);
371 0 : }
372 :
373 0 : void SetRenderOffset(const nsIntPoint& aOffset) {
374 0 : float vals[4] = { float(aOffset.x), float(aOffset.y), 0.0f, 0.0f };
375 0 : SetUniform(mUniformLocations[OffsetUniform], 4, vals);
376 0 : }
377 :
378 : void SetRenderOffset(float aX, float aY) {
379 : float vals[4] = { aX, aY, 0.0f, 0.0f };
380 : SetUniform(mUniformLocations[OffsetUniform], 4, vals);
381 : }
382 :
383 0 : void SetLayerOpacity(float aOpacity) {
384 0 : SetUniform(mUniformLocations[LayerOpacityUniform], aOpacity);
385 0 : }
386 :
387 : protected:
388 : nsTArray<GLint> mUniformLocations;
389 : nsTArray<GLint> mAttribLocations;
390 : };
391 :
392 : /*
393 : * A ColorTextureLayerProgram is a LayerProgram that renders
394 : * a single texture. It adds the following attributes and uniforms:
395 : *
396 : * Attribute inputs:
397 : * aTexCoord - texture coordinate
398 : *
399 : * Uniforms:
400 : * uTexture - 2D texture unit which to sample
401 : */
402 :
403 : class ColorTextureLayerProgram :
404 : public LayerProgram
405 0 : {
406 : public:
407 : enum {
408 : TextureUniform = NumLayerUniforms,
409 : NumUniforms
410 : };
411 :
412 : enum {
413 : TexCoordAttrib = NumLayerAttribs,
414 : NumAttribs
415 : };
416 :
417 0 : ColorTextureLayerProgram(GLContext *aGL)
418 0 : : LayerProgram(aGL)
419 0 : { }
420 :
421 0 : bool Initialize(const char *aVertexShaderString,
422 : const char *aFragmentShaderString)
423 : {
424 0 : if (!LayerProgram::Initialize(aVertexShaderString, aFragmentShaderString))
425 0 : return false;
426 :
427 : const char *uniformNames[] = {
428 : "uTexture",
429 : NULL
430 0 : };
431 :
432 0 : mUniformLocations.SetLength(NumUniforms);
433 0 : GetUniformLocations(uniformNames, &mUniformLocations[NumLayerUniforms]);
434 :
435 : const char *attribNames[] = {
436 : "aTexCoord",
437 : NULL
438 0 : };
439 :
440 0 : mAttribLocations.SetLength(NumAttribs);
441 0 : GetAttribLocations(attribNames, &mAttribLocations[NumLayerAttribs]);
442 :
443 : // this is a one-off that's present in the 2DRect versions of some shaders.
444 : mTexCoordMultiplierUniformLocation =
445 0 : mGL->fGetUniformLocation(mProgram, "uTexCoordMultiplier");
446 :
447 0 : return true;
448 : }
449 :
450 0 : void SetTextureUnit(GLint aUnit) {
451 0 : SetUniform(mUniformLocations[TextureUniform], aUnit);
452 0 : }
453 :
454 0 : GLint GetTexCoordMultiplierUniformLocation() {
455 0 : return mTexCoordMultiplierUniformLocation;
456 : }
457 :
458 : protected:
459 : GLint mTexCoordMultiplierUniformLocation;
460 : };
461 :
462 : /*
463 : * A YCbCrTextureLayerProgram is a LayerProgram that renders a YCbCr
464 : * image, reading from three texture units. The textures are assumed
465 : * to be single-channel textures.
466 : *
467 : * Attribute inputs:
468 : * aTexCoord - texture coordinate
469 : *
470 : * Uniforms:
471 : * uYTexture - 2D texture unit which to sample Y
472 : * uCbTexture - 2D texture unit which to sample Cb
473 : * uCrTexture - 2D texture unit which to sample Cr
474 : */
475 :
476 : class YCbCrTextureLayerProgram :
477 : public LayerProgram
478 0 : {
479 : public:
480 : enum {
481 : YTextureUniform = NumLayerUniforms,
482 : CbTextureUniform,
483 : CrTextureUniform,
484 : NumUniforms
485 : };
486 :
487 : enum {
488 : TexCoordAttrib = NumLayerAttribs,
489 : NumAttribs
490 : };
491 :
492 0 : YCbCrTextureLayerProgram(GLContext *aGL)
493 0 : : LayerProgram(aGL)
494 0 : { }
495 :
496 0 : bool Initialize(const char *aVertexShaderString,
497 : const char *aFragmentShaderString)
498 : {
499 0 : if (!LayerProgram::Initialize(aVertexShaderString, aFragmentShaderString))
500 0 : return false;
501 :
502 : const char *uniformNames[] = {
503 : "uYTexture",
504 : "uCbTexture",
505 : "uCrTexture",
506 : NULL
507 0 : };
508 :
509 0 : mUniformLocations.SetLength(NumUniforms);
510 0 : GetUniformLocations(uniformNames, &mUniformLocations[NumLayerUniforms]);
511 :
512 : const char *attribNames[] = {
513 : "aTexCoord",
514 : NULL
515 0 : };
516 :
517 0 : mAttribLocations.SetLength(NumAttribs);
518 0 : GetAttribLocations(attribNames, &mAttribLocations[NumLayerAttribs]);
519 :
520 0 : return true;
521 : }
522 :
523 : void SetYTextureUnit(GLint aUnit) {
524 : SetUniform(mUniformLocations[YTextureUniform], aUnit);
525 : }
526 :
527 : void SetCbTextureUnit(GLint aUnit) {
528 : SetUniform(mUniformLocations[CbTextureUniform], aUnit);
529 : }
530 :
531 : void SetCrTextureUnit(GLint aUnit) {
532 : SetUniform(mUniformLocations[CrTextureUniform], aUnit);
533 : }
534 :
535 0 : void SetYCbCrTextureUnits(GLint aYUnit, GLint aCbUnit, GLint aCrUnit) {
536 0 : SetUniform(mUniformLocations[YTextureUniform], aYUnit);
537 0 : SetUniform(mUniformLocations[CbTextureUniform], aCbUnit);
538 0 : SetUniform(mUniformLocations[CrTextureUniform], aCrUnit);
539 0 : }
540 : };
541 :
542 : /*
543 : * A ComponentAlphaTextureLayerProgram is a LayerProgram that renders one pass
544 : * of the two-pass component alpha rendering system using two textures.
545 : * It adds the following attributes and uniforms:
546 : *
547 : * Attribute inputs:
548 : * aTexCoord - texture coordinate
549 : *
550 : * Uniforms:
551 : * uBlackTexture - 2D texture on top of an opaque black background
552 : * uWhiteTexture - 2D texture on top of an opaque white background
553 : */
554 :
555 : class ComponentAlphaTextureLayerProgram :
556 : public LayerProgram
557 0 : {
558 : public:
559 : enum {
560 : BlackTextureUniform = NumLayerUniforms,
561 : WhiteTextureUniform,
562 : NumUniforms
563 : };
564 :
565 : enum {
566 : TexCoordAttrib = NumLayerAttribs,
567 : NumAttribs
568 : };
569 :
570 0 : ComponentAlphaTextureLayerProgram(GLContext *aGL)
571 0 : : LayerProgram(aGL)
572 0 : { }
573 :
574 0 : bool Initialize(const char *aVertexShaderString,
575 : const char *aFragmentShaderString)
576 : {
577 0 : if (!LayerProgram::Initialize(aVertexShaderString, aFragmentShaderString))
578 0 : return false;
579 :
580 : const char *uniformNames[] = {
581 : "uBlackTexture",
582 : "uWhiteTexture",
583 : NULL
584 0 : };
585 :
586 0 : mUniformLocations.SetLength(NumUniforms);
587 0 : GetUniformLocations(uniformNames, &mUniformLocations[NumLayerUniforms]);
588 :
589 : const char *attribNames[] = {
590 : "aTexCoord",
591 : NULL
592 0 : };
593 :
594 0 : mAttribLocations.SetLength(NumAttribs);
595 0 : GetAttribLocations(attribNames, &mAttribLocations[NumLayerAttribs]);
596 :
597 0 : return true;
598 : }
599 :
600 0 : void SetBlackTextureUnit(GLint aUnit) {
601 0 : SetUniform(mUniformLocations[BlackTextureUniform], aUnit);
602 0 : }
603 :
604 0 : void SetWhiteTextureUnit(GLint aUnit) {
605 0 : SetUniform(mUniformLocations[WhiteTextureUniform], aUnit);
606 0 : }
607 : };
608 :
609 : /*
610 : * A SolidColorLayerProgram is a LayerProgram that renders
611 : * a solid color. It adds the following attributes and uniforms:
612 : *
613 : * Uniforms:
614 : * uRenderColor - solid color to render;
615 : * This should be with premultiplied opacity, as it's written
616 : * to the color buffer directly. Layer Opacity is ignored.
617 : */
618 :
619 : class SolidColorLayerProgram :
620 : public LayerProgram
621 0 : {
622 : public:
623 : enum {
624 : RenderColorUniform = NumLayerUniforms,
625 : NumUniforms
626 : };
627 :
628 : enum {
629 : NumAttribs = NumLayerAttribs
630 : };
631 :
632 0 : SolidColorLayerProgram(GLContext *aGL)
633 0 : : LayerProgram(aGL)
634 0 : { }
635 :
636 0 : bool Initialize(const char *aVertexShaderString,
637 : const char *aFragmentShaderString)
638 : {
639 0 : if (!LayerProgram::Initialize(aVertexShaderString, aFragmentShaderString))
640 0 : return false;
641 :
642 : const char *uniformNames[] = {
643 : "uRenderColor",
644 : NULL
645 0 : };
646 :
647 0 : mUniformLocations.SetLength(NumUniforms);
648 0 : GetUniformLocations(uniformNames, &mUniformLocations[NumLayerUniforms]);
649 :
650 0 : return true;
651 : }
652 :
653 0 : void SetRenderColor(const gfxRGBA& aColor) {
654 0 : SetUniform(mUniformLocations[RenderColorUniform], aColor);
655 0 : }
656 : };
657 :
658 : /*
659 : * A CopyProgram is an OpenGL program that copies a 4-channel texture
660 : * to the destination, making no attempt to transform any incoming
661 : * vertices. It has the following attributes and uniforms:
662 : *
663 : * Attribute inputs:
664 : * aVertexCoord - vertex coordinate
665 : * aTexCoord - texture coordinate
666 : *
667 : * Uniforms:
668 : * uTexture - 2D texture unit which to sample
669 : */
670 :
671 : class CopyProgram :
672 : public LayerManagerOGLProgram
673 0 : {
674 : public:
675 : enum {
676 : TextureUniform = 0,
677 : NumUniforms
678 : };
679 :
680 : enum {
681 : VertexCoordAttrib = 0,
682 : TexCoordAttrib,
683 : NumAttribs
684 : };
685 :
686 0 : CopyProgram(GLContext *aGL)
687 0 : : LayerManagerOGLProgram(aGL)
688 0 : { }
689 :
690 0 : bool Initialize(const char *aVertexShaderString,
691 : const char *aFragmentShaderString)
692 : {
693 0 : if (!CreateProgram(aVertexShaderString, aFragmentShaderString))
694 0 : return false;
695 :
696 : const char *uniformNames[] = {
697 : "uTexture",
698 : NULL
699 0 : };
700 :
701 0 : mUniformLocations.SetLength(NumUniforms);
702 0 : GetUniformLocations(uniformNames, &mUniformLocations[0]);
703 :
704 : const char *attribNames[] = {
705 : "aVertexCoord",
706 : "aTexCoord",
707 : NULL
708 0 : };
709 :
710 0 : mAttribLocations.SetLength(NumAttribs);
711 0 : GetAttribLocations(attribNames, &mAttribLocations[0]);
712 :
713 : // this is a one-off that's present in the 2DRect versions of some shaders.
714 : mTexCoordMultiplierUniformLocation =
715 0 : mGL->fGetUniformLocation(mProgram, "uTexCoordMultiplier");
716 :
717 0 : return true;
718 : }
719 :
720 0 : GLint AttribLocation(int aWhich) {
721 0 : if (aWhich < 0 || aWhich >= int(mAttribLocations.Length()))
722 0 : return -1;
723 0 : return mAttribLocations[aWhich];
724 : }
725 :
726 0 : void SetTextureUnit(GLint aUnit) {
727 0 : SetUniform(mUniformLocations[TextureUniform], aUnit);
728 0 : }
729 :
730 0 : GLint GetTexCoordMultiplierUniformLocation() {
731 0 : return mTexCoordMultiplierUniformLocation;
732 : }
733 :
734 : protected:
735 : nsTArray<GLint> mUniformLocations;
736 : nsTArray<GLint> mAttribLocations;
737 :
738 : GLint mTexCoordMultiplierUniformLocation;
739 : };
740 :
741 : } /* layers */
742 : } /* mozilla */
743 :
744 : #endif /* GFX_LAYERMANAGEROGLPROGRAM_H */
|