[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

eric at webkit.org eric at webkit.org
Thu Apr 8 00:31:50 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 082f71927cbd45719531f7f2a8ad2fb99f5f658f
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Dec 10 23:55:26 2009 +0000

    2009-12-10  Kenneth Russell  <kbr at google.com>
    
            Reviewed by Oliver Hunt.
    
            Changed WebGLRenderingContext to synthesize GL errors rather than
            raising JavaScript exceptions. Removed internal getError() calls
            after each graphics call. The GraphicsContext3D maintains the
            synthetic exceptions because only it has complete information
            about certain conditions requiring them to be raised.
    
            Based on idea from Ilmari Heikkinen, added create3DDebugContext()
            to webgl-test.js and changed the WebGL layout tests expecting
            error conditions to use it. Updated expected.txt files, which now
            implicitly test the OpenGL error as it is part of the exception's
            message.
    
            Added new targeted test covering aspects of synthetic errors as
            well as regression tests for bugs uncovered during its development.
    
            Test: fast/canvas/webgl/error-reporting.html
    
            * fast/canvas/webgl/drawArraysOutOfBounds-expected.txt:
            * fast/canvas/webgl/drawArraysOutOfBounds.html:
            * fast/canvas/webgl/drawElementssOutOfBounds-expected.txt:
            * fast/canvas/webgl/drawElementssOutOfBounds.html:
            * fast/canvas/webgl/error-reporting-expected.txt: Added.
            * fast/canvas/webgl/error-reporting.html: Added.
            * fast/canvas/webgl/getActiveTest-expected.txt:
            * fast/canvas/webgl/incorrect-context-object-behaviour-expected.txt:
            * fast/canvas/webgl/invalidPassedParams-expected.txt:
            * fast/canvas/webgl/invalidPassedParams.html:
            * fast/canvas/webgl/null-object-behaviour-expected.txt:
            * fast/canvas/webgl/resources/webgl-test.js:
            (create3DDebugContext.wrap.getError):
            (create3DDebugContext):
            * fast/canvas/webgl/script-tests/error-reporting.js: Added.
            * fast/canvas/webgl/script-tests/getActiveTest.js:
            * fast/canvas/webgl/script-tests/incorrect-context-object-behaviour.js:
            * fast/canvas/webgl/script-tests/null-object-behaviour.js:
            * fast/canvas/webgl/script-tests/uniform-location.js:
            * fast/canvas/webgl/uniform-location-expected.txt:
    2009-12-10  Kenneth Russell  <kbr at google.com>
    
            Reviewed by Oliver Hunt.
    
            Changed WebGLRenderingContext to synthesize GL errors rather than
            raising JavaScript exceptions. Removed internal getError() calls
            after each graphics call. The GraphicsContext3D maintains the
            synthetic exceptions because only it has complete information
            about certain conditions requiring them to be raised.
    
            Based on idea from Ilmari Heikkinen, added create3DDebugContext()
            to webgl-test.js and changed the WebGL layout tests expecting
            error conditions to use it. Updated expected.txt files, which now
            implicitly test the OpenGL error as it is part of the exception's
            message.
    
            Added new targeted test covering aspects of synthetic errors as
            well as regression tests for bugs uncovered during its development.
    
            Test: fast/canvas/webgl/error-reporting.html
    
            * html/canvas/WebGLRenderingContext.cpp:
            (WebCore::WebGLRenderingContext::sizeInBytes):
            (WebCore::WebGLRenderingContext::activeTexture):
            (WebCore::WebGLRenderingContext::attachShader):
            (WebCore::WebGLRenderingContext::bindAttribLocation):
            (WebCore::WebGLRenderingContext::bindBuffer):
            (WebCore::WebGLRenderingContext::bindFramebuffer):
            (WebCore::WebGLRenderingContext::bindRenderbuffer):
            (WebCore::WebGLRenderingContext::bindTexture):
            (WebCore::WebGLRenderingContext::bufferData):
            (WebCore::WebGLRenderingContext::bufferSubData):
            (WebCore::WebGLRenderingContext::compileShader):
            (WebCore::WebGLRenderingContext::createShader):
            (WebCore::WebGLRenderingContext::detachShader):
            (WebCore::WebGLRenderingContext::disableVertexAttribArray):
            (WebCore::WebGLRenderingContext::drawArrays):
            (WebCore::WebGLRenderingContext::drawElements):
            (WebCore::WebGLRenderingContext::enableVertexAttribArray):
            (WebCore::WebGLRenderingContext::framebufferRenderbuffer):
            (WebCore::WebGLRenderingContext::framebufferTexture2D):
            (WebCore::WebGLRenderingContext::getActiveAttrib):
            (WebCore::WebGLRenderingContext::getActiveUniform):
            (WebCore::WebGLRenderingContext::getBufferParameter):
            (WebCore::WebGLRenderingContext::getFramebufferAttachmentParameter):
            (WebCore::WebGLRenderingContext::getParameter):
            (WebCore::WebGLRenderingContext::getProgramParameter):
            (WebCore::WebGLRenderingContext::getProgramInfoLog):
            (WebCore::WebGLRenderingContext::getRenderbufferParameter):
            (WebCore::WebGLRenderingContext::getShaderParameter):
            (WebCore::WebGLRenderingContext::getShaderInfoLog):
            (WebCore::WebGLRenderingContext::getShaderSource):
            (WebCore::WebGLRenderingContext::getTexParameter):
            (WebCore::WebGLRenderingContext::getUniform):
            (WebCore::WebGLRenderingContext::getUniformLocation):
            (WebCore::WebGLRenderingContext::getVertexAttrib):
            (WebCore::WebGLRenderingContext::linkProgram):
            (WebCore::WebGLRenderingContext::shaderSource):
            (WebCore::WebGLRenderingContext::texImage2D):
            (WebCore::WebGLRenderingContext::texSubImage2D):
            (WebCore::WebGLRenderingContext::uniform1f):
            (WebCore::WebGLRenderingContext::uniform1fv):
            (WebCore::WebGLRenderingContext::uniform1i):
            (WebCore::WebGLRenderingContext::uniform1iv):
            (WebCore::WebGLRenderingContext::uniform2f):
            (WebCore::WebGLRenderingContext::uniform2fv):
            (WebCore::WebGLRenderingContext::uniform2i):
            (WebCore::WebGLRenderingContext::uniform2iv):
            (WebCore::WebGLRenderingContext::uniform3f):
            (WebCore::WebGLRenderingContext::uniform3fv):
            (WebCore::WebGLRenderingContext::uniform3i):
            (WebCore::WebGLRenderingContext::uniform3iv):
            (WebCore::WebGLRenderingContext::uniform4f):
            (WebCore::WebGLRenderingContext::uniform4fv):
            (WebCore::WebGLRenderingContext::uniform4i):
            (WebCore::WebGLRenderingContext::uniform4iv):
            (WebCore::WebGLRenderingContext::uniformMatrix2fv):
            (WebCore::WebGLRenderingContext::uniformMatrix3fv):
            (WebCore::WebGLRenderingContext::uniformMatrix4fv):
            (WebCore::WebGLRenderingContext::useProgram):
            (WebCore::WebGLRenderingContext::validateProgram):
            (WebCore::WebGLRenderingContext::vertexAttribPointer):
            * html/canvas/WebGLRenderingContext.h:
            (WebCore::WebGLRenderingContext::cleanupAfterGraphicsCall):
            * platform/graphics/GraphicsContext3D.h:
            * platform/graphics/mac/GraphicsContext3DMac.cpp:
            (WebCore::GraphicsContext3D::getActiveAttrib):
            (WebCore::GraphicsContext3D::getActiveUniform):
            (WebCore::GraphicsContext3D::getError):
            (WebCore::GraphicsContext3D::synthesizeGLError):
    2009-12-10  Kenneth Russell  <kbr at google.com>
    
            Reviewed by Oliver Hunt.
    
            Changed WebGLRenderingContext to synthesize GL errors rather than
            raising JavaScript exceptions. Removed internal getError() calls
            after each graphics call. The GraphicsContext3D maintains the
            synthetic exceptions because only it has complete information
            about certain conditions requiring them to be raised.
    
            Based on idea from Ilmari Heikkinen, added create3DDebugContext()
            to webgl-test.js and changed the WebGL layout tests expecting
            error conditions to use it. Updated expected.txt files, which now
            implicitly test the OpenGL error as it is part of the exception's
            message.
    
            Added new targeted test covering aspects of synthetic errors as
            well as regression tests for bugs uncovered during its development.
    
            Test: fast/canvas/webgl/error-reporting.html
    
            * src/GraphicsContext3D.cpp:
            (WebCore::GraphicsContext3DInternal::reshape):
            (WebCore::GraphicsContext3DInternal::getError):
            (WebCore::GraphicsContext3DInternal::synthesizeGLError):
            (WebCore::GraphicsContext3D::getActiveAttrib):
            (WebCore::GraphicsContext3D::getActiveUniform):
            (WebCore::GraphicsContext3D::getError):
            (WebCore::GraphicsContext3D::synthesizeGLError):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51970 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index a62e4d3..d9f580b 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,45 @@
+2009-12-10  Kenneth Russell  <kbr at google.com>
+
+        Reviewed by Oliver Hunt.
+
+        Changed WebGLRenderingContext to synthesize GL errors rather than
+        raising JavaScript exceptions. Removed internal getError() calls
+        after each graphics call. The GraphicsContext3D maintains the
+        synthetic exceptions because only it has complete information
+        about certain conditions requiring them to be raised.
+
+        Based on idea from Ilmari Heikkinen, added create3DDebugContext()
+        to webgl-test.js and changed the WebGL layout tests expecting
+        error conditions to use it. Updated expected.txt files, which now
+        implicitly test the OpenGL error as it is part of the exception's
+        message.
+
+        Added new targeted test covering aspects of synthetic errors as
+        well as regression tests for bugs uncovered during its development.
+
+        Test: fast/canvas/webgl/error-reporting.html
+
+        * fast/canvas/webgl/drawArraysOutOfBounds-expected.txt:
+        * fast/canvas/webgl/drawArraysOutOfBounds.html:
+        * fast/canvas/webgl/drawElementssOutOfBounds-expected.txt:
+        * fast/canvas/webgl/drawElementssOutOfBounds.html:
+        * fast/canvas/webgl/error-reporting-expected.txt: Added.
+        * fast/canvas/webgl/error-reporting.html: Added.
+        * fast/canvas/webgl/getActiveTest-expected.txt:
+        * fast/canvas/webgl/incorrect-context-object-behaviour-expected.txt:
+        * fast/canvas/webgl/invalidPassedParams-expected.txt:
+        * fast/canvas/webgl/invalidPassedParams.html:
+        * fast/canvas/webgl/null-object-behaviour-expected.txt:
+        * fast/canvas/webgl/resources/webgl-test.js:
+        (create3DDebugContext.wrap.getError):
+        (create3DDebugContext):
+        * fast/canvas/webgl/script-tests/error-reporting.js: Added.
+        * fast/canvas/webgl/script-tests/getActiveTest.js:
+        * fast/canvas/webgl/script-tests/incorrect-context-object-behaviour.js:
+        * fast/canvas/webgl/script-tests/null-object-behaviour.js:
+        * fast/canvas/webgl/script-tests/uniform-location.js:
+        * fast/canvas/webgl/uniform-location-expected.txt:
+
 2009-12-10  Alpha Lam  <hclam at chromium.org>
 
         Reviewed by Eric Carlson.
diff --git a/LayoutTests/fast/canvas/webgl/drawArraysOutOfBounds-expected.txt b/LayoutTests/fast/canvas/webgl/drawArraysOutOfBounds-expected.txt
index ec4f2e5..406f490 100644
--- a/LayoutTests/fast/canvas/webgl/drawArraysOutOfBounds-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/drawArraysOutOfBounds-expected.txt
@@ -3,24 +3,24 @@ Test of drawArrays with out-of-bounds parameters
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 Test empty buffer
-PASS context.drawArrays(context.TRIANGLES, 0, 1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, 0, 10000) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, 0, 10000000000000) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, 0, -1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, 1, 0) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, -1, 0) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, 1, -1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, -1, 1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
+PASS context.drawArrays(context.TRIANGLES, 0, 1) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, 0, 10000) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, 0, 10000000000000) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, 0, -1) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, 1, 0) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, -1, 0) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, 1, -1) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, -1, 1) threw exception GL error 1282 in drawArrays.
 
 Test buffer with 3 float vectors
 PASS context.drawArrays(context.TRIANGLES, 0, 3) is undefined
-PASS context.drawArrays(context.TRIANGLES, 3, 2) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, 0, 10000) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, 0, 10000000000000) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, 0, -1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, -1, 0) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, 1, -1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawArrays(context.TRIANGLES, -1, 1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
+PASS context.drawArrays(context.TRIANGLES, 3, 2) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, 0, 10000) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, 0, 10000000000000) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, 0, -1) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, -1, 0) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, 1, -1) threw exception GL error 1282 in drawArrays.
+PASS context.drawArrays(context.TRIANGLES, -1, 1) threw exception GL error 1282 in drawArrays.
 
 PASS successfullyParsed is true
 
diff --git a/LayoutTests/fast/canvas/webgl/drawArraysOutOfBounds.html b/LayoutTests/fast/canvas/webgl/drawArraysOutOfBounds.html
index 63992bf..506fa9d 100644
--- a/LayoutTests/fast/canvas/webgl/drawArraysOutOfBounds.html
+++ b/LayoutTests/fast/canvas/webgl/drawArraysOutOfBounds.html
@@ -11,7 +11,7 @@
 <script>
 description("Test of drawArrays with out-of-bounds parameters");
 
-var context = create3DContext();
+var context = create3DDebugContext();
 var program = loadStandardProgram(context);
 
 context.useProgram(program);
diff --git a/LayoutTests/fast/canvas/webgl/drawElementssOutOfBounds-expected.txt b/LayoutTests/fast/canvas/webgl/drawElementssOutOfBounds-expected.txt
index ec85a45..e2244ab 100644
--- a/LayoutTests/fast/canvas/webgl/drawElementssOutOfBounds-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/drawElementssOutOfBounds-expected.txt
@@ -3,22 +3,22 @@ Test of drawElements with out-of-bounds parameters
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 Test empty index buffer
-PASS context.drawElements(context.TRIANGLES, 3, context.UNSIGNED_BYTE, 0) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawElements(context.TRIANGLES, 10000, context.UNSIGNED_BYTE, 0) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawElements(context.TRIANGLES, 10000000000000, context.UNSIGNED_BYTE, 0) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawElements(context.TRIANGLES, 1, context.UNSIGNED_BYTE, 0) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawElements(context.TRIANGLES, 0, context.UNSIGNED_BYTE, -1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawElements(context.TRIANGLES, -1, context.UNSIGNED_BYTE, 1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawElements(context.TRIANGLES, 1, context.UNSIGNED_BYTE, -1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
+PASS context.drawElements(context.TRIANGLES, 3, context.UNSIGNED_BYTE, 0) threw exception GL error 1282 in drawElements.
+PASS context.drawElements(context.TRIANGLES, 10000, context.UNSIGNED_BYTE, 0) threw exception GL error 1282 in drawElements.
+PASS context.drawElements(context.TRIANGLES, 10000000000000, context.UNSIGNED_BYTE, 0) threw exception GL error 1282 in drawElements.
+PASS context.drawElements(context.TRIANGLES, 1, context.UNSIGNED_BYTE, 0) threw exception GL error 1282 in drawElements.
+PASS context.drawElements(context.TRIANGLES, 0, context.UNSIGNED_BYTE, -1) threw exception GL error 1282 in drawElements.
+PASS context.drawElements(context.TRIANGLES, -1, context.UNSIGNED_BYTE, 1) threw exception GL error 1282 in drawElements.
+PASS context.drawElements(context.TRIANGLES, 1, context.UNSIGNED_BYTE, -1) threw exception GL error 1282 in drawElements.
 
 Test buffer with 3 byte indexes
 PASS context.drawElements(context.TRIANGLES, 3, context.UNSIGNED_BYTE, 0) is undefined
-PASS context.drawElements(context.TRIANGLES, 3, context.UNSIGNED_BYTE, 2) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawElements(context.TRIANGLES, 10000, context.UNSIGNED_BYTE, 0) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawElements(context.TRIANGLES, 10000000000000, context.UNSIGNED_BYTE, 0) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawElements(context.TRIANGLES, 0, context.UNSIGNED_BYTE, -1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawElements(context.TRIANGLES, -1, context.UNSIGNED_BYTE, 1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS context.drawElements(context.TRIANGLES, 1, context.UNSIGNED_BYTE, -1) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
+PASS context.drawElements(context.TRIANGLES, 3, context.UNSIGNED_BYTE, 2) threw exception GL error 1282 in drawElements.
+PASS context.drawElements(context.TRIANGLES, 10000, context.UNSIGNED_BYTE, 0) threw exception GL error 1282 in drawElements.
+PASS context.drawElements(context.TRIANGLES, 10000000000000, context.UNSIGNED_BYTE, 0) threw exception GL error 1282 in drawElements.
+PASS context.drawElements(context.TRIANGLES, 0, context.UNSIGNED_BYTE, -1) threw exception GL error 1282 in drawElements.
+PASS context.drawElements(context.TRIANGLES, -1, context.UNSIGNED_BYTE, 1) threw exception GL error 1282 in drawElements.
+PASS context.drawElements(context.TRIANGLES, 1, context.UNSIGNED_BYTE, -1) threw exception GL error 1282 in drawElements.
 
 PASS successfullyParsed is true
 
diff --git a/LayoutTests/fast/canvas/webgl/drawElementssOutOfBounds.html b/LayoutTests/fast/canvas/webgl/drawElementssOutOfBounds.html
index 29a02f4..377bfa7 100644
--- a/LayoutTests/fast/canvas/webgl/drawElementssOutOfBounds.html
+++ b/LayoutTests/fast/canvas/webgl/drawElementssOutOfBounds.html
@@ -11,7 +11,7 @@
 <script>
 description("Test of drawElements with out-of-bounds parameters");
 
-var context = create3DContext();
+var context = create3DDebugContext();
 var program = loadStandardProgram(context);
 
 context.useProgram(program);
diff --git a/LayoutTests/fast/canvas/webgl/error-reporting-expected.txt b/LayoutTests/fast/canvas/webgl/error-reporting-expected.txt
new file mode 100644
index 0000000..b1b2914
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/error-reporting-expected.txt
@@ -0,0 +1,23 @@
+Tests generation of synthetic and real GL errors
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS context.getError() is 0
+Testing getActiveAttrib
+PASS context.getActiveAttrib(null, 2) is null
+PASS context.getError() is context.INVALID_OPERATION
+PASS context.getError() is context.NO_ERROR
+PASS context.getActiveAttrib(program, 2) is null
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.NO_ERROR
+Testing getActiveUniform
+PASS context.getActiveUniform(null, 0) is null
+PASS context.getError() is context.INVALID_OPERATION
+PASS context.getError() is context.NO_ERROR
+PASS context.getActiveUniform(program, 50) is null
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.NO_ERROR
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/webgl/error-reporting.html b/LayoutTests/fast/canvas/webgl/error-reporting.html
new file mode 100644
index 0000000..26e77f2
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/error-reporting.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="resources/webgl-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script src="script-tests/error-reporting.js"></script>
+
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/canvas/webgl/getActiveTest-expected.txt b/LayoutTests/fast/canvas/webgl/getActiveTest-expected.txt
index 8de69a8..a0cddde 100644
--- a/LayoutTests/fast/canvas/webgl/getActiveTest-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/getActiveTest-expected.txt
@@ -6,11 +6,11 @@ PASS context.getError() is 0
 PASS context.getActiveUniform(program, 0).name is 'u_modelViewProjMatrix'
 PASS context.getActiveUniform(program, 0).type is context.FLOAT_MAT4
 PASS context.getActiveUniform(program, 0).size is 1
-PASS context.getActiveUniform(program, 1) threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
-PASS context.getError() is context.INVALID_VALUE
-PASS context.getActiveUniform(program, -1) threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
-PASS context.getError() is context.INVALID_VALUE
-PASS context.getActiveUniform(null, 0) threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
+PASS context.getActiveUniform(program, 1) threw exception GL error 1281 in getActiveUniform.
+PASS context.getError() is 0
+PASS context.getActiveUniform(program, -1) threw exception GL error 1281 in getActiveUniform.
+PASS context.getError() is 0
+PASS context.getActiveUniform(null, 0) threw exception GL error 1282 in getActiveUniform.
 PASS context.getError() is 0
 PASS context.getActiveAttrib(program, 0).name is 'a_normal'
 PASS context.getActiveAttrib(program, 0).type is context.FLOAT_VEC3
@@ -18,20 +18,20 @@ PASS context.getActiveAttrib(program, 0).size is 1
 PASS context.getActiveAttrib(program, 1).name is 'a_vertex'
 PASS context.getActiveAttrib(program, 1).type is context.FLOAT_VEC4
 PASS context.getActiveAttrib(program, 1).size is 1
-PASS context.getActiveAttrib(program, 2) threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
-PASS context.getError() is context.INVALID_VALUE
-PASS context.getActiveAttrib(program, -1) threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
-PASS context.getError() is context.INVALID_VALUE
-PASS context.getActiveAttrib(null, 0) threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
+PASS context.getActiveAttrib(program, 2) threw exception GL error 1281 in getActiveAttrib.
+PASS context.getError() is 0
+PASS context.getActiveAttrib(program, -1) threw exception GL error 1281 in getActiveAttrib.
+PASS context.getError() is 0
+PASS context.getActiveAttrib(null, 0) threw exception GL error 1282 in getActiveAttrib.
 PASS context.getError() is 0
 PASS context2.getError() is 0
-PASS context2.getActiveAttrib(program, 0) threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
+PASS context2.getActiveAttrib(program, 0) threw exception GL error 1282 in getActiveAttrib.
 PASS context2.getError() is 0
-PASS context2.getActiveUniform(program, 0) threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
+PASS context2.getActiveUniform(program, 0) threw exception GL error 1282 in getActiveUniform.
 PASS context2.getError() is 0
-PASS context.getActiveUniform(program, 0) threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
+PASS context.getActiveUniform(program, 0) threw exception GL error 1281 in getActiveUniform.
 PASS context.getError() is 0
-PASS context.getActiveAttrib(program, 0) threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
+PASS context.getActiveAttrib(program, 0) threw exception GL error 1281 in getActiveAttrib.
 PASS context.getError() is 0
 PASS successfullyParsed is true
 
diff --git a/LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour-expected.txt b/LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour-expected.txt
index 2b94908..9356934 100644
--- a/LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour-expected.txt
@@ -2,28 +2,28 @@ Tests calling WebGL APIs with objects from other contexts
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-PASS contextA.compileShader(shaderB) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.linkProgram(programB) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.attachShader(programA, shaderB) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.attachShader(programB, shaderA) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.attachShader(programB, shaderB) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.detachShader(programA, shaderB) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.detachShader(programB, shaderA) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.detachShader(programB, shaderB) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.shaderSource(shaderB, 'foo') threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.bindAttribLocation(programB, 0, 'foo') threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.bindFramebuffer(contextA.FRAMEBUFFER, frameBufferB) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.bindRenderbuffer(contextA.RENDERBUFFER, renderBufferB) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.bindTexture(contextA.TEXTURE_2D, textureB) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.framebufferRenderbuffer(contextA.FRAMEBUFFER, contextA.DEPTH_ATTACHMENT, contextA.RENDERBUFFER, renderBufferB) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.framebufferTexture2D(contextA.FRAMEBUFFER, contextA.COLOR_ATTACHMENT0, contextA.TEXTURE_2D, textureB, 0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.getProgramParameter(programB, 0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.getProgramInfoLog(programB, 0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.getShaderParameter(shaderB, 0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.getShaderInfoLog(shaderB, 0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.getShaderSource(shaderB) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.getUniform(programB, locationA) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS contextA.getUniformLocation(programB, 'u_modelViewProjMatrix') threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS contextA.compileShader(shaderB) threw exception GL error 1282 in compileShader.
+PASS contextA.linkProgram(programB) threw exception GL error 1282 in linkProgram.
+PASS contextA.attachShader(programA, shaderB) threw exception GL error 1281 in attachShader.
+PASS contextA.attachShader(programB, shaderA) threw exception GL error 1281 in attachShader.
+PASS contextA.attachShader(programB, shaderB) threw exception GL error 1281 in attachShader.
+PASS contextA.detachShader(programA, shaderB) threw exception GL error 1282 in detachShader.
+PASS contextA.detachShader(programB, shaderA) threw exception GL error 1282 in detachShader.
+PASS contextA.detachShader(programB, shaderB) threw exception GL error 1282 in detachShader.
+PASS contextA.shaderSource(shaderB, 'foo') threw exception GL error 1282 in shaderSource.
+PASS contextA.bindAttribLocation(programB, 0, 'foo') threw exception GL error 1282 in bindAttribLocation.
+PASS contextA.bindFramebuffer(contextA.FRAMEBUFFER, frameBufferB) threw exception GL error 1282 in bindFramebuffer.
+PASS contextA.bindRenderbuffer(contextA.RENDERBUFFER, renderBufferB) threw exception GL error 1282 in bindRenderbuffer.
+PASS contextA.bindTexture(contextA.TEXTURE_2D, textureB) threw exception GL error 1282 in bindTexture.
+PASS contextA.framebufferRenderbuffer(contextA.FRAMEBUFFER, contextA.DEPTH_ATTACHMENT, contextA.RENDERBUFFER, renderBufferB) threw exception GL error 1282 in framebufferRenderbuffer.
+PASS contextA.framebufferTexture2D(contextA.FRAMEBUFFER, contextA.COLOR_ATTACHMENT0, contextA.TEXTURE_2D, textureB, 0) threw exception GL error 1282 in framebufferTexture2D.
+PASS contextA.getProgramParameter(programB, 0) threw exception GL error 1282 in getProgramParameter.
+PASS contextA.getProgramInfoLog(programB, 0) threw exception GL error 1282 in getProgramInfoLog.
+PASS contextA.getShaderParameter(shaderB, 0) threw exception GL error 1282 in getShaderParameter.
+PASS contextA.getShaderInfoLog(shaderB, 0) threw exception GL error 1282 in getShaderInfoLog.
+PASS contextA.getShaderSource(shaderB) threw exception GL error 1282 in getShaderSource.
+PASS contextA.getUniform(programB, locationA) threw exception GL error 1282 in getUniform.
+PASS contextA.getUniformLocation(programB, 'u_modelViewProjMatrix') threw exception GL error 1282 in getUniformLocation.
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/fast/canvas/webgl/invalidPassedParams-expected.txt b/LayoutTests/fast/canvas/webgl/invalidPassedParams-expected.txt
index 38d2fd8..f4434dc 100644
--- a/LayoutTests/fast/canvas/webgl/invalidPassedParams-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/invalidPassedParams-expected.txt
@@ -5,8 +5,8 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 Test shaders
 PASS shader = context.createShader(context.FRAGMENT_SHADER) is shader
 PASS shader = context.createShader(context.VERTEX_SHADER) is shader
-PASS context.createShader(0) threw exception Error: SYNTAX_ERR: DOM Exception 12.
-PASS context.createShader(context.TRIANGLES) threw exception Error: SYNTAX_ERR: DOM Exception 12.
+PASS context.createShader(0) threw exception GL error 1280 in createShader.
+PASS context.createShader(context.TRIANGLES) threw exception GL error 1280 in createShader.
 
 PASS successfullyParsed is true
 
diff --git a/LayoutTests/fast/canvas/webgl/invalidPassedParams.html b/LayoutTests/fast/canvas/webgl/invalidPassedParams.html
index 768d2a6..18266aa 100644
--- a/LayoutTests/fast/canvas/webgl/invalidPassedParams.html
+++ b/LayoutTests/fast/canvas/webgl/invalidPassedParams.html
@@ -11,7 +11,7 @@
 <script>
 description("Test for invalid passed parameters");
 
-var context = create3DContext();
+var context = create3DDebugContext();
 
 debug("Test shaders");
 var shader;
diff --git a/LayoutTests/fast/canvas/webgl/null-object-behaviour-expected.txt b/LayoutTests/fast/canvas/webgl/null-object-behaviour-expected.txt
index be50669..8731e75 100644
--- a/LayoutTests/fast/canvas/webgl/null-object-behaviour-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/null-object-behaviour-expected.txt
@@ -2,29 +2,27 @@ Tests calling WebGL APIs without providing the necessary objects
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-PASS context.compileShader() threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.linkProgram() threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.attachShader() threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.attachShader(program, undefined) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.attachShader(undefined, shader) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.detachShader(program, undefined) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.detachShader(undefined, shader) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.shaderSource() threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.shaderSource(undefined, 'foo') threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.bindAttribLocation(undefined, 0, 'foo') threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS context.compileShader() threw exception GL error 1282 in compileShader.
+PASS context.linkProgram() threw exception GL error 1282 in linkProgram.
+PASS context.attachShader() threw exception GL error 1281 in attachShader.
+PASS context.attachShader(program, undefined) threw exception GL error 1281 in attachShader.
+PASS context.attachShader(undefined, shader) threw exception GL error 1281 in attachShader.
+PASS context.detachShader(program, undefined) threw exception GL error 1282 in detachShader.
+PASS context.detachShader(undefined, shader) threw exception GL error 1282 in detachShader.
+PASS context.shaderSource() threw exception GL error 1282 in shaderSource.
+PASS context.shaderSource(undefined, 'foo') threw exception GL error 1282 in shaderSource.
+PASS context.bindAttribLocation(undefined, 0, 'foo') threw exception GL error 1282 in bindAttribLocation.
 PASS context.bindBuffer(context.ARRAY_BUFFER, 0) is undefined.
 PASS context.bindFramebuffer(context.FRAMEBUFFER, 0) is undefined.
 PASS context.bindRenderbuffer(context.RENDERBUFFER, 0) is undefined.
 PASS context.bindTexture(context.TEXTURE_2D, 0) is undefined.
-PASS context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, 0) is undefined.
-PASS context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, 0, 0) is undefined.
-PASS context.getProgramParameter(undefined, 0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.getProgramInfoLog(undefined, 0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.getShaderParameter(undefined, 0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.getShaderInfoLog(undefined, 0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.getShaderSource(undefined) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.getUniform(undefined, 0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
-PASS context.getUniformLocation(undefined, 'foo') threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS context.getProgramParameter(undefined, 0) threw exception GL error 1282 in getProgramParameter.
+PASS context.getProgramInfoLog(undefined, 0) threw exception GL error 1282 in getProgramInfoLog.
+PASS context.getShaderParameter(undefined, 0) threw exception GL error 1282 in getShaderParameter.
+PASS context.getShaderInfoLog(undefined, 0) threw exception GL error 1282 in getShaderInfoLog.
+PASS context.getShaderSource(undefined) threw exception GL error 1282 in getShaderSource.
+PASS context.getUniform(undefined, 0) threw exception GL error 1282 in getUniform.
+PASS context.getUniformLocation(undefined, 'foo') threw exception GL error 1282 in getUniformLocation.
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/fast/canvas/webgl/resources/webgl-test.js b/LayoutTests/fast/canvas/webgl/resources/webgl-test.js
index 6c8cff1..4af528c 100644
--- a/LayoutTests/fast/canvas/webgl/resources/webgl-test.js
+++ b/LayoutTests/fast/canvas/webgl/resources/webgl-test.js
@@ -16,6 +16,37 @@ function create3DContext() {
     return canvas.getContext("moz-webgl");
 }
 
+function createGLErrorWrapper(context, fname) {
+    return function() {
+        var rv = context[fname].apply(context, arguments);
+        var err = context.getError();
+        if (err != 0)
+            throw "GL error " + err + " in " + fname;
+        return rv;
+    };
+}
+
+function create3DDebugContext() {
+    var context = create3DContext();
+    // Thanks to Ilmari Heikkinen for the idea on how to implement this so elegantly.
+    var wrap = {};
+    for (var i in context) {
+        try {
+            if (typeof context[i] == 'function') {
+                wrap[i] = createGLErrorWrapper(context, i);
+            } else {
+                wrap[i] = context[i];
+            }
+        } catch (e) {
+            // console.log("create3DDebugContext: Error accessing " + i);
+        }
+    }
+    wrap.getError = function() {
+        return context.getError();
+    };
+    return wrap;
+}
+
 function loadStandardProgram(context) {
     var program = context.createProgram();
     context.attachShader(program, loadStandardVertexShader(context));
diff --git a/LayoutTests/fast/canvas/webgl/script-tests/error-reporting.js b/LayoutTests/fast/canvas/webgl/script-tests/error-reporting.js
new file mode 100644
index 0000000..694204b
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/script-tests/error-reporting.js
@@ -0,0 +1,55 @@
+description("Tests generation of synthetic and real GL errors");
+
+var context = create3DContext();
+var program = loadStandardProgram(context);
+
+// Other tests in this directory like getActiveTest and
+// incorrect-context-object-behaviour already test the raising of many
+// synthetic GL errors. This test verifies the raising of certain
+// known real GL errors, and contains a few regression tests for bugs
+// discovered in the synthetic error generation and in the WebGL
+// implementation itself.
+
+shouldBe("context.getError()", "0");
+
+debug("Testing getActiveAttrib");
+// Synthetic OpenGL error
+shouldBeNull("context.getActiveAttrib(null, 2)");
+shouldBe("context.getError()", "context.INVALID_OPERATION");
+// Error state should be clear by this point
+shouldBe("context.getError()", "context.NO_ERROR");
+// Real OpenGL error
+shouldBeNull("context.getActiveAttrib(program, 2)");
+shouldBe("context.getError()", "context.INVALID_VALUE");
+// Error state should be clear by this point
+shouldBe("context.getError()", "context.NO_ERROR");
+
+debug("Testing getActiveUniform");
+// Synthetic OpenGL error
+shouldBeNull("context.getActiveUniform(null, 0)");
+shouldBe("context.getError()", "context.INVALID_OPERATION");
+// Error state should be clear by this point
+shouldBe("context.getError()", "context.NO_ERROR");
+// Real OpenGL error
+shouldBeNull("context.getActiveUniform(program, 50)");
+shouldBe("context.getError()", "context.INVALID_VALUE");
+// Error state should be clear by this point
+shouldBe("context.getError()", "context.NO_ERROR");
+
+// FIXME: the following tests don't work properly yet
+// https://bugs.webkit.org/show_bug.cgi?id=32391
+// debug("Testing attempts to manipulate the default framebuffer");
+// shouldBeUndefined("context.bindFramebuffer(context.FRAMEBUFFER, 0)");
+// shouldBe("context.getError()", "context.NO_ERROR");
+// shouldBeUndefined("context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, 0)");
+// // Synthetic OpenGL error
+// shouldBe("context.getError()", "context.INVALID_OPERATION");
+// // Error state should be clear by this point
+// shouldBe("context.getError()", "context.NO_ERROR");
+// shouldBeUndefined("context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, 0, 0)");
+// // Synthetic OpenGL error
+// shouldBe("context.getError()", "context.INVALID_OPERATION");
+// // Error state should be clear by this point
+// shouldBe("context.getError()", "context.NO_ERROR");
+
+successfullyParsed = true;
diff --git a/LayoutTests/fast/canvas/webgl/script-tests/getActiveTest.js b/LayoutTests/fast/canvas/webgl/script-tests/getActiveTest.js
index 1410bf1..f9706fa 100644
--- a/LayoutTests/fast/canvas/webgl/script-tests/getActiveTest.js
+++ b/LayoutTests/fast/canvas/webgl/script-tests/getActiveTest.js
@@ -1,7 +1,7 @@
 description("Test of getActiveAttrib and getActiveUniform");
 
-var context = create3DContext();
-var context2 = create3DContext();
+var context = create3DDebugContext();
+var context2 = create3DDebugContext();
 var program = loadStandardProgram(context);
 var program2 = loadStandardProgram(context2);
 
@@ -10,9 +10,9 @@ shouldBe("context.getActiveUniform(program, 0).name", "'u_modelViewProjMatrix'")
 shouldBe("context.getActiveUniform(program, 0).type", "context.FLOAT_MAT4");
 shouldBe("context.getActiveUniform(program, 0).size", "1");
 shouldThrow("context.getActiveUniform(program, 1)");
-shouldBe("context.getError()", "context.INVALID_VALUE");
+shouldBe("context.getError()", "0");
 shouldThrow("context.getActiveUniform(program, -1)");
-shouldBe("context.getError()", "context.INVALID_VALUE");
+shouldBe("context.getError()", "0");
 shouldThrow("context.getActiveUniform(null, 0)");
 shouldBe("context.getError()", "0");
 
@@ -23,9 +23,9 @@ shouldBe("context.getActiveAttrib(program, 1).name", "'a_vertex'");
 shouldBe("context.getActiveAttrib(program, 1).type", "context.FLOAT_VEC4");
 shouldBe("context.getActiveAttrib(program, 1).size", "1");
 shouldThrow("context.getActiveAttrib(program, 2)");
-shouldBe("context.getError()", "context.INVALID_VALUE");
+shouldBe("context.getError()", "0");
 shouldThrow("context.getActiveAttrib(program, -1)");
-shouldBe("context.getError()", "context.INVALID_VALUE");
+shouldBe("context.getError()", "0");
 shouldThrow("context.getActiveAttrib(null, 0)");
 shouldBe("context.getError()", "0");
 
diff --git a/LayoutTests/fast/canvas/webgl/script-tests/incorrect-context-object-behaviour.js b/LayoutTests/fast/canvas/webgl/script-tests/incorrect-context-object-behaviour.js
index cf1f5a1..9b7e8af 100644
--- a/LayoutTests/fast/canvas/webgl/script-tests/incorrect-context-object-behaviour.js
+++ b/LayoutTests/fast/canvas/webgl/script-tests/incorrect-context-object-behaviour.js
@@ -1,7 +1,7 @@
 description("Tests calling WebGL APIs with objects from other contexts");
 
-var contextA = create3DContext();
-var contextB = create3DContext();
+var contextA = create3DDebugContext();
+var contextB = create3DDebugContext();
 var programA = loadStandardProgram(contextA);
 var programB = loadStandardProgram(contextB);
 var shaderA = loadStandardVertexShader(contextA);
diff --git a/LayoutTests/fast/canvas/webgl/script-tests/null-object-behaviour.js b/LayoutTests/fast/canvas/webgl/script-tests/null-object-behaviour.js
index 1fddb0e..68c69ac 100644
--- a/LayoutTests/fast/canvas/webgl/script-tests/null-object-behaviour.js
+++ b/LayoutTests/fast/canvas/webgl/script-tests/null-object-behaviour.js
@@ -1,6 +1,6 @@
 description("Tests calling WebGL APIs without providing the necessary objects");
 
-var context = create3DContext();
+var context = create3DDebugContext();
 var program = loadStandardProgram(context);
 var shader = loadStandardVertexShader(context);
 
@@ -18,8 +18,10 @@ shouldBeUndefined("context.bindBuffer(context.ARRAY_BUFFER, 0)");
 shouldBeUndefined("context.bindFramebuffer(context.FRAMEBUFFER, 0)");
 shouldBeUndefined("context.bindRenderbuffer(context.RENDERBUFFER, 0)");
 shouldBeUndefined("context.bindTexture(context.TEXTURE_2D, 0)");
-shouldBeUndefined("context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, 0)");
-shouldBeUndefined("context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, 0, 0)");
+// FIXME: the following two tests should state shouldThrow, not shouldBeUndefined
+// https://bugs.webkit.org/show_bug.cgi?id=32391
+// shouldBeUndefined("context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, 0)");
+// shouldBeUndefined("context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, 0, 0)");
 shouldThrow("context.getProgramParameter(undefined, 0)");
 shouldThrow("context.getProgramInfoLog(undefined, 0)");
 shouldThrow("context.getShaderParameter(undefined, 0)");
diff --git a/LayoutTests/fast/canvas/webgl/script-tests/uniform-location.js b/LayoutTests/fast/canvas/webgl/script-tests/uniform-location.js
index bc6c2f2..87ecf7b 100644
--- a/LayoutTests/fast/canvas/webgl/script-tests/uniform-location.js
+++ b/LayoutTests/fast/canvas/webgl/script-tests/uniform-location.js
@@ -1,7 +1,7 @@
 description("Tests calling WebGL APIs with objects from other contexts");
 
-var contextA = create3DContext();
-var contextB = create3DContext();
+var contextA = create3DDebugContext();
+var contextB = create3DDebugContext();
 var programA1 = loadStandardProgram(contextA);
 var programA2 = loadStandardProgram(contextA);
 var programB = loadStandardProgram(contextB);
diff --git a/LayoutTests/fast/canvas/webgl/uniform-location-expected.txt b/LayoutTests/fast/canvas/webgl/uniform-location-expected.txt
index babdaab..df15eb5 100644
--- a/LayoutTests/fast/canvas/webgl/uniform-location-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/uniform-location-expected.txt
@@ -3,10 +3,10 @@ Tests calling WebGL APIs with objects from other contexts
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 PASS contextA.useProgram(programA2) is undefined.
-PASS contextA.uniformMatrix4fv(locationA, false, mat) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS contextA.uniformMatrix4fv(locationA, false, mat) threw exception GL error 1282 in uniformMatrix4fv.
 PASS contextA.useProgram(programA1) is undefined.
 PASS contextA.uniformMatrix4fv(locationA, false, mat) is undefined.
-PASS contextA.uniformMatrix4fv(0, false, mat) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS contextA.uniformMatrix4fv(0, false, mat) threw exception GL error 1282 in uniformMatrix4fv.
 PASS contextA.useProgram(programS) is undefined.
 PASS contextA.uniform1i(locationSx, 3) is undefined.
 PASS contextA.uniform1f(locationArray0, 4.0) is undefined.
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 921ceae..0d40404 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,94 @@
+2009-12-10  Kenneth Russell  <kbr at google.com>
+
+        Reviewed by Oliver Hunt.
+
+        Changed WebGLRenderingContext to synthesize GL errors rather than
+        raising JavaScript exceptions. Removed internal getError() calls
+        after each graphics call. The GraphicsContext3D maintains the
+        synthetic exceptions because only it has complete information
+        about certain conditions requiring them to be raised.
+
+        Based on idea from Ilmari Heikkinen, added create3DDebugContext()
+        to webgl-test.js and changed the WebGL layout tests expecting
+        error conditions to use it. Updated expected.txt files, which now
+        implicitly test the OpenGL error as it is part of the exception's
+        message.
+
+        Added new targeted test covering aspects of synthetic errors as
+        well as regression tests for bugs uncovered during its development.
+
+        Test: fast/canvas/webgl/error-reporting.html
+
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::sizeInBytes):
+        (WebCore::WebGLRenderingContext::activeTexture):
+        (WebCore::WebGLRenderingContext::attachShader):
+        (WebCore::WebGLRenderingContext::bindAttribLocation):
+        (WebCore::WebGLRenderingContext::bindBuffer):
+        (WebCore::WebGLRenderingContext::bindFramebuffer):
+        (WebCore::WebGLRenderingContext::bindRenderbuffer):
+        (WebCore::WebGLRenderingContext::bindTexture):
+        (WebCore::WebGLRenderingContext::bufferData):
+        (WebCore::WebGLRenderingContext::bufferSubData):
+        (WebCore::WebGLRenderingContext::compileShader):
+        (WebCore::WebGLRenderingContext::createShader):
+        (WebCore::WebGLRenderingContext::detachShader):
+        (WebCore::WebGLRenderingContext::disableVertexAttribArray):
+        (WebCore::WebGLRenderingContext::drawArrays):
+        (WebCore::WebGLRenderingContext::drawElements):
+        (WebCore::WebGLRenderingContext::enableVertexAttribArray):
+        (WebCore::WebGLRenderingContext::framebufferRenderbuffer):
+        (WebCore::WebGLRenderingContext::framebufferTexture2D):
+        (WebCore::WebGLRenderingContext::getActiveAttrib):
+        (WebCore::WebGLRenderingContext::getActiveUniform):
+        (WebCore::WebGLRenderingContext::getBufferParameter):
+        (WebCore::WebGLRenderingContext::getFramebufferAttachmentParameter):
+        (WebCore::WebGLRenderingContext::getParameter):
+        (WebCore::WebGLRenderingContext::getProgramParameter):
+        (WebCore::WebGLRenderingContext::getProgramInfoLog):
+        (WebCore::WebGLRenderingContext::getRenderbufferParameter):
+        (WebCore::WebGLRenderingContext::getShaderParameter):
+        (WebCore::WebGLRenderingContext::getShaderInfoLog):
+        (WebCore::WebGLRenderingContext::getShaderSource):
+        (WebCore::WebGLRenderingContext::getTexParameter):
+        (WebCore::WebGLRenderingContext::getUniform):
+        (WebCore::WebGLRenderingContext::getUniformLocation):
+        (WebCore::WebGLRenderingContext::getVertexAttrib):
+        (WebCore::WebGLRenderingContext::linkProgram):
+        (WebCore::WebGLRenderingContext::shaderSource):
+        (WebCore::WebGLRenderingContext::texImage2D):
+        (WebCore::WebGLRenderingContext::texSubImage2D):
+        (WebCore::WebGLRenderingContext::uniform1f):
+        (WebCore::WebGLRenderingContext::uniform1fv):
+        (WebCore::WebGLRenderingContext::uniform1i):
+        (WebCore::WebGLRenderingContext::uniform1iv):
+        (WebCore::WebGLRenderingContext::uniform2f):
+        (WebCore::WebGLRenderingContext::uniform2fv):
+        (WebCore::WebGLRenderingContext::uniform2i):
+        (WebCore::WebGLRenderingContext::uniform2iv):
+        (WebCore::WebGLRenderingContext::uniform3f):
+        (WebCore::WebGLRenderingContext::uniform3fv):
+        (WebCore::WebGLRenderingContext::uniform3i):
+        (WebCore::WebGLRenderingContext::uniform3iv):
+        (WebCore::WebGLRenderingContext::uniform4f):
+        (WebCore::WebGLRenderingContext::uniform4fv):
+        (WebCore::WebGLRenderingContext::uniform4i):
+        (WebCore::WebGLRenderingContext::uniform4iv):
+        (WebCore::WebGLRenderingContext::uniformMatrix2fv):
+        (WebCore::WebGLRenderingContext::uniformMatrix3fv):
+        (WebCore::WebGLRenderingContext::uniformMatrix4fv):
+        (WebCore::WebGLRenderingContext::useProgram):
+        (WebCore::WebGLRenderingContext::validateProgram):
+        (WebCore::WebGLRenderingContext::vertexAttribPointer):
+        * html/canvas/WebGLRenderingContext.h:
+        (WebCore::WebGLRenderingContext::cleanupAfterGraphicsCall):
+        * platform/graphics/GraphicsContext3D.h:
+        * platform/graphics/mac/GraphicsContext3DMac.cpp:
+        (WebCore::GraphicsContext3D::getActiveAttrib):
+        (WebCore::GraphicsContext3D::getActiveUniform):
+        (WebCore::GraphicsContext3D::getError):
+        (WebCore::GraphicsContext3D::synthesizeGLError):
+
 2009-12-10  Stephen White  <senorblanco at chromium.org>
 
         Reviewed by Dimitri Glazkov.
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index aadcbb4..7a7215d 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -141,18 +141,19 @@ void WebGLRenderingContext::reshape(int width, int height)
 
 int WebGLRenderingContext::sizeInBytes(int type, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     int result = m_context->sizeInBytes(type);
     if (result <= 0)
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
 
     return result;
 }
 
 void WebGLRenderingContext::activeTexture(unsigned long texture, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if ((texture - GraphicsContext3D::TEXTURE0) > sizeof(m_textureUnits) / sizeof(TextureUnitState)) {
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return;
     }
     m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0;
@@ -162,8 +163,9 @@ void WebGLRenderingContext::activeTexture(unsigned long texture, ExceptionCode&
 
 void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!program || program->context() != this || !shader || shader->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
     m_context->attachShader(program, shader);
@@ -172,8 +174,9 @@ void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* sha
 
 void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!program || program->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
     m_context->bindAttribLocation(program, index, name);
@@ -182,8 +185,9 @@ void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned l
 
 void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (buffer && buffer->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
 
@@ -192,8 +196,7 @@ void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer
     else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
         m_boundElementArrayBuffer = buffer;
     else {
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return;
     }
 
@@ -204,13 +207,13 @@ void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer
 
 void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (buffer && buffer->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
     if (target != GraphicsContext3D::FRAMEBUFFER) {
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return;
     }
     m_framebufferBinding = buffer;
@@ -220,13 +223,13 @@ void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuff
 
 void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (renderBuffer && renderBuffer->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
     if (target != GraphicsContext3D::RENDERBUFFER) {
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return;
     }
     m_renderbufferBinding = renderBuffer;
@@ -237,8 +240,9 @@ void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbu
 
 void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* texture, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (texture && texture->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
     if (target == GraphicsContext3D::TEXTURE_2D)
@@ -246,8 +250,7 @@ void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* text
     else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP)
         m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
     else {
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return;
     }
     m_context->bindTexture(target, texture);
@@ -287,18 +290,19 @@ void WebGLRenderingContext::blendFuncSeparate(unsigned long srcRGB, unsigned lon
 
 void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned long usage, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) {
         if (!m_boundElementArrayBuffer->associateBufferData(target, size)) {
-            ec = SYNTAX_ERR;
+            m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
             return;
         }
     } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) {
         if (!m_boundArrayBuffer->associateBufferData(target, size)) {
-            ec = SYNTAX_ERR;
+            m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
             return;
         }
     } else {
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return;
     }
 
@@ -308,18 +312,19 @@ void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned
 
 void WebGLRenderingContext::bufferData(unsigned long target, WebGLArray* data, unsigned long usage, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) {
         if (!m_boundElementArrayBuffer->associateBufferData(target, data)) {
-            ec = SYNTAX_ERR;
+            m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
             return;
         }
     } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) {
         if (!m_boundArrayBuffer->associateBufferData(target, data)) {
-            ec = SYNTAX_ERR;
+            m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
             return;
         }
     } else {
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return;
     }
 
@@ -329,18 +334,19 @@ void WebGLRenderingContext::bufferData(unsigned long target, WebGLArray* data, u
 
 void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, WebGLArray* data, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) {
         if (!m_boundElementArrayBuffer->associateBufferSubData(target, offset, data)) {
-            ec = SYNTAX_ERR;
+            m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
             return;
         }
     } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) {
         if (!m_boundArrayBuffer->associateBufferSubData(target, offset, data)) {
-            ec = SYNTAX_ERR;
+            m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
             return;
         }
     } else {
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return;
     }
 
@@ -394,8 +400,9 @@ void WebGLRenderingContext::colorMask(bool red, bool green, bool blue, bool alph
 
 void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!shader || shader->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
     m_context->compileShader(shader);
@@ -451,8 +458,9 @@ PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
 
 PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(unsigned long type, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) {
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return 0;
     }
     
@@ -535,8 +543,9 @@ void WebGLRenderingContext::depthRange(double zNear, double zFar)
 
 void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!program || program->context() != this || !shader || shader->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
     m_context->detachShader(program, shader);
@@ -552,8 +561,9 @@ void WebGLRenderingContext::disable(unsigned long cap)
 
 void WebGLRenderingContext::disableVertexAttribArray(unsigned long index, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (index >= m_maxVertexAttribs) {
-        ec = INVALID_STATE_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
     
@@ -631,9 +641,10 @@ bool WebGLRenderingContext::validateRenderingState(long numElements)
 
 void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long count, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     // Ensure we have a valid rendering state
     if (first < 0 || count < 0 || !validateRenderingState(first + count)) {
-        ec = INVALID_STATE_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
     
@@ -643,11 +654,12 @@ void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long coun
 
 void WebGLRenderingContext::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     // Ensure we have a valid rendering state
     long numElements;
     
     if (offset < 0 || !validateIndexArray(count, type, offset, numElements) || !validateRenderingState(numElements)) {
-        ec = INVALID_STATE_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
     
@@ -663,8 +675,9 @@ void WebGLRenderingContext::enable(unsigned long cap)
 
 void WebGLRenderingContext::enableVertexAttribArray(unsigned long index, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (index >= m_maxVertexAttribs) {
-        ec = INVALID_STATE_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
     
@@ -692,8 +705,9 @@ void WebGLRenderingContext::flush()
 
 void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (buffer && buffer->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }       
     m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, buffer);
@@ -702,8 +716,9 @@ void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsign
 
 void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture* texture, long level, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (texture && texture->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
     m_context->framebufferTexture2D(target, attachment, textarget, texture, level);
@@ -724,9 +739,13 @@ void WebGLRenderingContext::generateMipmap(unsigned long target)
 
 PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, unsigned long index, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     ActiveInfo info;
-    if (!program || program->context() != this || !m_context->getActiveAttrib(program, index, info)) {
-        ec = INDEX_SIZE_ERR;
+    if (!program || program->context() != this) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+        return 0;
+    }
+    if (!m_context->getActiveAttrib(program, index, info)) {
         return 0;
     }
     return WebGLActiveInfo::create(info.name, info.type, info.size);
@@ -734,9 +753,13 @@ PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram*
 
 PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, unsigned long index, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     ActiveInfo info;
-    if (!program || program->context() != this || !m_context->getActiveUniform(program, index, info)) {
-        ec = INDEX_SIZE_ERR;
+    if (!program || program->context() != this) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+        return 0;
+    }
+    if (!m_context->getActiveUniform(program, index, info)) {
         return 0;
     }
     return WebGLActiveInfo::create(info.name, info.type, info.size);
@@ -749,15 +772,14 @@ int WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String
 
 WebGLGetInfo WebGLRenderingContext::getBufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) {
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return WebGLGetInfo();
     }
 
     if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) {
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return WebGLGetInfo();
     }
 
@@ -777,6 +799,7 @@ unsigned long WebGLRenderingContext::getError()
 
 WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, unsigned long pname, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (target != GraphicsContext3D::FRAMEBUFFER
         || (attachment != GraphicsContext3D::COLOR_ATTACHMENT0
             && attachment != GraphicsContext3D::DEPTH_ATTACHMENT
@@ -785,8 +808,7 @@ WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned l
             && pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME
             && pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL
             && pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE)) {
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return WebGLGetInfo();
     }
 
@@ -825,6 +847,7 @@ WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned l
 
 WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     WebGLStateRestorer(this, false);
     switch (pname) {
     case GraphicsContext3D::ACTIVE_TEXTURE:
@@ -991,17 +1014,16 @@ WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionC
     case GraphicsContext3D::VIEWPORT:
         return getWebGLIntArrayParameter(pname);
     default:
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return WebGLGetInfo();
     }
 }
 
 WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, unsigned long pname, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!program || program->context() != this) {
-        // FIXME: raise GL_INVALID_VALUE error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return WebGLGetInfo();
     }
 
@@ -1022,17 +1044,16 @@ WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, u
         m_context->getProgramiv(program, pname, &value);
         return WebGLGetInfo(static_cast<long>(value));
     default:
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return WebGLGetInfo();
     }
 }
 
 String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!program || program->context() != this) {
-        // FIXME: raise GL_INVALID_VALUE error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return "";
     }
     WebGLStateRestorer(this, false);
@@ -1041,9 +1062,9 @@ String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, Exception
 
 WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (target != GraphicsContext3D::RENDERBUFFER) {
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return WebGLGetInfo();
     }
 
@@ -1064,17 +1085,16 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long targe
         m_context->getRenderbufferParameteriv(target, pname, &value);
         return WebGLGetInfo(static_cast<unsigned long>(value));
     default:
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return WebGLGetInfo();
     }
 }
 
 WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsigned long pname, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!shader || shader->context() != this) {
-        // FIXME: raise GL_INVALID_VALUE error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return WebGLGetInfo();
     }
     WebGLStateRestorer(this, false);
@@ -1092,16 +1112,16 @@ WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsi
         m_context->getShaderiv(shader, pname, &value);
         return WebGLGetInfo(static_cast<long>(value));
     default:
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return WebGLGetInfo();
     }
 }
 
 String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!shader || shader->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return "";
     }
     WebGLStateRestorer(this, false);
@@ -1110,8 +1130,9 @@ String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCod
 
 String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!shader || shader->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return "";
     }
     WebGLStateRestorer(this, false);
@@ -1126,10 +1147,10 @@ String WebGLRenderingContext::getString(unsigned long name)
 
 WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (target != GraphicsContext3D::TEXTURE_2D
         && target != GraphicsContext3D::TEXTURE_CUBE_MAP) {
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return WebGLGetInfo();
     }
     WebGLStateRestorer(this, false);
@@ -1142,17 +1163,16 @@ WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsign
         m_context->getTexParameteriv(target, pname, &value);
         return WebGLGetInfo(static_cast<unsigned long>(value));
     default:
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return WebGLGetInfo();
     }
 }
 
 WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!program || uniformLocation->program() != program || program->context() != this) {
-        // FIXME: raise GL_INVALID_VALUE error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return WebGLGetInfo();
     }
     long location = uniformLocation->location();
@@ -1163,11 +1183,8 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG
     m_context->getProgramiv(program, GraphicsContext3D::ACTIVE_UNIFORMS, &activeUniforms);
     for (int i = 0; i < activeUniforms; i++) {
         ActiveInfo info;
-        if (!m_context->getActiveUniform(program, i, info)) {
-            // FIXME: raise some GL error
-            ec = INVALID_STATE_ERR;
+        if (!m_context->getActiveUniform(program, i, info))
             return WebGLGetInfo();
-        }
         // Now need to look this up by name again to find its location
         long loc = m_context->getUniformLocation(program, info.name);
         if (loc == location) {
@@ -1238,6 +1255,7 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG
                 default:
                     // Can't handle this type
                     // FIXME: what to do about samplers?
+                    m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
                     return WebGLGetInfo();
             }
             switch (baseType) {
@@ -1275,13 +1293,15 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG
         }
     }
     // If we get here, something went wrong in our unfortunately complex logic above
+    m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
     return WebGLGetInfo();
 }
 
 PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!program || program->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return 0;
     }
     WebGLStateRestorer(this, false);
@@ -1290,6 +1310,7 @@ PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGL
 
 WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigned long pname, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     WebGLStateRestorer(this, false);
     switch (pname) {
     case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
@@ -1324,8 +1345,7 @@ WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigne
         return WebGLGetInfo(WebGLFloatArray::create(value, 4));
     }
     default: {
-        // FIXME: raise GL_INVALID_ENUM error
-        ec = SYNTAX_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return WebGLGetInfo();
     }
     }
@@ -1405,8 +1425,9 @@ void WebGLRenderingContext::lineWidth(double width)
 
 void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!program || program->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
         
@@ -1459,8 +1480,9 @@ void WebGLRenderingContext::scissor(long x, long y, unsigned long width, unsigne
 
 void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!shader || shader->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
     m_context->shaderSource(shader, string);
@@ -1530,13 +1552,15 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImag
 {
     ec = 0;
     if (!image) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
 
     CachedImage* cachedImage = image->cachedImage();
-    if (!cachedImage)
+    if (!cachedImage) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
+    }
 
     // FIXME: For now we ignore any errors returned
     m_context->texImage2D(target, level, cachedImage->image(), flipY, premultiplyAlpha);
@@ -1548,13 +1572,15 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanv
 {
     ec = 0;
     if (!canvas) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
 
     ImageBuffer* buffer = canvas->buffer();
-    if (!buffer)
+    if (!buffer) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
+    }
 
     // FIXME: For now we ignore any errors returned
     m_context->texImage2D(target, level, buffer->image(), flipY, premultiplyAlpha);
@@ -1609,13 +1635,15 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
     // FIXME: For now we ignore any errors returned
     ec = 0;
     if (!image) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
     
     CachedImage* cachedImage = image->cachedImage();
-    if (!cachedImage)
+    if (!cachedImage) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
+    }
 
     m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, cachedImage->image(), flipY, premultiplyAlpha);
     cleanupAfterGraphicsCall(false);
@@ -1627,13 +1655,15 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
 {
     ec = 0;
     if (!canvas) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
     
     ImageBuffer* buffer = canvas->buffer();
-    if (!buffer)
+    if (!buffer) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
+    }
     
     // FIXME: For now we ignore any errors returned
     m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, buffer->image(), flipY, premultiplyAlpha);
@@ -1652,9 +1682,9 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
 
 void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
 
@@ -1664,104 +1694,104 @@ void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, floa
 
 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     m_context->uniform1fv(location->location(), v->data(), v->length());
     cleanupAfterGraphicsCall(false);
 }
 
 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     m_context->uniform1fv(location->location(), v, size);
     cleanupAfterGraphicsCall(false);
 }
 
 void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, int x, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
+
     m_context->uniform1i(location->location(), x);
     cleanupAfterGraphicsCall(false);
 }
 
 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, WebGLIntArray* v, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     m_context->uniform1iv(location->location(), v->data(), v->length());
     cleanupAfterGraphicsCall(false);
 }
 
 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     m_context->uniform1iv(location->location(), v, size);
     cleanupAfterGraphicsCall(false);
 }
 
 void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, float x, float y, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
+
     m_context->uniform2f(location->location(), x, y);
     cleanupAfterGraphicsCall(false);
 }
 
 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 2
     m_context->uniform2fv(location->location(), v->data(), v->length() / 2);
     cleanupAfterGraphicsCall(false);
@@ -1769,16 +1799,16 @@ void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Web
 
 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 2
     m_context->uniform2fv(location->location(), v, size / 2);
     cleanupAfterGraphicsCall(false);
@@ -1786,28 +1816,28 @@ void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, flo
 
 void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, int x, int y, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
+
     m_context->uniform2i(location->location(), x, y);
     cleanupAfterGraphicsCall(false);
 }
 
 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, WebGLIntArray* v, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 2
     m_context->uniform2iv(location->location(), v->data(), v->length() / 2);
     cleanupAfterGraphicsCall(false);
@@ -1815,16 +1845,16 @@ void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Web
 
 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 2
     m_context->uniform2iv(location->location(), v, size / 2);
     cleanupAfterGraphicsCall(false);
@@ -1832,28 +1862,28 @@ void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int
 
 void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, float x, float y, float z, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
+
     m_context->uniform3f(location->location(), x, y, z);
     cleanupAfterGraphicsCall(false);
 }
 
 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 3
     m_context->uniform3fv(location->location(), v->data(), v->length() / 3);
     cleanupAfterGraphicsCall(false);
@@ -1861,16 +1891,16 @@ void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Web
 
 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 3
     m_context->uniform3fv(location->location(), v, size / 3);
     cleanupAfterGraphicsCall(false);
@@ -1878,28 +1908,28 @@ void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, flo
 
 void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, int x, int y, int z, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
+
     m_context->uniform3i(location->location(), x, y, z);
     cleanupAfterGraphicsCall(false);
 }
 
 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, WebGLIntArray* v, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 3
     m_context->uniform3iv(location->location(), v->data(), v->length() / 3);
     cleanupAfterGraphicsCall(false);
@@ -1907,16 +1937,16 @@ void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Web
 
 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 3
     m_context->uniform3iv(location->location(), v, size / 3);
     cleanupAfterGraphicsCall(false);
@@ -1924,28 +1954,28 @@ void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int
 
 void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, float x, float y, float z, float w, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
+
     m_context->uniform4f(location->location(), x, y, z, w);
     cleanupAfterGraphicsCall(false);
 }
 
 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 4
     m_context->uniform4fv(location->location(), v->data(), v->length() / 4);
     cleanupAfterGraphicsCall(false);
@@ -1953,16 +1983,16 @@ void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Web
 
 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 4
     m_context->uniform4fv(location->location(), v, size / 4);
     cleanupAfterGraphicsCall(false);
@@ -1970,28 +2000,28 @@ void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, flo
 
 void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, int x, int y, int z, int w, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
+
     m_context->uniform4i(location->location(), x, y, z, w);
     cleanupAfterGraphicsCall(false);
 }
 
 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, WebGLIntArray* v, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 4
     m_context->uniform4iv(location->location(), v->data(), v->length() / 4);
     cleanupAfterGraphicsCall(false);
@@ -1999,16 +2029,16 @@ void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Web
 
 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 4
     m_context->uniform4iv(location->location(), v, size / 4);
     cleanupAfterGraphicsCall(false);
@@ -2016,16 +2046,16 @@ void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int
 
 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, WebGLFloatArray* v, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 4
     m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4);
     cleanupAfterGraphicsCall(false);
@@ -2033,16 +2063,16 @@ void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* locatio
 
 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 4
     m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4);
     cleanupAfterGraphicsCall(false);
@@ -2050,16 +2080,16 @@ void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* locatio
 
 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, WebGLFloatArray* v, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 9
     m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9);
     cleanupAfterGraphicsCall(false);
@@ -2067,16 +2097,16 @@ void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* locatio
 
 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 9
     m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9);
     cleanupAfterGraphicsCall(false);
@@ -2084,16 +2114,16 @@ void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* locatio
 
 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, WebGLFloatArray* v, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 16
     m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16);
     cleanupAfterGraphicsCall(false);
@@ -2101,16 +2131,16 @@ void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* locatio
 
 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!location || location->program() != m_currentProgram) {
-        // FIXME: raise GL_INVALID_OPERATION error
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    
-    // FIXME: we need to throw if no array passed in
-    if (!v)
+
+    if (!v) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
-        
+    }
     // FIXME: length needs to be a multiple of 16
     m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16);
     cleanupAfterGraphicsCall(false);
@@ -2118,8 +2148,9 @@ void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* locatio
 
 void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!program || program->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
         
@@ -2130,8 +2161,9 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
 
 void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!program || program->context() != this) {
-        ec = TYPE_MISMATCH_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
         
@@ -2229,9 +2261,9 @@ void WebGLRenderingContext::vertexAttrib4fv(unsigned long indx, float* v, int si
 
 void WebGLRenderingContext::vertexAttribPointer(unsigned long indx, long size, unsigned long type, bool normalized, unsigned long stride, unsigned long offset, ExceptionCode& ec)
 {
+    UNUSED_PARAM(ec);
     if (!m_boundArrayBuffer || indx >= m_maxVertexAttribs) {
-        // FIXME: raise GL_INVALID_VALUE error
-        ec = INVALID_STATE_ERR;
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
     
@@ -2239,15 +2271,13 @@ void WebGLRenderingContext::vertexAttribPointer(unsigned long indx, long size, u
         m_vertexAttribState.resize(indx + 1);
 
     // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
-    ec = 0;
     long bytesPerElement = size * sizeInBytes(type, ec);
-    if (ec != 0)
+    if (bytesPerElement <= 0)
         return;
     long validatedStride = bytesPerElement;
     if (stride != 0) {
         if ((long) stride < bytesPerElement) {
-            // FIXME: raise GL_INVALID_VALUE error
-            ec = SYNTAX_ERR;
+            m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
             return;
         }
         
diff --git a/WebCore/html/canvas/WebGLRenderingContext.h b/WebCore/html/canvas/WebGLRenderingContext.h
index 399b155..3335eba 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/WebCore/html/canvas/WebGLRenderingContext.h
@@ -297,7 +297,6 @@ class WebKitCSSMatrix;
         void markContextChanged();
         void cleanupAfterGraphicsCall(bool changed)
         {
-            m_context->checkError();
             if (changed)
                 markContextChanged();
         }
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index 155b4ed..aad8dd4 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -28,6 +28,7 @@
 
 #include "PlatformString.h"
 
+#include <wtf/ListHashSet.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/PassOwnPtr.h>
 
@@ -397,7 +398,6 @@ namespace WebCore {
         PlatformGraphicsContext3D platformGraphicsContext3D() const { return NullPlatformGraphicsContext3D; }
         Platform3DObject platformTexture() const { return NullPlatform3DObject; }
 #endif
-        void checkError() const;
         void makeContextCurrent();
         
         // Helper to return the size in bytes of OpenGL data types
@@ -612,6 +612,16 @@ namespace WebCore {
         void deleteShader(unsigned);
         void deleteTexture(unsigned);        
         
+        // Synthesizes an OpenGL error which will be returned from a
+        // later call to getError. This is used to emulate OpenGL ES
+        // 2.0 behavior on the desktop and to enforce additional error
+        // checking mandated by WebGL.
+        //
+        // Per the behavior of glGetError, this stores at most one
+        // instance of any given error, and returns them from calls to
+        // getError in the order they were added.
+        void synthesizeGLError(unsigned long error);
+
     private:        
         GraphicsContext3D();
 
@@ -624,6 +634,8 @@ namespace WebCore {
         GLuint m_texture;
         GLuint m_fbo;
         GLuint m_depthBuffer;
+        // Errors raised by synthesizeGLError().
+        ListHashSet<unsigned long> m_syntheticErrors;
 #endif        
 
         // FIXME: ideally this would be used on all platforms.
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
index 071e2d0..41f63a9 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
@@ -175,15 +175,6 @@ GraphicsContext3D::~GraphicsContext3D()
     }
 }
 
-void GraphicsContext3D::checkError() const
-{
-    // FIXME: This needs to only be done in the debug context. It will probably throw an exception
-    // on error and print the error message to the debug console
-    GLenum error = ::glGetError();
-    if (error != GL_NO_ERROR)
-        notImplemented();
-}
-
 void GraphicsContext3D::makeContextCurrent()
 {
     CGLSetCurrentContext(m_contextObj);
@@ -502,8 +493,10 @@ void GraphicsContext3D::generateMipmap(unsigned long target)
 
 bool GraphicsContext3D::getActiveAttrib(WebGLProgram* program, unsigned long index, ActiveInfo& info)
 {
-    if (!program->object())
+    if (!program->object()) {
+        synthesizeGLError(INVALID_VALUE);
         return false;
+    }
     ensureContext(m_contextObj);
     GLint maxAttributeSize = 0;
     ::glGetProgramiv(static_cast<GLuint>(program->object()), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize);
@@ -522,8 +515,10 @@ bool GraphicsContext3D::getActiveAttrib(WebGLProgram* program, unsigned long ind
     
 bool GraphicsContext3D::getActiveUniform(WebGLProgram* program, unsigned long index, ActiveInfo& info)
 {
-    if (!program->object())
+    if (!program->object()) {
+        synthesizeGLError(INVALID_VALUE);
         return false;
+    }
     ensureContext(m_contextObj);
     GLint maxUniformSize = 0;
     ::glGetProgramiv(static_cast<GLuint>(program->object()), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize);
@@ -551,6 +546,13 @@ int GraphicsContext3D::getAttribLocation(WebGLProgram* program, const String& na
 
 unsigned long GraphicsContext3D::getError()
 {
+    if (m_syntheticErrors.size() > 0) {
+        ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin();
+        unsigned long err = *iter;
+        m_syntheticErrors.remove(iter);
+        return err;
+    }
+
     ensureContext(m_contextObj);
     return ::glGetError();
 }
@@ -1353,6 +1355,11 @@ int GraphicsContext3D::sizeInBytes(int type)
     }
 }
 
+void GraphicsContext3D::synthesizeGLError(unsigned long error)
+{
+    m_syntheticErrors.add(error);
+}
+
 }
 
 #endif // ENABLE(3D_CANVAS)
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 5c22d6f..40da899 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,33 @@
+2009-12-10  Kenneth Russell  <kbr at google.com>
+
+        Reviewed by Oliver Hunt.
+
+        Changed WebGLRenderingContext to synthesize GL errors rather than
+        raising JavaScript exceptions. Removed internal getError() calls
+        after each graphics call. The GraphicsContext3D maintains the
+        synthetic exceptions because only it has complete information
+        about certain conditions requiring them to be raised.
+
+        Based on idea from Ilmari Heikkinen, added create3DDebugContext()
+        to webgl-test.js and changed the WebGL layout tests expecting
+        error conditions to use it. Updated expected.txt files, which now
+        implicitly test the OpenGL error as it is part of the exception's
+        message.
+
+        Added new targeted test covering aspects of synthetic errors as
+        well as regression tests for bugs uncovered during its development.
+
+        Test: fast/canvas/webgl/error-reporting.html
+
+        * src/GraphicsContext3D.cpp:
+        (WebCore::GraphicsContext3DInternal::reshape):
+        (WebCore::GraphicsContext3DInternal::getError):
+        (WebCore::GraphicsContext3DInternal::synthesizeGLError):
+        (WebCore::GraphicsContext3D::getActiveAttrib):
+        (WebCore::GraphicsContext3D::getActiveUniform):
+        (WebCore::GraphicsContext3D::getError):
+        (WebCore::GraphicsContext3D::synthesizeGLError):
+
 2009-12-10  Mike Belshe  <mike at belshe.com>
 
         Reviewed by Darin Fisher.
diff --git a/WebKit/chromium/src/GraphicsContext3D.cpp b/WebKit/chromium/src/GraphicsContext3D.cpp
index f8687f3..c9ba5a1 100644
--- a/WebKit/chromium/src/GraphicsContext3D.cpp
+++ b/WebKit/chromium/src/GraphicsContext3D.cpp
@@ -101,7 +101,6 @@ public:
     GraphicsContext3DInternal();
     ~GraphicsContext3DInternal();
 
-    void checkError() const;
     bool makeContextCurrent();
 
     PlatformGraphicsContext3D platformGraphicsContext3D() const;
@@ -122,10 +121,13 @@ public:
     void bufferDataImpl(unsigned long target, int size, const void* data, unsigned long usage);
     void disableVertexAttribArray(unsigned long index);
     void enableVertexAttribArray(unsigned long index);
+    unsigned long getError();
     void vertexAttribPointer(unsigned long indx, int size, int type, bool normalized,
                              unsigned long stride, unsigned long offset);
     void viewportImpl(long x, long y, unsigned long width, unsigned long height);
 
+    void synthesizeGLError(unsigned long error);
+
 private:
     unsigned int m_texture;
     unsigned int m_fbo;
@@ -162,6 +164,9 @@ private:
     };
     VertexAttribPointerState m_vertexAttribPointerState[NumTrackedPointerStates];
 
+    // Errors raised by synthesizeGLError().
+    ListHashSet<unsigned long> m_syntheticErrors;
+
 #if PLATFORM(SKIA)
     // If the width and height of the Canvas's backing store don't
     // match those that we were given in the most recent call to
@@ -515,17 +520,6 @@ GraphicsContext3DInternal::~GraphicsContext3DInternal()
     m_contextObj = 0;
 }
 
-void GraphicsContext3DInternal::checkError() const
-{
-    // FIXME: This needs to only be done in the debug context. It
-    // will need to throw an exception on error.
-    GLenum error = glGetError();
-    if (error != GL_NO_ERROR) {
-        printf("GraphicsContext3DInternal: GL Error : %x\n", error);
-        notImplemented();
-    }
-}
-
 bool GraphicsContext3DInternal::makeContextCurrent()
 {
 #if PLATFORM(WIN_OS)
@@ -592,7 +586,6 @@ void GraphicsContext3DInternal::reshape(int width, int height)
         glGenFramebuffersEXT(1, &m_fbo);
         // Generate the depth buffer
         glGenRenderbuffersEXT(1, &m_depthBuffer);
-        checkError();
     }
 
     // Reallocate the color and depth buffers
@@ -858,6 +851,19 @@ void GraphicsContext3DInternal::enableVertexAttribArray(unsigned long index)
     glEnableVertexAttribArray(index);
 }
 
+unsigned long GraphicsContext3DInternal::getError()
+{
+    if (m_syntheticErrors.size() > 0) {
+        ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin();
+        unsigned long err = *iter;
+        m_syntheticErrors.remove(iter);
+        return err;
+    }
+
+    makeContextCurrent();
+    return glGetError();
+}
+
 void GraphicsContext3DInternal::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized,
                                                     unsigned long stride, unsigned long offset)
 {
@@ -889,6 +895,11 @@ void GraphicsContext3DInternal::viewportImpl(long x, long y, unsigned long width
     glViewport(x, y, width, height);
 }
 
+void GraphicsContext3DInternal::synthesizeGLError(unsigned long error)
+{
+    m_syntheticErrors.add(error);
+}
+
 // GraphicsContext3D -----------------------------------------------------
 
 /* Helper macros for when we're just wrapping a gl method, so that
@@ -1029,11 +1040,6 @@ Platform3DObject GraphicsContext3D::platformTexture() const
     return m_internal->platformTexture();
 }
 
-void GraphicsContext3D::checkError() const
-{
-    m_internal->checkError();
-}
-
 void GraphicsContext3D::makeContextCurrent()
 {
     m_internal->makeContextCurrent();
@@ -1361,15 +1367,19 @@ void GraphicsContext3D::generateMipmap(unsigned long target)
 
 bool GraphicsContext3D::getActiveAttrib(WebGLProgram* program, unsigned long index, ActiveInfo& info)
 {
-    if (!program)
+    if (!program) {
+        synthesizeGLError(INVALID_VALUE);
         return false;
+    }
     GLint maxNameLength = -1;
     glGetProgramiv(EXTRACT(program), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength);
     if (maxNameLength < 0)
         return false;
     GLchar* name = 0;
-    if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name))
+    if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) {
+        synthesizeGLError(OUT_OF_MEMORY);
         return false;
+    }
     GLsizei length = 0;
     GLint size = -1;
     GLenum type = 0;
@@ -1388,15 +1398,19 @@ bool GraphicsContext3D::getActiveAttrib(WebGLProgram* program, unsigned long ind
 
 bool GraphicsContext3D::getActiveUniform(WebGLProgram* program, unsigned long index, ActiveInfo& info)
 {
-    if (!program)
+    if (!program) {
+        synthesizeGLError(INVALID_VALUE);
         return false;
+    }
     GLint maxNameLength = -1;
     glGetProgramiv(EXTRACT(program), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
     if (maxNameLength < 0)
         return false;
     GLchar* name = 0;
-    if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name))
+    if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) {
+        synthesizeGLError(OUT_OF_MEMORY);
         return false;
+    }
     GLsizei length = 0;
     GLint size = -1;
     GLenum type = 0;
@@ -1436,8 +1450,7 @@ void GraphicsContext3D::getBufferParameteriv(unsigned long target, unsigned long
 
 unsigned long GraphicsContext3D::getError()
 {
-    makeContextCurrent();
-    return glGetError();
+    return m_internal->getError();
 }
 
 void GraphicsContext3D::getFloatv(unsigned long pname, float* value)
@@ -1709,6 +1722,11 @@ GL_SAME_METHOD_3(StencilOp, stencilOp, unsigned long, unsigned long, unsigned lo
 
 GL_SAME_METHOD_4(StencilOpSeparate, stencilOpSeparate, unsigned long, unsigned long, unsigned long, unsigned long)
 
+void GraphicsContext3D::synthesizeGLError(unsigned long error)
+{
+    m_internal->synthesizeGLError(error);
+}
+
 int GraphicsContext3D::texImage2D(unsigned target,
                                   unsigned level,
                                   unsigned internalformat,

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list