gfx/layers/opengl/OGLShaderProgram.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/layers/opengl/OGLShaderProgram.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,541 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#include "OGLShaderProgram.h"
     1.9 +#include <stdint.h>                     // for uint32_t
    1.10 +#include <sstream>                      // for ostringstream
    1.11 +#include "gfxRect.h"                    // for gfxRect
    1.12 +#include "mozilla/DebugOnly.h"          // for DebugOnly
    1.13 +#include "nsAString.h"
    1.14 +#include "nsAutoPtr.h"                  // for nsRefPtr
    1.15 +#include "nsString.h"                   // for nsAutoCString
    1.16 +#include "prenv.h"                      // for PR_GetEnv
    1.17 +#include "Layers.h"
    1.18 +#include "GLContext.h"
    1.19 +
    1.20 +struct gfxRGBA;
    1.21 +
    1.22 +namespace mozilla {
    1.23 +namespace layers {
    1.24 +
    1.25 +using namespace std;
    1.26 +
    1.27 +typedef ProgramProfileOGL::Argument Argument;
    1.28 +
    1.29 +#define GAUSSIAN_KERNEL_HALF_WIDTH 11
    1.30 +#define GAUSSIAN_KERNEL_STEP 0.2
    1.31 +
    1.32 +void
    1.33 +AddUniforms(ProgramProfileOGL& aProfile)
    1.34 +{
    1.35 +    static const char *sKnownUniformNames[] = {
    1.36 +        "uLayerTransform",
    1.37 +        "uMaskQuadTransform",
    1.38 +        "uLayerQuadTransform",
    1.39 +        "uMatrixProj",
    1.40 +        "uTextureTransform",
    1.41 +        "uRenderTargetOffset",
    1.42 +        "uLayerOpacity",
    1.43 +        "uTexture",
    1.44 +        "uYTexture",
    1.45 +        "uCbTexture",
    1.46 +        "uCrTexture",
    1.47 +        "uBlackTexture",
    1.48 +        "uWhiteTexture",
    1.49 +        "uMaskTexture",
    1.50 +        "uRenderColor",
    1.51 +        "uTexCoordMultiplier",
    1.52 +        "uTexturePass2",
    1.53 +        nullptr
    1.54 +    };
    1.55 +
    1.56 +    for (int i = 0; sKnownUniformNames[i] != nullptr; ++i) {
    1.57 +        aProfile.mUniforms[i].mNameString = sKnownUniformNames[i];
    1.58 +        aProfile.mUniforms[i].mName = (KnownUniform::KnownUniformName) i;
    1.59 +    }
    1.60 +}
    1.61 +
    1.62 +void
    1.63 +ShaderConfigOGL::SetRenderColor(bool aEnabled)
    1.64 +{
    1.65 +  SetFeature(ENABLE_RENDER_COLOR, aEnabled);
    1.66 +}
    1.67 +
    1.68 +void
    1.69 +ShaderConfigOGL::SetTextureTarget(GLenum aTarget)
    1.70 +{
    1.71 +  SetFeature(ENABLE_TEXTURE_EXTERNAL | ENABLE_TEXTURE_RECT, false);
    1.72 +  switch (aTarget) {
    1.73 +  case LOCAL_GL_TEXTURE_EXTERNAL:
    1.74 +    SetFeature(ENABLE_TEXTURE_EXTERNAL, true);
    1.75 +    break;
    1.76 +  case LOCAL_GL_TEXTURE_RECTANGLE_ARB:
    1.77 +    SetFeature(ENABLE_TEXTURE_RECT, true);
    1.78 +    break;
    1.79 +  }
    1.80 +}
    1.81 +
    1.82 +void
    1.83 +ShaderConfigOGL::SetRBSwap(bool aEnabled)
    1.84 +{
    1.85 +  SetFeature(ENABLE_TEXTURE_RB_SWAP, aEnabled);
    1.86 +}
    1.87 +
    1.88 +void
    1.89 +ShaderConfigOGL::SetNoAlpha(bool aEnabled)
    1.90 +{
    1.91 +  SetFeature(ENABLE_TEXTURE_NO_ALPHA, aEnabled);
    1.92 +}
    1.93 +
    1.94 +void
    1.95 +ShaderConfigOGL::SetOpacity(bool aEnabled)
    1.96 +{
    1.97 +  SetFeature(ENABLE_OPACITY, aEnabled);
    1.98 +}
    1.99 +
   1.100 +void
   1.101 +ShaderConfigOGL::SetYCbCr(bool aEnabled)
   1.102 +{
   1.103 +  SetFeature(ENABLE_TEXTURE_YCBCR, aEnabled);
   1.104 +}
   1.105 +
   1.106 +void
   1.107 +ShaderConfigOGL::SetComponentAlpha(bool aEnabled)
   1.108 +{
   1.109 +  SetFeature(ENABLE_TEXTURE_COMPONENT_ALPHA, aEnabled);
   1.110 +}
   1.111 +
   1.112 +void
   1.113 +ShaderConfigOGL::SetColorMatrix(bool aEnabled)
   1.114 +{
   1.115 +  SetFeature(ENABLE_COLOR_MATRIX, aEnabled);
   1.116 +}
   1.117 +
   1.118 +void
   1.119 +ShaderConfigOGL::SetBlur(bool aEnabled)
   1.120 +{
   1.121 +  SetFeature(ENABLE_BLUR, aEnabled);
   1.122 +}
   1.123 +
   1.124 +void
   1.125 +ShaderConfigOGL::SetMask2D(bool aEnabled)
   1.126 +{
   1.127 +  SetFeature(ENABLE_MASK_2D, aEnabled);
   1.128 +}
   1.129 +
   1.130 +void
   1.131 +ShaderConfigOGL::SetMask3D(bool aEnabled)
   1.132 +{
   1.133 +  SetFeature(ENABLE_MASK_3D, aEnabled);
   1.134 +}
   1.135 +
   1.136 +/* static */ ProgramProfileOGL
   1.137 +ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig)
   1.138 +{
   1.139 +  ProgramProfileOGL result;
   1.140 +  ostringstream fs, vs;
   1.141 +
   1.142 +  AddUniforms(result);
   1.143 +
   1.144 +  vs << "uniform mat4 uMatrixProj;" << endl;
   1.145 +  vs << "uniform mat4 uLayerQuadTransform;" << endl;
   1.146 +  vs << "uniform mat4 uLayerTransform;" << endl;
   1.147 +  vs << "uniform vec4 uRenderTargetOffset;" << endl;
   1.148 +
   1.149 +  vs << "attribute vec4 aVertexCoord;" << endl;
   1.150 +
   1.151 +  if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) {
   1.152 +    vs << "uniform mat4 uTextureTransform;" << endl;
   1.153 +    vs << "attribute vec2 aTexCoord;" << endl;
   1.154 +    vs << "varying vec2 vTexCoord;" << endl;
   1.155 +  }
   1.156 +
   1.157 +  if (aConfig.mFeatures & ENABLE_MASK_2D ||
   1.158 +      aConfig.mFeatures & ENABLE_MASK_3D) {
   1.159 +    vs << "uniform mat4 uMaskQuadTransform;" << endl;
   1.160 +    vs << "varying vec3 vMaskCoord;" << endl;
   1.161 +  }
   1.162 +
   1.163 +  vs << "void main() {" << endl;
   1.164 +  vs << "  vec4 finalPosition = aVertexCoord;" << endl;
   1.165 +  vs << "  finalPosition = uLayerQuadTransform * finalPosition;" << endl;
   1.166 +  vs << "  finalPosition = uLayerTransform * finalPosition;" << endl;
   1.167 +  vs << "  finalPosition.xyz /= finalPosition.w;" << endl;
   1.168 +
   1.169 +  if (aConfig.mFeatures & ENABLE_MASK_3D) {
   1.170 +    vs << "  vMaskCoord.xy = (uMaskQuadTransform * vec4(finalPosition.xyz, 1.0)).xy;" << endl;
   1.171 +    // correct for perspective correct interpolation, see comment in D3D10 shader
   1.172 +    vs << "  vMaskCoord.z = 1.0;" << endl;
   1.173 +    vs << "  vMaskCoord *= finalPosition.w;" << endl;
   1.174 +  } else if (aConfig.mFeatures & ENABLE_MASK_2D) {
   1.175 +    vs << "  vMaskCoord.xy = (uMaskQuadTransform * finalPosition).xy;" << endl;
   1.176 +  }
   1.177 +
   1.178 +  vs << "  finalPosition = finalPosition - uRenderTargetOffset;" << endl;
   1.179 +  vs << "  finalPosition.xyz *= finalPosition.w;" << endl;
   1.180 +  vs << "  finalPosition = uMatrixProj * finalPosition;" << endl;
   1.181 +
   1.182 +  if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) {
   1.183 +    vs << "  vTexCoord = (uTextureTransform * vec4(aTexCoord.x, aTexCoord.y, 0.0, 1.0)).xy;" << endl;
   1.184 +  }
   1.185 +
   1.186 +  vs << "  gl_Position = finalPosition;" << endl;
   1.187 +  vs << "}" << endl;
   1.188 +
   1.189 +  if (aConfig.mFeatures & ENABLE_TEXTURE_RECT) {
   1.190 +    fs << "#extension GL_ARB_texture_rectangle : require" << endl;
   1.191 +  }
   1.192 +  if (aConfig.mFeatures & ENABLE_TEXTURE_EXTERNAL) {
   1.193 +    fs << "#extension GL_OES_EGL_image_external : require" << endl;
   1.194 +  }
   1.195 +  fs << "#ifdef GL_ES" << endl;
   1.196 +  fs << "precision mediump float;" << endl;
   1.197 +  fs << "#define COLOR_PRECISION lowp" << endl;
   1.198 +  fs << "#else" << endl;
   1.199 +  fs << "#define COLOR_PRECISION" << endl;
   1.200 +  fs << "#endif" << endl;
   1.201 +  if (aConfig.mFeatures & ENABLE_RENDER_COLOR) {
   1.202 +    fs << "uniform COLOR_PRECISION vec4 uRenderColor;" << endl;
   1.203 +  } else {
   1.204 +    // for tiling, texcoord can be greater than the lowfp range
   1.205 +    fs << "varying vec2 vTexCoord;" << endl;
   1.206 +    if (aConfig.mFeatures & ENABLE_BLUR) {
   1.207 +      fs << "uniform bool uBlurAlpha;" << endl;
   1.208 +      fs << "uniform vec2 uBlurRadius;" << endl;
   1.209 +      fs << "uniform vec2 uBlurOffset;" << endl;
   1.210 +      fs << "uniform float uBlurGaussianKernel[" << GAUSSIAN_KERNEL_HALF_WIDTH << "];" << endl;
   1.211 +    }
   1.212 +    if (aConfig.mFeatures & ENABLE_COLOR_MATRIX) {
   1.213 +      fs << "uniform mat4 uColorMatrix;" << endl;
   1.214 +      fs << "uniform vec4 uColorMatrixVector;" << endl;
   1.215 +    }
   1.216 +    if (aConfig.mFeatures & ENABLE_OPACITY) {
   1.217 +      fs << "uniform COLOR_PRECISION float uLayerOpacity;" << endl;
   1.218 +    }
   1.219 +  }
   1.220 +
   1.221 +  const char *sampler2D = "sampler2D";
   1.222 +  const char *texture2D = "texture2D";
   1.223 +
   1.224 +  if (aConfig.mFeatures & ENABLE_TEXTURE_RECT) {
   1.225 +    fs << "uniform vec2 uTexCoordMultiplier;" << endl;
   1.226 +    sampler2D = "sampler2DRect";
   1.227 +    texture2D = "texture2DRect";
   1.228 +  }
   1.229 +
   1.230 +  if (aConfig.mFeatures & ENABLE_TEXTURE_EXTERNAL) {
   1.231 +    sampler2D = "samplerExternalOES";
   1.232 +  }
   1.233 +
   1.234 +  if (aConfig.mFeatures & ENABLE_TEXTURE_YCBCR) {
   1.235 +    fs << "uniform sampler2D uYTexture;" << endl;
   1.236 +    fs << "uniform sampler2D uCbTexture;" << endl;
   1.237 +    fs << "uniform sampler2D uCrTexture;" << endl;
   1.238 +  } else if (aConfig.mFeatures & ENABLE_TEXTURE_COMPONENT_ALPHA) {
   1.239 +    fs << "uniform sampler2D uBlackTexture;" << endl;
   1.240 +    fs << "uniform sampler2D uWhiteTexture;" << endl;
   1.241 +    fs << "uniform bool uTexturePass2;" << endl;
   1.242 +  } else {
   1.243 +    fs << "uniform " << sampler2D << " uTexture;" << endl;
   1.244 +  }
   1.245 +
   1.246 +  if (aConfig.mFeatures & ENABLE_MASK_2D ||
   1.247 +      aConfig.mFeatures & ENABLE_MASK_3D) {
   1.248 +    fs << "varying vec3 vMaskCoord;" << endl;
   1.249 +    fs << "uniform sampler2D uMaskTexture;" << endl;
   1.250 +  }
   1.251 +
   1.252 +  if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) {
   1.253 +    fs << "vec4 sample(vec2 coord) {" << endl;
   1.254 +    fs << "  vec4 color;" << endl;
   1.255 +    if (aConfig.mFeatures & ENABLE_TEXTURE_YCBCR) {
   1.256 +      fs << "  COLOR_PRECISION float y = texture2D(uYTexture, coord).r;" << endl;
   1.257 +      fs << "  COLOR_PRECISION float cb = texture2D(uCbTexture, coord).r;" << endl;
   1.258 +      fs << "  COLOR_PRECISION float cr = texture2D(uCrTexture, coord).r;" << endl;
   1.259 +      fs << "  y = (y - 0.0625) * 1.164;" << endl;
   1.260 +      fs << "  cb = cb - 0.5;" << endl;
   1.261 +      fs << "  cr = cr - 0.5;" << endl;
   1.262 +      fs << "  color.r = y + cr * 1.596;" << endl;
   1.263 +      fs << "  color.g = y - 0.813 * cr - 0.391 * cb;" << endl;
   1.264 +      fs << "  color.b = y + cb * 2.018;" << endl;
   1.265 +      fs << "  color.a = 1.0;" << endl;
   1.266 +    } else if (aConfig.mFeatures & ENABLE_TEXTURE_COMPONENT_ALPHA) {
   1.267 +      fs << "  COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, coord).rgb;" << endl;
   1.268 +      fs << "  COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, coord).rgb;" << endl;
   1.269 +      fs << "  COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;" << endl;
   1.270 +      fs << "  if (uTexturePass2)" << endl;
   1.271 +      fs << "    color = vec4(onBlack, alphas.a);" << endl;
   1.272 +      fs << "  else" << endl;
   1.273 +      fs << "    color = alphas;" << endl;
   1.274 +    } else {
   1.275 +      fs << "  color = " << texture2D << "(uTexture, coord);" << endl;
   1.276 +    }
   1.277 +    if (aConfig.mFeatures & ENABLE_TEXTURE_RB_SWAP) {
   1.278 +      fs << "  color = color.bgra;" << endl;
   1.279 +    }
   1.280 +    if (aConfig.mFeatures & ENABLE_TEXTURE_NO_ALPHA) {
   1.281 +      fs << "  color = vec4(color.rgb, 1.0);" << endl;
   1.282 +    }
   1.283 +    fs << "  return color;" << endl;
   1.284 +    fs << "}" << endl;
   1.285 +    if (aConfig.mFeatures & ENABLE_BLUR) {
   1.286 +      fs << "vec4 sampleAtRadius(vec2 coord, float radius) {" << endl;
   1.287 +      fs << "  coord += uBlurOffset;" << endl;
   1.288 +      fs << "  coord += radius * uBlurRadius;" << endl;
   1.289 +      fs << "  if (coord.x < 0. || coord.y < 0. || coord.x > 1. || coord.y > 1.)" << endl;
   1.290 +      fs << "    return vec4(0, 0, 0, 0);" << endl;
   1.291 +      fs << "  return sample(coord);" << endl;
   1.292 +      fs << "}" << endl;
   1.293 +      fs << "vec4 blur(vec4 color, vec2 coord) {" << endl;
   1.294 +      fs << "  vec4 total = color * uBlurGaussianKernel[0];" << endl;
   1.295 +      fs << "  for (int i = 1; i < " << GAUSSIAN_KERNEL_HALF_WIDTH << "; ++i) {" << endl;
   1.296 +      fs << "    float r = float(i) * " << GAUSSIAN_KERNEL_STEP << " << endl;" << endl;
   1.297 +      fs << "    float k = uBlurGaussianKernel[i];" << endl;
   1.298 +      fs << "    total += sampleAtRadius(coord, r) * k;" << endl;
   1.299 +      fs << "    total += sampleAtRadius(coord, -r) * k;" << endl;
   1.300 +      fs << "  }" << endl;
   1.301 +      fs << "  if (uBlurAlpha) {" << endl;
   1.302 +      fs << "    color *= total.a;" << endl;
   1.303 +      fs << "  } else {" << endl;
   1.304 +      fs << "    color = total;" << endl;
   1.305 +      fs << "  }" << endl;
   1.306 +      fs << "  return color;" << endl;
   1.307 +      fs << "}" << endl;
   1.308 +    }
   1.309 +  }
   1.310 +  fs << "void main() {" << endl;
   1.311 +  if (aConfig.mFeatures & ENABLE_RENDER_COLOR) {
   1.312 +    fs << "  vec4 color = uRenderColor;" << endl;
   1.313 +  } else {
   1.314 +    if (aConfig.mFeatures & ENABLE_TEXTURE_RECT) {
   1.315 +      fs << "  vec4 color = sample(vTexCoord * uTexCoordMultiplier);" << endl;
   1.316 +    } else {
   1.317 +      fs << "  vec4 color = sample(vTexCoord);" << endl;
   1.318 +    }
   1.319 +    if (aConfig.mFeatures & ENABLE_BLUR) {
   1.320 +      fs << "  color = blur(color, vTexCoord);" << endl;
   1.321 +    }
   1.322 +    if (aConfig.mFeatures & ENABLE_COLOR_MATRIX) {
   1.323 +      fs << "  color = uColorMatrix * vec4(color.rgb / color.a, color.a) + uColorMatrixVector;" << endl;
   1.324 +      fs << "  color.rgb *= color.a;" << endl;
   1.325 +    }
   1.326 +    if (aConfig.mFeatures & ENABLE_OPACITY) {
   1.327 +      fs << "  color *= uLayerOpacity;" << endl;
   1.328 +    }
   1.329 +  }
   1.330 +  if (aConfig.mFeatures & ENABLE_MASK_3D) {
   1.331 +    fs << "  vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;" << endl;
   1.332 +    fs << "  COLOR_PRECISION float mask = texture2D(uMaskTexture, maskCoords).r;" << endl;
   1.333 +    fs << "  color *= mask;" << endl;
   1.334 +  } else if (aConfig.mFeatures & ENABLE_MASK_2D) {
   1.335 +    fs << "  COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord.xy).r;" << endl;
   1.336 +    fs << "  color *= mask;" << endl;
   1.337 +  } else {
   1.338 +    fs << "  COLOR_PRECISION float mask = 1.0;" << endl;
   1.339 +    fs << "  color *= mask;" << endl;
   1.340 +  }
   1.341 +  fs << "  gl_FragColor = color;" << endl;
   1.342 +  fs << "}" << endl;
   1.343 +
   1.344 +  result.mVertexShaderString = vs.str();
   1.345 +  result.mFragmentShaderString = fs.str();
   1.346 +
   1.347 +  result.mAttributes.AppendElement(Argument("aVertexCoord"));
   1.348 +  if (aConfig.mFeatures & ENABLE_RENDER_COLOR) {
   1.349 +    result.mTextureCount = 0;
   1.350 +  } else {
   1.351 +    result.mAttributes.AppendElement(Argument("aTexCoord"));
   1.352 +    if (aConfig.mFeatures & ENABLE_TEXTURE_YCBCR) {
   1.353 +      result.mTextureCount = 3;
   1.354 +    } else if (aConfig.mFeatures & ENABLE_TEXTURE_COMPONENT_ALPHA) {
   1.355 +      result.mTextureCount = 2;
   1.356 +    } else {
   1.357 +      result.mTextureCount = 1;
   1.358 +    }
   1.359 +  }
   1.360 +  if (aConfig.mFeatures & ENABLE_MASK_2D ||
   1.361 +      aConfig.mFeatures & ENABLE_MASK_3D) {
   1.362 +    result.mTextureCount = 1;
   1.363 +  }
   1.364 +
   1.365 +  return result;
   1.366 +}
   1.367 +
   1.368 +const char* const ShaderProgramOGL::VertexCoordAttrib = "aVertexCoord";
   1.369 +const char* const ShaderProgramOGL::TexCoordAttrib = "aTexCoord";
   1.370 +
   1.371 +ShaderProgramOGL::ShaderProgramOGL(GLContext* aGL, const ProgramProfileOGL& aProfile)
   1.372 +  : mGL(aGL)
   1.373 +  , mProgram(0)
   1.374 +  , mProfile(aProfile)
   1.375 +  , mProgramState(STATE_NEW)
   1.376 +{
   1.377 +}
   1.378 +
   1.379 +ShaderProgramOGL::~ShaderProgramOGL()
   1.380 +{
   1.381 +  if (mProgram <= 0) {
   1.382 +    return;
   1.383 +  }
   1.384 +
   1.385 +  nsRefPtr<GLContext> ctx = mGL->GetSharedContext();
   1.386 +  if (!ctx) {
   1.387 +    ctx = mGL;
   1.388 +  }
   1.389 +  ctx->MakeCurrent();
   1.390 +  ctx->fDeleteProgram(mProgram);
   1.391 +}
   1.392 +
   1.393 +bool
   1.394 +ShaderProgramOGL::Initialize()
   1.395 +{
   1.396 +  NS_ASSERTION(mProgramState == STATE_NEW, "Shader program has already been initialised");
   1.397 +
   1.398 +  ostringstream vs, fs;
   1.399 +  for (uint32_t i = 0; i < mProfile.mDefines.Length(); ++i) {
   1.400 +    vs << mProfile.mDefines[i] << endl;
   1.401 +    fs << mProfile.mDefines[i] << endl;
   1.402 +  }
   1.403 +  vs << mProfile.mVertexShaderString << endl;
   1.404 +  fs << mProfile.mFragmentShaderString << endl;
   1.405 +
   1.406 +  if (!CreateProgram(vs.str().c_str(), fs.str().c_str())) {
   1.407 +    mProgramState = STATE_ERROR;
   1.408 +    return false;
   1.409 +  }
   1.410 +
   1.411 +  mProgramState = STATE_OK;
   1.412 +
   1.413 +  for (uint32_t i = 0; i < KnownUniform::KnownUniformCount; ++i) {
   1.414 +    mProfile.mUniforms[i].mLocation =
   1.415 +      mGL->fGetUniformLocation(mProgram, mProfile.mUniforms[i].mNameString);
   1.416 +  }
   1.417 +
   1.418 +  for (uint32_t i = 0; i < mProfile.mAttributes.Length(); ++i) {
   1.419 +    mProfile.mAttributes[i].mLocation =
   1.420 +      mGL->fGetAttribLocation(mProgram, mProfile.mAttributes[i].mName);
   1.421 +    NS_ASSERTION(mProfile.mAttributes[i].mLocation >= 0, "Bad attribute location.");
   1.422 +  }
   1.423 +
   1.424 +  //mProfile.mHasMatrixProj = mProfile.mUniforms[KnownUniform::MatrixProj].mLocation != -1;
   1.425 +
   1.426 +  return true;
   1.427 +}
   1.428 +
   1.429 +GLint
   1.430 +ShaderProgramOGL::CreateShader(GLenum aShaderType, const char *aShaderSource)
   1.431 +{
   1.432 +  GLint success, len = 0;
   1.433 +
   1.434 +  GLint sh = mGL->fCreateShader(aShaderType);
   1.435 +  mGL->fShaderSource(sh, 1, (const GLchar**)&aShaderSource, nullptr);
   1.436 +  mGL->fCompileShader(sh);
   1.437 +  mGL->fGetShaderiv(sh, LOCAL_GL_COMPILE_STATUS, &success);
   1.438 +  mGL->fGetShaderiv(sh, LOCAL_GL_INFO_LOG_LENGTH, (GLint*) &len);
   1.439 +  /* Even if compiling is successful, there may still be warnings.  Print them
   1.440 +   * in a debug build.  The > 10 is to catch silly compilers that might put
   1.441 +   * some whitespace in the log but otherwise leave it empty.
   1.442 +   */
   1.443 +  if (!success
   1.444 +#ifdef DEBUG
   1.445 +      || (len > 10 && PR_GetEnv("MOZ_DEBUG_SHADERS"))
   1.446 +#endif
   1.447 +      )
   1.448 +  {
   1.449 +    nsAutoCString log;
   1.450 +    log.SetCapacity(len);
   1.451 +    mGL->fGetShaderInfoLog(sh, len, (GLint*) &len, (char*) log.BeginWriting());
   1.452 +    log.SetLength(len);
   1.453 +
   1.454 +    if (!success) {
   1.455 +      printf_stderr("=== SHADER COMPILATION FAILED ===\n");
   1.456 +    } else {
   1.457 +      printf_stderr("=== SHADER COMPILATION WARNINGS ===\n");
   1.458 +    }
   1.459 +
   1.460 +      printf_stderr("=== Source:\n%s\n", aShaderSource);
   1.461 +      printf_stderr("=== Log:\n%s\n", log.get());
   1.462 +      printf_stderr("============\n");
   1.463 +
   1.464 +    if (!success) {
   1.465 +      mGL->fDeleteShader(sh);
   1.466 +      return 0;
   1.467 +    }
   1.468 +  }
   1.469 +
   1.470 +  return sh;
   1.471 +}
   1.472 +
   1.473 +bool
   1.474 +ShaderProgramOGL::CreateProgram(const char *aVertexShaderString,
   1.475 +                                const char *aFragmentShaderString)
   1.476 +{
   1.477 +  GLuint vertexShader = CreateShader(LOCAL_GL_VERTEX_SHADER, aVertexShaderString);
   1.478 +  GLuint fragmentShader = CreateShader(LOCAL_GL_FRAGMENT_SHADER, aFragmentShaderString);
   1.479 +
   1.480 +  if (!vertexShader || !fragmentShader)
   1.481 +    return false;
   1.482 +
   1.483 +  GLint result = mGL->fCreateProgram();
   1.484 +  mGL->fAttachShader(result, vertexShader);
   1.485 +  mGL->fAttachShader(result, fragmentShader);
   1.486 +
   1.487 +  mGL->fLinkProgram(result);
   1.488 +
   1.489 +  GLint success, len;
   1.490 +  mGL->fGetProgramiv(result, LOCAL_GL_LINK_STATUS, &success);
   1.491 +  mGL->fGetProgramiv(result, LOCAL_GL_INFO_LOG_LENGTH, (GLint*) &len);
   1.492 +  /* Even if linking is successful, there may still be warnings.  Print them
   1.493 +   * in a debug build.  The > 10 is to catch silly compilers that might put
   1.494 +   * some whitespace in the log but otherwise leave it empty.
   1.495 +   */
   1.496 +  if (!success
   1.497 +#ifdef DEBUG
   1.498 +      || (len > 10 && PR_GetEnv("MOZ_DEBUG_SHADERS"))
   1.499 +#endif
   1.500 +      )
   1.501 +  {
   1.502 +    nsAutoCString log;
   1.503 +    log.SetCapacity(len);
   1.504 +    mGL->fGetProgramInfoLog(result, len, (GLint*) &len, (char*) log.BeginWriting());
   1.505 +    log.SetLength(len);
   1.506 +
   1.507 +    if (!success) {
   1.508 +      printf_stderr("=== PROGRAM LINKING FAILED ===\n");
   1.509 +    } else {
   1.510 +      printf_stderr("=== PROGRAM LINKING WARNINGS ===\n");
   1.511 +    }
   1.512 +    printf_stderr("=== Log:\n%s\n", log.get());
   1.513 +    printf_stderr("============\n");
   1.514 +  }
   1.515 +
   1.516 +  // We can mark the shaders for deletion; they're attached to the program
   1.517 +  // and will remain attached.
   1.518 +  mGL->fDeleteShader(vertexShader);
   1.519 +  mGL->fDeleteShader(fragmentShader);
   1.520 +
   1.521 +  if (!success) {
   1.522 +    mGL->fDeleteProgram(result);
   1.523 +    return false;
   1.524 +  }
   1.525 +
   1.526 +  mProgram = result;
   1.527 +  return true;
   1.528 +}
   1.529 +
   1.530 +void
   1.531 +ShaderProgramOGL::Activate()
   1.532 +{
   1.533 +  if (mProgramState == STATE_NEW) {
   1.534 +    if (!Initialize()) {
   1.535 +      NS_WARNING("Shader could not be initialised");
   1.536 +      return;
   1.537 +    }
   1.538 +  }
   1.539 +  NS_ASSERTION(HasInitialized(), "Attempting to activate a program that's not in use!");
   1.540 +  mGL->fUseProgram(mProgram);
   1.541 +}
   1.542 +
   1.543 +} /* layers */
   1.544 +} /* mozilla */

mercurial