Title: [127452] trunk
Revision
127452
Author
commit-qu...@webkit.org
Date
2012-09-04 02:37:41 -0700 (Tue, 04 Sep 2012)

Log Message

Web Inspector: [WebGL] Save gl.getError() status before taking a WebGL state snapshot and restore it afterwards
https://bugs.webkit.org/show_bug.cgi?id=95443

Patch by Andrey Adaikin <aand...@chromium.org> on 2012-09-04
Reviewed by Vsevolod Vlasov.

Source/WebCore:

Save gl.getError() status before taking the GL snapshot and restore it afterwards.

* inspector/InjectedScriptWebGLModuleSource.js:
(.):

LayoutTests:

Adds a test to check that we properly save the WebGL getError() status while doing the instrumentation.

* inspector/profiler/webgl/webgl-profiler-get-error-expected.txt: Added.
* inspector/profiler/webgl/webgl-profiler-get-error.html: Added.
* inspector/profiler/webgl/webgl-profiler-test.js: Added.
(initialize_WebGLProfilerTest.InspectorTest.enableWebGLAgent):
(initialize_WebGLProfilerTest):
(createWebGLContext):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (127451 => 127452)


--- trunk/LayoutTests/ChangeLog	2012-09-04 09:25:24 UTC (rev 127451)
+++ trunk/LayoutTests/ChangeLog	2012-09-04 09:37:41 UTC (rev 127452)
@@ -1,3 +1,19 @@
+2012-09-04  Andrey Adaikin  <aand...@chromium.org>
+
+        Web Inspector: [WebGL] Save gl.getError() status before taking a WebGL state snapshot and restore it afterwards
+        https://bugs.webkit.org/show_bug.cgi?id=95443
+
+        Reviewed by Vsevolod Vlasov.
+
+        Adds a test to check that we properly save the WebGL getError() status while doing the instrumentation.
+
+        * inspector/profiler/webgl/webgl-profiler-get-error-expected.txt: Added.
+        * inspector/profiler/webgl/webgl-profiler-get-error.html: Added.
+        * inspector/profiler/webgl/webgl-profiler-test.js: Added.
+        (initialize_WebGLProfilerTest.InspectorTest.enableWebGLAgent):
+        (initialize_WebGLProfilerTest):
+        (createWebGLContext):
+
 2012-09-04  Alexander Pavlov  <apav...@chromium.org>
 
         Web Inspector: More directional control characters for debugging in inspector

Added: trunk/LayoutTests/inspector/profiler/webgl/webgl-profiler-get-error-expected.txt (0 => 127452)


--- trunk/LayoutTests/inspector/profiler/webgl/webgl-profiler-get-error-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/profiler/webgl/webgl-profiler-get-error-expected.txt	2012-09-04 09:37:41 UTC (rev 127452)
@@ -0,0 +1,3 @@
+Tests WebGL getError() status.
+
+Bug 95443

Added: trunk/LayoutTests/inspector/profiler/webgl/webgl-profiler-get-error.html (0 => 127452)


--- trunk/LayoutTests/inspector/profiler/webgl/webgl-profiler-get-error.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/profiler/webgl/webgl-profiler-get-error.html	2012-09-04 09:37:41 UTC (rev 127452)
@@ -0,0 +1,140 @@
+<html>
+<head>
+    <script src=""
+    <script src=""
+<script>
+
+var gl;
+var rawGL;
+var glResource;
+
+function assertNoErrors(gl)
+{
+    console.assert(gl.getError() === gl.NO_ERROR, "No GL error was expected at this time");
+}
+
+function assertEqualArrays(a, b)
+{
+    console.assert(a.length === b.length, "assertEqualArrays: a.length=" + a.length + ", b.length=" + b.length);
+    a = a.slice();
+    b = b.slice();
+    a.sort();
+    b.sort();
+    a.forEach(function(element, index) {
+        console.assert(a[index] === b[index], "assertEqualArrays: different values at index " + index);
+    });
+}
+
+function generateWebGLError(gl, error)
+{
+    switch (error) {
+    case gl.INVALID_ENUM:
+        gl.pixelStorei(123, 234);
+        break;
+    case gl.INVALID_VALUE:
+        gl.pixelStorei(gl.PACK_ALIGNMENT, 234);
+        break;
+    case gl.INVALID_OPERATION:
+    default:
+        gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+        break;
+    }
+}
+
+function getAllErrors(gl)
+{
+    var errors = [];
+    while (true) {
+        var error = gl.getError();
+        if (error === gl.NO_ERROR)
+            break;
+        console.assert(typeof error === "number", "getError() should return a number instead of a " + (typeof error));
+        errors.push(error);
+    }
+    return errors;
+}
+
+function createAndRunWebGLProgram()
+{
+    gl = createWebGLContext();
+    console.assert(gl, "Failed to create WebGL context");
+
+    glResource = gl["__resourceObject"];
+    console.assert(glResource, "WebGL context is not wrapped");
+
+    rawGL = glResource.wrappedObject();
+    console.assert(rawGL, "No raw WebGL context found");
+    console.assert(gl !== rawGL, "Proxy and RAW contexts should not be the same");
+
+    assertNoErrors(gl);
+    assertNoErrors(rawGL);
+
+    // 1) Generate errors directly on the RAW context
+    // 2) Pick them via proxy.
+    var errors = [rawGL.INVALID_ENUM, rawGL.INVALID_VALUE, rawGL.INVALID_OPERATION];
+    errors.forEach(generateWebGLError.bind(this, rawGL));
+    assertEqualArrays(errors, getAllErrors(gl));
+    assertNoErrors(gl);
+    assertNoErrors(rawGL);
+
+    // 1) Generate errors on RAW context
+    // 2) Convert Resource to a Replayable => this should clean up the RAW context and save the errors in proxy
+    // 3) Check that RAW context no longer have errors
+    // 4) Check that proxy still has the original errors saved
+    var errors = [rawGL.INVALID_ENUM, rawGL.INVALID_VALUE, rawGL.INVALID_OPERATION];
+    errors.forEach(generateWebGLError.bind(this, rawGL));
+    var cache = {
+        put: function() {},
+        get: function() {}
+    };
+    glResource.toReplayable(cache);
+    assertNoErrors(rawGL);
+    assertEqualArrays(errors, getAllErrors(gl));
+    assertNoErrors(gl);
+
+    // 1) Repeat 1-3 steps from the above
+    // 2) Check proxy and RAW errors interleaved
+    var errors = [rawGL.INVALID_ENUM, rawGL.INVALID_VALUE, rawGL.INVALID_OPERATION];
+    errors.forEach(generateWebGLError.bind(this, rawGL));
+    var cache = {
+        put: function() {},
+        get: function() {}
+    };
+    glResource.toReplayable(cache);
+    assertNoErrors(rawGL);
+
+    var value = gl.getError();
+    console.assert(typeof value === "number", "getError() should return a number instead of a " + (typeof value));
+    console.assert(value !== gl.NO_ERROR, "An error was expected");
+    errors.forEach(generateWebGLError.bind(this, rawGL)); // Generate again in the RAW context.
+    // Now we "have" 2 errors left in the proxy and 3 new errors in the RAW context => should return 3 errors from the proxy.
+    assertEqualArrays(errors, getAllErrors(gl));
+    assertNoErrors(gl);
+    assertNoErrors(rawGL);
+
+    return "SUCCESS";
+}
+
+function test()
+{
+    InspectorTest.enableWebGLAgent(step1);
+    function step1()
+    {
+        InspectorTest.evaluateInConsole("createAndRunWebGLProgram()", step2);
+    }
+    function step2(error)
+    {
+        InspectorTest.assertEquals("\"SUCCESS\"", error);
+        InspectorTest.completeTest();
+    }
+}
+
+</script>
+</head>
+<body _onload_="runTest()">
+<p>
+Tests WebGL getError() status.
+</p>
+<a href="" 95443</a>
+</body>
+</html>

Added: trunk/LayoutTests/inspector/profiler/webgl/webgl-profiler-test.js (0 => 127452)


--- trunk/LayoutTests/inspector/profiler/webgl/webgl-profiler-test.js	                        (rev 0)
+++ trunk/LayoutTests/inspector/profiler/webgl/webgl-profiler-test.js	2012-09-04 09:37:41 UTC (rev 127452)
@@ -0,0 +1,37 @@
+var initialize_WebGLProfilerTest = function() {
+
+InspectorTest.enableWebGLAgent = function(callback)
+{
+    function webGLAgentEnabled(error)
+    {
+        if (!error)
+            InspectorTest.safeWrap(callback)();
+        else {
+            InspectorTest.addResult("FAILED to enable WebGLAgent: " + error);
+            InspectorTest.completeTest();
+        }
+    }
+    try {
+        WebGLAgent.enable(webGLAgentEnabled);
+    } catch (e) {
+        InspectorTest.addResult("Exception while enabling WebGLAgent", e);
+        InspectorTest.completeTest();
+    }
+};
+
+};
+
+function createWebGLContext(opt_canvas)
+{
+    var canvas = opt_canvas || document.createElement("canvas");
+    var contextIds = ["experimental-webgl", "webkit-3d", "3d"];
+    for (var i = 0, contextId; contextId = contextIds[i]; ++i) {
+        var gl = canvas.getContext(contextId);
+        if (gl)
+            return gl;
+    }
+    return null;
+}
+
+if (window.testRunner)
+    testRunner.overridePreference("WebKitWebGLEnabled", "1");

Modified: trunk/Source/WebCore/ChangeLog (127451 => 127452)


--- trunk/Source/WebCore/ChangeLog	2012-09-04 09:25:24 UTC (rev 127451)
+++ trunk/Source/WebCore/ChangeLog	2012-09-04 09:37:41 UTC (rev 127452)
@@ -1,3 +1,15 @@
+2012-09-04  Andrey Adaikin  <aand...@chromium.org>
+
+        Web Inspector: [WebGL] Save gl.getError() status before taking a WebGL state snapshot and restore it afterwards
+        https://bugs.webkit.org/show_bug.cgi?id=95443
+
+        Reviewed by Vsevolod Vlasov.
+
+        Save gl.getError() status before taking the GL snapshot and restore it afterwards.
+
+        * inspector/InjectedScriptWebGLModuleSource.js:
+        (.):
+
 2012-09-04  Alexander Pavlov  <apav...@chromium.org>
 
         Web Inspector: More directional control characters for debugging in inspector

Modified: trunk/Source/WebCore/inspector/InjectedScriptWebGLModuleSource.js (127451 => 127452)


--- trunk/Source/WebCore/inspector/InjectedScriptWebGLModuleSource.js	2012-09-04 09:25:24 UTC (rev 127451)
+++ trunk/Source/WebCore/inspector/InjectedScriptWebGLModuleSource.js	2012-09-04 09:37:41 UTC (rev 127452)
@@ -339,6 +339,14 @@
         this._stackTrace = stackTrace;
     },
 
+    /**
+     * @param {*} result
+     */
+    setResult: function(result)
+    {
+        this._result = result;
+    },
+
     freeze: function()
     {
         if (this._freezed)
@@ -895,6 +903,8 @@
         var gl = glResource.wrappedObject();
         var program = this.wrappedObject();
 
+        var originalErrors = glResource.getAllErrors();
+
         var uniforms = [];
         var uniformsCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
         for (var i = 0; i < uniformsCount; ++i) {
@@ -912,6 +922,8 @@
             });
         }
         data.uniforms = uniforms;
+
+        glResource.restoreErrors(originalErrors);
     },
 
     /**
@@ -1215,6 +1227,79 @@
     },
 
     /**
+     * @return {Array.<number>}
+     */
+    getAllErrors: function()
+    {
+        var errors = [];
+        var gl = this.wrappedObject();
+        if (gl) {
+            while (true) {
+                var error = gl.getError();
+                if (error === gl.NO_ERROR)
+                    break;
+                this.clearError(error);
+                errors.push(error);
+            }
+        }
+        if (this._customErrors) {
+            for (var key in this._customErrors) {
+                var error = Number(key);
+                errors.push(error);
+            }
+            delete this._customErrors;
+        }
+        return errors;
+    },
+
+    /**
+     * @param {Array.<number>} errors
+     */
+    restoreErrors: function(errors)
+    {
+        var gl = this.wrappedObject();
+        if (gl) {
+            var wasError = false;
+            while (gl.getError() !== gl.NO_ERROR)
+                wasError = true;
+            console.assert(!wasError, "Error(s) while capturing current WebGL state.");
+        }
+        if (!errors.length)
+            delete this._customErrors;
+        else {
+            this._customErrors = {};
+            for (var i = 0, n = errors.length; i < n; ++i)
+                this._customErrors[errors[i]] = true;
+        }
+    },
+
+    /**
+     * @param {number} error
+     */
+    clearError: function(error)
+    {
+        if (this._customErrors)
+            delete this._customErrors[error];
+    },
+
+    /**
+     * @return {number}
+     */
+    nextError: function()
+    {
+        if (this._customErrors) {
+            for (var key in this._customErrors) {
+                var error = Number(key);
+                delete this._customErrors[error];
+                return error;
+            }
+        }
+        delete this._customErrors;
+        var gl = this.wrappedObject();
+        return gl ? gl.NO_ERROR : 0;
+    },
+
+    /**
      * @override
      * @param {Object} data
      * @param {Cache} cache
@@ -1224,7 +1309,7 @@
         var gl = this.wrappedObject();
         data.replayContextCallback = this._replayContextCallback;
 
-        // FIXME: Save the getError() status and restore it after taking the GL state snapshot.
+        var originalErrors = this.getAllErrors();
 
         // Take a full GL state snapshot.
         var glState = {};
@@ -1233,7 +1318,6 @@
         });
         WebGLRenderingContextResource.StateParameters.forEach(function(parameter) {
             glState[parameter] = Resource.toReplayable(gl.getParameter(gl[parameter]), cache);
-            // FIXME: Call while(gl.getError() != gl.NO_ERROR) {...} to check if a particular parameter is supported.
         });
 
         // VERTEX_ATTRIB_ARRAYS
@@ -1266,6 +1350,8 @@
         gl.activeTexture(currentTextureBinding);
 
         data.glState = glState;
+
+        this.restoreErrors(originalErrors);
     },
 
     /**
@@ -1546,6 +1632,16 @@
         if (!this._call)
             this._call = new Call(this._glResource, this._functionName, this._args, this.result());
         return this._call;
+    },
+
+    /**
+     * @param {*} result
+     */
+    _overrideResult: function(result)
+    {
+        var call = this.call();
+        call.setResult(result);
+        this._result = result;
     }
 }
 
@@ -1627,6 +1723,20 @@
         customWrapFunction("framebufferTexture2D");
         customWrapFunction("renderbufferStorage");
 
+        /** @this WebGLRenderingContextResource.WrapFunction */
+        wrapFunctions["getError"] = function()
+        {
+            var gl = this._originalObject;
+            var error = this.result();
+            if (error !== gl.NO_ERROR)
+                this._glResource.clearError(error);
+            else {
+                error = this._glResource.nextError();
+                if (error !== gl.NO_ERROR)
+                    this._overrideResult(error);
+            }
+        }
+
         WebGLRenderingContextResource._wrapFunctions = wrapFunctions;
     }
     return wrapFunctions;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to