Bug 698856 - Upgrade WebGL conformance test suite to r15981 - no review
☠☠ backed out by 0c55634fffb6 ☠ ☠
authorBenoit Jacob <bjacob@mozilla.com>
Wed, 02 Nov 2011 08:44:41 -0400
changeset 79552 be8056caccb4db8b1ff89dba474847d2a65b9184
parent 79551 53ba7abbf1daf97cf43da3bf41c757a2b157c6f2
child 79564 631b19db4eb5a58084fc3153a46a968fcbf80dd6
push id3052
push userbjacob@mozilla.com
push dateWed, 02 Nov 2011 12:46:14 +0000
treeherdermozilla-inbound@be8056caccb4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs698856
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 698856 - Upgrade WebGL conformance test suite to r15981 - no review The upstream is https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/tests/ This changeset also updates our lists of failing tests, and the garbageCollect() call before each test page is now done on all platforms, instead of only on linux, as it's now clear that we've been having this problem everywhere.
content/canvas/test/webgl/README.mozilla
content/canvas/test/webgl/conformance/attribs/gl-enable-vertex-attrib.html
content/canvas/test/webgl/conformance/attribs/gl-vertexattribpointer-offsets.html
content/canvas/test/webgl/conformance/context/resource-sharing-test.html
content/canvas/test/webgl/conformance/glsl/00_test_list.txt
content/canvas/test/webgl/conformance/glsl/misc/00_test_list.txt
content/canvas/test/webgl/conformance/glsl/misc/attrib-location-length-limits.html
content/canvas/test/webgl/conformance/glsl/misc/embedded-struct-definitions-forbidden.html
content/canvas/test/webgl/conformance/glsl/misc/glsl-2types-of-textures-on-same-unit.html
content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html
content/canvas/test/webgl/conformance/glsl/misc/glsl-long-variable-names.html
content/canvas/test/webgl/conformance/glsl/misc/shader-with-attrib-struct.vert.html
content/canvas/test/webgl/conformance/glsl/misc/struct-nesting-exceeds-maximum.html
content/canvas/test/webgl/conformance/glsl/misc/struct-nesting-under-maximum.html
content/canvas/test/webgl/conformance/glsl/misc/uniform-location-length-limits.html
content/canvas/test/webgl/conformance/glsl/samplers/00_test_list.txt
content/canvas/test/webgl/conformance/glsl/samplers/glsl-function-texture2d-bias.html
content/canvas/test/webgl/conformance/glsl/samplers/glsl-function-texture2dlod.html
content/canvas/test/webgl/conformance/glsl/samplers/glsl-function-texture2dproj.html
content/canvas/test/webgl/conformance/glsl/variables/gl-fragcoord.html
content/canvas/test/webgl/conformance/glsl/variables/gl-frontfacing.html
content/canvas/test/webgl/conformance/limits/gl-max-texture-dimensions.html
content/canvas/test/webgl/conformance/limits/gl-min-attribs.html
content/canvas/test/webgl/conformance/limits/gl-min-textures.html
content/canvas/test/webgl/conformance/limits/gl-min-uniforms.html
content/canvas/test/webgl/conformance/misc/instanceof-test.html
content/canvas/test/webgl/conformance/renderbuffers/framebuffer-object-attachment.html
content/canvas/test/webgl/conformance/renderbuffers/framebuffer-test.html
content/canvas/test/webgl/conformance/rendering/gl-drawelements.html
content/canvas/test/webgl/conformance/rendering/triangle.html
content/canvas/test/webgl/conformance/resources/webgl-test-utils.js
content/canvas/test/webgl/conformance/textures/gl-pixelstorei.html
content/canvas/test/webgl/conformance/textures/texparameter-test.html
content/canvas/test/webgl/conformance/textures/texture-active-bind-2.html
content/canvas/test/webgl/conformance/textures/texture-active-bind.html
content/canvas/test/webgl/conformance/textures/texture-complete.html
content/canvas/test/webgl/conformance/textures/texture-mips.html
content/canvas/test/webgl/conformance/textures/texture-npot.html
content/canvas/test/webgl/conformance/uniforms/uniform-samplers-test.html
content/canvas/test/webgl/failing_tests_linux.txt
content/canvas/test/webgl/failing_tests_mac.txt
content/canvas/test/webgl/failing_tests_windows.txt
content/canvas/test/webgl/test_webgl_conformance_test_suite.html
content/canvas/test/webgl/webgl-conformance-tests.html
--- a/content/canvas/test/webgl/README.mozilla
+++ b/content/canvas/test/webgl/README.mozilla
@@ -1,9 +1,9 @@
-This is a local copy of the WebGL conformance suite, SVN revision 15892
+This is a local copy of the WebGL conformance suite, SVN revision 15981
 
 The canonical location for this testsuite is:
 
   https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/tests
 
 All files and directories in this directory, with the exceptions listed below, come from
 upstream and should not be modified without corresponding upstream fixes and/or a
 patch file in this directory. The exceptions (the Mozilla-specific files) are:
--- a/content/canvas/test/webgl/conformance/attribs/gl-enable-vertex-attrib.html
+++ b/content/canvas/test/webgl/conformance/attribs/gl-enable-vertex-attrib.html
@@ -28,18 +28,18 @@
 <script id="fshader" type="x-shader/x-fragment">
     void main()
     {
         gl_FragColor = vec4(1.0,0.0,0.0,1.0);
     }
 </script>
 
 <script>
+description("tests that turning on attribs that have no buffer bound fails to draw");
 gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
-gl.viewport(0, 0, 50, 50);
 
 var vertexObject = gl.createBuffer();
 gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW);
 gl.enableVertexAttribArray(0);
 gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
 
 gl.enableVertexAttribArray(3);
--- a/content/canvas/test/webgl/conformance/attribs/gl-vertexattribpointer-offsets.html
+++ b/content/canvas/test/webgl/conformance/attribs/gl-vertexattribpointer-offsets.html
@@ -22,17 +22,17 @@ OF LIABILITY, WHETHER IN CONTRACT, STRIC
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 -->
 
 <!DOCTYPE html>
 <html>
   <head>
 <meta charset="utf-8">
-    <title>Rendering Test</title>
+    <title>vertexattribpointer offsets test</title>
     <link rel="stylesheet" href="../../resources/js-test-style.css"/>
     <script src="../../resources/js-test-pre.js"></script>
     <script src="../resources/webgl-test.js"> </script>
     <script src="../resources/webgl-test-utils.js"> </script>
 </head>
 <body>
 <canvas id="example" width="50" height="50">
 There is supposed to be an example drawing here, but it's not important.
@@ -69,16 +69,17 @@ There is supposed to be an example drawi
             testPassed("drawing is correct");
         }
 
         function init()
         {
             if (window.initNonKhronosFramework) {
                 window.initNonKhronosFramework(false);
             }
+            description("test vertexattribpointer offsets work");
 
             wtu = WebGLTestUtils;
             gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
 
             var tests = [
               { data: new Float32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
                 type: gl.FLOAT,
                 componentSize: 4,
--- a/content/canvas/test/webgl/conformance/context/resource-sharing-test.html
+++ b/content/canvas/test/webgl/conformance/context/resource-sharing-test.html
@@ -14,17 +14,17 @@ found in the LICENSE file.
     <script src="../../debug/webgl-debug.js"> </script>
 </head>
 <body>
 <canvas id="example1" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
 <canvas id="example2" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
 <div id="description"></div>
 <div id="console"></div>
 <script>
-debug("Tests that resources can not be shared.");
+description("Tests that resources can not be shared.");
 debug("");
 
 var gl1 = create3DContext(document.getElementById("example1"));
 var gl2 = create3DContext(document.getElementById("example2"));
 assertMsg(gl1 && gl2,
           "Got 3d context.");
 
 var vertexObject = gl1.createBuffer();
--- a/content/canvas/test/webgl/conformance/glsl/00_test_list.txt
+++ b/content/canvas/test/webgl/conformance/glsl/00_test_list.txt
@@ -1,6 +1,8 @@
 functions/00_test_list.txt
 implicit/00_test_list.txt
 misc/00_test_list.txt
 reserved/00_test_list.txt
+# commented out for version 1.0.1 of the conforamnce tests.
+#samplers/00_test_list.txt
 variables/00_test_list.txt
 
--- a/content/canvas/test/webgl/conformance/glsl/misc/00_test_list.txt
+++ b/content/canvas/test/webgl/conformance/glsl/misc/00_test_list.txt
@@ -1,19 +1,22 @@
+attrib-location-length-limits.html
+embedded-struct-definitions-forbidden.html
 #glsl-2types-of-textures-on-same-unit.html
 glsl-function-nodes.html
 glsl-long-variable-names.html
 non-ascii-comments.vert.html
 non-ascii.vert.html
 shader-with-256-character-identifier.frag.html
 shader-with-257-character-identifier.frag.html
 shader-with-_webgl-identifier.vert.html
 shader-with-arbitrary-indexing.frag.html
 shader-with-arbitrary-indexing.vert.html
 shader-with-attrib-array.vert.html
+shader-with-attrib-struct.vert.html
 shader-with-clipvertex.vert.html
 shader-with-default-precision.frag.html
 shader-with-default-precision.vert.html
 shader-with-define-line-continuation.frag.html
 shader-with-dfdx-no-ext.frag.html
 shader-with-dfdx.frag.html
 shader-with-error-directive.html
 shader-with-explicit-int-cast.vert.html
@@ -44,8 +47,11 @@ shader-with-vec3-return-value.frag.html
 shader-with-vec4-return-value.frag.html
 shader-with-version-100.frag.html
 shader-with-version-100.vert.html
 shader-with-version-120.vert.html
 shader-with-version-130.vert.html
 shader-with-webgl-identifier.vert.html
 shader-without-precision.frag.html
 shared.html
+struct-nesting-exceeds-maximum.html
+struct-nesting-under-maximum.html
+uniform-location-length-limits.html
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/conformance/glsl/misc/attrib-location-length-limits.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL attrib location length tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../resources/webgl-test.js"> </script>
+<script src="../../resources/webgl-test-utils.js"> </script>
+</head>
+<body>
+<canvas id="example" width="50" height="50">
+There is supposed to be an example drawing here, but it's not important.
+</canvas>
+<div id="description">Verify limits on the lengths of attribute locations per WebGL spec, "Maximum Uniform and Attribute Location Lengths".</div>
+<div id="console"></div>
+<script id="goodVertexShader" type="x-shader/x-vertex">
+// A vertex shader where the needed attrib location is exactly 256 characters.
+attribute vec4 vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
+
+void main()
+{
+    gl_Position = vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
+}
+</script>
+<script id="badVertexShader" type="x-shader/x-vertex">
+// A vertex shader where the needed attrib location is 257 characters.
+attribute vec4 vPosition01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567;
+
+void main()
+{
+    gl_Position = vPosition01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567;
+}
+</script>
+<script id="fragmentShader" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+if (window.initNonKhronosFramework) {
+    window.initNonKhronosFramework(false);
+}
+description("test attrib location length limit");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(document.getElementById("example"));
+
+debug("Test attrib location underneath the length limit");
+var program = wtu.loadProgramFromScript(gl, "goodVertexShader", "fragmentShader");
+shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
+var attribLoc = gl.getAttribLocation(program, "vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456");
+if (attribLoc == -1) {
+    testFailed("attrib location was -1, should not be");
+} else {
+    testPassed("attrib location should not be -1");
+}
+wtu.glErrorShouldBe(gl, gl.NONE);
+
+debug("Test attrib location over the length limit");
+debug("Shader compilation should fail");
+shouldBe('wtu.loadShaderFromScript(gl, "badVertexShader", gl.VERTEX_SHADER, function (err) {})', 'null');
+wtu.glErrorShouldBe(gl, gl.NONE);
+
+debug("Attempt to bind too-long attrib location should produce error");
+program = gl.createProgram();
+gl.bindAttribLocation(program, 0, "vPosition01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567");
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
+
+debug("Attempt to fetch too-long attrib location should produce error");
+program = wtu.loadStandardProgram(gl);
+shouldBe('gl.getAttribLocation(program, "vPosition01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567")', '-1');
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
+
+successfullyParsed = true;
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/conformance/glsl/misc/embedded-struct-definitions-forbidden.html
@@ -0,0 +1,38 @@
+<!--
+Copyright (c) 2011 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL GLSL Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../resources/webgl-test-utils.js"></script>
+<script src="../../resources/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertexShader" type="text/something-not-javascript">
+// embedded structure definitions are forbidden per GLSL ES section 4.1.8, "Structures", and should fail
+struct nesting1 {
+  struct nesting2 {
+    vec4 vector;
+  } field2;
+};
+
+uniform nesting1 uniform1;
+void main()
+{
+    gl_Position = uniform1.field2.vector;
+}
+</script>
+<script>
+GLSLConformanceTester.runTest();
+successfullyParsed = true;
+</script>
+</body>
+</html>
--- a/content/canvas/test/webgl/conformance/glsl/misc/glsl-2types-of-textures-on-same-unit.html
+++ b/content/canvas/test/webgl/conformance/glsl/misc/glsl-2types-of-textures-on-same-unit.html
@@ -44,20 +44,20 @@ void main()
 
   <script>
 function init()
 {
   if (window.initNonKhronosFramework) {
       window.initNonKhronosFramework(false);
   }
 
-  debug("Tests that using 2 types of textures on the same texture unit");
-  debug("and referencing them both in the same program fails as per");
-  debug("OpenGL ES 2.0.24 spec section 2.10.4, Samplers subsection.");
-  debug("");
+  description(
+    "Tests that using 2 types of textures on the same texture unit" +
+    "and referencing them both in the same program fails as per" +
+    "OpenGL ES 2.0.24 spec section 2.10.4, Samplers subsection.");
 
   var canvas2d = document.getElementById("canvas2d");
   var ctx2d = canvas2d.getContext("2d");
 
   gl = initWebGL("example", "vshader", "fshader", [ "vPosition", "texCoord0"],
                  [ 0, 0, 0, 1 ], 1);
 
   gl.disable(gl.DEPTH_TEST);
--- a/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html
+++ b/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html
@@ -107,16 +107,18 @@ function compareRendering(buffer1, buffe
 }
 
 function init()
 {
     if (window.initNonKhronosFramework) {
         window.initNonKhronosFramework(false);
     }
 
+    description("tests function nodes");
+
     var bufFunction = new Uint8Array(width * height * 4);
     var bufMacro = new Uint8Array(width * height * 4);
 
     if (drawAndRead("canvasFunction", "vshaderFunction", bufFunction) == false ||
         drawAndRead("canvasMacro", "vshaderMacro", bufMacro) == false) {
         testFailed("Setup failed");
     } else {
         if (compareRendering(bufFunction, bufMacro, 4) == false)
--- a/content/canvas/test/webgl/conformance/glsl/misc/glsl-long-variable-names.html
+++ b/content/canvas/test/webgl/conformance/glsl/misc/glsl-long-variable-names.html
@@ -6,17 +6,17 @@
     <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
     <script src="../../../resources/js-test-pre.js"></script>
     <script src="../../resources/webgl-test.js"> </script>
 </head>
 <body>
     <canvas id="example" width="50" height="50">
     There is supposed to be an example drawing here, but it's not important.
     </canvas>
-    <div id="description">Verify that shader long variable names works fine if they are within 256 characters.</div>
+    <div id="description"></div>
     <div id="console"></div>
     <script id="vshader" type="x-shader/x-vertex">
         attribute vec4 vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
         varying float alpha01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890;
         void main()
         {
             alpha01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 = 1.0;
             gl_Position = vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
@@ -48,16 +48,18 @@
         {
             testPassed("drawing is correct");
         }
 
         if (window.initNonKhronosFramework) {
             window.initNonKhronosFramework(false);
         }
 
+        description("Verify that shader long variable names works fine if they are within 256 characters.");
+
         gl = initWebGL("example", "vshader", "fshader", [ "vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456"], [ 0, 0, 0, 1 ], 1);
 
         var prog = gl.getParameter(gl.CURRENT_PROGRAM);
         shouldBeNonNull(prog);
         var redLoc = gl.getUniformLocation(prog, "color01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567[0]");
         shouldBeNonNull(redLoc);
         var greenLoc = gl.getUniformLocation(prog, "color01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567[1]");
         shouldBeNonNull(greenLoc);
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/conformance/glsl/misc/shader-with-attrib-struct.vert.html
@@ -0,0 +1,38 @@
+<!--
+Copyright (c) 2011 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL GLSL Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../resources/webgl-test-utils.js"></script>
+<script src="../../resources/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertexShader" type="text/something-not-javascript">
+// vertex shader that uses attribute struct should fail per GLSL ES section 4.4.3, "Attribute", p. 30
+struct UserType {
+    attribute vec4 position;
+};
+
+attribute UserType userAttr;
+void main()
+{
+    gl_Position = userAttr.position;
+}
+</script>
+<script>
+GLSLConformanceTester.runTest();
+successfullyParsed = true;
+</script>
+</body>
+</html>
+
+
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/conformance/glsl/misc/struct-nesting-exceeds-maximum.html
@@ -0,0 +1,48 @@
+<!--
+Copyright (c) 2011 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL GLSL Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../resources/webgl-test-utils.js"></script>
+<script src="../../resources/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertexShader" type="text/something-not-javascript">
+// shader with too-deep struct nesting should fail per WebGL spec
+struct nesting4 {
+  vec4 vector;
+};
+
+struct nesting3 {
+  nesting4 field4;
+};
+
+struct nesting2 {
+  nesting3 field3;
+};
+
+struct nesting1 {
+  nesting2 field2;
+};
+
+uniform nesting1 uniform1;
+void main()
+{
+    gl_Position = uniform1.field2.field3.field4.vector;
+}
+</script>
+<script>
+GLSLConformanceTester.runTest();
+successfullyParsed = true;
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/conformance/glsl/misc/struct-nesting-under-maximum.html
@@ -0,0 +1,44 @@
+<!--
+Copyright (c) 2011 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL GLSL Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../resources/webgl-test-utils.js"></script>
+<script src="../../resources/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertexShader" type="text/something-not-javascript">
+// shader with struct nesting less than maximum in WebGL spec should succeed
+struct nesting3 {
+  vec4 vector;
+};
+
+struct nesting2 {
+  nesting3 field3;
+};
+
+struct nesting1 {
+  nesting2 field2;
+};
+
+uniform nesting1 uniform1;
+void main()
+{
+    gl_Position = uniform1.field2.field3.vector;
+}
+</script>
+<script>
+GLSLConformanceTester.runTest();
+successfullyParsed = true;
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/conformance/glsl/misc/uniform-location-length-limits.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL uniform location length tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../resources/webgl-test.js"> </script>
+<script src="../../resources/webgl-test-utils.js"> </script>
+</head>
+<body>
+<canvas id="example" width="50" height="50">
+There is supposed to be an example drawing here, but it's not important.
+</canvas>
+<div id="description">Verify limits on the lengths of uniform locations per WebGL spec, "Maximum Uniform and Attribute Location Lengths".</div>
+<div id="console"></div>
+<script id="goodVertexShader" type="x-shader/x-vertex">
+// A vertex shader where the needed uniform location is exactly 256 characters.
+struct Nesting2 {
+    vec4 identifier62CharactersLong_01234567890123456789012345678901234;
+};
+
+struct Nesting1 {
+    Nesting2 identifier64CharactersLong_0123456789012345678901234567890123456;
+};
+
+uniform Nesting1 identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789;
+
+void main() {
+    gl_Position = identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.identifier64CharactersLong_0123456789012345678901234567890123456.identifier62CharactersLong_01234567890123456789012345678901234;
+}
+</script>
+<script id="badVertexShader" type="x-shader/x-vertex">
+// A vertex shader where the needed uniform location is 257 characters.
+struct Nesting2 {
+    vec4 identifier63CharactersLong_012345678901234567890123456789012345;
+};
+
+struct Nesting1 {
+    Nesting2 identifier64CharactersLong_0123456789012345678901234567890123456;
+};
+
+uniform Nesting1 identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789;
+
+void main() {
+    Nesting2 temp = identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.identifier64CharactersLong_0123456789012345678901234567890123456;
+    gl_Position = temp.identifier63CharactersLong_012345678901234567890123456789012345;
+}
+</script>
+<script id="fragmentShader" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+if (window.initNonKhronosFramework) {
+    window.initNonKhronosFramework(false);
+}
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(document.getElementById("example"));
+
+debug("Test uniform location underneath the length limit");
+var program = wtu.loadProgramFromScript(gl, "goodVertexShader", "fragmentShader");
+shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
+var uniformLoc = gl.getUniformLocation(program, "identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.identifier64CharactersLong_0123456789012345678901234567890123456.identifier62CharactersLong_01234567890123456789012345678901234");
+shouldBeNonNull('uniformLoc');
+wtu.glErrorShouldBe(gl, gl.NONE);
+
+debug("Test uniform location over the length limit");
+program = wtu.loadProgramFromScript(gl, "badVertexShader", "fragmentShader");
+wtu.glErrorShouldBe(gl, gl.NONE);
+shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
+var uniformLoc = gl.getUniformLocation(program, "identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.identifier64CharactersLong_0123456789012345678901234567890123456.identifier63CharactersLong_012345678901234567890123456789012345");
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
+shouldBeNull('uniformLoc');
+
+successfullyParsed = true;
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/conformance/glsl/samplers/00_test_list.txt
@@ -0,0 +1,4 @@
+glsl-function-texture2d-bias.html
+glsl-function-texture2dlod.html
+glsl-function-texture2dproj.html
+
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/conformance/glsl/samplers/glsl-function-texture2d-bias.html
@@ -0,0 +1,104 @@
+<!--
+Copyright (c) 2011 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+ -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL texture2D GLSL conformance test.</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../resources/webgl-test.js"> </script>
+<script src="../../resources/webgl-test-utils.js"> </script>
+</head>
+<body>
+<canvas id="example" width="256" height="256" style="width: 16px; height: 16px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader2d" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+void main() {
+    gl_Position = vPosition;
+    texCoord = texCoord0;
+}
+</script>
+<script id="fshader2d" type="x-shader/x-vertex">
+precision mediump float;
+uniform sampler2D tex;
+uniform float bias;
+varying vec2 texCoord;
+void main() {
+    gl_FragData[0] = texture2D(tex, texCoord, bias);
+}
+</script>
+<script>
+description("tests GLSL texture2D function with bias");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("example");
+
+shouldBe("canvas.width", "256");
+shouldBe("canvas.height", "256");
+
+var gl = wtu.create3DContext(canvas);
+var program = wtu.setupProgram(
+    gl,
+    [wtu.loadShaderFromScript(gl, 'vshader2d', gl.VERTEX_SHADER),
+     wtu.loadShaderFromScript(gl, 'fshader2d', gl.FRAGMENT_SHADER)],
+    ['vPosition', 'texCoord0'], [0, 1]);
+wtu.setupUnitQuad(gl, 0, 1);
+
+var colors = [
+  {name: 'red', color:[255, 0, 0, 255]},
+  {name: 'green', color:[0, 255, 0, 255]},
+  {name: 'blue', color:[0, 0, 255, 255]},
+  {name: 'yellow', color:[255, 255, 0, 255]},
+  {name: 'magenta', color:[255, 0, 255, 255]},
+  {name: 'cyan', color:[0, 255, 255, 255]},
+  {name: 'pink', color:[255, 128, 128, 255]},
+  {name: 'gray', color:[128, 128, 128, 255]},
+  {name: 'light green', color:[128, 255, 128, 255]},
+];
+
+shouldBe("colors.length", "9");
+
+var tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+gl.texParameteri(
+    gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+
+for (var ii = 0; ii < colors.length; ++ii) {
+  var color = colors[ii];
+  var size = Math.pow(2, colors.length - ii - 1);
+  wtu.fillTexture(gl, tex, size, size, color.color, ii);
+}
+
+var loc = gl.getUniformLocation(program, "bias");
+
+for (var ii = 0; ii < colors.length; ++ii) {
+  gl.uniform1f(loc, ii);
+  var color = colors[ii];
+  wtu.drawQuad(gl);
+  wtu.checkCanvas(
+      gl, color.color,
+      "256x256 texture drawn to 256x256 dest with bias = " + ii +
+      " should be " + color.name);
+}
+glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
+
+successfullyParsed = true;
+
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+
+</body>
+</html>
+
+
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/conformance/glsl/samplers/glsl-function-texture2dlod.html
@@ -0,0 +1,104 @@
+<!--
+Copyright (c) 2011 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+ -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL texture2D GLSL conformance test.</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../resources/webgl-test.js"> </script>
+<script src="../../resources/webgl-test-utils.js"> </script>
+</head>
+<body>
+<canvas id="example" width="256" height="256" style="width: 16px; height: 16px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader2d" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+attribute vec2 texCoord0;
+varying vec4 color;
+uniform sampler2D tex;
+uniform float lod;
+void main() {
+    gl_Position = vPosition;
+    color = texture2DLod(tex, texCoord0, lod);
+}
+</script>
+<script id="fshader2d" type="x-shader/x-vertex">
+precision mediump float;
+varying vec4 color;
+void main() {
+    gl_FragData[0] = color;
+}
+</script>
+<script>
+description("tests GLSL texture2DLod function");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("example");
+
+shouldBe("canvas.width", "256");
+shouldBe("canvas.height", "256");
+
+var gl = wtu.create3DContext(canvas);
+var program = wtu.setupProgram(
+    gl,
+    [wtu.loadShaderFromScript(gl, 'vshader2d', gl.VERTEX_SHADER),
+     wtu.loadShaderFromScript(gl, 'fshader2d', gl.FRAGMENT_SHADER)],
+    ['vPosition', 'texCoord0'], [0, 1]);
+wtu.setupUnitQuad(gl, 0, 1);
+
+var colors = [
+  {name: 'red', color:[255, 0, 0, 255]},
+  {name: 'green', color:[0, 255, 0, 255]},
+  {name: 'blue', color:[0, 0, 255, 255]},
+  {name: 'yellow', color:[255, 255, 0, 255]},
+  {name: 'magenta', color:[255, 0, 255, 255]},
+  {name: 'cyan', color:[0, 255, 255, 255]},
+  {name: 'pink', color:[255, 128, 128, 255]},
+  {name: 'gray', color:[128, 128, 128, 255]},
+  {name: 'light green', color:[128, 255, 128, 255]},
+];
+
+shouldBe("colors.length", "9");
+
+var tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+gl.texParameteri(
+    gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+
+for (var ii = 0; ii < colors.length; ++ii) {
+  var color = colors[ii];
+  var size = Math.pow(2, colors.length - ii - 1);
+  wtu.fillTexture(gl, tex, size, size, color.color, ii);
+}
+
+var loc = gl.getUniformLocation(program, "lod");
+
+for (var ii = 0; ii < colors.length; ++ii) {
+  gl.uniform1f(loc, ii);
+  var color = colors[ii];
+  wtu.drawQuad(gl);
+  wtu.checkCanvas(
+      gl, color.color,
+      "256x256 texture drawn to 256x256 dest with lod = " + ii +
+      " should be " + color.name);
+}
+glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
+
+successfullyParsed = true;
+
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+
+</body>
+</html>
+
+
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/conformance/glsl/samplers/glsl-function-texture2dproj.html
@@ -0,0 +1,120 @@
+<!--
+Copyright (c) 2011 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+ -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL texture2D GLSL conformance test.</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../resources/webgl-test.js"> </script>
+<script src="../../resources/webgl-test-utils.js"> </script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader0" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+void main() {
+    gl_Position = vPosition;
+    texCoord = texCoord0;
+}
+</script>
+<script id="fshader0" type="x-shader/x-vertex">
+precision mediump float;
+uniform sampler2D tex;
+uniform float divisor;
+varying vec2 texCoord;
+void main() {
+    gl_FragData[0] = texture2DProj(tex, vec3(texCoord, divisor));
+}
+</script>
+<script id="vshader1" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+void main() {
+    gl_Position = vPosition;
+    texCoord = texCoord0;
+}
+</script>
+<script id="fshader1" type="x-shader/x-vertex">
+precision mediump float;
+uniform sampler2D tex;
+uniform float divisor;
+varying vec2 texCoord;
+void main() {
+    gl_FragData[0] = texture2DProj(tex, vec4(texCoord, 123.0, divisor));
+}
+</script>
+<script>
+description("tests GLSL texture2DProj function with");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("example");
+
+var gl = wtu.create3DContext(canvas, {antialias: false});
+
+wtu.setupUnitQuad(gl, 0, 1);
+var tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+
+var c = document.createElement("canvas");
+c.width = 16;
+c.height = 16;
+var ctx = c.getContext("2d");
+ctx.fillStyle = "rgb(0,255,0)";
+ctx.fillRect(0, 0, 16, 16);
+ctx.fillStyle = "rgb(0,0,255)";
+ctx.fillRect(0, 0, 8, 8);
+ctx.fillRect(8, 8, 8, 8);
+
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);
+
+for (var ss = 0; ss < 2; ++ss) {
+  debug("");
+  debug(ss ? "testing vec4 version" : "testing vec3 version");
+  var program = wtu.setupProgram(
+	  gl,
+	  [wtu.loadShaderFromScript(gl, 'vshader' + ss, gl.VERTEX_SHADER),
+	   wtu.loadShaderFromScript(gl, 'fshader' + ss, gl.FRAGMENT_SHADER)],
+	  ['vPosition', 'texCoord0'], [0, 1]);
+  gl.useProgram(program);
+  var loc = gl.getUniformLocation(program, "divisor");
+
+  for (var ii = 0; ii < 3; ++ii) {
+	var denominator = Math.pow(2, ii);
+	gl.uniform1f(loc, 1 / denominator);
+	wtu.drawQuad(gl);
+	var size = 16 / denominator;
+	for (var yy = 0; yy < 32; yy += size) {
+	  for (var xx = 0; xx < 32; xx += size) {
+		var odd = (xx / size + yy / size) % 2;
+		var color = odd ? [0, 255, 0, 255] : [0, 0, 255, 255];
+		var msg = "" + xx + ", " + yy + ", " + size + ", " + size + " should be " + (odd ? "green" : "blue");
+		wtu.checkCanvasRect(gl, xx, yy, size, size, color, msg);
+	  }
+	}
+  }
+}
+glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
+
+successfullyParsed = true;
+
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+
+</body>
+</html>
+
+
--- a/content/canvas/test/webgl/conformance/glsl/variables/gl-fragcoord.html
+++ b/content/canvas/test/webgl/conformance/glsl/variables/gl-fragcoord.html
@@ -40,16 +40,18 @@ found in the LICENSE file.
 
   <script>
     function init()
     {
       if (window.initNonKhronosFramework) {
         window.initNonKhronosFramework(false);
       }
 
+      description("tests gl_FragCoord");
+
       wtu = WebGLTestUtils;
       gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
 
       var vertexObject = gl.createBuffer();
       gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
       gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(
         [-1, -1, -1,  1, -1,  0, -1,  1,  0,
          -1,  1,  0,  1, -1,  0,  1,  1,  1]),
--- a/content/canvas/test/webgl/conformance/glsl/variables/gl-frontfacing.html
+++ b/content/canvas/test/webgl/conformance/glsl/variables/gl-frontfacing.html
@@ -40,16 +40,18 @@ found in the LICENSE file.
 
   <script>
     function init()
     {
       if (window.initNonKhronosFramework) {
         window.initNonKhronosFramework(false);
       }
 
+      description("tests gl_FrontFacing");
+
       wtu = WebGLTestUtils;
       gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
 
       var gridRes = 4;
       wtu.setupQuad(gl, gridRes, 0, true);
 
       gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
       gl.drawElements(gl.TRIANGLES, gridRes * gridRes * 6, gl.UNSIGNED_SHORT, 0);
--- a/content/canvas/test/webgl/conformance/limits/gl-max-texture-dimensions.html
+++ b/content/canvas/test/webgl/conformance/limits/gl-max-texture-dimensions.html
@@ -33,16 +33,17 @@ precision mediump float;
 uniform samplerCube tex;
 varying vec2 texCoord;
 void main()
 {
     gl_FragColor = textureCube(tex, normalize(vec3(texCoord, 1)));
 }
 </script>
 <script>
+description(document.title);
 var wtu = WebGLTestUtils;
 var canvas = document.getElementById("example");
 var gl = wtu.create3DContext(canvas);
 var program = wtu.setupTexturedQuad(gl);
 
 // Note: It seems like a reasonable assuption that a 1xN texture size should
 // work. Even 1 by 128k is only 512k
 var maxSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
--- a/content/canvas/test/webgl/conformance/limits/gl-min-attribs.html
+++ b/content/canvas/test/webgl/conformance/limits/gl-min-attribs.html
@@ -38,16 +38,17 @@ void main()
 precision mediump float;
 varying vec4 color;
 void main()
 {
     gl_FragColor = color;
 }
 </script>
 <script>
+description(document.title);
 var wtu = WebGLTestUtils;
 var canvas = document.getElementById("example");
 var gl = wtu.create3DContext(canvas);
 var program = wtu.setupTexturedQuad(gl);
 
 var program = wtu.setupProgram(
     gl,
     [wtu.loadShaderFromScript(gl, 'vshader', gl.VERTEX_SHADER),
--- a/content/canvas/test/webgl/conformance/limits/gl-min-textures.html
+++ b/content/canvas/test/webgl/conformance/limits/gl-min-textures.html
@@ -23,27 +23,28 @@ void main()
 {
     gl_Position = vPosition;
 }
 </script>
 
 <script id="fshader" type="x-shader/x-fragment">
 #define NUM_TEXTURES 8 // See spec
 precision mediump float;
-uniform sampler2D uni[8];
+uniform sampler2D uni[NUM_TEXTURES];
 void main()
 {
     vec4 c = vec4(0,0,0,0);
     for (int ii = 0; ii < NUM_TEXTURES; ++ii) {
       c += texture2D(uni[ii], vec2(0.5, 0.5));
     }
     gl_FragColor = c;
 }
 </script>
 <script>
+description(document.title);
 var wtu = WebGLTestUtils;
 var canvas = document.getElementById("example");
 var gl = wtu.create3DContext(canvas);
 var program = wtu.setupTexturedQuad(gl);
 
 //------------------------------------------------------------------------------
 var program = wtu.setupProgram(
     gl,
@@ -57,17 +58,17 @@ for (var ii = 0; ii < 8; ++ii) {
   var tex = gl.createTexture();
   wtu.fillTexture(gl, tex, 1, 1, [32, 16, 8, ii * 9], 0);
   gl.uniform1i(loc, ii);
 }
 
 wtu.drawQuad(gl);
 glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
 wtu.checkCanvas(gl, [255, 128, 64, 252],
-                "Should render using all texture units");
+                "Should render using all texture units", 1);
 
 successfullyParsed = true;
 
 </script>
 <script src="../../resources/js-test-post.js"></script>
 
 </body>
 </html>
--- a/content/canvas/test/webgl/conformance/limits/gl-min-uniforms.html
+++ b/content/canvas/test/webgl/conformance/limits/gl-min-uniforms.html
@@ -58,16 +58,17 @@ void main()
     vec4 c = vec4(0,0,0,0);
     for (int ii = 0; ii < NUM_UNIFORMS; ++ii) {
        c += uni[ii];
     }
     gl_FragColor = vec4(c.r, c.g, c.b, c.a / 120.0);
 }
 </script>
 <script>
+description(document.title);
 var wtu = WebGLTestUtils;
 var canvas = document.getElementById("example");
 var gl = wtu.create3DContext(canvas);
 var program = wtu.setupTexturedQuad(gl);
 
 //------------------------------------------------------------------------------
 var program = wtu.setupProgram(
     gl,
--- a/content/canvas/test/webgl/conformance/misc/instanceof-test.html
+++ b/content/canvas/test/webgl/conformance/misc/instanceof-test.html
@@ -1,91 +1,92 @@
-<!--
-Copyright (c) 2011 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
- -->
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-<title>WebGL instanceof test.</title>
-<link rel="stylesheet" href="../../resources/js-test-style.css"/>
-<script src="../../resources/js-test-pre.js"></script>
-<script src="../resources/webgl-test.js"> </script>
-<script src="../resources/webgl-test-utils.js"> </script>
-</head>
-<body>
-<canvas id="canvas" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
-<div id="description"></div>
-<div id="console"></div>
-<script id="vshader" type="x-shader/x-vertex">
-attribute vec4 vPosition;
-varying vec2 texCoord;
-void main()
-{
-    gl_Position = vPosition;
-}
-</script>
-
-<script id="fshader" type="x-shader/x-fragment">
-precision mediump float;
-uniform vec4 color;
-void main()
-{
-    gl_FragColor = color;
-}
-</script>
-<script>
-var wtu = WebGLTestUtils;
-debug("Tests that instanceof works on WebGL objects.");
-debug("");
-var gl = create3DContext(document.getElementById("canvas"));
-shouldBeTrue('gl instanceof WebGLRenderingContext');
-shouldBeTrue('gl.createBuffer() instanceof WebGLBuffer');
-shouldBeTrue('gl.createFramebuffer() instanceof WebGLFramebuffer');
-shouldBeTrue('gl.createProgram() instanceof WebGLProgram');
-shouldBeTrue('gl.createRenderbuffer() instanceof WebGLRenderbuffer');
-shouldBeTrue('gl.createShader(gl.VERTEX_SHADER) instanceof WebGLShader');
-shouldBeTrue('gl.createTexture() instanceof WebGLTexture');
-
-var program = wtu.setupProgram(
-    gl,
-    [wtu.loadShaderFromScript(gl, 'vshader', gl.VERTEX_SHADER),
-     wtu.loadShaderFromScript(gl, 'fshader', gl.FRAGMENT_SHADER)],
-    ['vPosition'], [0]);
-
-shouldBeTrue('gl.getUniformLocation(program, "color") instanceof WebGLUniformLocation');
-shouldBeTrue('gl.getActiveAttrib(program, 0) instanceof WebGLActiveInfo');
-shouldBeTrue('gl.getActiveUniform(program, 0) instanceof WebGLActiveInfo');
-
-debug("");
-debug("Tests that those WebGL objects can not be constructed through new operator");
-debug("");
-
-function shouldThrowWithNew(objectType, objectName)
-{
-    try {
-        new objectType;
-        testFailed('new ' + objectName + ' did not throw');
-    } catch (e) {
-        testPassed('new ' + objectName + ' threw an error');
-    }
-}
-
-shouldThrowWithNew(WebGLRenderingContext, 'WebGLRenderingContext');
-shouldThrowWithNew(WebGLActiveInfo, 'WebGLActiveInfo');
-shouldThrowWithNew(WebGLBuffer, 'WebGLBuffer');
-shouldThrowWithNew(WebGLFramebuffer, 'WebGLFramebuffer');
-shouldThrowWithNew(WebGLProgram, 'WebGLProgram');
-shouldThrowWithNew(WebGLRenderbuffer, 'WebGLRenderbuffer');
-shouldThrowWithNew(WebGLShader, 'WebGLShader');
-shouldThrowWithNew(WebGLTexture, 'WebGLTexture');
-shouldThrowWithNew(WebGLUniformLocation, 'WebGLUniformLocation');
-
-successfullyParsed = true;
-</script>
-<script src="../../resources/js-test-post.js"></script>
-
-</body>
-</html>
-
-
+<!--
+Copyright (c) 2011 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+ -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL instanceof test.</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"> </script>
+<script src="../resources/webgl-test-utils.js"> </script>
+</head>
+<body>
+<canvas id="canvas" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+varying vec2 texCoord;
+void main()
+{
+    gl_Position = vPosition;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform vec4 color;
+void main()
+{
+    gl_FragColor = color;
+}
+</script>
+<script>
+var wtu = WebGLTestUtils;
+description(document.title);
+debug("Tests that instanceof works on WebGL objects.");
+debug("");
+var gl = create3DContext(document.getElementById("canvas"));
+shouldBeTrue('gl instanceof WebGLRenderingContext');
+shouldBeTrue('gl.createBuffer() instanceof WebGLBuffer');
+shouldBeTrue('gl.createFramebuffer() instanceof WebGLFramebuffer');
+shouldBeTrue('gl.createProgram() instanceof WebGLProgram');
+shouldBeTrue('gl.createRenderbuffer() instanceof WebGLRenderbuffer');
+shouldBeTrue('gl.createShader(gl.VERTEX_SHADER) instanceof WebGLShader');
+shouldBeTrue('gl.createTexture() instanceof WebGLTexture');
+
+var program = wtu.setupProgram(
+    gl,
+    [wtu.loadShaderFromScript(gl, 'vshader', gl.VERTEX_SHADER),
+     wtu.loadShaderFromScript(gl, 'fshader', gl.FRAGMENT_SHADER)],
+    ['vPosition'], [0]);
+
+shouldBeTrue('gl.getUniformLocation(program, "color") instanceof WebGLUniformLocation');
+shouldBeTrue('gl.getActiveAttrib(program, 0) instanceof WebGLActiveInfo');
+shouldBeTrue('gl.getActiveUniform(program, 0) instanceof WebGLActiveInfo');
+
+debug("");
+debug("Tests that those WebGL objects can not be constructed through new operator");
+debug("");
+
+function shouldThrowWithNew(objectType, objectName)
+{
+    try {
+        new objectType;
+        testFailed('new ' + objectName + ' did not throw');
+    } catch (e) {
+        testPassed('new ' + objectName + ' threw an error');
+    }
+}
+
+shouldThrowWithNew(WebGLRenderingContext, 'WebGLRenderingContext');
+shouldThrowWithNew(WebGLActiveInfo, 'WebGLActiveInfo');
+shouldThrowWithNew(WebGLBuffer, 'WebGLBuffer');
+shouldThrowWithNew(WebGLFramebuffer, 'WebGLFramebuffer');
+shouldThrowWithNew(WebGLProgram, 'WebGLProgram');
+shouldThrowWithNew(WebGLRenderbuffer, 'WebGLRenderbuffer');
+shouldThrowWithNew(WebGLShader, 'WebGLShader');
+shouldThrowWithNew(WebGLTexture, 'WebGLTexture');
+shouldThrowWithNew(WebGLUniformLocation, 'WebGLUniformLocation');
+
+successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
+
+
--- a/content/canvas/test/webgl/conformance/renderbuffers/framebuffer-object-attachment.html
+++ b/content/canvas/test/webgl/conformance/renderbuffers/framebuffer-object-attachment.html
@@ -5,23 +5,24 @@ found in the LICENSE file.
  -->
 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="utf-8">
 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
 <script src="../../resources/js-test-pre.js"></script>
 <script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
 </head>
 <body>
 <div id="description"></div>
 <div id="console"></div>
 
 <script>
-
+var wtu = WebGLTestUtils;
 var gl;
 var fbo;
 var depthBuffer;
 var stencilBuffer;
 var depthStencilBuffer;
 var colorBuffer;
 var width;
 var height;
@@ -106,16 +107,17 @@ function testDepthStencilRenderbuffer()
 }
 
 description("Test framebuffer object attachment behaviors");
 
 for (width = 0; width <= 2; width += 2)
 {
     for (height = 0; height <= 2; height += 2)
     {
+        debug("");
         debug("Dimensions " + width + " x " + height);
 
         debug("Create renderbuffers");
         shouldBeNonNull("gl = create3DContext()");
         shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
         gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
         gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, width, height);
         glErrorShouldBe(gl, gl.NO_ERROR);
@@ -173,14 +175,217 @@ for (width = 0; width <= 2; width += 2)
         debug("Attach color renderbuffer with internalformat == RGB565");
         testColorRenderbuffer(gl.RGB565);
 
         debug("Create and attach depthStencil renderbuffer");
         testDepthStencilRenderbuffer();
     }
 }
 
+// Determine if we can attach both color and depth or color and depth_stencil
+var depthFormat;
+var depthAttachment;
+
+function checkValidColorDepthCombination() {
+    shouldBeNonNull("fbo = gl.createFramebuffer()");
+    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+    shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
+    gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+    gl.framebufferRenderbuffer(
+        gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
+    gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
+
+    shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
+    gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
+
+    return tryDepth(gl.DEPTH_COMPONENT16, gl.DEPTH_ATTACHMENT) || tryDepth(gl.DEPTH_STENCIL, gl.DEPTH_STENCIL_ATTACHMENT);
+
+    function tryDepth(try_format, try_attachment) {
+        if (depthAttachment) {
+            // If we've tried once unattach the old one.
+            gl.framebufferRenderbuffer(
+                gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, null);
+        }
+        depthFormat = try_format;
+        depthAttachment = try_attachment;
+        gl.framebufferRenderbuffer(
+            gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer);
+        gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
+        glErrorShouldBe(gl, gl.NO_ERROR);
+        return gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE;
+    }
+}
+
+if (checkValidColorDepthCombination()) {
+    testFramebufferIncompleteDimensions();
+    testFramebufferIncompleteAttachment();
+    testFramebufferIncompleteMissingAttachment();
+    testUsingIncompleteFramebuffer();
+}
+
+function CheckFramebuffer(expected) {
+    var actual = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+    var msg = "gl.checkFramebufferStatus(gl.FRAMEBUFFER) should be " + wtu.glEnumToString(gl, expected) + " was " + wtu.glEnumToString(gl, actual);
+    if (expected != gl.FRAMEBUFFER_COMPLETE) {
+        msg += " or FRAMEBUFFER_UNSUPPORTED";
+    }
+    if (actual == expected ||
+        (expected != gl.FRAMEBUFFER_COMPLETE &&
+         actual == gl.FRAMBUFFER_UNSUPPORTED)) {
+        testPassed(msg);
+    } else {
+        testFailed(msg);
+    }
+}
+
+function testUsingIncompleteFramebuffer() {
+    debug("");
+    debug("Test drawing or reading from an incomplete framebuffer");
+    var program = wtu.setupTexturedQuad(gl);
+    var tex = gl.createTexture();
+    wtu.fillTexture(gl, tex, 1, 1, [0,255,0,255]);
+
+    shouldBeNonNull("fbo = gl.createFramebuffer()");
+    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+    shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
+    gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+    gl.framebufferRenderbuffer(
+        gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
+    gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
+
+    shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
+    gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
+    gl.framebufferRenderbuffer(
+        gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer);
+    gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
+    glErrorShouldBe(gl, gl.NO_ERROR);
+    CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
+
+    // We pick this combination because it works on desktop OpenGL but should not work on OpenGL ES 2.0
+    gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 32, 16);
+    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
+    debug("");
+    debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
+    testRenderingAndReading();
+
+    shouldBeNonNull("fbo = gl.createFramebuffer()");
+    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
+    debug("");
+    debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
+    testRenderingAndReading();
+
+    function testRenderingAndReading() {
+        glErrorShouldBe(gl, gl.NO_ERROR);
+        wtu.drawQuad(gl);
+        glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "drawArrays with incomplete framebuffer");
+        gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));
+        glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "readPixels from incomplete framebuffer");
+        gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
+        glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D from incomplete framebuffer");
+        gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 1, 1, 0);
+        glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D from incomplete framebuffer");
+        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+        glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "clear with incomplete framebuffer");
+    }
+}
+
+function testFramebufferIncompleteAttachment() {
+    shouldBeNonNull("fbo = gl.createFramebuffer()");
+    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+    shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
+    gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+    gl.framebufferRenderbuffer(
+        gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
+    gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
+    CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
+
+    debug("");
+    debug("Wrong storage type for type of attachment be FRAMEBUFFER_INCOMPLETE_ATTACHMENT (OpenGL ES 2.0 4.4.5)");
+    gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
+    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
+
+    gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
+    CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
+
+    debug("");
+    debug("0 size attachment should be FRAMEBUFFER_INCOMPLETE_ATTACHMENT (OpenGL ES 2.0 4.4.5)");
+    gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0);
+    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
+
+    glErrorShouldBe(gl, gl.NO_ERROR);
+}
+
+function testFramebufferIncompleteMissingAttachment() {
+    debug("");
+    debug("No attachments should be INCOMPLETE_FRAMEBUFFER_MISSING_ATTACHMENT (OpenGL ES 2.0 4.4.5)");
+    shouldBeNonNull("fbo = gl.createFramebuffer()");
+    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
+
+    shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
+    gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+    gl.framebufferRenderbuffer(
+        gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
+    gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
+    CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
+
+    gl.framebufferRenderbuffer(
+        gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
+
+    glErrorShouldBe(gl, gl.NO_ERROR);
+}
+
+function testFramebufferIncompleteDimensions() {
+    debug("");
+    debug("Attachments of different sizes should be FRAMEBUFFER_INCOMPLETE_DIMENSIONS (OpenGL ES 2.0 4.4.5)");
+
+    shouldBeNonNull("fbo = gl.createFramebuffer()");
+    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+    shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
+    gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+    gl.framebufferRenderbuffer(
+        gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
+    gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
+
+    shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
+    gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
+    gl.framebufferRenderbuffer(
+        gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer);
+    gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
+    glErrorShouldBe(gl, gl.NO_ERROR);
+    CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
+
+    gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 32, 16);
+    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
+    gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
+    CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
+    gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+    gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 32);
+    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
+    gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
+    CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
+    glErrorShouldBe(gl, gl.NO_ERROR);
+
+    var tex = gl.createTexture();
+    gl.bindTexture(gl.TEXTURE_2D, tex);
+    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+    glErrorShouldBe(gl, gl.NO_ERROR);
+    if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+        return;
+    }
+
+    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
+    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+    CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
+
+    glErrorShouldBe(gl, gl.NO_ERROR);
+}
+
 successfullyParsed = true;
 </script>
 
 <script src="../../resources/js-test-post.js"></script>
 </body>
 </html>
--- a/content/canvas/test/webgl/conformance/renderbuffers/framebuffer-test.html
+++ b/content/canvas/test/webgl/conformance/renderbuffers/framebuffer-test.html
@@ -6,16 +6,17 @@ found in the LICENSE file.
 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="utf-8">
 <title>WebGL Framebuffer Test</title>
 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
 <script src="../../resources/js-test-pre.js"></script>
 <script src="../resources/webgl-test.js"></script>
+<script src="../../resources/desktop-gl-constants.js"></script>
 </head>
 <body>
 <div id="description"></div>
 <div id="console"></div>
 <canvas id="canvas" width="2" height="2"> </canvas>
 <script>
 description("This tests framebuffer/renderbuffer-related functions");
 
@@ -92,17 +93,17 @@ if (!gl) {
   gl.bindTexture(gl.TEXTURE_2D, fbtex);
   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, canvas.width, canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
   var fb = gl.createFramebuffer();
 
   gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
   glErrorShouldBe(gl, gl.NO_ERROR,
             "binding a newly created framebuffer should succeed.");
 
-  var target = 0x8CA8; // GL_READ_FRAMEBUFFER
+  var target = desktopGL.READ_FRAMEBUFFER
   gl.getFramebufferAttachmentParameter(
      target,
      gl.COLOR_ATTACHMENT0,
      gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
   glErrorShouldBe(gl, gl.INVALID_ENUM,
             "calling getFramebufferAttachmentParameter with target = READ_FRAMEBUFFER should generate INVALID_ENUM.");
   assertMsg(gl.checkFramebufferStatus(target) == 0,
             "calling checkFramebufferStatus with target = READ_FRAMEBUFFER should return 0.");
@@ -118,27 +119,27 @@ if (!gl) {
             "calling getFramebufferAttachmentParameter with target = READ_FRAMEBUFFER should generate INVALID_ENUM.");
   gl.framebufferTexture2D(target, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbtex, 0);
   glErrorShouldBe(gl, gl.INVALID_ENUM,
             "calling framebufferTexImage2D with target = READ_FRAMEBUFFER should generate INVALID_ENUM.");
   gl.framebufferRenderbuffer(target, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
   glErrorShouldBe(gl, gl.INVALID_ENUM,
             "calling framebufferRenderbuffer with target = READ_FRAMEBUFFER should generate INVALID_ENUM.");
 
-  var attachment = 0x8CE1; // GL_COLOR_ATTACHMENT1
+  var attachment = desktopGL.COLOR_ATTACHMENT1
   gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, fbtex, 0);
   glErrorShouldBe(gl, gl.INVALID_ENUM,
             "calling framebufferTexImage2D with attachment = COLOR_ATTACHMENT1 should generate INVALID_ENUM.");
   gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, rb);
   glErrorShouldBe(gl, gl.INVALID_ENUM,
             "calling framebufferRenderbuffer with attachment = COLOR_ATTACHMENT1 should generate INVALID_ENUM.");
 
   gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER,
                                        gl.COLOR_ATTACHMENT0,
-                                       0x8210); // GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
+                                       desktopGL.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
   glErrorShouldBe(gl, gl.INVALID_ENUM,
             "calling getFramebufferAttachmentParameter with pname = GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING should generate INVALID_ENUM.");
 
   gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbtex, 0);
   glErrorShouldBe(gl, gl.NO_ERROR,
             "attaching a texture to a framebuffer should succeed.");
 
   gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
--- a/content/canvas/test/webgl/conformance/rendering/gl-drawelements.html
+++ b/content/canvas/test/webgl/conformance/rendering/gl-drawelements.html
@@ -34,16 +34,18 @@ found in the LICENSE file.
 
     <script>
         function init()
         {
             if (window.initNonKhronosFramework) {
                 window.initNonKhronosFramework(false);
             }
 
+            description(document.title);
+
             function checkDrawElements(mode, count, type, expect, msg) {
               gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
               gl.drawElements(mode, count, type, 0);
               glErrorShouldBe(gl, expect, msg);
             }
 
             gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
 
--- a/content/canvas/test/webgl/conformance/rendering/triangle.html
+++ b/content/canvas/test/webgl/conformance/rendering/triangle.html
@@ -67,16 +67,18 @@ There is supposed to be an example drawi
         }
 
         function init()
         {
             if (window.initNonKhronosFramework) {
                 window.initNonKhronosFramework(false);
             }
 
+            description(document.title);
+
             gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
 
             var vertexObject = gl.createBuffer();
             gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
             gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW);
             gl.enableVertexAttribArray(0);
             gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
 
--- a/content/canvas/test/webgl/conformance/resources/webgl-test-utils.js
+++ b/content/canvas/test/webgl/conformance/resources/webgl-test-utils.js
@@ -586,18 +586,16 @@ var linkProgram = function(gl, program, 
   var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
   if (!linked) {
     // something went wrong with the link
     var error = gl.getProgramInfoLog (program);
 
     testFailed("Error in program linking:" + error);
 
     gl.deleteProgram(program);
-    //gl.deleteProgram(fragmentShader);
-    //gl.deleteProgram(vertexShader);
   }
 };
 
 /**
  * Sets up WebGL with shaders.
  * @param {string} canvasName The id of the canvas.
  * @param {string} vshader The id of the script tag that contains the vertex
  *     shader source.
--- a/content/canvas/test/webgl/conformance/textures/gl-pixelstorei.html
+++ b/content/canvas/test/webgl/conformance/textures/gl-pixelstorei.html
@@ -41,22 +41,21 @@ function fail(x,y, name, buf, shouldBe) 
   testFailed(reason);
 }
 
 function pass(name) {
   testPassed("drawing is correct in " + name);
 }
 
 function init() {
+  description("This test checks that drawImage and readPixels are not effected by gl.Pixelstorei(gl.PACK_ALIGNMENT) and visa versa");
+
   debug("There should be 5 red triangles on 5 black squares above");
   debug("");
 
-  debug("This test checks that drawImage and readPixels are not effected by gl.Pixelstorei(gl.PACK_ALIGNMENT) and visa versa");
-  debug("");
-
   var canvas3d = document.getElementById("example");
   gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
 
   var vertexObject = gl.createBuffer();
   gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
   gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW);
   gl.enableVertexAttribArray(0);
   gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
--- a/content/canvas/test/webgl/conformance/textures/texparameter-test.html
+++ b/content/canvas/test/webgl/conformance/textures/texparameter-test.html
@@ -42,17 +42,17 @@ void main()
 
 <script>
 function init()
 {
   if (window.initNonKhronosFramework) {
     window.initNonKhronosFramework(false);
   }
 
-  debug("Tests TexParameter works as expected");
+  description("Tests TexParameter works as expected");
   debug("");
 
   var canvas2d = document.getElementById("canvas2d");
   var ctx2d = canvas2d.getContext("2d");
 
   gl = initWebGL("example", "vshader", "fshader", [ "vPosition", "texCoord0"],
                  [ 0, 0, 0, 1 ], 1);
 
--- a/content/canvas/test/webgl/conformance/textures/texture-active-bind-2.html
+++ b/content/canvas/test/webgl/conformance/textures/texture-active-bind-2.html
@@ -50,20 +50,20 @@ void main()
 
 <script>
 function init()
 {
   if (window.initNonKhronosFramework) {
     window.initNonKhronosFramework(false);
   }
 
-  debug("Tests that binding both TEXTURE_2D and TEXTURE_CUBE_MAP to the same");
-  debug("active texture unit works as long as they are not used");
-  debug("simultaneously in the same shader program.");
-  debug("");
+  description(
+      "Tests that binding both TEXTURE_2D and TEXTURE_CUBE_MAP to the same" +
+      "active texture unit works as long as they are not used" +
+      "simultaneously in the same shader program.");
 
   var canvas2d = document.getElementById("canvas2d");
   var ctx2d = canvas2d.getContext("2d");
   ctx2d.globalCompositeOperation = "copy";
 
   gl = initWebGL("example", "vshader", "fshader2d", ["vPosition", "texCoord0"],
                  [ 0, 0, 0, 1 ], 1);
 
--- a/content/canvas/test/webgl/conformance/textures/texture-active-bind.html
+++ b/content/canvas/test/webgl/conformance/textures/texture-active-bind.html
@@ -33,19 +33,19 @@ void main()
 var gl;
 
 function init()
 {
   if (window.initNonKhronosFramework) {
     window.initNonKhronosFramework(false);
   }
 
-  debug("Tests that glActiveTexture and glBindTexture work as expected");
-  debug("Specifically texture targets are per active texture unit.");
-  debug("");
+  description(
+      "Tests that glActiveTexture and glBindTexture work as expected" +
+      "Specifically texture targets are per active texture unit.");
 
   var canvas2d = document.getElementById("canvas2d");
   var ctx2d = canvas2d.getContext("2d");
 
   var wtu = WebGLTestUtils;
   var canvas = document.getElementById("example");
   gl = wtu.create3DContext(canvas);
   var program = wtu.setupProgram(
--- a/content/canvas/test/webgl/conformance/textures/texture-complete.html
+++ b/content/canvas/test/webgl/conformance/textures/texture-complete.html
@@ -20,19 +20,19 @@ found in the LICENSE file.
 <div id="console"></div>
 <script>
 function init()
 {
   if (window.initNonKhronosFramework) {
     window.initNonKhronosFramework(false);
   }
 
-  debug("Checks that a texture that is not -texture-complete- does not draw if"+
-        " filtering needs mips");
-  debug("");
+  description(
+      "Checks that a texture that is not -texture-complete- does not draw if"+
+      " filtering needs mips");
 
   var canvas2d = document.getElementById("canvas2d");
   var ctx2d = canvas2d.getContext("2d");
   ctx2d.fillStyle = "rgba(0,192,128,1)";
   ctx2d.fillRect(0, 0, 16, 16);
 
   var wtu = WebGLTestUtils;
   var canvas = document.getElementById("example");
--- a/content/canvas/test/webgl/conformance/textures/texture-mips.html
+++ b/content/canvas/test/webgl/conformance/textures/texture-mips.html
@@ -42,18 +42,17 @@ void main()
 var canvas;
 var wtu = WebGLTestUtils;
 function init()
 {
   if (window.initNonKhronosFramework) {
     window.initNonKhronosFramework(false);
   }
 
-  debug("Checks mip issues");
-  debug("");
+  description("Checks mip issues");
 
   canvas = document.getElementById("example");
   shouldBe("canvas.width", "2");
   shouldBe("canvas.height", "2");
 
   gl = wtu.create3DContext(canvas);
   wtu.setupUnitQuad(gl, 0, 1);
   var program = wtu.setupProgram(
--- a/content/canvas/test/webgl/conformance/textures/texture-npot.html
+++ b/content/canvas/test/webgl/conformance/textures/texture-npot.html
@@ -33,16 +33,17 @@ precision mediump float;
 uniform samplerCube tex;
 varying vec2 texCoord;
 void main()
 {
     gl_FragColor = textureCube(tex, normalize(vec3(texCoord, 1)));
 }
 </script>
 <script>
+description(document.title);
 var wtu = WebGLTestUtils;
 var canvas = document.getElementById("example");
 var gl = wtu.create3DContext(canvas);
 var program = wtu.setupTexturedQuad(gl);
 
 glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
 
 var tex = gl.createTexture();
--- a/content/canvas/test/webgl/conformance/uniforms/uniform-samplers-test.html
+++ b/content/canvas/test/webgl/conformance/uniforms/uniform-samplers-test.html
@@ -20,19 +20,19 @@ found in the LICENSE file.
 
   <script>
 function init()
 {
   if (window.initNonKhronosFramework) {
     window.initNonKhronosFramework(false);
   }
 
-  debug("Tests that only Uniform1i and Uniform1iv can be used to set");
-  debug("sampler uniforms.");
-  debug("");
+  description(
+      "Tests that only Uniform1i and Uniform1iv can be used to set" +
+      "sampler uniforms.");
 
   var canvas2d = document.getElementById("canvas2d");
 
   var wtu = WebGLTestUtils;
   var canvas = document.getElementById("example");
   gl = wtu.create3DContext(canvas);
   var program = wtu.setupTexturedQuad(gl);
 
--- a/content/canvas/test/webgl/failing_tests_linux.txt
+++ b/content/canvas/test/webgl/failing_tests_linux.txt
@@ -3,8 +3,12 @@ conformance/glsl/misc/glsl-long-variable
 conformance/glsl/misc/shader-with-256-character-identifier.frag.html
 conformance/glsl/misc/shader-with-long-line.html
 conformance/misc/uninitialized-test.html
 conformance/programs/gl-get-active-attribute.html
 conformance/textures/texture-mips.html
 conformance/uniforms/gl-uniform-bool.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/more/functions/uniformfArrayLen1.html
+conformance/glsl/misc/attrib-location-length-limits.html
+conformance/glsl/misc/struct-nesting-exceeds-maximum.html
+conformance/glsl/misc/uniform-location-length-limits.html
+conformance/renderbuffers/framebuffer-object-attachment.html
--- a/content/canvas/test/webgl/failing_tests_mac.txt
+++ b/content/canvas/test/webgl/failing_tests_mac.txt
@@ -5,8 +5,12 @@ conformance/glsl/misc/shader-with-256-ch
 conformance/glsl/misc/shader-with-long-line.html
 conformance/programs/program-test.html
 conformance/state/gl-object-get-calls.html
 conformance/textures/texture-mips.html
 conformance/textures/texture-npot.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/more/functions/uniformfBadArgs.html
 conformance/more/functions/uniformiBadArgs.html
+conformance/glsl/misc/attrib-location-length-limits.html
+conformance/glsl/misc/struct-nesting-exceeds-maximum.html
+conformance/glsl/misc/uniform-location-length-limits.html
+conformance/renderbuffers/framebuffer-object-attachment.html
--- a/content/canvas/test/webgl/failing_tests_windows.txt
+++ b/content/canvas/test/webgl/failing_tests_windows.txt
@@ -2,8 +2,14 @@ conformance/context/premultiplyalpha-tes
 conformance/glsl/functions/glsl-function-atan.html
 conformance/glsl/functions/glsl-function-atan-xy.html
 conformance/glsl/functions/glsl-function-mod-gentype.html
 conformance/glsl/misc/glsl-long-variable-names.html
 conformance/glsl/misc/shader-with-256-character-identifier.frag.html
 conformance/glsl/misc/shader-with-long-line.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/more/functions/uniformfArrayLen1.html
+conformance/glsl/misc/attrib-location-length-limits.html
+conformance/glsl/misc/embedded-struct-definitions-forbidden.html
+conformance/glsl/misc/struct-nesting-exceeds-maximum.html
+conformance/glsl/misc/struct-nesting-under-maximum.html
+conformance/glsl/misc/uniform-location-length-limits.html
+conformance/renderbuffers/framebuffer-object-attachment.html
--- a/content/canvas/test/webgl/test_webgl_conformance_test_suite.html
+++ b/content/canvas/test/webgl/test_webgl_conformance_test_suite.html
@@ -206,20 +206,24 @@ function start() {
     this.currentPage = new Page(this, url, this.resultElem);
     this.resultElem.appendChild(this.currentPage.elem);
     ++this.totalPages;
     this.pagesByURL[url] = this.currentPage;
   };
 
   Reporter.prototype.startPage = function(url) {
     dump('WebGL mochitest: starting page ' + url + '\n');
-    if (kIsLinux) {
-      dump('Calling garbageCollect()\n');
-      SpecialPowers.DOMWindowUtils.garbageCollect();
-    }
+
+    // Calling garbageCollect before each test page fixes intermittent failures with
+    // out-of-memory errors, often failing to create a WebGL context.
+    // The explanation is that the JS engine keeps unreferenced WebGL contexts around
+    // for too long before GCing (bug 617453), so that during this mochitest dozens of unreferenced
+    // WebGL contexts can accumulate at a given time.
+    SpecialPowers.DOMWindowUtils.garbageCollect();
+
     var page = this.pagesByURL[url];
     this.currentPage = page;
     statusTextNode.textContent = 'Running URL: ' + url;
     expectedtofailTextNode.textContent = testsExpectedToFail.length +
                                          ' test pages are expected to fail out of ' +
                                          this.totalPages;
     ignoredtestsTextNode.textContent = testsToIgnore.length +
                                          ' test pages have their results ignored';
--- a/content/canvas/test/webgl/webgl-conformance-tests.html
+++ b/content/canvas/test/webgl/webgl-conformance-tests.html
@@ -289,16 +289,22 @@ function start() {
       this.contextInfo["VERSION"] = ctx.getParameter(ctx.VERSION);
       this.contextInfo["RENDERER"] = ctx.getParameter(ctx.RENDERER);
       this.contextInfo["RED_BITS"] = ctx.getParameter(ctx.RED_BITS);
       this.contextInfo["GREEN_BITS"] = ctx.getParameter(ctx.GREEN_BITS);
       this.contextInfo["BLUE_BITS"] = ctx.getParameter(ctx.BLUE_BITS);
       this.contextInfo["ALPHA_BITS"] = ctx.getParameter(ctx.ALPHA_BITS);
       this.contextInfo["DEPTH_BITS"] = ctx.getParameter(ctx.DEPTH_BITS);
       this.contextInfo["STENCIL_BITS"] = ctx.getParameter(ctx.STENCIL_BITS);
+
+      var ext = ctx.getExtension("WEBGL_debug_renderer_info");
+      if (ext) {
+        this.contextInfo["UNMASKED_VENDOR"] = ctx.getParameter(ext.UNMASKED_VENDOR_WEBGL);
+        this.contextInfo["UNMASKED_RENDERER"] = ctx.getParameter(ext.UNMASKED_RENDERER_WEBGL);
+      }
     }
   };
 
   Reporter.prototype.runTest = function(url) {
     var page = this.pagesByURL[url];
     page.startPage();
     this.currentPage = page;
     this.iframe.src = url;
@@ -359,16 +365,18 @@ function start() {
       tx += "WebGL Conformance Test Results\n";
       tx += "Version " + CONFORMANCE_TEST_VERSION + "\n";
       tx += "\n";
       tx += "-------------------\n\n";
       tx += "User Agent: " + (navigator.userAgent ? navigator.userAgent : "(navigator.userAgent is null)") + "\n";
       tx += "WebGL VENDOR: " + this.contextInfo["VENDOR"] + "\n";
       tx += "WebGL VERSION: " + this.contextInfo["VERSION"] + "\n";
       tx += "WebGL RENDERER: " + this.contextInfo["RENDERER"] + "\n";
+      tx += "Unmasked VENDOR: " + this.contextInfo["UNMASKED_VENDOR"] + "\n";
+      tx += "Unmasked RENDERER: " + this.contextInfo["UNMASKED_RENDERER"] + "\n";
       tx += "WebGL R/G/B/A/Depth/Stencil bits (default config): " + this.contextInfo["RED_BITS"] + "/" + this.contextInfo["GREEN_BITS"] + "/" + this.contextInfo["BLUE_BITS"] + "/" + this.contextInfo["ALPHA_BITS"] + "/" + this.contextInfo["DEPTH_BITS"] + "/" + this.contextInfo["STENCIL_BITS"] + "\n";
       tx += "\n";
       tx += "-------------------\n\n";
       tx += "Test Summary (" + totalTests + " total tests):\n";
       tx += "Tests PASSED: " + totalSuccessful + "\n";
       tx += "Tests FAILED: " + (totalTests - totalSuccessful) + "\n";
       tx += "Tests TIMED OUT: " + totalTimeouts + "\n";
       tx += "\n";