Web Inspector: [WebGL] Save gl.getError() status before taking a WebGL state...

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 <aandrey@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):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@127452 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 3a5958b5
2012-09-04 Andrey Adaikin <aandrey@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 <apavlov@chromium.org>
Web Inspector: More directional control characters for debugging in inspector
<html>
<head>
<script src="../../../http/tests/inspector/inspector-test.js"></script>
<script src="webgl-profiler-test.js"></script>
<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="https://bugs.webkit.org/show_bug.cgi?id=95443">Bug 95443</a>
</body>
</html>
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");
2012-09-04 Andrey Adaikin <aandrey@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 <apavlov@chromium.org>
Web Inspector: More directional control characters for debugging in inspector
......@@ -339,6 +339,14 @@ Call.prototype = {
this._stackTrace = stackTrace;
},
/**
* @param {*} result
*/
setResult: function(result)
{
this._result = result;
},
freeze: function()
{
if (this._freezed)
......@@ -895,6 +903,8 @@ WebGLProgramResource.prototype = {
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 @@ WebGLProgramResource.prototype = {
});
}
data.uniforms = uniforms;
glResource.restoreErrors(originalErrors);
},
/**
......@@ -1214,6 +1226,79 @@ WebGLRenderingContextResource.prototype = {
return this._proxyObject;
},
/**
* @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
......@@ -1224,7 +1309,7 @@ WebGLRenderingContextResource.prototype = {
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.prototype = {
});
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 @@ WebGLRenderingContextResource.prototype = {
gl.activeTexture(currentTextureBinding);
data.glState = glState;
this.restoreErrors(originalErrors);
},
/**
......@@ -1546,6 +1632,16 @@ WebGLRenderingContextResource.WrapFunction.prototype = {
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 @@ WebGLRenderingContextResource.wrapFunctions = function()
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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment