B2G/gecko/content/canvas/test/webgl/conformance/resources/glsl-generator.js
/**
   * Creates and returns a texture containing the reference image for
   * the function being tested. Exactly how the function is evaluated,
   * and the size of the returned texture, depends on whether we are
   * testing a vertex or fragment shader. If a fragment shader, the
   * function is evaluated at the pixel centers. If a vertex shader,
   * the function is evaluated at the triangle's vertices, and the
   * resulting texture must be offset by half a texel during
   * rendering.
   *
   * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use to generate texture objects.
   * @param {!function(number,number,number,number): !Array.<number>} generator The reference image generator function.
   * @param {number} width The width of the texture to generate if testing a fragment shader; the grid resolution if testing a vertex shader.
   * @param {number} height The height of the texture to generate if testing a fragment shader; the grid resolution if testing a vertex shader.
   * @param {boolean} isVertex True if generating a reference image for a vertex shader; false if for a fragment shader.
   * @return {!WebGLTexture} The texture object that was generated.
   */
Creates and returns a texture containing the reference image for
the function being tested. Exactly how the function is evaluated,
and the size of the returned texture, depends on whether we are
testing a vertex or fragment shader. If a fragment shader, the
function is evaluated at the pixel centers. If a vertex shader,
the function is evaluated at the triangle's vertices, and the
resulting texture must be offset by half a texel during
rendering.

@param {!WebGLRenderingContext} gl The WebGLRenderingContext to use to generate texture objects.
Creates and returns a texture containing the reference image for the function being tested . Exactly how the function is evaluated and the size of the returned texture depends on whether we are testing a vertex or fragment shader . If a fragment shader the function is evaluated at the pixel centers . If a vertex shader the function is evaluated at the triangle ' s vertices and the resulting texture must be offset by half a texel during rendering . @param { !WebGLRenderingContext } gl The WebGLRenderingContext to use to generate texture objects .
function generateReferenceTexture(
    gl,
    generator,
    width,
    height,
    isVertex) {
    function computeTexCoord(x) {
      return x * 0.5 + 0.5;
    }
    function computeColor(texCoordX, texCoordY) {
      return [ texCoordX,
               texCoordY,
               texCoordX * texCoordY,
               (1.0 - texCoordX) * texCoordY * 0.5 + 0.5 ];
    }
    function clamp(value, minVal, maxVal) {
      return Math.max(minVal, Math.min(value, maxVal));
    }
    function evaluateAtClipCoords(px, py, pixel) {
      var tcx = computeTexCoord(px);
      var tcy = computeTexCoord(py);
      var color = computeColor(tcx, tcy);
      var output = generator(color[0], color[1], color[2], color[3]);
      pixel[0] = clamp(Math.round(256 * output[0]), 0, 255);
      pixel[1] = clamp(Math.round(256 * output[1]), 0, 255);
      pixel[2] = clamp(Math.round(256 * output[2]), 0, 255);
      pixel[3] = clamp(Math.round(256 * output[3]), 0, 255);
    }
    function fillFragmentReference() {
      var data = new Uint8Array(4 * width * height);
      var horizTexel = 1.0 / width;
      var vertTexel = 1.0 / height;
      var halfHorizTexel = 0.5 * horizTexel;
      var halfVertTexel = 0.5 * vertTexel;
      var pixel = new Array(4);
      for (var yi = 0; yi < height; ++yi) {
        for (var xi = 0; xi < width; ++xi) {
          var px = -1.0 + 2.0 * (halfHorizTexel + xi * horizTexel);
          var py = -1.0 + 2.0 * (halfVertTexel + yi * vertTexel);
          evaluateAtClipCoords(px, py, pixel);
          var index = 4 * (width * yi + xi);
          data[index + 0] = pixel[0];
          data[index + 1] = pixel[1];
          data[index + 2] = pixel[2];
          data[index + 3] = pixel[3];
        }
      }
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0,
                    gl.RGBA, gl.UNSIGNED_BYTE, data);
    }
    function fillVertexReference() {
      if (width != height) {
        throw "width and height must be equal";
      }
      var texSize = 1 + width;
      var data = new Uint8Array(4 * texSize * texSize);
      var step = 2.0 / width;
      var pixel = new Array(4);
      for (var yi = 0; yi < texSize; ++yi) {
        for (var xi = 0; xi < texSize; ++xi) {
          var px = -1.0 + (xi * step);
          var py = -1.0 + (yi * step);
          evaluateAtClipCoords(px, py, pixel);
          var index = 4 * (texSize * yi + xi);
          data[index + 0] = pixel[0];
          data[index + 1] = pixel[1];
          data[index + 2] = pixel[2];
          data[index + 3] = pixel[3];
        }
      }
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0,
                    gl.RGBA, gl.UNSIGNED_BYTE, data);
    }
    var texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    if (isVertex) {
      fillVertexReference();
    } else {
      fillFragmentReference();
    }
    return texture;
  }
function generateReferenceTexture ( gl , generator , width , height , isVertex ) { function computeTexCoord ( x ) { return x * 0.5 + 0.5 ; } function computeColor ( texCoordX , texCoordY ) { return [ texCoordX , texCoordY , texCoordX * texCoordY , ( 1.0 - texCoordX ) * texCoordY * 0.5 + 0.5 ] ; } function clamp ( value , minVal , maxVal ) { return Math . max ( minVal , Math . min ( value , maxVal ) ) ; } function evaluateAtClipCoords ( px , py , pixel ) { var tcx = computeTexCoord ( px ) ; var tcy = computeTexCoord ( py ) ; var color = computeColor ( tcx , tcy ) ; var output = generator ( color [ 0 ] , color [ 1 ] , color [ 2 ] , color [ 3 ] ) ; pixel [ 0 ] = clamp ( Math . round ( 256 * output [ 0 ] ) , 0 , 255 ) ; pixel [ 1 ] = clamp ( Math . round ( 256 * output [ 1 ] ) , 0 , 255 ) ; pixel [ 2 ] = clamp ( Math . round ( 256 * output [ 2 ] ) , 0 , 255 ) ; pixel [ 3 ] = clamp ( Math . round ( 256 * output [ 3 ] ) , 0 , 255 ) ; } function fillFragmentReference ( ) { var data = new Uint8Array ( 4 * width * height ) ; var horizTexel = 1.0 / width ; var vertTexel = 1.0 / height ; var halfHorizTexel = 0.5 * horizTexel ; var halfVertTexel = 0.5 * vertTexel ; var pixel = new Array ( 4 ) ; for ( var yi = 0 ; yi < height ; ++ yi ) { for ( var xi = 0 ; xi < width ; ++ xi ) { var px = - 1.0 + 2.0 * ( halfHorizTexel + xi * horizTexel ) ; var py = - 1.0 + 2.0 * ( halfVertTexel + yi * vertTexel ) ; evaluateAtClipCoords ( px , py , pixel ) ; var index = 4 * ( width * yi + xi ) ; data [ index + 0 ] = pixel [ 0 ] ; data [ index + 1 ] = pixel [ 1 ] ; data [ index + 2 ] = pixel [ 2 ] ; data [ index + 3 ] = pixel [ 3 ] ; } } gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . RGBA , width , height , 0 , gl . RGBA , gl . UNSIGNED_BYTE , data ) ; } function fillVertexReference ( ) { if ( width != height ) { throw "width and height must be equal" ; } var texSize = 1 + width ; var data = new Uint8Array ( 4 * texSize * texSize ) ; var step = 2.0 / width ; var pixel = new Array ( 4 ) ; for ( var yi = 0 ; yi < texSize ; ++ yi ) { for ( var xi = 0 ; xi < texSize ; ++ xi ) { var px = - 1.0 + ( xi * step ) ; var py = - 1.0 + ( yi * step ) ; evaluateAtClipCoords ( px , py , pixel ) ; var index = 4 * ( texSize * yi + xi ) ; data [ index + 0 ] = pixel [ 0 ] ; data [ index + 1 ] = pixel [ 1 ] ; data [ index + 2 ] = pixel [ 2 ] ; data [ index + 3 ] = pixel [ 3 ] ; } } gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . RGBA , texSize , texSize , 0 , gl . RGBA , gl . UNSIGNED_BYTE , data ) ; } var texture = gl . createTexture ( ) ; gl . bindTexture ( gl . TEXTURE_2D , texture ) ; gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_MIN_FILTER , gl . LINEAR ) ; gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_MAG_FILTER , gl . LINEAR ) ; gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_WRAP_S , gl . CLAMP_TO_EDGE ) ; gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_WRAP_T , gl . CLAMP_TO_EDGE ) ; if ( isVertex ) { fillVertexReference ( ) ; } else { fillFragmentReference ( ) ; } return texture ; }
Creates and returns a texture containing the reference image for
 the function being tested.
Creates and returns a texture containing the reference image for the function being tested .
// Note: the math in this function must match that in the vertex and // fragment shader templates above. // Evaluates the function at clip coordinates (px,py), storing the // result in the array "pixel". Each channel's result is clamped // between 0 and 255. // Multiply by 256 to get even distribution for all values between 0 and 1. // Use rounding rather than truncation to more closely match the GPU's behavior. // The function must be evaluated at pixel centers. // Compute desired position in clip space // We generate a texture which contains the evaluation of the // function at the vertices of the triangle mesh. It is expected // that the width and the height are identical, and equivalent // to the grid resolution. // The function is evaluated at the triangles' vertices. // Compute desired position in clip space //---------------------------------------------------------------------- // Body of generateReferenceTexture //