Bug 713276 - Upgrade WebGL conformance test suite to r16456 - no review
authorBenoit Jacob <bjacob@mozilla.com>
Tue, 03 Jan 2012 12:28:10 -0500
changeset 84922 7f4ccc0e14d32631b78053853bd0ab923fa33657
parent 84921 5bbbb0127380504fccaaacb64e807a74af9cb789
child 84923 df86a9abc6fade2af444c98a51c8479260ebf1e3
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs713276
milestone12.0a1
Bug 713276 - Upgrade WebGL conformance test suite to r16456 - no review No review because this is just syncing us with the upstream, https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/tests/conformance/
content/canvas/test/webgl/README.mozilla
content/canvas/test/webgl/conformance/context/context-lost-restored.html
content/canvas/test/webgl/conformance/context/context-lost.html
content/canvas/test/webgl/conformance/glsl/00_test_list.txt
content/canvas/test/webgl/conformance/misc/00_test_list.txt
content/canvas/test/webgl/conformance/misc/instanceof-test.html
content/canvas/test/webgl/conformance/misc/object-deletion-behaviour.html
content/canvas/test/webgl/conformance/renderbuffers/framebuffer-object-attachment.html
content/canvas/test/webgl/conformance/resources/glsl-generator.js
content/canvas/test/webgl/conformance/resources/webgl-test-utils.js
content/canvas/test/webgl/conformance/textures/gl-teximage.html
content/canvas/test/webgl/dont-load-image-from-internet.patch
content/canvas/test/webgl/extra/out-of-bounds-uniform-array-access.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/log-more-info-about-test-failures.patch
content/canvas/test/webgl/remove-uniqueObjectTest.patch
content/canvas/test/webgl/resources/js-test-pre.js
content/canvas/test/webgl/undo-r15330-async-test-list-loading.patch
--- 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 16237
+This is a local copy of the WebGL conformance suite, SVN revision 16456
 
 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/context/context-lost-restored.html
+++ b/content/canvas/test/webgl/conformance/context/context-lost-restored.html
@@ -6,17 +6,20 @@
 <script src="../../resources/js-test-pre.js"></script>
 <script src="../resources/webgl-test.js"></script>
 <script src="../resources/webgl-test-utils.js"></script>
 <script>
 var wtu = WebGLTestUtils;
 var canvas;
 var gl;
 var shouldGenerateGLError;
-var extension_name = "WEBGL_EXT_lose_context";
+var extensionNames = [
+    "WEBKIT_WEBGL_lose_context",
+    "MOZ_WEBGL_lose_context",
+];
 var extension;
 var bufferObjects;
 var program;
 var texture;
 var texColor = [255, 10, 20, 255];
 var allowRestore;
 var contextLostEventFired;
 var contextRestoredEventFired;
@@ -28,89 +31,86 @@ function init()
     }
 
     description("Tests behavior under a restored context.");
 
     shouldGenerateGLError = wtu.shouldGenerateGLError;
     testLosingContext();
 }
 
-function runTest1()
-{
-    testLosingAndRestoringContext();
-
-    finishTest();
-}
-
 function setupTest()
 {
     canvas = document.createElement("canvas");
     canvas.width = 1;
     canvas.height = 1;
     gl = wtu.create3DContext(canvas);
-    extension = gl.getExtension(extension_name);
+    for (var ii = 0; ii < extensionNames.length; ++ii) {
+        extension = gl.getExtension(extensionNames[ii]);
+        if (extension)
+            break;
+    }
     if (!extension) {
-        debug(extension_name + " extension not found.");
+        debug("Could not find lose_context extension under the following names: " + extensionNames.join(" "));
         return false;
     }
     return true;
 }
 
 function testLosingContext()
 {
     if (!setupTest())
         finishTest();
 
     debug("Test losing a context and inability to restore it.");
 
-    canvas.addEventListener("webglcontextlost", function() {
-       testLostContext();
+    canvas.addEventListener("webglcontextlost", function(e) {
+       testLostContext(e);
        // restore the context after this event has exited.
        setTimeout(function() {
          // we didn't call prevent default so we should not be able to restore the context
          shouldGenerateGLError(gl, gl.INVALID_OPERATION, "extension.restoreContext()");
-         testLosingAndRetoreingContext();
+         testLosingAndRestoringContext();
        }, 1);
     });
     canvas.addEventListener("webglcontextrestored", testShouldNotRestoreContext);
     allowRestore = false;
     contextLostEventFired = false;
     contextRestoredEventFired = false;
 
     testOriginalContext();
     extension.loseContext();
     // The context should be lost immediately.
     shouldBeTrue("gl.isContextLost()");
     shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
     shouldBe("gl.getError()", "gl.NO_ERROR");
     // gl methods should be no-ops
-    shouldGenerateGLError(gl, gl.NO_ERROR, gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP));
+    shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
     // but the event should not have been fired.
     shouldBeFalse("contextLostEventFired");
 }
 
 function testLosingAndRestoringContext()
 {
     if (!setupTest())
         finishTest();
 
     debug("");
     debug("Test losing and restoring a context.");
 
-    canvas.addEventListener("webglcontextlost", function() {
-      testLostContext();
+    canvas.addEventListener("webglcontextlost", function(e) {
+      testLostContext(e);
       // restore the context after this event has exited.
       setTimeout(function() {
         shouldGenerateGLError(gl, gl.NO_ERROR, "extension.restoreContext()");
         // The context should still be lost. It will not get restored until the 
         // webglrestorecontext event is fired.
         shouldBeTrue("gl.isContextLost()");
         shouldBe("gl.getError()", "gl.NO_ERROR");
         // gl methods should still be no-ops
-        shouldGenerateGLError(gl, gl.NO_ERROR, gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP));
+        shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
       }, 1);
     });
     canvas.addEventListener("webglcontextrestored", function() {
       testRestoredContext();
       finishTest();
     });
     allowRestore = true;
     contextLostEventFired = false;
@@ -118,17 +118,17 @@ function testLosingAndRestoringContext()
 
     testOriginalContext();
     extension.loseContext();
     // The context should be lost immediately.
     shouldBeTrue("gl.isContextLost()");
     shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
     shouldBe("gl.getError()", "gl.NO_ERROR");
     // gl methods should be no-ops
-    shouldGenerateGLError(gl, gl.NO_ERROR, gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP));
+    shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
     // but the event should not have been fired.
     shouldBeFalse("contextLostEventFired");
 }
 
 function testRendering()
 {
     gl.clearColor(0, 0, 0, 255);
     gl.colorMask(1, 1, 1, 0);
--- a/content/canvas/test/webgl/conformance/context/context-lost.html
+++ b/content/canvas/test/webgl/conformance/context/context-lost.html
@@ -6,17 +6,21 @@
 <script src="../../resources/js-test-pre.js"></script>
 <script src="../resources/webgl-test.js"></script>
 <script src="../resources/webgl-test-utils.js"></script>
 <script>
 var wtu;
 var canvas;
 var gl;
 var shouldGenerateGLError;
-var extension_name = "WEBGL_EXT_lose_context";
+var extensionNames = [
+    "WEBKIT_WEBGL_lose_context",
+    "MOZ_WEBGL_lose_context",
+];
+var extensionName;
 var extension;
 
 var buffer;
 var framebuffer;
 var program;
 var renderbuffer;
 var shader;
 var texture;
@@ -43,36 +47,42 @@ function init()
     if (window.initNonKhronosFramework) {
         window.initNonKhronosFramework(true);
     }
 
     // call testValidContext() before checking for the extension, because this is where we check
     // for the isContextLost() method, which we want to do regardless of the extension's presence.
     testValidContext();
 
-    extension = gl.getExtension(extension_name);
+    for (var ii = 0; ii < extensionNames.length; ++ii) {
+        extension = gl.getExtension(extensionNames[ii]);
+        if (extension) {
+            extensionName = extensionNames[ii];
+            break;
+        }
+    }
     if (!extension) {
-        debug(extension_name + " extension not found.");
+        debug("Could not find lose_context extension under the following names: " + extensionNames.join(" "));
         finishTest();
-        return;
+        return false;
     }
 
     canvas.addEventListener("webglcontextlost", testLostContext, false);
 
     loseContext();
 }
 
 function loseContext()
 {
     debug("");
     debug("Lose context");
 
     // Note: this will cause the context to be lost, but the
     // webglcontextlost event listener to be queued.
-    shouldGenerateGLError(gl, gl.NO_ERROR, "extension.loseContext()");
+    extension.loseContext();
     debug("");
 }
 
 function testValidContext()
 {
     debug("Test valid context");
 
     shouldBeFalse("gl.isContextLost()");
@@ -278,17 +288,17 @@ function testLostContext()
         "gl.getShaderInfoLog(shader)",
         "gl.getShaderParameter(shader, gl.SHADER_TYPE)",
         "gl.getShaderSource(shader)",
         "gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S)",
         "gl.getUniform(program, uniformLocation)",
         "gl.getUniformLocation(program, 'vPosition')",
         "gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)",
         "gl.getSupportedExtensions()",
-        "gl.getExtension('" + extension_name + "')",
+        "gl.getExtension('" + extensionName + "')",
     ];
     for (var i = 0; i < nullTests.length; ++i) {
         shouldBeNull(nullTests[i]);
     }
 
     // "Is" queries should all return false.
     shouldBeFalse("gl.isBuffer(buffer)");
     shouldBeFalse("gl.isEnabled(gl.BLEND)");
--- a/content/canvas/test/webgl/conformance/glsl/00_test_list.txt
+++ b/content/canvas/test/webgl/conformance/glsl/00_test_list.txt
@@ -1,8 +1,10 @@
 functions/00_test_list.txt
 implicit/00_test_list.txt
+# commented out for version 1.0.1 of the conforamnce tests.
+#matrices/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/misc/00_test_list.txt
+++ b/content/canvas/test/webgl/conformance/misc/00_test_list.txt
@@ -1,11 +1,11 @@
 bad-arguments-test.html
 error-reporting.html
 instanceof-test.html
 invalid-passed-params.html
 is-object.html
 null-object-behaviour.html
 object-deletion-behaviour.html
+#shader-precision-format.html
 type-conversion-test.html
 uninitialized-test.html
 webgl-specific.html
-
--- a/content/canvas/test/webgl/conformance/misc/instanceof-test.html
+++ b/content/canvas/test/webgl/conformance/misc/instanceof-test.html
@@ -76,16 +76,17 @@ shouldThrowWithNew(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');
+shouldThrowWithNew(WebGLShaderPrecisionFormat, 'WebGLShaderPrecisionFormat');
 
 successfullyParsed = true;
 </script>
 <script src="../../resources/js-test-post.js"></script>
 
 </body>
 </html>
 
--- a/content/canvas/test/webgl/conformance/misc/object-deletion-behaviour.html
+++ b/content/canvas/test/webgl/conformance/misc/object-deletion-behaviour.html
@@ -1,10 +1,13 @@
 <!--
-Copyright (c) 2011 The Chromium Authors. All rights reserved.
+Copyright (c) 2011 The Chromium Authors.
+Copyright (c) 2011 Mozilla Foundation.
+
+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">
 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
@@ -27,17 +30,17 @@ debug("");
 debug("shader and program deletion");
 
 var vertexShader = wtu.loadStandardVertexShader(gl);
 assertMsg(vertexShader, "vertex shader loaded");
 var fragmentShader = wtu.loadStandardFragmentShader(gl);
 assertMsg(fragmentShader, "fragment shader loaded");
 
 var program = gl.createProgram();
-shouldBeTrue("program != null");
+shouldBeNonNull("program");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.attachShader(program, vertexShader)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.attachShader(program, fragmentShader)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.linkProgram(program)");
 shouldBeTrue("gl.getProgramParameter(program, gl.LINK_STATUS)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.useProgram(program)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteShader(vertexShader)");
 shouldBeTrue("gl.isShader(vertexShader)");
 shouldBeTrue("gl.getShaderParameter(vertexShader, gl.DELETE_STATUS)");
@@ -52,76 +55,76 @@ shouldBeTrue("gl.getProgramParameter(pro
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.useProgram(null)");
 shouldBeFalse("gl.isProgram(program)");
 shouldBeFalse("gl.isShader(fragmentShader)");
 
 debug("");
 debug("texture deletion");
 
 var fbo = gl.createFramebuffer(), fbo2 = gl.createFramebuffer(), fbo3 = gl.createFramebuffer();
-shouldBeTrue("fbo != null");
-shouldBeTrue("fbo2 != null");
-shouldBeTrue("fbo3 != null");
+shouldBeNonNull("fbo");
+shouldBeNonNull("fbo2");
+shouldBeNonNull("fbo3");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
 
 var tex = gl.createTexture();
-shouldBeTrue("tex != null");
+shouldBeNonNull("tex");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
 shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "tex");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex");
 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.TEXTURE");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)");
 // Deleting a texture bound to the currently-bound fbo is the same as
 // detaching the textue from fbo first, then delete the texture.
 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
 shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
 shouldBeFalse("gl.isTexture(tex)");
 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
 
 var texCubeMap = gl.createTexture();
-shouldBeTrue("texCubeMap != null");
+shouldBeNonNull("texCubeMap");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap)");
 shouldBe("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)", "texCubeMap");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(texCubeMap)");
 shouldBeFalse("gl.isTexture(texCubeMap)");
 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap)");
 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)");
 
 var t = gl.createTexture();
-shouldBeTrue("t != null");
+shouldBeNonNull("t");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(t)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t)");
 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)");
 
 var t2 = gl.createTexture();
-shouldBeTrue("t2 != null");
+shouldBeNonNull("t2");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE0)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t2)");
 shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "t2");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE1)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t2)");
 shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "t2");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(t2)");
 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE0)");
 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
 
 debug("");
 debug("renderbuffer deletion");
 
 var rbo = gl.createRenderbuffer(), rbo2 = gl.createRenderbuffer(), rbo3 = gl.createRenderbuffer();
-shouldBeTrue("rbo != null");
-shouldBeTrue("rbo2 != null");
-shouldBeTrue("rbo3 != null");
+shouldBeNonNull("rbo");
+shouldBeNonNull("rbo2");
+shouldBeNonNull("rbo3");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
 shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
 // Deleting a renderbuffer bound to the currently-bound fbo is the same as
 // detaching the renderbuffer from fbo first, then delete the renderbuffer.
 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
@@ -170,33 +173,33 @@ if (gl.checkFramebufferStatus(gl.FRAMEBU
 debug("");
 debug("renderbuffer attached twice to same framebuffer");
 rbo = gl.createRenderbuffer();
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
-  var rbo2 = gl.createRenderbuffer();
+  rbo2 = gl.createRenderbuffer();
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo2)");
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
   // attach rbo2 at two attachment points incompatible with it
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rbo2)");
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo2)");
-  shouldBeTrue("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) == rbo2");
-  shouldBeTrue("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) == rbo2");
+  shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo2");
+  shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo2");
   // fbo can't be complete as rbo2 is attached at incompatible attachment points
-  shouldBeFalse("gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE");
+  shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
   // now we delete rbo2, which detaches it from the two attachment points where it currently is attached
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo2)");
   shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
   shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
   // we should now be in the same state as before with only rbo attached, so fbo should be complete again
   shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
-  shouldBeTrue("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) == rbo");
+  shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo");
 }
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
 
 
 
 debug("");
 debug("using deleted texture");
@@ -224,17 +227,17 @@ if (gl.checkFramebufferStatus(gl.FRAMEBU
   // Bind backbuffer.
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
   shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
 }
 
 debug("");
 debug("using deleted renderbuffer");
 rbo = gl.createRenderbuffer();
-shouldBeTrue("rbo != null");
+shouldBeNonNull("rbo");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
   shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
@@ -244,119 +247,119 @@ if (gl.checkFramebufferStatus(gl.FRAMEBU
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
   // make fbo green
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
   // delete renderbuffer. It should still be attached to fbo2 though.
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
   // fbo has no attachments
-  shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE");
+  shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
   // Use fbo2 that has deleted rbo.
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
   shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")');
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
   shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,0,255,255], "fbo should be blue")');
-  shouldBeTrue("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) == rbo");
+  shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo");
 
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
   shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
   shouldGenerateGLError(gl, gl.NONE, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)");
-  shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE");
+  shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
   // Bind backbuffer.
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
   shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
 }
 
 debug("");
 debug("using deleted texture");
 tex = gl.createTexture();
-shouldBeTrue("tex != null");
+shouldBeNonNull("tex");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)");
 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
   // make fbo green
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
   // delete texture. It should still be attached to fbo2 though.
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)");
   // fbo has no attachments
-  shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE");
+  shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
   // Use fbo that has deleted texture.
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
-  shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE");
+  shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
   shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,255,0,255], "fbo should be green")');
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
   shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,0,255,255], "fbo should be blue")');
-  shouldBeTrue("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) == tex");
+  shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex");
 
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
   shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
-  shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE");
+  shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
   // Bind backbuffer.
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
   shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
 }
 
 debug("");
 debug("buffer deletion");
 
 var buffer = gl.createBuffer();
-shouldBeTrue("buffer != null");
+shouldBeNonNull("buffer");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)");
 shouldBe("gl.getParameter(gl.ARRAY_BUFFER_BINDING)", "buffer");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(buffer)");
 shouldBeFalse("gl.isBuffer(buffer)");
 shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)");
 shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
 
 var buffer2 = gl.createBuffer();
-shouldBeTrue("buffer2 != null");
+shouldBeNonNull("buffer2");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer2)");
 shouldBe("gl.getParameter(gl.ARRAY_BUFFER_BINDING)", "buffer2");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, null)");
 shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(buffer2)");
 shouldBeFalse("gl.isBuffer(buffer2)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer2)");
 shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
 
 var bufferElement = gl.createBuffer();
-shouldBeTrue("bufferElement != null");
+shouldBeNonNull("bufferElement");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferElement)");
 shouldBe("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)", "bufferElement");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferElement)");
 shouldBeFalse("gl.isBuffer(bufferElement)");
 shouldBeNull("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferElement)");
 shouldBeNull("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)");
 
 var b = gl.createBuffer();
-shouldBeTrue("b != null");
+shouldBeNonNull("b");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b)");
 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW)");
 
 var b1 = gl.createBuffer();
-shouldBeTrue("b1 != null");
+shouldBeNonNull("b1");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b1);");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(1);");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0);");
 var b2 = gl.createBuffer();
-shouldBeTrue("b2 != null");
+shouldBeNonNull("b2");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b2);");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(2);");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(2, 4, gl.FLOAT, false, 0, 0);");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(3);");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(3, 4, gl.FLOAT, false, 0, 0);");
 shouldBe("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b1");
 shouldBe("gl.getVertexAttrib(2, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b2");
 shouldBe("gl.getVertexAttrib(3, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b2");
@@ -379,18 +382,18 @@ shouldGenerateGLError(gl, gl.NO_ERROR, "
 shouldBeNull("gl.getParameter(gl.FRAMEBUFFER_BINDING)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
 shouldBe("gl.getParameter(gl.FRAMEBUFFER_BINDING)", "fbo2");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteFramebuffer(fbo3)");
 shouldBe("gl.getParameter(gl.FRAMEBUFFER_BINDING)", "fbo2");
 
 fbo = gl.createFramebuffer();
 rbo = gl.createRenderbuffer();
-shouldBeTrue("fbo != null");
-shouldBeTrue("rbo != null");
+shouldBeNonNull("fbo");
+shouldBeNonNull("rbo");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
   // set backbuffer to red
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
   shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)");
--- a/content/canvas/test/webgl/conformance/renderbuffers/framebuffer-object-attachment.html
+++ b/content/canvas/test/webgl/conformance/renderbuffers/framebuffer-object-attachment.html
@@ -1,10 +1,13 @@
 <!--
-Copyright (c) 2011 The Chromium Authors. All rights reserved.
+Copyright (c) 2011 The Chromium Authors.
+Copyright (c) 2011 Mozilla Foundation.
+
+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">
 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
@@ -26,17 +29,17 @@ var depthStencilBuffer;
 var colorBuffer;
 var width;
 var height;
 
 const ALLOW_COMPLETE              = 0x01;
 const ALLOW_UNSUPPORTED           = 0x02;
 const ALLOW_INCOMPLETE_ATTACHMENT = 0x04;
 
-function CheckFramebufferForAllowedStatuses(allowedStatuses)
+function checkFramebufferForAllowedStatuses(allowedStatuses)
 {
     // If the framebuffer is in an error state for multiple reasons,
     // we can't guarantee which one will be reported.
     var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
     var statusAllowed = ((allowedStatuses & ALLOW_COMPLETE) && (status == gl.FRAMEBUFFER_COMPLETE)) ||
                         ((allowedStatuses & ALLOW_UNSUPPORTED) && (status == gl.FRAMEBUFFER_UNSUPPORTED)) ||
                         ((allowedStatuses & ALLOW_INCOMPLETE_ATTACHMENT) && (status == gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT));
     var msg = "gl.checkFramebufferStatus(gl.FRAMEBUFFER) returned " + status;
@@ -48,17 +51,17 @@ function CheckFramebufferForAllowedStatu
 
 function testAttachment(attachment, buffer, allowedStatuses)
 {
     shouldBeNonNull("fbo = gl.createFramebuffer()");
     gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
     gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
     gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, buffer);
     glErrorShouldBe(gl, gl.NO_ERROR);
-    CheckFramebufferForAllowedStatuses(allowedStatuses);
+    checkFramebufferForAllowedStatuses(allowedStatuses);
     if ((allowedStatuses & ALLOW_COMPLETE) == 0) {
         gl.clear(gl.COLOR_BUFFER_BIT);
         glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION);
         gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(width * height * 4));
         glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION);
     }
     gl.deleteFramebuffer(fbo);
 }
@@ -67,17 +70,17 @@ function testAttachments(attachment0, bu
 {
     shouldBeNonNull("fbo = gl.createFramebuffer()");
     gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
     gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
     gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment0, gl.RENDERBUFFER, buffer0);
     glErrorShouldBe(gl, gl.NO_ERROR);
     gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment1, gl.RENDERBUFFER, buffer1);
     glErrorShouldBe(gl, gl.NO_ERROR);
-    CheckFramebufferForAllowedStatuses(allowedStatuses);
+    checkFramebufferForAllowedStatuses(allowedStatuses);
     gl.deleteFramebuffer(fbo);
 }
 
 function testColorRenderbuffer(internalformat, allowedStatuses)
 {
     shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
     gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
     gl.renderbufferStorage(gl.RENDERBUFFER, internalformat, width, height);
@@ -233,17 +236,17 @@ function checkValidColorDepthCombination
 
 if (checkValidColorDepthCombination()) {
     testFramebufferIncompleteDimensions();
     testFramebufferIncompleteAttachment();
     testFramebufferIncompleteMissingAttachment();
     testUsingIncompleteFramebuffer();
 }
 
-function CheckFramebuffer(expected) {
+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)) {
@@ -269,28 +272,28 @@ function testUsingIncompleteFramebuffer(
     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);
+    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);
+    checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
     debug("");
     debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
     testRenderingAndReading();
 
     shouldBeNonNull("fbo2 = gl.createFramebuffer()");
     gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2);
-    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
+    checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
     debug("");
     debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
     testRenderingAndReading();
 
     shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
     gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
     gl.framebufferRenderbuffer(
         gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
@@ -320,51 +323,51 @@ function testUsingIncompleteFramebuffer(
 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);
+    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);
+    checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
 
     gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
-    CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
+    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);
+    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);
+    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);
+    checkFramebuffer(gl.FRAMEBUFFER_COMPLETE);
 
     gl.framebufferRenderbuffer(
         gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
-    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
+    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)");
 
@@ -377,42 +380,42 @@ function testFramebufferIncompleteDimens
     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);
+    checkFramebuffer(gl.FRAMEBUFFER_COMPLETE);
 
     gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 32, 16);
-    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
+    checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
     gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
-    CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
+    checkFramebuffer(gl.FRAMEBUFFER_COMPLETE);
     gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
     gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 32);
-    CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
+    checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
     gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
-    CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
+    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);
+    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);
+    checkFramebuffer(gl.FRAMEBUFFER_COMPLETE);
 
     glErrorShouldBe(gl, gl.NO_ERROR);
 }
 
 successfullyParsed = true;
 </script>
 
 <script src="../../resources/js-test-post.js"></script>
--- a/content/canvas/test/webgl/conformance/resources/glsl-generator.js
+++ b/content/canvas/test/webgl/conformance/resources/glsl-generator.js
@@ -127,22 +127,25 @@ var bvecTypes = [
       "      $(func)_base($(baseArgsZ)),",
       "      $(func)_base($(baseArgsW)));",
       "}"].join("\n")
   }
 ];
 
 var replaceRE = /\$\((\w+)\)/g;
 
-var replaceParams = function(str, params) {
+var replaceParams = function(str) {
+  var args = arguments;
   return str.replace(replaceRE, function(str, p1, offset, s) {
-    if (params[p1] === undefined) {
-      throw "unknown string param '" + p1 + "'";
+    for (var ii = 1; ii < args.length; ++ii) {
+      if (args[ii][p1] !== undefined) {
+        return args[ii][p1];
+      }
     }
-    return params[p1];
+    throw "unknown string param '" + p1 + "'";
   });
 };
 
 var generateReferenceShader = function(
     shaderInfo, template, params, typeInfo, test) {
   var input = shaderInfo.input;
   var output = shaderInfo.output;
   var feature = params.feature;
@@ -438,16 +441,243 @@ var runFeatureTest = function(params) {
 
     var img = new Uint8Array(width * height * 4);
     gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, img);
     return img;
   }
 
 };
 
+var runBasicTest = function(params) {
+  if (window.initNonKhronosFramework) {
+    window.initNonKhronosFramework(false);
+  }
+
+  var wtu = WebGLTestUtils;
+  var gridRes = params.gridRes;
+  var vertexTolerance = params.tolerance || 0;
+  var fragmentTolerance = vertexTolerance;
+  if ('fragmentTolerance' in params)
+    fragmentTolerance = params.fragmentTolerance || 0;
+
+  description("Testing : " + document.getElementsByTagName("title")[0].innerText);
+
+  var width = 32;
+  var height = 32;
+
+  var console = document.getElementById("console");
+  var canvas = document.createElement('canvas');
+  canvas.width = width;
+  canvas.height = height;
+  var gl = wtu.create3DContext(canvas);
+  if (!gl) {
+    testFailed("context does not exist");
+    finishTest();
+    return;
+  }
+
+  var canvas2d = document.createElement('canvas');
+  canvas2d.width = width;
+  canvas2d.height = height;
+  var ctx = canvas2d.getContext("2d");
+  var imgData = ctx.getImageData(0, 0, width, height);
+
+  var shaderInfos = [
+    { type: "vertex",
+      input: "color",
+      output: "vColor",
+      vertexShaderTemplate: vertexShaderTemplate,
+      fragmentShaderTemplate: baseFragmentShader,
+      tolerance: vertexTolerance
+    },
+    { type: "fragment",
+      input: "vColor",
+      output: "gl_FragColor",
+      vertexShaderTemplate: baseVertexShader,
+      fragmentShaderTemplate: fragmentShaderTemplate,
+      tolerance: fragmentTolerance
+    }
+  ];
+  for (var ss = 0; ss < shaderInfos.length; ++ss) {
+    var shaderInfo = shaderInfos[ss];
+    var tests = params.tests;
+//    var testTypes = params.emuFuncs || (params.bvecTest ? bvecTypes : types);
+    // Test vertex shaders
+    for (var ii = 0; ii < tests.length; ++ii) {
+      var test = tests[ii];
+      debug("");
+      debug("Testing: " + test.name + " in " + shaderInfo.type + " shader");
+
+      function genShader(shaderInfo, template, shader, subs) {
+        shader = replaceParams(shader, subs, {
+            input: shaderInfo.input,
+            output: shaderInfo.output
+          });
+        shader = replaceParams(template, subs, {
+            test: shader,
+            emu: "",
+            extra: ""
+          });
+        return shader;
+      }
+
+      var referenceVertexShaderSource = genShader(
+          shaderInfo,
+          shaderInfo.vertexShaderTemplate,
+          test.reference.shader,
+          test.reference.subs);
+      var referenceFragmentShaderSource = genShader(
+          shaderInfo,
+          shaderInfo.fragmentShaderTemplate,
+          test.reference.shader,
+          test.reference.subs);
+      var testVertexShaderSource = genShader(
+          shaderInfo,
+          shaderInfo.vertexShaderTemplate,
+          test.test.shader,
+          test.test.subs);
+      var testFragmentShaderSource = genShader(
+          shaderInfo,
+          shaderInfo.fragmentShaderTemplate,
+          test.test.shader,
+          test.test.subs);
+
+      debug("");
+      addShaderSource(
+          "reference vertex shader", referenceVertexShaderSource);
+      addShaderSource(
+          "reference fragment shader", referenceFragmentShaderSource);
+      addShaderSource(
+          "test vertex shader", testVertexShaderSource);
+      addShaderSource(
+          "test fragment shader", testFragmentShaderSource);
+      debug("");
+
+      var refData = draw(
+          canvas, referenceVertexShaderSource, referenceFragmentShaderSource);
+      var refImg = makeImage(canvas);
+      if (ss == 0) {
+        var testData = draw(
+            canvas, testVertexShaderSource, referenceFragmentShaderSource);
+      } else {
+        var testData = draw(
+            canvas, referenceVertexShaderSource, testFragmentShaderSource);
+      }
+      var testImg = makeImage(canvas);
+
+      reportResults(refData, refImg, testData, testImg, shaderInfo.tolerance);
+    }
+  }
+
+  finishTest();
+
+  function addShaderSource(label, source) {
+    var div = document.createElement("div");
+    var s = document.createElement("pre");
+    s.className = "shader-source";
+    s.style.display = "none";
+    var ol = document.createElement("ol");
+    //s.appendChild(document.createTextNode(source));
+    var lines = source.split("\n");
+    for (var ii = 0; ii < lines.length; ++ii) {
+      var line = lines[ii];
+      var li = document.createElement("li");
+      li.appendChild(document.createTextNode(line));
+      ol.appendChild(li);
+    }
+    s.appendChild(ol);
+    var l = document.createElement("a");
+    l.href = "show-shader-source";
+    l.appendChild(document.createTextNode(label));
+    l.addEventListener('click', function(event) {
+        if (event.preventDefault) {
+          event.preventDefault();
+        }
+        s.style.display = (s.style.display == 'none') ? 'block' : 'none';
+        return false;
+      }, false);
+    div.appendChild(l);
+    div.appendChild(s);
+    console.appendChild(div);
+  }
+
+  function reportResults(refData, refImage, testData, testImage, tolerance) {
+    var same = true;
+    for (var yy = 0; yy < height; ++yy) {
+      for (var xx = 0; xx < width; ++xx) {
+        var offset = (yy * width + xx) * 4;
+        var imgOffset = ((height - yy - 1) * width + xx) * 4;
+        imgData.data[imgOffset + 0] = 0;
+        imgData.data[imgOffset + 1] = 0;
+        imgData.data[imgOffset + 2] = 0;
+        imgData.data[imgOffset + 3] = 255;
+        if (Math.abs(refData[offset + 0] - testData[offset + 0]) > tolerance ||
+            Math.abs(refData[offset + 1] - testData[offset + 1]) > tolerance ||
+            Math.abs(refData[offset + 2] - testData[offset + 2]) > tolerance ||
+            Math.abs(refData[offset + 3] - testData[offset + 3]) > tolerance) {
+          imgData.data[imgOffset] = 255;
+          same = false;
+        }
+      }
+    }
+
+    var diffImg = null;
+    if (!same) {
+      ctx.putImageData(imgData, 0, 0);
+      diffImg = makeImage(canvas2d);
+    }
+
+    var div = document.createElement("div");
+    div.className = "testimages";
+    insertImg(div, "ref", refImg);
+    insertImg(div, "test", testImg);
+    if (diffImg) {
+      insertImg(div, "diff", diffImg);
+    }
+    div.appendChild(document.createElement('br'));
+
+    function insertImg(element, caption, img) {
+      var div = document.createElement("div");
+      div.appendChild(img);
+      var label = document.createElement("div");
+      label.appendChild(document.createTextNode(caption));
+      div.appendChild(label);
+      element.appendChild(div);
+    }
+
+    console.appendChild(div);
+
+    if (!same) {
+      testFailed("images are different");
+    } else {
+      testPassed("images are the same");
+    }
+
+    console.appendChild(document.createElement('hr'));
+  }
+
+  function draw(canvas, vsSource, fsSource) {
+    var program = wtu.loadProgram(gl, vsSource, fsSource, testFailed);
+
+    var posLoc = gl.getAttribLocation(program, "aPosition");
+    WebGLTestUtils.setupQuad(gl, gridRes, posLoc);
+
+    gl.useProgram(program);
+    gl.clearColor(0, 0, 1, 1);
+    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+    gl.drawElements(gl.TRIANGLES, gridRes * gridRes * 6, gl.UNSIGNED_SHORT, 0);
+    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors from draw");
+
+    var img = new Uint8Array(width * height * 4);
+    gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, img);
+    return img;
+  }
+
+};
+
 return {
   /**
    * runs a bunch of GLSL tests using the passed in parameters
    * The parameters are:
    *
    * feature:
    *    the name of the function being tested (eg, sin, dot,
    *    normalize)
@@ -502,13 +732,89 @@ return {
    *    Specify a tolerance which only applies to fragment shaders. The 
    *    fragment-only tolerance will override the shared tolerance for 
    *    fragment shaders if both are specified. Fragment shaders usually
    *    use mediump float precision so they sometimes require higher tolerance
    *    than vertex shaders which use highp.
    */
   runFeatureTest: runFeatureTest,
 
+  /*
+   * Runs a bunch of GLSL tests using the passed in parameters
+   *
+   * The parameters are:
+   *
+   * tests:
+   *    Array of tests. For each test the following parameters are expected
+   *
+   *    name:
+   *       some description of the test
+   *    reference:
+   *       parameters for the reference shader (see below)
+   *    test:
+   *       parameters for the test shader (see below)
+   *
+   *    The parameter for the reference and test shaders are
+   *
+   *    shader: the GLSL for the shader
+   *    subs: any substitutions you wish to define for the shader.
+   *
+   *    Each shader is created from a basic template that
+   *    defines an input and an output. You can see the
+   *    templates at the top of this file. The input and output
+   *    change depending on whether or not we are generating
+   *    a vertex or fragment shader.
+   *
+   *    All this code function does is a bunch of string substitutions.
+   *    A substitution is defined by $(name). If name is found in
+   *    the 'subs' parameter it is replaced. 4 special names exist.
+   *
+   *    'input' the input to your GLSL. Always a vec4. All change
+   *    from 0 to 1 over the quad to be drawn.
+   *
+   *    'output' the output color. Also a vec4
+   *
+   *    'emu' a place to insert extra stuff
+   *    'extra' a place to insert extra stuff.
+   *
+   *    You can think of the templates like this
+   *
+   *       $(extra)
+   *       $(emu)
+   *
+   *       void main() {
+   *          // do math to calculate input
+   *          ...
+   *
+   *          $(shader)
+   *       }
+   *
+   *    Your shader first has any subs you provided applied as well
+   *    as 'input' and 'output'
+   *
+   *    It is then inserted into the template which is also provided
+   *    with your subs.
+   *
+   * gridRes: (optional)
+   *    The resolution of the mesh to generate. The default is a
+   *    1x1 grid but many vertex shaders need a higher resolution
+   *    otherwise the only values passed in are the 4 corners
+   *    which often have the same value.
+   *
+   * tolerance: (optional)
+   *    Allow some tolerance in the comparisons. The tolerance is applied to
+   *    both vertex and fragment shaders. The default tolerance is 0, meaning
+   *    the values have to be identical.
+   *
+   * fragmentTolerance: (optional)
+   *    Specify a tolerance which only applies to fragment shaders. The
+   *    fragment-only tolerance will override the shared tolerance for
+   *    fragment shaders if both are specified. Fragment shaders usually
+   *    use mediump float precision so they sometimes require higher tolerance
+   *    than vertex shaders which use highp.
+   */
+  runBasicTest: runBasicTest,
+
   none: false
 };
 
 }());
 
--- a/content/canvas/test/webgl/conformance/resources/webgl-test-utils.js
+++ b/content/canvas/test/webgl/conformance/resources/webgl-test-utils.js
@@ -901,16 +901,27 @@ var loadShader = function(gl, shaderSour
  * @return {!WebGLShader} The created shader.
  */
 var loadShaderFromFile = function(gl, file, type, opt_errorCallback) {
   var shaderSource = readFile(file);
   return loadShader(gl, shaderSource, type, opt_errorCallback);
 };
 
 /**
+ * Gets the content of script.
+ */
+var getScript = function(scriptId) {
+  var shaderScript = document.getElementById(scriptId);
+  if (!shaderScript) {
+    throw("*** Error: unknown script element" + scriptId);
+  }
+  return shaderScript.text;
+};
+
+/**
  * Loads a shader from a script tag.
  * @param {!WebGLContext} gl The WebGLContext to use.
  * @param {string} scriptId The id of the script tag.
  * @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. 
  * @return {!WebGLShader} The created shader.
  */
@@ -1118,16 +1129,17 @@ return {
     create3DContextWithWrapperThatThrowsOnGLError,
   checkCanvas: checkCanvas,
   checkCanvasRect: checkCanvasRect,
   createColoredTexture: createColoredTexture,
   drawQuad: drawQuad,
   endsWith: endsWith,
   getFileListAsync: getFileListAsync,
   getLastError: getLastError,
+  getScript: getScript,
   getUrlArguments: getUrlArguments,
   glEnumToString: glEnumToString,
   glErrorShouldBe: glErrorShouldBe,
   fillTexture: fillTexture,
   loadImageAsync: loadImageAsync,
   loadImagesAsync: loadImagesAsync,
   loadProgram: loadProgram,
   loadProgramFromFile: loadProgramFromFile,
--- a/content/canvas/test/webgl/conformance/textures/gl-teximage.html
+++ b/content/canvas/test/webgl/conformance/textures/gl-teximage.html
@@ -394,16 +394,28 @@ function runTests(imgs) {
   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
                 imgs['../resources/red-indexed.png']);
   glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
   wtu.drawQuad(gl);
   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
   // The image should be red.
   checkPixelRange(buf, middle, center, [ 255, 0, 0, 255 ], 10);
 
+  debug("")
+  debug("check calling texImage2D with NULL clears the texture");
+  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB,
+                imgs['../resources/red-indexed.png'].width,
+                imgs['../resources/red-indexed.png'].height,
+				0, gl.RGB, gl.UNSIGNED_BYTE, null);
+  glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+  wtu.drawQuad(gl);
+  gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+  // The image should be white.
+  checkPixelRange(buf, middle, center, [ 0, 0, 0, 255 ], 10);
+
   debug("");
   successfullyParsed = true;
   shouldBeTrue("successfullyParsed");
   debug('<br /><span class="pass">TEST COMPLETE</span>');
   notifyFinishedToHarness();
 }
 </script>
 </body>
--- a/content/canvas/test/webgl/dont-load-image-from-internet.patch
+++ b/content/canvas/test/webgl/dont-load-image-from-internet.patch
@@ -1,10 +1,10 @@
 # HG changeset patch
-# Parent 9c1a90f789e3d43455cb18a9a911627c80c0d9ac
+# Parent 07fbbfde4173da7d8e513bb2d52ae07e333dbf43
 diff --git a/content/canvas/test/webgl/conformance/more/functions/readPixelsBadArgs.html b/content/canvas/test/webgl/conformance/more/functions/readPixelsBadArgs.html
 --- a/content/canvas/test/webgl/conformance/more/functions/readPixelsBadArgs.html
 +++ b/content/canvas/test/webgl/conformance/more/functions/readPixelsBadArgs.html
 @@ -110,10 +110,10 @@ Tests.testReadPixelsSOPCanvas = function
  
  Tests.endUnit = function(gl) {
  }
  
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/extra/out-of-bounds-uniform-array-access.html
@@ -0,0 +1,109 @@
+<!--
+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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+  "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL ouf of bounds uniform array access.</title>
+<link rel="stylesheet" href="../resources/js-test-style.css"/>
+<script src="../resources/js-test-pre.js"></script>
+<script src="../conformance/resources/webgl-test-utils.js"> </script>
+</head>
+<body style="background: #666;">
+<div id="description"></div>
+<div id="console"></div>
+<div>elem mult: <span id="elemMultDisplay"></span></div>
+<input type="range" id="elemMult" value="4" min="0" max="2048" style="width: 100%;"/>
+<div>line width: <span id="lineWidthDisplay"></span></div>
+<input type="range" id="lineWidth" value="512" min="0" max="2540" style="width: 100%;"/>
+<canvas id="example" width="256" height="256" style="background: black;">
+</canvas>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+varying vec4 v_color;
+uniform float lineWidth;
+uniform int elemMult;
+uniform vec4 someArray[2];
+void main()
+{
+    vec2 texcoord = vec2(vPosition.xy * 0.5 + vec2(0.5, 0.5));
+    int index = int(texcoord.x + texcoord.y * lineWidth) * elemMult;
+    v_color = someArray[index];
+    gl_Position = vPosition;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+varying vec4 v_color;
+void main()
+{
+  gl_FragColor = v_color * vec4(1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0) + vec4(0,0,0,0.5);
+}
+</script>
+<script>
+window.onload = main;
+debug("Tests a WebGL program that accesses out of bounds uniform array elements");
+
+function main() {
+  var wtu = WebGLTestUtils;
+  var canvas = document.getElementById("example");
+
+  var gl = wtu.create3DContext(canvas);
+  var program = wtu.setupProgram(
+      gl,
+      [wtu.loadShaderFromScript(gl, 'vshader', gl.VERTEX_SHADER),
+       wtu.loadShaderFromScript(gl, 'fshader', gl.FRAGMENT_SHADER)],
+      ['vPosition'], [0]);
+  var gridRes = 255;
+  wtu.setupQuad(gl, gridRes, 0);
+  var lineWidthLoc = gl.getUniformLocation(program, "lineWidth");
+  var elemMultLoc = gl.getUniformLocation(program, "elemMult");
+  assertMsg(gl.getError() == gl.NO_ERROR, "Should be no errors from setup.");
+
+  var lineWidth = 512;
+  var lineWidthElem = document.getElementById("lineWidth");
+  var lineWidthDisplayElem = document.getElementById("lineWidthDisplay");
+
+  lineWidthElem.value = lineWidth;
+
+  lineWidthElem.addEventListener('change', function(event) {
+      //console.log(event.target.value);
+      lineWidth = event.target.value;
+      draw();
+    }, false);
+
+  var elemMult = 4;
+  var elemMultElem = document.getElementById("elemMult");
+  var elemMultDisplayElem = document.getElementById("elemMultDisplay");
+
+  elemMultElem.value = elemMult;
+
+  elemMultElem.addEventListener('change', function(event) {
+      //console.log(event.target.value);
+      elemMult = event.target.value;
+      draw();
+    }, false);
+
+  draw();
+
+  function draw() {
+    lineWidthDisplayElem.innerText = lineWidth;
+    elemMultDisplayElem.innerText = elemMult;
+    gl.uniform1f(lineWidthLoc, lineWidth);
+    gl.uniform1i(elemMultLoc, elemMult);
+    gl.drawElements(gl.TRIANGLES, gridRes * gridRes * 6, gl.UNSIGNED_SHORT, 0);
+  }
+
+  successfullyParsed = true;
+}
+
+</script>
+</body>
+</html>
+
+
--- a/content/canvas/test/webgl/failing_tests_linux.txt
+++ b/content/canvas/test/webgl/failing_tests_linux.txt
@@ -1,9 +1,8 @@
-conformance/context/context-lost-restored.html
 conformance/context/premultiplyalpha-test.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/misc/uninitialized-test.html
 conformance/programs/gl-get-active-attribute.html
 conformance/textures/texture-mips.html
 conformance/uniforms/gl-uniform-bool.html
--- a/content/canvas/test/webgl/failing_tests_mac.txt
+++ b/content/canvas/test/webgl/failing_tests_mac.txt
@@ -1,9 +1,8 @@
-conformance/context/context-lost-restored.html
 conformance/context/premultiplyalpha-test.html
 conformance/glsl/misc/glsl-function-nodes.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/uniformfBadArgs.html
 conformance/more/functions/uniformiBadArgs.html
--- a/content/canvas/test/webgl/failing_tests_windows.txt
+++ b/content/canvas/test/webgl/failing_tests_windows.txt
@@ -1,9 +1,8 @@
-conformance/context/context-lost-restored.html
 conformance/context/premultiplyalpha-test.html
 conformance/glsl/functions/glsl-function-atan.html
 conformance/glsl/functions/glsl-function-atan-xy.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
--- a/content/canvas/test/webgl/log-more-info-about-test-failures.patch
+++ b/content/canvas/test/webgl/log-more-info-about-test-failures.patch
@@ -1,10 +1,10 @@
 # HG changeset patch
-# Parent 4ed0bad4933ba69927ee5f75cf67093d3e99566a
+# Parent 1910ae60536dce7272cb0478089bf40806666de8
 diff --git a/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html b/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html
 --- a/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html
 +++ b/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html
 @@ -117,17 +117,18 @@ function init()
      var bufFunction = new Uint8Array(width * height * 4);
      var bufMacro = new Uint8Array(width * height * 4);
  
      if (drawAndRead("canvasFunction", "vshaderFunction", bufFunction) == false ||
--- a/content/canvas/test/webgl/remove-uniqueObjectTest.patch
+++ b/content/canvas/test/webgl/remove-uniqueObjectTest.patch
@@ -1,10 +1,10 @@
 # HG changeset patch
-# Parent bf9d7872738cdb7cf425e6dd060ae62882487e1a
+# Parent a41d853e5110aca4f2c77c63db502f670d0e50a1
 diff --git a/content/canvas/test/webgl/conformance/extensions/oes-standard-derivatives.html b/content/canvas/test/webgl/conformance/extensions/oes-standard-derivatives.html
 --- a/content/canvas/test/webgl/conformance/extensions/oes-standard-derivatives.html
 +++ b/content/canvas/test/webgl/conformance/extensions/oes-standard-derivatives.html
 @@ -107,17 +107,18 @@ if (!gl) {
      } else {
          testPassed("Successfully enabled OES_standard_derivatives extension");
  
          runSupportedTest(true);
--- a/content/canvas/test/webgl/resources/js-test-pre.js
+++ b/content/canvas/test/webgl/resources/js-test-pre.js
@@ -212,37 +212,62 @@ function evalAndLog(_a)
   try {
      _av = eval(_a);
   } catch (e) {
     testFailed(_a + " threw exception " + e);
   }
   return _av;
 }
 
-function shouldBe(_a, _b)
+function shouldBe(_a, _b, quiet)
 {
-  if (typeof _a != "string" || typeof _b != "string")
-    debug("WARN: shouldBe() expects string arguments");
-  var exception;
-  var _av;
-  try {
-     _av = eval(_a);
-  } catch (e) {
-     exception = e;
-  }
-  var _bv = eval(_b);
+    if (typeof _a != "string" || typeof _b != "string")
+        debug("WARN: shouldBe() expects string arguments");
+    var exception;
+    var _av;
+    try {
+        _av = eval(_a);
+    } catch (e) {
+        exception = e;
+    }
+    var _bv = eval(_b);
 
-  if (exception)
-    testFailed(_a + " should be " + _bv + ". Threw exception " + exception);
-  else if (isResultCorrect(_av, _bv))
-    testPassed(_a + " is " + _b);
-  else if (typeof(_av) == typeof(_bv))
-    testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + ".");
-  else
-    testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
+    if (exception)
+        testFailed(_a + " should be " + _bv + ". Threw exception " + exception);
+    else if (isResultCorrect(_av, _bv)) {
+        if (!quiet) {
+            testPassed(_a + " is " + _b);
+        }
+    } else if (typeof(_av) == typeof(_bv))
+        testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + ".");
+    else
+        testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
+}
+
+function shouldNotBe(_a, _b, quiet)
+{
+    if (typeof _a != "string" || typeof _b != "string")
+        debug("WARN: shouldNotBe() expects string arguments");
+    var exception;
+    var _av;
+    try {
+        _av = eval(_a);
+    } catch (e) {
+        exception = e;
+    }
+    var _bv = eval(_b);
+
+    if (exception)
+        testFailed(_a + " should not be " + _bv + ". Threw exception " + exception);
+    else if (!isResultCorrect(_av, _bv)) {
+        if (!quiet) {
+            testPassed(_a + " is not " + _b);
+        }
+    } else
+        testFailed(_a + " should not be " + _bv + ".");
 }
 
 function shouldBeTrue(_a) { shouldBe(_a, "true"); }
 function shouldBeFalse(_a) { shouldBe(_a, "false"); }
 function shouldBeNaN(_a) { shouldBe(_a, "NaN"); }
 function shouldBeNull(_a) { shouldBe(_a, "null"); }
 
 function shouldBeEqualToString(a, b)
--- a/content/canvas/test/webgl/undo-r15330-async-test-list-loading.patch
+++ b/content/canvas/test/webgl/undo-r15330-async-test-list-loading.patch
@@ -1,11 +1,10 @@
 # HG changeset patch
-# Parent 41137626edf2a358f2be1b7ed3f83211230ab4f5
-
+# Parent fb36d18f04ef9b01ca87d3fde539d50c204f9bba
 diff --git a/content/canvas/test/webgl/resources/webgl-test-harness.js b/content/canvas/test/webgl/resources/webgl-test-harness.js
 --- a/content/canvas/test/webgl/resources/webgl-test-harness.js
 +++ b/content/canvas/test/webgl/resources/webgl-test-harness.js
 @@ -90,190 +90,105 @@ var log = function(msg) {
    if (window.console && window.console.log) {
      window.console.log(msg);
    }
  };