Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / webgl / src / sdk / tests / conformance / resources / webgl-test-utils.js
index ca251e7..6ae6762 100644 (file)
@@ -262,8 +262,10 @@ var setupSimpleColorFragmentShader = function(gl) {
  *        the source from.
  * @param {!Array.<string>} opt_attribs The attribs names.
  * @param {!Array.<number>} opt_locations The locations for the attribs.
+ * @param {boolean} opt_logShaders Whether to log shader source.
  */
-var setupProgram = function(gl, shaders, opt_attribs, opt_locations) {
+var setupProgram = function(
+    gl, shaders, opt_attribs, opt_locations, opt_logShaders) {
   var realShaders = [];
   var program = gl.createProgram();
   var shaderCount = 0;
@@ -275,14 +277,16 @@ var setupProgram = function(gl, shaders, opt_attribs, opt_locations) {
       if (element) {
         if (element.type != "x-shader/x-vertex" && element.type != "x-shader/x-fragment")
           shaderType = ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER;
-        shader = loadShaderFromScript(gl, shader, shaderType);
+        shader = loadShaderFromScript(gl, shader, shaderType, undefined, opt_logShaders);
       } else if (endsWith(shader, ".vert")) {
-        shader = loadShaderFromFile(gl, shader, gl.VERTEX_SHADER);
+        shader = loadShaderFromFile(gl, shader, gl.VERTEX_SHADER, undefined, opt_logShaders);
       } else if (endsWith(shader, ".frag")) {
-        shader = loadShaderFromFile(gl, shader, gl.FRAGMENT_SHADER);
+        shader = loadShaderFromFile(gl, shader, gl.FRAGMENT_SHADER, undefined, opt_logShaders);
       } else {
-        shader = loadShader(gl, shader, ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER);
+        shader = loadShader(gl, shader, ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER, undefined, opt_logShaders);
       }
+    } else if (opt_logShaders) {
+      throw 'Shader source logging requested but no shader source provided';
     }
     if (shader) {
       ++shaderCount;
@@ -689,14 +693,14 @@ var setupIndexedQuadWithOptions = function (gl, options) {
 };
 
 /**
- * Returns the constructor for an ArrayBuffer that
- * corresponds to the given WebGL type.
+ * Returns the constructor for a typed array that corresponds to the given
+ * WebGL type.
  * @param {!WebGLRenderingContext} gl A WebGLRenderingContext.
  * @param {number} type The WebGL type (eg, gl.UNSIGNED_BYTE)
- * @return {!Constructor} The ArrayBuffer constructor that
+ * @return {!Constructor} The typed array constructor that
  *      corresponds to the given type.
  */
-var glTypeToArrayBufferType = function(gl, type) {
+var glTypeToTypedArrayType = function(gl, type) {
   switch (type) {
     case gl.BYTE:
       return window.Int8Array;
@@ -719,12 +723,10 @@ var glTypeToArrayBufferType = function(gl, type) {
 };
 
 /**
- * Returns the number of bytes per component for a given WebGL
- * type.
+ * Returns the number of bytes per component for a given WebGL type.
  * @param {!WebGLRenderingContext} gl A WebGLRenderingContext.
- * @param {number} type The WebGL type (eg, gl.UNSIGNED_BYTE)
- * @return {!Constructor} The ArrayBuffer constructor that
- *      corresponds to the given type.
+ * @param {GLenum} type The WebGL type (eg, gl.UNSIGNED_BYTE)
+ * @return {number} The number of bytes per component.
  */
 var getBytesPerComponent = function(gl, type) {
   switch (type) {
@@ -746,6 +748,42 @@ var getBytesPerComponent = function(gl, type) {
 };
 
 /**
+ * Returns the number of typed array elements per pixel for a given WebGL
+ * format/type combination. The corresponding typed array type can be determined
+ * by calling glTypeToTypedArrayType.
+ * @param {!WebGLRenderingContext} gl A WebGLRenderingContext.
+ * @param {GLenum} format The WebGL format (eg, gl.RGBA)
+ * @param {GLenum} type The WebGL type (eg, gl.UNSIGNED_BYTE)
+ * @return {number} The number of typed array elements per pixel.
+ */
+var getTypedArrayElementsPerPixel = function(gl, format, type) {
+  switch (type) {
+    case gl.UNSIGNED_SHORT_5_6_5:
+    case gl.UNSIGNED_SHORT_4_4_4_4:
+    case gl.UNSIGNED_SHORT_5_5_5_1:
+      return 1;
+    case gl.UNSIGNED_BYTE:
+      break;
+    default:
+      throw 'not a gl type for color information ' + glEnumToString(gl, type);
+  }
+
+  switch (format) {
+    case gl.RGBA:
+      return 4;
+    case gl.RGB:
+      return 3;
+    case gl.LUMINANCE_ALPHA:
+      return 2;
+    case gl.LUMINANCE:
+    case gl.ALPHA:
+      return 1;
+    default:
+      throw 'unknown gl format ' + glEnumToString(gl, format);
+  }
+};
+
+/**
  * Fills the given texture with a solid color.
  * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
  * @param {!WebGLTexture} tex The texture to fill.
@@ -767,7 +805,7 @@ var fillTexture = function(gl, tex, width, height, color, opt_level, opt_format,
   var paddedRowSize = Math.floor((rowSize + pack - 1) / pack) * pack;
   var size = rowSize + (height - 1) * paddedRowSize;
   size = Math.floor((size + bytesPerComponent - 1) / bytesPerComponent) * bytesPerComponent;
-  var buf = new (glTypeToArrayBufferType(gl, opt_type))(size);
+  var buf = new (glTypeToTypedArrayType(gl, opt_type))(size);
   for (var yy = 0; yy < height; ++yy) {
     var off = yy * paddedRowSize;
     for (var xx = 0; xx < width; ++xx) {
@@ -1116,6 +1154,44 @@ var loadTexture = function(gl, url, callback) {
 };
 
 /**
+ * Checks whether the bound texture has expected dimensions. One corner pixel
+ * of the texture will be changed as a side effect.
+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
+ * @param {!WebGLTexture} texture The texture to check.
+ * @param {number} width Expected width.
+ * @param {number} height Expected height.
+ * @param {GLenum} opt_format The texture's format. Defaults to RGBA.
+ * @param {GLenum} opt_type The texture's type. Defaults to UNSIGNED_BYTE.
+ */
+var checkTextureSize = function(gl, width, height, opt_format, opt_type) {
+  opt_format = opt_format || gl.RGBA;
+  opt_type = opt_type || gl.UNSIGNED_BYTE;
+
+  var numElements = getTypedArrayElementsPerPixel(gl, opt_format, opt_type);
+  var buf = new (glTypeToTypedArrayType(gl, opt_type))(numElements);
+
+  var errors = 0;
+  gl.texSubImage2D(gl.TEXTURE_2D, 0, width - 1, height - 1, 1, 1, opt_format, opt_type, buf);
+  if (gl.getError() != gl.NO_ERROR) {
+    testFailed("Texture was smaller than the expected size " + width + "x" + height);
+    ++errors;
+  }
+  gl.texSubImage2D(gl.TEXTURE_2D, 0, width - 1, height, 1, 1, opt_format, opt_type, buf);
+  if (gl.getError() == gl.NO_ERROR) {
+    testFailed("Texture was taller than " + height);
+    ++errors;
+  }
+  gl.texSubImage2D(gl.TEXTURE_2D, 0, width, height - 1, 1, 1, opt_format, opt_type, buf);
+  if (gl.getError() == gl.NO_ERROR) {
+    testFailed("Texture was wider than " + width);
+    ++errors;
+  }
+  if (errors == 0) {
+    testPassed("Texture had the expected size " + width + "x" + height);
+  }
+};
+
+/**
  * Makes a shallow copy of an object.
  * @param {!Object) src Object to copy
  * @return {!Object} The copy of src.
@@ -1529,9 +1605,17 @@ var readFileList = function(url) {
  * @param {string} shaderSource The shader source.
  * @param {number} shaderType The type of shader. 
  * @param {function(string): void) opt_errorCallback callback for errors. 
+ * @param {boolean} opt_logShaders Whether to log shader source.
+ * @param {string} opt_shaderLabel Label that identifies the shader source in
+ *     the log.
+ * @param {string} opt_url URL from where the shader source was loaded from.
+ *     If opt_logShaders is set, then a link to the source file will also be
+ *     added.
  * @return {!WebGLShader} The created shader.
  */
-var loadShader = function(gl, shaderSource, shaderType, opt_errorCallback) {
+var loadShader = function(
+    gl, shaderSource, shaderType, opt_errorCallback, opt_logShaders,
+    opt_shaderLabel, opt_url) {
   var errFn = opt_errorCallback || error;
   // Create the shader object
   var shader = gl.createShader(shaderType);
@@ -1551,6 +1635,15 @@ var loadShader = function(gl, shaderSource, shaderType, opt_errorCallback) {
   // Compile the shader
   gl.compileShader(shader);
 
+  if (opt_logShaders) {
+    var label = shaderType == gl.VERTEX_SHADER ? 'vertex shader' : 'fragment_shader';
+    if (opt_shaderLabel) {
+      label = opt_shaderLabel + ' ' + label;
+    }
+    addShaderSources(
+        gl, document.getElementById('console'), label, shader, shaderSource, opt_url);
+  }
+
   // Check the compile status
   var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
   if (!compiled) {
@@ -1570,11 +1663,14 @@ var loadShader = function(gl, shaderSource, shaderType, opt_errorCallback) {
  * @param {file} file The URL of the shader source.
  * @param {number} type The type of shader.
  * @param {function(string): void) opt_errorCallback callback for errors. 
+ * @param {boolean} opt_logShaders Whether to log shader source.
  * @return {!WebGLShader} The created shader.
  */
-var loadShaderFromFile = function(gl, file, type, opt_errorCallback) {
+var loadShaderFromFile = function(
+    gl, file, type, opt_errorCallback, opt_logShaders) {
   var shaderSource = readFile(file);
-  return loadShader(gl, shaderSource, type, opt_errorCallback);
+  return loadShader(gl, shaderSource, type, opt_errorCallback,
+      opt_logShaders, undefined, file);
 };
 
 /**
@@ -1585,7 +1681,7 @@ var loadShaderFromFile = function(gl, file, type, opt_errorCallback) {
 var getScript = function(scriptId) {
   var shaderScript = document.getElementById(scriptId);
   if (!shaderScript) {
-    throw("*** Error: unknown script element" + scriptId);
+    throw("*** Error: unknown script element " + scriptId);
   }
   return shaderScript.text;
 };
@@ -1597,10 +1693,11 @@ var getScript = function(scriptId) {
  * @param {number} opt_shaderType The type of shader. If not passed in it will
  *     be derived from the type of the script tag.
  * @param {function(string): void) opt_errorCallback callback for errors. 
+ * @param {boolean} opt_logShaders Whether to log shader source.
  * @return {!WebGLShader} The created shader.
  */
 var loadShaderFromScript = function(
-    gl, scriptId, opt_shaderType, opt_errorCallback) {
+    gl, scriptId, opt_shaderType, opt_errorCallback, opt_logShaders) {
   var shaderSource = "";
   var shaderScript = document.getElementById(scriptId);
   if (!shaderScript) {
@@ -1619,8 +1716,8 @@ var loadShaderFromScript = function(
     }
   }
 
-  return loadShader(
-      gl, shaderSource, opt_shaderType, opt_errorCallback);
+  return loadShader(gl, shaderSource, opt_shaderType, opt_errorCallback,
+      opt_logShaders);
 };
 
 var loadStandardProgram = function(gl) {
@@ -1712,15 +1809,16 @@ var createProgram = function(gl, vertexShader, fragmentShader, opt_errorCallback
  * @param {string} vertexShader The vertex shader source.
  * @param {string} fragmentShader The fragment shader source.
  * @param {function(string): void) opt_errorCallback callback for errors. 
+ * @param {boolean} opt_logShaders Whether to log shader source.
  * @return {!WebGLProgram} The created program.
  */
 var loadProgram = function(
-    gl, vertexShader, fragmentShader, opt_errorCallback) {
+    gl, vertexShader, fragmentShader, opt_errorCallback, opt_logShaders) {
   var program;
   var vs = loadShader(
-      gl, vertexShader, gl.VERTEX_SHADER, opt_errorCallback);
+      gl, vertexShader, gl.VERTEX_SHADER, opt_errorCallback, opt_logShaders);
   var fs = loadShader(
-      gl, fragmentShader, gl.FRAGMENT_SHADER, opt_errorCallback);
+      gl, fragmentShader, gl.FRAGMENT_SHADER, opt_errorCallback, opt_logShaders);
   if (vs && fs) {
     program = createProgram(gl, vs, fs, opt_errorCallback)
   }
@@ -1971,13 +2069,13 @@ var insertImage = function(element, caption, img) {
 };
 
 /**
- * Inserts a 'label' that when clicked expands to the pre
- * formatted text supplied by 'source'.
+ * Inserts a 'label' that when clicked expands to the pre formatted text
+ * supplied by 'source'.
  * @param {!HTMLElement} element element to append label to.
  * @param {string} label label for anchor.
  * @param {string} source preformatted text to expand to.
- * @param {string} opt_url url of source. If provided a 2nd link
- *     will be added.
+ * @param {string} opt_url URL of source. If provided a link to the source file
+ *     will also be added.
  */
 var addShaderSource = function(element, label, source, opt_url) {
   var div = document.createElement("div");
@@ -2016,6 +2114,30 @@ var addShaderSource = function(element, label, source, opt_url) {
   element.appendChild(div);
 };
 
+/**
+ * Inserts labels that when clicked expand to show the original source of the
+ * shader and also translated source of the shader, if that is available.
+ * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.
+ * @param {!HTMLElement} element element to append label to.
+ * @param {string} label label for anchor.
+ * @param {WebGLShader} shader Shader to show the sources for.
+ * @param {string} shaderSource Original shader source.
+ * @param {string} opt_url URL of source. If provided a link to the source file
+ *     will also be added.
+ */
+var addShaderSources = function(
+    gl, element, label, shader, shaderSource, opt_url) {
+  addShaderSource(element, label, shaderSource, opt_url);
+
+  var debugShaders = gl.getExtension('WEBGL_debug_shaders');
+  if (debugShaders && shader) {
+    var translatedSource = debugShaders.getTranslatedShaderSource(shader);
+    if (translatedSource != '') {
+      addShaderSource(element, label + ' translated for driver', translatedSource);
+    }
+  }
+};
+
 // Add your prefix here.
 var browserPrefixes = [
   "",
@@ -2060,6 +2182,33 @@ var getExtensionWithKnownPrefixes = function(gl, name) {
   }
 };
 
+/**
+ * Returns possible prefixed versions of an extension's name.
+ * @param {string} name Name of extension. May already include a prefix.
+ * @return {Array.<string>} Variations of the extension name with known
+ *     browser prefixes.
+ */
+var getExtensionPrefixedNames = function(name) {
+  var unprefix = function(name) {
+    for (var ii = 0; ii < browserPrefixes.length; ++ii) {
+      if (browserPrefixes[ii].length > 0 &&
+          name.substring(0, browserPrefixes[ii].length).toLowerCase() ===
+          browserPrefixes[ii].toLowerCase()) {
+        return name.substring(browserPrefixes[ii].length);
+      }
+    }
+    return name;
+  }
+
+  var unprefixed = unprefix(name);
+
+  var variations = [];
+  for (var ii = 0; ii < browserPrefixes.length; ++ii) {
+    variations.push(browserPrefixes[ii] + unprefixed);
+  }
+
+  return variations;
+};
 
 var replaceRE = /\$\((\w+)\)/g;
 
@@ -2414,6 +2563,7 @@ var setupImageForCrossOriginTest = function(img, imgUrl, localUrl, callback) {
 
 return {
   addShaderSource: addShaderSource,
+  addShaderSources: addShaderSources,
   cancelAnimFrame: cancelAnimFrame,
   create3DContext: create3DContext,
   create3DContextWithWrapperThatThrowsOnGLError:
@@ -2422,6 +2572,7 @@ return {
   checkCanvas: checkCanvas,
   checkCanvasRect: checkCanvasRect,
   checkCanvasRectColor: checkCanvasRectColor,
+  checkTextureSize: checkTextureSize,
   clipToRange: clipToRange,
   createColoredTexture: createColoredTexture,
   createProgram: createProgram,
@@ -2434,19 +2585,21 @@ return {
   endsWith: endsWith,
   fillTexture: fillTexture,
   getBytesPerComponent: getBytesPerComponent,
+  getExtensionPrefixedNames: getExtensionPrefixedNames,
   getExtensionWithKnownPrefixes: getExtensionWithKnownPrefixes,
   getFileListAsync: getFileListAsync,
   getLastError: getLastError,
   getPrefixedProperty: getPrefixedProperty,
   getScript: getScript,
   getSupportedExtensionWithKnownPrefixes: getSupportedExtensionWithKnownPrefixes,
+  getTypedArrayElementsPerPixel: getTypedArrayElementsPerPixel,
   getUrlArguments: getUrlArguments,
   getUrlOptions: getUrlOptions,
   getAttribMap: getAttribMap,
   getUniformMap: getUniformMap,
   glEnumToString: glEnumToString,
   glErrorShouldBe: glErrorShouldBe,
-  glTypeToArrayBufferType: glTypeToArrayBufferType,
+  glTypeToTypedArrayType: glTypeToTypedArrayType,
   hasAttributeCaseInsensitive: hasAttributeCaseInsensitive,
   insertImage: insertImage,
   loadImageAsync: loadImageAsync,