gfx/layers/opengl/OGLShaderProgram.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "OGLShaderProgram.h"
michael@0 6 #include <stdint.h> // for uint32_t
michael@0 7 #include <sstream> // for ostringstream
michael@0 8 #include "gfxRect.h" // for gfxRect
michael@0 9 #include "mozilla/DebugOnly.h" // for DebugOnly
michael@0 10 #include "nsAString.h"
michael@0 11 #include "nsAutoPtr.h" // for nsRefPtr
michael@0 12 #include "nsString.h" // for nsAutoCString
michael@0 13 #include "prenv.h" // for PR_GetEnv
michael@0 14 #include "Layers.h"
michael@0 15 #include "GLContext.h"
michael@0 16
michael@0 17 struct gfxRGBA;
michael@0 18
michael@0 19 namespace mozilla {
michael@0 20 namespace layers {
michael@0 21
michael@0 22 using namespace std;
michael@0 23
michael@0 24 typedef ProgramProfileOGL::Argument Argument;
michael@0 25
michael@0 26 #define GAUSSIAN_KERNEL_HALF_WIDTH 11
michael@0 27 #define GAUSSIAN_KERNEL_STEP 0.2
michael@0 28
michael@0 29 void
michael@0 30 AddUniforms(ProgramProfileOGL& aProfile)
michael@0 31 {
michael@0 32 static const char *sKnownUniformNames[] = {
michael@0 33 "uLayerTransform",
michael@0 34 "uMaskQuadTransform",
michael@0 35 "uLayerQuadTransform",
michael@0 36 "uMatrixProj",
michael@0 37 "uTextureTransform",
michael@0 38 "uRenderTargetOffset",
michael@0 39 "uLayerOpacity",
michael@0 40 "uTexture",
michael@0 41 "uYTexture",
michael@0 42 "uCbTexture",
michael@0 43 "uCrTexture",
michael@0 44 "uBlackTexture",
michael@0 45 "uWhiteTexture",
michael@0 46 "uMaskTexture",
michael@0 47 "uRenderColor",
michael@0 48 "uTexCoordMultiplier",
michael@0 49 "uTexturePass2",
michael@0 50 nullptr
michael@0 51 };
michael@0 52
michael@0 53 for (int i = 0; sKnownUniformNames[i] != nullptr; ++i) {
michael@0 54 aProfile.mUniforms[i].mNameString = sKnownUniformNames[i];
michael@0 55 aProfile.mUniforms[i].mName = (KnownUniform::KnownUniformName) i;
michael@0 56 }
michael@0 57 }
michael@0 58
michael@0 59 void
michael@0 60 ShaderConfigOGL::SetRenderColor(bool aEnabled)
michael@0 61 {
michael@0 62 SetFeature(ENABLE_RENDER_COLOR, aEnabled);
michael@0 63 }
michael@0 64
michael@0 65 void
michael@0 66 ShaderConfigOGL::SetTextureTarget(GLenum aTarget)
michael@0 67 {
michael@0 68 SetFeature(ENABLE_TEXTURE_EXTERNAL | ENABLE_TEXTURE_RECT, false);
michael@0 69 switch (aTarget) {
michael@0 70 case LOCAL_GL_TEXTURE_EXTERNAL:
michael@0 71 SetFeature(ENABLE_TEXTURE_EXTERNAL, true);
michael@0 72 break;
michael@0 73 case LOCAL_GL_TEXTURE_RECTANGLE_ARB:
michael@0 74 SetFeature(ENABLE_TEXTURE_RECT, true);
michael@0 75 break;
michael@0 76 }
michael@0 77 }
michael@0 78
michael@0 79 void
michael@0 80 ShaderConfigOGL::SetRBSwap(bool aEnabled)
michael@0 81 {
michael@0 82 SetFeature(ENABLE_TEXTURE_RB_SWAP, aEnabled);
michael@0 83 }
michael@0 84
michael@0 85 void
michael@0 86 ShaderConfigOGL::SetNoAlpha(bool aEnabled)
michael@0 87 {
michael@0 88 SetFeature(ENABLE_TEXTURE_NO_ALPHA, aEnabled);
michael@0 89 }
michael@0 90
michael@0 91 void
michael@0 92 ShaderConfigOGL::SetOpacity(bool aEnabled)
michael@0 93 {
michael@0 94 SetFeature(ENABLE_OPACITY, aEnabled);
michael@0 95 }
michael@0 96
michael@0 97 void
michael@0 98 ShaderConfigOGL::SetYCbCr(bool aEnabled)
michael@0 99 {
michael@0 100 SetFeature(ENABLE_TEXTURE_YCBCR, aEnabled);
michael@0 101 }
michael@0 102
michael@0 103 void
michael@0 104 ShaderConfigOGL::SetComponentAlpha(bool aEnabled)
michael@0 105 {
michael@0 106 SetFeature(ENABLE_TEXTURE_COMPONENT_ALPHA, aEnabled);
michael@0 107 }
michael@0 108
michael@0 109 void
michael@0 110 ShaderConfigOGL::SetColorMatrix(bool aEnabled)
michael@0 111 {
michael@0 112 SetFeature(ENABLE_COLOR_MATRIX, aEnabled);
michael@0 113 }
michael@0 114
michael@0 115 void
michael@0 116 ShaderConfigOGL::SetBlur(bool aEnabled)
michael@0 117 {
michael@0 118 SetFeature(ENABLE_BLUR, aEnabled);
michael@0 119 }
michael@0 120
michael@0 121 void
michael@0 122 ShaderConfigOGL::SetMask2D(bool aEnabled)
michael@0 123 {
michael@0 124 SetFeature(ENABLE_MASK_2D, aEnabled);
michael@0 125 }
michael@0 126
michael@0 127 void
michael@0 128 ShaderConfigOGL::SetMask3D(bool aEnabled)
michael@0 129 {
michael@0 130 SetFeature(ENABLE_MASK_3D, aEnabled);
michael@0 131 }
michael@0 132
michael@0 133 /* static */ ProgramProfileOGL
michael@0 134 ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig)
michael@0 135 {
michael@0 136 ProgramProfileOGL result;
michael@0 137 ostringstream fs, vs;
michael@0 138
michael@0 139 AddUniforms(result);
michael@0 140
michael@0 141 vs << "uniform mat4 uMatrixProj;" << endl;
michael@0 142 vs << "uniform mat4 uLayerQuadTransform;" << endl;
michael@0 143 vs << "uniform mat4 uLayerTransform;" << endl;
michael@0 144 vs << "uniform vec4 uRenderTargetOffset;" << endl;
michael@0 145
michael@0 146 vs << "attribute vec4 aVertexCoord;" << endl;
michael@0 147
michael@0 148 if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) {
michael@0 149 vs << "uniform mat4 uTextureTransform;" << endl;
michael@0 150 vs << "attribute vec2 aTexCoord;" << endl;
michael@0 151 vs << "varying vec2 vTexCoord;" << endl;
michael@0 152 }
michael@0 153
michael@0 154 if (aConfig.mFeatures & ENABLE_MASK_2D ||
michael@0 155 aConfig.mFeatures & ENABLE_MASK_3D) {
michael@0 156 vs << "uniform mat4 uMaskQuadTransform;" << endl;
michael@0 157 vs << "varying vec3 vMaskCoord;" << endl;
michael@0 158 }
michael@0 159
michael@0 160 vs << "void main() {" << endl;
michael@0 161 vs << " vec4 finalPosition = aVertexCoord;" << endl;
michael@0 162 vs << " finalPosition = uLayerQuadTransform * finalPosition;" << endl;
michael@0 163 vs << " finalPosition = uLayerTransform * finalPosition;" << endl;
michael@0 164 vs << " finalPosition.xyz /= finalPosition.w;" << endl;
michael@0 165
michael@0 166 if (aConfig.mFeatures & ENABLE_MASK_3D) {
michael@0 167 vs << " vMaskCoord.xy = (uMaskQuadTransform * vec4(finalPosition.xyz, 1.0)).xy;" << endl;
michael@0 168 // correct for perspective correct interpolation, see comment in D3D10 shader
michael@0 169 vs << " vMaskCoord.z = 1.0;" << endl;
michael@0 170 vs << " vMaskCoord *= finalPosition.w;" << endl;
michael@0 171 } else if (aConfig.mFeatures & ENABLE_MASK_2D) {
michael@0 172 vs << " vMaskCoord.xy = (uMaskQuadTransform * finalPosition).xy;" << endl;
michael@0 173 }
michael@0 174
michael@0 175 vs << " finalPosition = finalPosition - uRenderTargetOffset;" << endl;
michael@0 176 vs << " finalPosition.xyz *= finalPosition.w;" << endl;
michael@0 177 vs << " finalPosition = uMatrixProj * finalPosition;" << endl;
michael@0 178
michael@0 179 if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) {
michael@0 180 vs << " vTexCoord = (uTextureTransform * vec4(aTexCoord.x, aTexCoord.y, 0.0, 1.0)).xy;" << endl;
michael@0 181 }
michael@0 182
michael@0 183 vs << " gl_Position = finalPosition;" << endl;
michael@0 184 vs << "}" << endl;
michael@0 185
michael@0 186 if (aConfig.mFeatures & ENABLE_TEXTURE_RECT) {
michael@0 187 fs << "#extension GL_ARB_texture_rectangle : require" << endl;
michael@0 188 }
michael@0 189 if (aConfig.mFeatures & ENABLE_TEXTURE_EXTERNAL) {
michael@0 190 fs << "#extension GL_OES_EGL_image_external : require" << endl;
michael@0 191 }
michael@0 192 fs << "#ifdef GL_ES" << endl;
michael@0 193 fs << "precision mediump float;" << endl;
michael@0 194 fs << "#define COLOR_PRECISION lowp" << endl;
michael@0 195 fs << "#else" << endl;
michael@0 196 fs << "#define COLOR_PRECISION" << endl;
michael@0 197 fs << "#endif" << endl;
michael@0 198 if (aConfig.mFeatures & ENABLE_RENDER_COLOR) {
michael@0 199 fs << "uniform COLOR_PRECISION vec4 uRenderColor;" << endl;
michael@0 200 } else {
michael@0 201 // for tiling, texcoord can be greater than the lowfp range
michael@0 202 fs << "varying vec2 vTexCoord;" << endl;
michael@0 203 if (aConfig.mFeatures & ENABLE_BLUR) {
michael@0 204 fs << "uniform bool uBlurAlpha;" << endl;
michael@0 205 fs << "uniform vec2 uBlurRadius;" << endl;
michael@0 206 fs << "uniform vec2 uBlurOffset;" << endl;
michael@0 207 fs << "uniform float uBlurGaussianKernel[" << GAUSSIAN_KERNEL_HALF_WIDTH << "];" << endl;
michael@0 208 }
michael@0 209 if (aConfig.mFeatures & ENABLE_COLOR_MATRIX) {
michael@0 210 fs << "uniform mat4 uColorMatrix;" << endl;
michael@0 211 fs << "uniform vec4 uColorMatrixVector;" << endl;
michael@0 212 }
michael@0 213 if (aConfig.mFeatures & ENABLE_OPACITY) {
michael@0 214 fs << "uniform COLOR_PRECISION float uLayerOpacity;" << endl;
michael@0 215 }
michael@0 216 }
michael@0 217
michael@0 218 const char *sampler2D = "sampler2D";
michael@0 219 const char *texture2D = "texture2D";
michael@0 220
michael@0 221 if (aConfig.mFeatures & ENABLE_TEXTURE_RECT) {
michael@0 222 fs << "uniform vec2 uTexCoordMultiplier;" << endl;
michael@0 223 sampler2D = "sampler2DRect";
michael@0 224 texture2D = "texture2DRect";
michael@0 225 }
michael@0 226
michael@0 227 if (aConfig.mFeatures & ENABLE_TEXTURE_EXTERNAL) {
michael@0 228 sampler2D = "samplerExternalOES";
michael@0 229 }
michael@0 230
michael@0 231 if (aConfig.mFeatures & ENABLE_TEXTURE_YCBCR) {
michael@0 232 fs << "uniform sampler2D uYTexture;" << endl;
michael@0 233 fs << "uniform sampler2D uCbTexture;" << endl;
michael@0 234 fs << "uniform sampler2D uCrTexture;" << endl;
michael@0 235 } else if (aConfig.mFeatures & ENABLE_TEXTURE_COMPONENT_ALPHA) {
michael@0 236 fs << "uniform sampler2D uBlackTexture;" << endl;
michael@0 237 fs << "uniform sampler2D uWhiteTexture;" << endl;
michael@0 238 fs << "uniform bool uTexturePass2;" << endl;
michael@0 239 } else {
michael@0 240 fs << "uniform " << sampler2D << " uTexture;" << endl;
michael@0 241 }
michael@0 242
michael@0 243 if (aConfig.mFeatures & ENABLE_MASK_2D ||
michael@0 244 aConfig.mFeatures & ENABLE_MASK_3D) {
michael@0 245 fs << "varying vec3 vMaskCoord;" << endl;
michael@0 246 fs << "uniform sampler2D uMaskTexture;" << endl;
michael@0 247 }
michael@0 248
michael@0 249 if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) {
michael@0 250 fs << "vec4 sample(vec2 coord) {" << endl;
michael@0 251 fs << " vec4 color;" << endl;
michael@0 252 if (aConfig.mFeatures & ENABLE_TEXTURE_YCBCR) {
michael@0 253 fs << " COLOR_PRECISION float y = texture2D(uYTexture, coord).r;" << endl;
michael@0 254 fs << " COLOR_PRECISION float cb = texture2D(uCbTexture, coord).r;" << endl;
michael@0 255 fs << " COLOR_PRECISION float cr = texture2D(uCrTexture, coord).r;" << endl;
michael@0 256 fs << " y = (y - 0.0625) * 1.164;" << endl;
michael@0 257 fs << " cb = cb - 0.5;" << endl;
michael@0 258 fs << " cr = cr - 0.5;" << endl;
michael@0 259 fs << " color.r = y + cr * 1.596;" << endl;
michael@0 260 fs << " color.g = y - 0.813 * cr - 0.391 * cb;" << endl;
michael@0 261 fs << " color.b = y + cb * 2.018;" << endl;
michael@0 262 fs << " color.a = 1.0;" << endl;
michael@0 263 } else if (aConfig.mFeatures & ENABLE_TEXTURE_COMPONENT_ALPHA) {
michael@0 264 fs << " COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, coord).rgb;" << endl;
michael@0 265 fs << " COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, coord).rgb;" << endl;
michael@0 266 fs << " COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;" << endl;
michael@0 267 fs << " if (uTexturePass2)" << endl;
michael@0 268 fs << " color = vec4(onBlack, alphas.a);" << endl;
michael@0 269 fs << " else" << endl;
michael@0 270 fs << " color = alphas;" << endl;
michael@0 271 } else {
michael@0 272 fs << " color = " << texture2D << "(uTexture, coord);" << endl;
michael@0 273 }
michael@0 274 if (aConfig.mFeatures & ENABLE_TEXTURE_RB_SWAP) {
michael@0 275 fs << " color = color.bgra;" << endl;
michael@0 276 }
michael@0 277 if (aConfig.mFeatures & ENABLE_TEXTURE_NO_ALPHA) {
michael@0 278 fs << " color = vec4(color.rgb, 1.0);" << endl;
michael@0 279 }
michael@0 280 fs << " return color;" << endl;
michael@0 281 fs << "}" << endl;
michael@0 282 if (aConfig.mFeatures & ENABLE_BLUR) {
michael@0 283 fs << "vec4 sampleAtRadius(vec2 coord, float radius) {" << endl;
michael@0 284 fs << " coord += uBlurOffset;" << endl;
michael@0 285 fs << " coord += radius * uBlurRadius;" << endl;
michael@0 286 fs << " if (coord.x < 0. || coord.y < 0. || coord.x > 1. || coord.y > 1.)" << endl;
michael@0 287 fs << " return vec4(0, 0, 0, 0);" << endl;
michael@0 288 fs << " return sample(coord);" << endl;
michael@0 289 fs << "}" << endl;
michael@0 290 fs << "vec4 blur(vec4 color, vec2 coord) {" << endl;
michael@0 291 fs << " vec4 total = color * uBlurGaussianKernel[0];" << endl;
michael@0 292 fs << " for (int i = 1; i < " << GAUSSIAN_KERNEL_HALF_WIDTH << "; ++i) {" << endl;
michael@0 293 fs << " float r = float(i) * " << GAUSSIAN_KERNEL_STEP << " << endl;" << endl;
michael@0 294 fs << " float k = uBlurGaussianKernel[i];" << endl;
michael@0 295 fs << " total += sampleAtRadius(coord, r) * k;" << endl;
michael@0 296 fs << " total += sampleAtRadius(coord, -r) * k;" << endl;
michael@0 297 fs << " }" << endl;
michael@0 298 fs << " if (uBlurAlpha) {" << endl;
michael@0 299 fs << " color *= total.a;" << endl;
michael@0 300 fs << " } else {" << endl;
michael@0 301 fs << " color = total;" << endl;
michael@0 302 fs << " }" << endl;
michael@0 303 fs << " return color;" << endl;
michael@0 304 fs << "}" << endl;
michael@0 305 }
michael@0 306 }
michael@0 307 fs << "void main() {" << endl;
michael@0 308 if (aConfig.mFeatures & ENABLE_RENDER_COLOR) {
michael@0 309 fs << " vec4 color = uRenderColor;" << endl;
michael@0 310 } else {
michael@0 311 if (aConfig.mFeatures & ENABLE_TEXTURE_RECT) {
michael@0 312 fs << " vec4 color = sample(vTexCoord * uTexCoordMultiplier);" << endl;
michael@0 313 } else {
michael@0 314 fs << " vec4 color = sample(vTexCoord);" << endl;
michael@0 315 }
michael@0 316 if (aConfig.mFeatures & ENABLE_BLUR) {
michael@0 317 fs << " color = blur(color, vTexCoord);" << endl;
michael@0 318 }
michael@0 319 if (aConfig.mFeatures & ENABLE_COLOR_MATRIX) {
michael@0 320 fs << " color = uColorMatrix * vec4(color.rgb / color.a, color.a) + uColorMatrixVector;" << endl;
michael@0 321 fs << " color.rgb *= color.a;" << endl;
michael@0 322 }
michael@0 323 if (aConfig.mFeatures & ENABLE_OPACITY) {
michael@0 324 fs << " color *= uLayerOpacity;" << endl;
michael@0 325 }
michael@0 326 }
michael@0 327 if (aConfig.mFeatures & ENABLE_MASK_3D) {
michael@0 328 fs << " vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;" << endl;
michael@0 329 fs << " COLOR_PRECISION float mask = texture2D(uMaskTexture, maskCoords).r;" << endl;
michael@0 330 fs << " color *= mask;" << endl;
michael@0 331 } else if (aConfig.mFeatures & ENABLE_MASK_2D) {
michael@0 332 fs << " COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord.xy).r;" << endl;
michael@0 333 fs << " color *= mask;" << endl;
michael@0 334 } else {
michael@0 335 fs << " COLOR_PRECISION float mask = 1.0;" << endl;
michael@0 336 fs << " color *= mask;" << endl;
michael@0 337 }
michael@0 338 fs << " gl_FragColor = color;" << endl;
michael@0 339 fs << "}" << endl;
michael@0 340
michael@0 341 result.mVertexShaderString = vs.str();
michael@0 342 result.mFragmentShaderString = fs.str();
michael@0 343
michael@0 344 result.mAttributes.AppendElement(Argument("aVertexCoord"));
michael@0 345 if (aConfig.mFeatures & ENABLE_RENDER_COLOR) {
michael@0 346 result.mTextureCount = 0;
michael@0 347 } else {
michael@0 348 result.mAttributes.AppendElement(Argument("aTexCoord"));
michael@0 349 if (aConfig.mFeatures & ENABLE_TEXTURE_YCBCR) {
michael@0 350 result.mTextureCount = 3;
michael@0 351 } else if (aConfig.mFeatures & ENABLE_TEXTURE_COMPONENT_ALPHA) {
michael@0 352 result.mTextureCount = 2;
michael@0 353 } else {
michael@0 354 result.mTextureCount = 1;
michael@0 355 }
michael@0 356 }
michael@0 357 if (aConfig.mFeatures & ENABLE_MASK_2D ||
michael@0 358 aConfig.mFeatures & ENABLE_MASK_3D) {
michael@0 359 result.mTextureCount = 1;
michael@0 360 }
michael@0 361
michael@0 362 return result;
michael@0 363 }
michael@0 364
michael@0 365 const char* const ShaderProgramOGL::VertexCoordAttrib = "aVertexCoord";
michael@0 366 const char* const ShaderProgramOGL::TexCoordAttrib = "aTexCoord";
michael@0 367
michael@0 368 ShaderProgramOGL::ShaderProgramOGL(GLContext* aGL, const ProgramProfileOGL& aProfile)
michael@0 369 : mGL(aGL)
michael@0 370 , mProgram(0)
michael@0 371 , mProfile(aProfile)
michael@0 372 , mProgramState(STATE_NEW)
michael@0 373 {
michael@0 374 }
michael@0 375
michael@0 376 ShaderProgramOGL::~ShaderProgramOGL()
michael@0 377 {
michael@0 378 if (mProgram <= 0) {
michael@0 379 return;
michael@0 380 }
michael@0 381
michael@0 382 nsRefPtr<GLContext> ctx = mGL->GetSharedContext();
michael@0 383 if (!ctx) {
michael@0 384 ctx = mGL;
michael@0 385 }
michael@0 386 ctx->MakeCurrent();
michael@0 387 ctx->fDeleteProgram(mProgram);
michael@0 388 }
michael@0 389
michael@0 390 bool
michael@0 391 ShaderProgramOGL::Initialize()
michael@0 392 {
michael@0 393 NS_ASSERTION(mProgramState == STATE_NEW, "Shader program has already been initialised");
michael@0 394
michael@0 395 ostringstream vs, fs;
michael@0 396 for (uint32_t i = 0; i < mProfile.mDefines.Length(); ++i) {
michael@0 397 vs << mProfile.mDefines[i] << endl;
michael@0 398 fs << mProfile.mDefines[i] << endl;
michael@0 399 }
michael@0 400 vs << mProfile.mVertexShaderString << endl;
michael@0 401 fs << mProfile.mFragmentShaderString << endl;
michael@0 402
michael@0 403 if (!CreateProgram(vs.str().c_str(), fs.str().c_str())) {
michael@0 404 mProgramState = STATE_ERROR;
michael@0 405 return false;
michael@0 406 }
michael@0 407
michael@0 408 mProgramState = STATE_OK;
michael@0 409
michael@0 410 for (uint32_t i = 0; i < KnownUniform::KnownUniformCount; ++i) {
michael@0 411 mProfile.mUniforms[i].mLocation =
michael@0 412 mGL->fGetUniformLocation(mProgram, mProfile.mUniforms[i].mNameString);
michael@0 413 }
michael@0 414
michael@0 415 for (uint32_t i = 0; i < mProfile.mAttributes.Length(); ++i) {
michael@0 416 mProfile.mAttributes[i].mLocation =
michael@0 417 mGL->fGetAttribLocation(mProgram, mProfile.mAttributes[i].mName);
michael@0 418 NS_ASSERTION(mProfile.mAttributes[i].mLocation >= 0, "Bad attribute location.");
michael@0 419 }
michael@0 420
michael@0 421 //mProfile.mHasMatrixProj = mProfile.mUniforms[KnownUniform::MatrixProj].mLocation != -1;
michael@0 422
michael@0 423 return true;
michael@0 424 }
michael@0 425
michael@0 426 GLint
michael@0 427 ShaderProgramOGL::CreateShader(GLenum aShaderType, const char *aShaderSource)
michael@0 428 {
michael@0 429 GLint success, len = 0;
michael@0 430
michael@0 431 GLint sh = mGL->fCreateShader(aShaderType);
michael@0 432 mGL->fShaderSource(sh, 1, (const GLchar**)&aShaderSource, nullptr);
michael@0 433 mGL->fCompileShader(sh);
michael@0 434 mGL->fGetShaderiv(sh, LOCAL_GL_COMPILE_STATUS, &success);
michael@0 435 mGL->fGetShaderiv(sh, LOCAL_GL_INFO_LOG_LENGTH, (GLint*) &len);
michael@0 436 /* Even if compiling is successful, there may still be warnings. Print them
michael@0 437 * in a debug build. The > 10 is to catch silly compilers that might put
michael@0 438 * some whitespace in the log but otherwise leave it empty.
michael@0 439 */
michael@0 440 if (!success
michael@0 441 #ifdef DEBUG
michael@0 442 || (len > 10 && PR_GetEnv("MOZ_DEBUG_SHADERS"))
michael@0 443 #endif
michael@0 444 )
michael@0 445 {
michael@0 446 nsAutoCString log;
michael@0 447 log.SetCapacity(len);
michael@0 448 mGL->fGetShaderInfoLog(sh, len, (GLint*) &len, (char*) log.BeginWriting());
michael@0 449 log.SetLength(len);
michael@0 450
michael@0 451 if (!success) {
michael@0 452 printf_stderr("=== SHADER COMPILATION FAILED ===\n");
michael@0 453 } else {
michael@0 454 printf_stderr("=== SHADER COMPILATION WARNINGS ===\n");
michael@0 455 }
michael@0 456
michael@0 457 printf_stderr("=== Source:\n%s\n", aShaderSource);
michael@0 458 printf_stderr("=== Log:\n%s\n", log.get());
michael@0 459 printf_stderr("============\n");
michael@0 460
michael@0 461 if (!success) {
michael@0 462 mGL->fDeleteShader(sh);
michael@0 463 return 0;
michael@0 464 }
michael@0 465 }
michael@0 466
michael@0 467 return sh;
michael@0 468 }
michael@0 469
michael@0 470 bool
michael@0 471 ShaderProgramOGL::CreateProgram(const char *aVertexShaderString,
michael@0 472 const char *aFragmentShaderString)
michael@0 473 {
michael@0 474 GLuint vertexShader = CreateShader(LOCAL_GL_VERTEX_SHADER, aVertexShaderString);
michael@0 475 GLuint fragmentShader = CreateShader(LOCAL_GL_FRAGMENT_SHADER, aFragmentShaderString);
michael@0 476
michael@0 477 if (!vertexShader || !fragmentShader)
michael@0 478 return false;
michael@0 479
michael@0 480 GLint result = mGL->fCreateProgram();
michael@0 481 mGL->fAttachShader(result, vertexShader);
michael@0 482 mGL->fAttachShader(result, fragmentShader);
michael@0 483
michael@0 484 mGL->fLinkProgram(result);
michael@0 485
michael@0 486 GLint success, len;
michael@0 487 mGL->fGetProgramiv(result, LOCAL_GL_LINK_STATUS, &success);
michael@0 488 mGL->fGetProgramiv(result, LOCAL_GL_INFO_LOG_LENGTH, (GLint*) &len);
michael@0 489 /* Even if linking is successful, there may still be warnings. Print them
michael@0 490 * in a debug build. The > 10 is to catch silly compilers that might put
michael@0 491 * some whitespace in the log but otherwise leave it empty.
michael@0 492 */
michael@0 493 if (!success
michael@0 494 #ifdef DEBUG
michael@0 495 || (len > 10 && PR_GetEnv("MOZ_DEBUG_SHADERS"))
michael@0 496 #endif
michael@0 497 )
michael@0 498 {
michael@0 499 nsAutoCString log;
michael@0 500 log.SetCapacity(len);
michael@0 501 mGL->fGetProgramInfoLog(result, len, (GLint*) &len, (char*) log.BeginWriting());
michael@0 502 log.SetLength(len);
michael@0 503
michael@0 504 if (!success) {
michael@0 505 printf_stderr("=== PROGRAM LINKING FAILED ===\n");
michael@0 506 } else {
michael@0 507 printf_stderr("=== PROGRAM LINKING WARNINGS ===\n");
michael@0 508 }
michael@0 509 printf_stderr("=== Log:\n%s\n", log.get());
michael@0 510 printf_stderr("============\n");
michael@0 511 }
michael@0 512
michael@0 513 // We can mark the shaders for deletion; they're attached to the program
michael@0 514 // and will remain attached.
michael@0 515 mGL->fDeleteShader(vertexShader);
michael@0 516 mGL->fDeleteShader(fragmentShader);
michael@0 517
michael@0 518 if (!success) {
michael@0 519 mGL->fDeleteProgram(result);
michael@0 520 return false;
michael@0 521 }
michael@0 522
michael@0 523 mProgram = result;
michael@0 524 return true;
michael@0 525 }
michael@0 526
michael@0 527 void
michael@0 528 ShaderProgramOGL::Activate()
michael@0 529 {
michael@0 530 if (mProgramState == STATE_NEW) {
michael@0 531 if (!Initialize()) {
michael@0 532 NS_WARNING("Shader could not be initialised");
michael@0 533 return;
michael@0 534 }
michael@0 535 }
michael@0 536 NS_ASSERTION(HasInitialized(), "Attempting to activate a program that's not in use!");
michael@0 537 mGL->fUseProgram(mProgram);
michael@0 538 }
michael@0 539
michael@0 540 } /* layers */
michael@0 541 } /* mozilla */

mercurial