Title: [126574] trunk/Source/WebCore
Revision
126574
Author
[email protected]
Date
2012-08-24 05:23:37 -0700 (Fri, 24 Aug 2012)

Log Message

Web Inspector: [WebGL] Implement custom wrap functions on GL context
https://bugs.webkit.org/show_bug.cgi?id=94799

Patch by Andrey Adaikin <[email protected]> on 2012-08-24
Reviewed by Pavel Feldman.

Implement custom wrap functions on WebGL rendering context for WebGL instrumentation.

* inspector/InjectedScriptWebGLModuleSource.js:
(.):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (126573 => 126574)


--- trunk/Source/WebCore/ChangeLog	2012-08-24 12:20:30 UTC (rev 126573)
+++ trunk/Source/WebCore/ChangeLog	2012-08-24 12:23:37 UTC (rev 126574)
@@ -1,3 +1,15 @@
+2012-08-24  Andrey Adaikin  <[email protected]>
+
+        Web Inspector: [WebGL] Implement custom wrap functions on GL context
+        https://bugs.webkit.org/show_bug.cgi?id=94799
+
+        Reviewed by Pavel Feldman.
+
+        Implement custom wrap functions on WebGL rendering context for WebGL instrumentation.
+
+        * inspector/InjectedScriptWebGLModuleSource.js:
+        (.):
+
 2012-08-24  Pavel Feldman  <[email protected]>
 
         Web Inspector: resolve URLs upon creation, get rid of populateHrefContextMenu

Modified: trunk/Source/WebCore/inspector/InjectedScriptWebGLModuleSource.js (126573 => 126574)


--- trunk/Source/WebCore/inspector/InjectedScriptWebGLModuleSource.js	2012-08-24 12:20:30 UTC (rev 126573)
+++ trunk/Source/WebCore/inspector/InjectedScriptWebGLModuleSource.js	2012-08-24 12:23:37 UTC (rev 126574)
@@ -440,6 +440,199 @@
 /**
  * @constructor
  * @extends {Resource}
+ */
+function WebGLBoundResource(wrappedObject)
+{
+    Resource.call(this, wrappedObject);
+    this._state = {};
+}
+
+WebGLBoundResource.prototype = {
+    /**
+     * @param {number} target
+     * @param {string} bindMethodName
+     */
+    pushBinding: function(target, bindMethodName)
+    {
+        if (this._state.BINDING !== target) {
+            this._state.BINDING = target;
+            this.pushCall(new Call(WebGLRenderingContextResource.forObject(this), bindMethodName, [target, this]));
+        }
+    }
+}
+
+WebGLBoundResource.prototype.__proto__ = Resource.prototype;
+
+/**
+ * @constructor
+ * @extends {WebGLBoundResource}
+ */
+function WebGLTextureResource(wrappedObject)
+{
+    WebGLBoundResource.call(this, wrappedObject);
+}
+
+WebGLTextureResource.prototype = {
+    /** @inheritDoc */
+    pushCall: function(call)
+    {
+        var gl = call.resource().wrappedObject();
+        WebGLRenderingContextResource.PixelStoreParameters.forEach(function(parameter) {
+            var value = gl.getParameter(gl[parameter]);
+            if (this._state[parameter] !== value) {
+                this._state[parameter] = value;
+                var pixelStoreCall = new Call(gl, "pixelStorei", [gl[parameter], value]);
+                WebGLBoundResource.prototype.pushCall.call(this, pixelStoreCall);
+            }
+        }, this);
+
+        // FIXME: remove any older calls that no longer contribute to the resource state.
+        // FIXME: optimize memory usage: maybe it's more efficient to store one texImage2D call instead of many texSubImage2D.
+        WebGLBoundResource.prototype.pushCall.call(this, call);
+    },
+
+    /**
+     * @param {Call} call
+     */
+    pushCall_texParameterf: function(call)
+    {
+        var args = call.args();
+        var pname = args[1];
+        var param = args[2];
+        if (this._state[pname] !== param) {
+            this._state[pname] = param;
+            WebGLBoundResource.prototype.pushCall.call(this, call);
+        }
+    },
+
+    /**
+     * copyTexImage2D and copyTexSubImage2D define a texture image with pixels from the current framebuffer.
+     * @param {Call} call
+     */
+    pushCall_copyTexImage2D: function(call)
+    {
+        var glResource = call.resource();
+        var gl = glResource.wrappedObject();
+        var framebufferResource = glResource.currentBinding(gl.FRAMEBUFFER);
+        if (framebufferResource)
+            this.pushCall(new Call(glResource, "bindFramebuffer", [gl.FRAMEBUFFER, framebufferResource]));
+        else
+            console.error("ASSERT_NOT_REACHED: No FRAMEBUFFER bound while calling gl." + call.functionName());
+        this.pushCall(call);
+    }
+}
+
+WebGLTextureResource.prototype.pushCall_texParameteri = WebGLTextureResource.prototype.pushCall_texParameterf;
+WebGLTextureResource.prototype.pushCall_copyTexSubImage2D = WebGLTextureResource.prototype.pushCall_copyTexImage2D;
+
+WebGLTextureResource.prototype.__proto__ = WebGLBoundResource.prototype;
+
+/**
+ * @constructor
+ * @extends {Resource}
+ */
+function WebGLProgramResource(wrappedObject)
+{
+    Resource.call(this, wrappedObject);
+}
+
+WebGLProgramResource.prototype = {
+    /** @inheritDoc */
+    pushCall: function(call)
+    {
+        // FIXME: remove any older calls that no longer contribute to the resource state.
+        // FIXME: handle multiple attachShader && detachShader.
+        Resource.prototype.pushCall.call(this, call);
+    }
+}
+
+WebGLProgramResource.prototype.__proto__ = Resource.prototype;
+
+/**
+ * @constructor
+ * @extends {Resource}
+ */
+function WebGLShaderResource(wrappedObject)
+{
+    Resource.call(this, wrappedObject);
+}
+
+WebGLShaderResource.prototype = {
+    /** @inheritDoc */
+    pushCall: function(call)
+    {
+        // FIXME: remove any older calls that no longer contribute to the resource state.
+        // FIXME: handle multiple shaderSource calls.
+        Resource.prototype.pushCall.call(this, call);
+    }
+}
+
+WebGLShaderResource.prototype.__proto__ = Resource.prototype;
+
+/**
+ * @constructor
+ * @extends {WebGLBoundResource}
+ */
+function WebGLBufferResource(wrappedObject)
+{
+    WebGLBoundResource.call(this, wrappedObject);
+}
+
+WebGLBufferResource.prototype = {
+    /** @inheritDoc */
+    pushCall: function(call)
+    {
+        // FIXME: remove any older calls that no longer contribute to the resource state.
+        // FIXME: Optimize memory for bufferSubData.
+        WebGLBoundResource.prototype.pushCall.call(this, call);
+    }
+}
+
+WebGLBufferResource.prototype.__proto__ = WebGLBoundResource.prototype;
+
+/**
+ * @constructor
+ * @extends {WebGLBoundResource}
+ */
+function WebGLFramebufferResource(wrappedObject)
+{
+    WebGLBoundResource.call(this, wrappedObject);
+}
+
+WebGLFramebufferResource.prototype = {
+    /** @inheritDoc */
+    pushCall: function(call)
+    {
+        // FIXME: remove any older calls that no longer contribute to the resource state.
+        WebGLBoundResource.prototype.pushCall.call(this, call);
+    }
+}
+
+WebGLFramebufferResource.prototype.__proto__ = WebGLBoundResource.prototype;
+
+/**
+ * @constructor
+ * @extends {WebGLBoundResource}
+ */
+function WebGLRenderbufferResource(wrappedObject)
+{
+    WebGLBoundResource.call(this, wrappedObject);
+}
+
+WebGLRenderbufferResource.prototype = {
+    /** @inheritDoc */
+    pushCall: function(call)
+    {
+        // FIXME: remove any older calls that no longer contribute to the resource state.
+        WebGLBoundResource.prototype.pushCall.call(this, call);
+    }
+}
+
+WebGLRenderbufferResource.prototype.__proto__ = WebGLBoundResource.prototype;
+
+/**
+ * @constructor
+ * @extends {Resource}
  * @param {WebGLRenderingContext} glContext
  */
 function WebGLRenderingContextResource(glContext)
@@ -448,6 +641,34 @@
     this._proxyObject = null;
 }
 
+/**
+ * @const
+ * @type {Array.<string>}
+ */
+WebGLRenderingContextResource.PixelStoreParameters = [
+    "PACK_ALIGNMENT",
+    "UNPACK_ALIGNMENT",
+    "UNPACK_COLORSPACE_CONVERSION_WEBGL",
+    "UNPACK_FLIP_Y_WEBGL",
+    "UNPACK_PREMULTIPLY_ALPHA_WEBGL"
+];
+
+/**
+ * @param {*} obj
+ * @return {WebGLRenderingContextResource}
+ */
+WebGLRenderingContextResource.forObject = function(obj)
+{
+    var resource = Resource.forObject(obj);
+    if (!resource || resource instanceof WebGLRenderingContextResource)
+        return resource;
+    var call = resource.calls();
+    if (!call || !call.length)
+        return null;
+    resource = call[0].resource();
+    return (resource instanceof WebGLRenderingContextResource) ? resource : null;
+}
+
 WebGLRenderingContextResource.prototype = {
     /**
      * @return {Object}
@@ -460,6 +681,59 @@
     },
 
     /**
+     * @param {Object|number} target
+     * @return {Resource}
+     */
+    currentBinding: function(target)
+    {
+        var resource = Resource.forObject(target);
+        if (resource)
+            return resource;
+        var gl = this.wrappedObject();
+        var bindingTarget;
+        var bindMethodName;
+        switch (target) {
+            case gl.ARRAY_BUFFER:
+                bindingTarget = gl.ARRAY_BUFFER_BINDING;
+                bindMethodName = "bindBuffer";
+                break;
+            case gl.ELEMENT_ARRAY_BUFFER:
+                bindingTarget = gl.ELEMENT_ARRAY_BUFFER_BINDING;
+                bindMethodName = "bindBuffer";
+                break;
+            case gl.TEXTURE_2D:
+                bindingTarget = gl.TEXTURE_BINDING_2D;
+                bindMethodName = "bindTexture";
+                break;
+            case gl.TEXTURE_CUBE_MAP:
+            case gl.TEXTURE_CUBE_MAP_POSITIVE_X:
+            case gl.TEXTURE_CUBE_MAP_NEGATIVE_X:
+            case gl.TEXTURE_CUBE_MAP_POSITIVE_Y:
+            case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y:
+            case gl.TEXTURE_CUBE_MAP_POSITIVE_Z:
+            case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z:
+                bindingTarget = gl.TEXTURE_BINDING_CUBE_MAP;
+                bindMethodName = "bindTexture";
+                break;
+            case gl.FRAMEBUFFER:
+                bindingTarget = gl.FRAMEBUFFER_BINDING;
+                bindMethodName = "bindFramebuffer";
+                break;
+            case gl.RENDERBUFFER:
+                bindingTarget = gl.RENDERBUFFER_BINDING;
+                bindMethodName = "bindRenderbuffer";
+                break;
+            default:
+                console.error("ASSERT_NOT_REACHED: unknown binding target " + target);
+                return null;
+        }
+        resource = Resource.forObject(gl.getParameter(bindingTarget));
+        if (resource)
+            resource.pushBinding(target, bindMethodName);
+        return resource;
+    },
+
+    /**
      * @return {Object}
      */
     _wrapObject: function()
@@ -471,8 +745,11 @@
         function processProperty(property)
         {
             if (typeof glContext[property] === "function") {
-                // FIXME: override GL calls affecting resources states here.
-                proxy[property] = self._wrapFunction(self, glContext, glContext[property], property);
+                var customWrapFunction = WebGLRenderingContextResource.WrapFunctions[property];
+                if (customWrapFunction)
+                    proxy[property] = self._wrapCustomFunction(self, glContext, glContext[property], property, customWrapFunction);
+                else
+                    proxy[property] = self._wrapFunction(self, glContext, glContext[property], property);
             } else if (/^[A-Z0-9_]+$/.test(property)) {
                 // Fast access to enums and constants.
                 proxy[property] = glContext[property];
@@ -501,8 +778,31 @@
      * @param {WebGLRenderingContext} originalObject
      * @param {Function} originalFunction
      * @param {string} functionName
+     * @param {Function} customWrapFunction
      * @return {*}
      */
+    _wrapCustomFunction: function(resource, originalObject, originalFunction, functionName, customWrapFunction)
+    {
+        return function()
+        {
+            var manager = resource.manager();
+            if (manager)
+                manager.captureArguments(resource, arguments);
+            var wrapFunction = new WebGLRenderingContextResource.WrapFunction(originalObject, originalFunction, functionName, arguments);
+            customWrapFunction.apply(wrapFunction, arguments);
+            if (manager)
+                manager.reportCall(wrapFunction.call());
+            return wrapFunction.result();
+        };
+    },
+
+    /**
+     * @param {Resource} resource
+     * @param {WebGLRenderingContext} originalObject
+     * @param {Function} originalFunction
+     * @param {string} functionName
+     * @return {*}
+     */
     _wrapFunction: function(resource, originalObject, originalFunction, functionName)
     {
         return function()
@@ -561,6 +861,73 @@
     }
 }
 
+WebGLRenderingContextResource.WrapFunctions = {
+    __proto__: null
+};
+
+(function(items) {
+    items.forEach(function(item) {
+        var methodName = item[0];
+        var resourceConstructor = item[1];
+        WebGLRenderingContextResource.WrapFunctions[methodName] = function()
+        {
+            var wrappedObject = this.result();
+            if (!wrappedObject)
+                return;
+            var resource = new resourceConstructor(wrappedObject);
+            var manager = this._glResource.manager();
+            if (manager)
+                manager.registerResource(resource);
+            resource.pushCall(this.call());
+        };
+    });
+})([
+    ["createBuffer", WebGLBufferResource],
+    ["createShader", WebGLShaderResource],
+    ["createProgram", WebGLProgramResource],
+    ["createTexture", WebGLTextureResource],
+    ["createFramebuffer", WebGLFramebufferResource],
+    ["createRenderbuffer", WebGLRenderbufferResource],
+    ["getUniformLocation", Resource]
+]);
+
+(function(methods) {
+    methods.forEach(function(methodName) {
+        var customPushCall = "pushCall_" + methodName;
+        WebGLRenderingContextResource.WrapFunctions[methodName] = function(target)
+        {
+            var resource = this._glResource.currentBinding(target);
+            if (resource) {
+                if (resource[customPushCall])
+                    resource[customPushCall].call(resource, this.call());
+                else
+                    resource.pushCall(this.call());
+            }
+        };
+    });
+})([
+    "attachShader",
+    "bindAttribLocation",
+    "compileShader",
+    "detachShader",
+    "linkProgram",
+    "shaderSource",
+    "bufferData",
+    "bufferSubData",
+    "compressedTexImage2D",
+    "compressedTexSubImage2D",
+    "copyTexImage2D",
+    "copyTexSubImage2D",
+    "generateMipmap",
+    "texImage2D",
+    "texSubImage2D",
+    "texParameterf",
+    "texParameteri",
+    "framebufferRenderbuffer",
+    "framebufferTexture2D",
+    "renderbufferStorage"
+]);
+
 /**
  * @constructor
  */
@@ -656,7 +1023,7 @@
         // FIXME: Replay all the cached resources first to warm-up.
         var replayableCalls = this._traceLog.replayableCalls();
         while (this._nextReplayStep <= stepNum)
-            replayableCalls[this._nextReplayStep++].replay(this._replayWorldCache);            
+            replayableCalls[this._nextReplayStep++].replay(this._replayWorldCache);
     },
 
     replay: function()
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to