Title: [140428] trunk/Source/WebCore
Revision
140428
Author
aand...@chromium.org
Date
2013-01-22 08:41:26 -0800 (Tue, 22 Jan 2013)

Log Message

Web Inspector: [Canvas] jump to prev/next drawing call in the replay
https://bugs.webkit.org/show_bug.cgi?id=107551

Reviewed by Pavel Feldman.

Implement jumping to the next(previous) drawing call in the WebGL and canvas 2D replay.

* English.lproj/localizedStrings.js:
* inspector/InjectedScriptCanvasModuleSource.js:
(.):
* inspector/Inspector.json:
* inspector/front-end/CanvasProfileView.js:
(WebInspector.CanvasProfileView):
(WebInspector.CanvasProfileView.prototype.dispose):
(WebInspector.CanvasProfileView.prototype._onReplayDrawingCallClick):
* inspector/front-end/canvasProfiler.css:
(.canvas-replay-prev-draw img):
(.canvas-replay-next-draw img):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (140427 => 140428)


--- trunk/Source/WebCore/ChangeLog	2013-01-22 16:19:11 UTC (rev 140427)
+++ trunk/Source/WebCore/ChangeLog	2013-01-22 16:41:26 UTC (rev 140428)
@@ -1,3 +1,24 @@
+2013-01-22  Andrey Adaikin  <aand...@chromium.org>
+
+        Web Inspector: [Canvas] jump to prev/next drawing call in the replay
+        https://bugs.webkit.org/show_bug.cgi?id=107551
+
+        Reviewed by Pavel Feldman.
+
+        Implement jumping to the next(previous) drawing call in the WebGL and canvas 2D replay.
+
+        * English.lproj/localizedStrings.js:
+        * inspector/InjectedScriptCanvasModuleSource.js:
+        (.):
+        * inspector/Inspector.json:
+        * inspector/front-end/CanvasProfileView.js:
+        (WebInspector.CanvasProfileView):
+        (WebInspector.CanvasProfileView.prototype.dispose):
+        (WebInspector.CanvasProfileView.prototype._onReplayDrawingCallClick):
+        * inspector/front-end/canvasProfiler.css:
+        (.canvas-replay-prev-draw img):
+        (.canvas-replay-next-draw img):
+
 2013-01-22  Andrey Lushnikov  <lushni...@chromium.org>
 
         Web Inspector: remove asynchronous behavior from DTE paintLines method

Modified: trunk/Source/WebCore/English.lproj/localizedStrings.js (140427 => 140428)


--- trunk/Source/WebCore/English.lproj/localizedStrings.js	2013-01-22 16:19:11 UTC (rev 140427)
+++ trunk/Source/WebCore/English.lproj/localizedStrings.js	2013-01-22 16:41:26 UTC (rev 140428)
@@ -783,6 +783,8 @@
 localizedStrings["First call."] = "First call.";
 localizedStrings["Previous call."] = "Previous call.";
 localizedStrings["Next call."] = "Next call.";
+localizedStrings["Previous drawing call."] = "Previous drawing call.";
+localizedStrings["Next drawing call."] = "Next drawing call.";
 localizedStrings["Last call."] = "Last call.";
 localizedStrings["Show screenshot of the last replayed resource."] = "Show screenshot of the last replayed resource.";
 localizedStrings["Show screenshot of this context's canvas."] = "Show screenshot of this context's canvas.";

Modified: trunk/Source/WebCore/inspector/InjectedScriptCanvasModuleSource.js (140427 => 140428)


--- trunk/Source/WebCore/inspector/InjectedScriptCanvasModuleSource.js	2013-01-22 16:19:11 UTC (rev 140427)
+++ trunk/Source/WebCore/inspector/InjectedScriptCanvasModuleSource.js	2013-01-22 16:41:26 UTC (rev 140428)
@@ -51,6 +51,12 @@
     })(["Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "Float32Array", "Float64Array"]),
 
     /**
+     * @const
+     * @type {!Array.<string>}
+     */
+    _supportedPropertyPrefixes: ["webkit"],
+
+    /**
      * @param {*} array
      * @return {function(new:ArrayBufferView, ArrayBufferView)|null}
      */
@@ -146,6 +152,22 @@
     },
 
     /**
+     * @param {!Array.<string>} names
+     * @return {!Object.<string, boolean>}
+     */
+    createPrefixedPropertyNamesSet: function(names)
+    {
+        var result = Object.create(null);
+        for (var i = 0, name; name = names[i]; ++i) {
+            result[name] = true;
+            var suffix = name.substr(0, 1).toUpperCase() + name.substr(1);
+            for (var j = 0, prefix; prefix = TypeUtils._supportedPropertyPrefixes[j]; ++j)
+                result[prefix + suffix] = true;
+        }
+        return result;
+    },
+
+    /**
      * @return {CanvasRenderingContext2D}
      */
     _dummyCanvas2dContext: function()
@@ -1076,6 +1098,14 @@
     /**
      * @return {string}
      */
+    name: function()
+    {
+        return this._data.name;
+    },
+
+    /**
+     * @return {string}
+     */
     description: function()
     {
         return this._data.name + "@" + this._data.kindId;
@@ -1702,6 +1732,16 @@
 ];
 
 /**
+ * @const
+ * @type {!Object.<string, boolean>}
+ */
+WebGLRenderingContextResource.DrawingMethods = TypeUtils.createPrefixedPropertyNamesSet([
+    "clear",
+    "drawArrays",
+    "drawElements"
+]);
+
+/**
  * @param {*} obj
  * @return {WebGLRenderingContextResource}
  */
@@ -2270,6 +2310,26 @@
     "setTransform"
 ];
 
+/**
+ * @const
+ * @type {!Object.<string, boolean>}
+ */
+CanvasRenderingContext2DResource.DrawingMethods = TypeUtils.createPrefixedPropertyNamesSet([
+    "clearRect",
+    "drawImage",
+    "drawImageFromRect",
+    "drawCustomFocusRing",
+    "drawSystemFocusRing",
+    "fill",
+    "fillRect",
+    "fillText",
+    "putImageData",
+    "putImageDataHD",
+    "stroke",
+    "strokeRect",
+    "strokeText"
+]);
+
 CanvasRenderingContext2DResource.prototype = {
     /**
      * @override (overrides @return type)
@@ -2579,7 +2639,86 @@
 
 /**
  * @constructor
+ * @param {!Object.<string, boolean>=} drawingMethodNames
  */
+function CallFormatter(drawingMethodNames)
+{
+    this._drawingMethodNames = drawingMethodNames || Object.create(null);
+}
+
+CallFormatter.prototype = {
+    /**
+     * @param {!ReplayableCall} replayableCall
+     * @return {!Object}
+     */
+    formatCall: function(replayableCall)
+    {
+        var result = {};
+        var functionName = replayableCall.functionName();
+        if (functionName) {
+            result.functionName = functionName;
+            result.arguments = replayableCall.args().map(this.formatValue.bind(this));
+            if (replayableCall.result() !== undefined)
+                result.result = this.formatValue(replayableCall.result());
+            if (this._drawingMethodNames[functionName])
+                result.isDrawingCall = true;
+        } else {
+            result.property = replayableCall.args()[0];
+            result.value = this.formatValue(replayableCall.args()[1]);
+        }
+        return result;
+    },
+
+    /**
+     * @param {*} value
+     * @return {!Object}
+     */
+    formatValue: function(value)
+    {
+        if (value instanceof ReplayableResource)
+            var description = value.description();
+        else
+            var description = "" + value;
+        return { description: description };
+    }
+}
+
+/**
+ * @const
+ * @type {!Object.<string, !CallFormatter>}
+ */
+CallFormatter._formatters = {};
+
+/**
+ * @param {string} resourceName
+ * @param {!CallFormatter} callFormatter
+ */
+CallFormatter.register = function(resourceName, callFormatter)
+{
+    CallFormatter._formatters[resourceName] = callFormatter;
+}
+
+/**
+ * @param {!ReplayableCall} replayableCall
+ * @return {!Object}
+ */
+CallFormatter.formatCall = function(replayableCall)
+{
+    var resource = replayableCall.replayableResource();
+    var formatter = CallFormatter._formatters[resource.name()];
+    if (!formatter) {
+        var contextResource = resource.replayableContextResource();
+        formatter = CallFormatter._formatters[contextResource.name()] || new CallFormatter();
+    }
+    return formatter.formatCall(replayableCall);
+}
+
+CallFormatter.register("CanvasRenderingContext2D", new CallFormatter(CanvasRenderingContext2DResource.DrawingMethods));
+CallFormatter.register("WebGLRenderingContext", new CallFormatter(WebGLRenderingContextResource.DrawingMethods));
+
+/**
+ * @constructor
+ */
 function TraceLog()
 {
     /** @type {!Array.<ReplayableCall>} */
@@ -2936,22 +3075,12 @@
             var contextResource = call.replayableResource().replayableContextResource();
             var stackTrace = call.stackTrace();
             var callFrame = stackTrace ? stackTrace.callFrame(0) || {} : {};
-            var traceLogItem = {
-                contextId: this._makeStringResourceId(contextResource.id()),
-                sourceURL: callFrame.sourceURL,
-                lineNumber: callFrame.lineNumber,
-                columnNumber: callFrame.columnNumber
-            };
-            if (call.functionName()) {
-                traceLogItem.functionName = call.functionName();
-                traceLogItem.arguments = call.args().map(this._makeCallArgument.bind(this));
-                if (call.result() !== undefined)
-                    traceLogItem.result = this._makeCallArgument(call.result());
-            } else {
-                traceLogItem.property = call.args()[0];
-                traceLogItem.value = this._makeCallArgument(call.args()[1]);
-            }
-            result.calls.push(traceLogItem);
+            var item = CallFormatter.formatCall(call);
+            item.contextId = this._makeStringResourceId(contextResource.id());
+            item.sourceURL = callFrame.sourceURL;
+            item.lineNumber = callFrame.lineNumber;
+            item.columnNumber = callFrame.columnNumber;
+            result.calls.push(item);
         }
         return result;
     },

Modified: trunk/Source/WebCore/inspector/Inspector.json (140427 => 140428)


--- trunk/Source/WebCore/inspector/Inspector.json	2013-01-22 16:19:11 UTC (rev 140427)
+++ trunk/Source/WebCore/inspector/Inspector.json	2013-01-22 16:41:26 UTC (rev 140428)
@@ -3230,6 +3230,7 @@
                     { "name": "functionName", "type": "string", "optional": true },
                     { "name": "arguments", "type": "array", "items": { "$ref": "CallArgument" }, "optional": true },
                     { "name": "result", "$ref": "CallArgument", "optional": true },
+                    { "name": "isDrawingCall", "type": "boolean", "optional": true },
                     { "name": "property", "type": "string", "optional": true },
                     { "name": "value", "$ref": "CallArgument", "optional": true },
                     { "name": "sourceURL", "type": "string", "optional": true },

Modified: trunk/Source/WebCore/inspector/front-end/CanvasProfileView.js (140427 => 140428)


--- trunk/Source/WebCore/inspector/front-end/CanvasProfileView.js	2013-01-22 16:19:11 UTC (rev 140427)
+++ trunk/Source/WebCore/inspector/front-end/CanvasProfileView.js	2013-01-22 16:41:26 UTC (rev 140428)
@@ -55,6 +55,8 @@
     this._createControlButton(controlsContainer, "canvas-replay-first-step", WebInspector.UIString("First call."), this._onReplayFirstStepClick.bind(this));
     this._createControlButton(controlsContainer, "canvas-replay-prev-step", WebInspector.UIString("Previous call."), this._onReplayStepClick.bind(this, false));
     this._createControlButton(controlsContainer, "canvas-replay-next-step", WebInspector.UIString("Next call."), this._onReplayStepClick.bind(this, true));
+    this._createControlButton(controlsContainer, "canvas-replay-prev-draw", WebInspector.UIString("Previous drawing call."), this._onReplayDrawingCallClick.bind(this, false));
+    this._createControlButton(controlsContainer, "canvas-replay-next-draw", WebInspector.UIString("Next drawing call."), this._onReplayDrawingCallClick.bind(this, true));
     this._createControlButton(controlsContainer, "canvas-replay-last-step", WebInspector.UIString("Last call."), this._onReplayLastStepClick.bind(this));
 
     this._replayContextSelector = new WebInspector.StatusBarComboBox(this._onReplayContextChanged.bind(this));
@@ -82,6 +84,9 @@
     this._logGrid.show(logGridContainer);
     this._logGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._replayTraceLog.bind(this));
 
+    /** @type {!Array.<WebInspector.DataGridNode>} */
+    this._logGridNodes = [];
+
     this._splitView.show(this.element);
 
     this._enableWaitIcon(true);
@@ -91,6 +96,7 @@
 WebInspector.CanvasProfileView.prototype = {
     dispose: function()
     {
+        this._logGridNodes = [];
         this._linkifier.reset();
         CanvasAgent.dropTraceLog(this._traceLogId);
     },
@@ -132,7 +138,7 @@
     _onReplayContextChanged: function()
     {
         /**
-         * @param {string?} error
+         * @param {?Protocol.Error} error
          * @param {CanvasAgent.ResourceState} resourceState
          */
         function didReceiveResourceState(error, resourceState)
@@ -174,6 +180,26 @@
             selectedNode.reveal();
     },
 
+    /**
+     * @param {boolean} forward
+     */
+    _onReplayDrawingCallClick: function(forward)
+    {
+        var callNode = this._logGrid.selectedNode;
+        if (!callNode)
+            return;
+        var index = callNode.index;
+        do {
+            var nextIndex = forward ? index + 1 : index - 1;
+            var nextCallNode = this._logGridNodes[nextIndex];
+            if (!nextCallNode)
+                break;
+            index = nextIndex;
+            callNode = nextCallNode;
+        } while (!callNode.call.isDrawingCall);
+        callNode.revealAndSelect();
+    },
+
     _onReplayFirstStepClick: function()
     {
         var firstNode = this._logGrid.rootNode().children[0];
@@ -220,7 +246,7 @@
             return;
         var time = Date.now();
         /**
-         * @param {string?} error
+         * @param {?Protocol.Error} error
          * @param {CanvasAgent.ResourceState} resourceState
          */
         function didReplayTraceLog(error, resourceState)
@@ -243,6 +269,10 @@
         CanvasAgent.replayTraceLog(this._traceLogId, callNode.index, didReplayTraceLog.bind(this));
     },
 
+    /**
+     * @param {?Protocol.Error} error
+     * @param {CanvasAgent.TraceLog} traceLog
+     */
     _didReceiveTraceLog: function(error, traceLog)
     {
         this._enableWaitIcon(false);
@@ -270,7 +300,7 @@
             return;
         this._replayContexts[contextId] = true;
         /**
-         * @param {string?} error
+         * @param {?Protocol.Error} error
          * @param {CanvasAgent.ResourceInfo} resourceInfo
          */
         function didReceiveResourceInfo(error, resourceInfo)
@@ -286,7 +316,7 @@
 
     /**
      * @param {number} index
-     * @param {Object} call
+     * @param {CanvasAgent.Call} call
      * @return {!WebInspector.DataGridNode}
      */
     _createCallNode: function(index, call)
@@ -316,6 +346,8 @@
         var node = new WebInspector.DataGridNode(data);
         node.index = index;
         node.selectable = true;
+        node.call = call;
+        this._logGridNodes[index] = node;
         return node;
     },
 

Modified: trunk/Source/WebCore/inspector/front-end/canvasProfiler.css (140427 => 140428)


--- trunk/Source/WebCore/inspector/front-end/canvasProfiler.css	2013-01-22 16:19:11 UTC (rev 140427)
+++ trunk/Source/WebCore/inspector/front-end/canvasProfiler.css	2013-01-22 16:41:26 UTC (rev 140428)
@@ -85,3 +85,10 @@
 .canvas-replay-last-step img {
     content: url(Images/debuggerContinue.png);
 }
+.canvas-replay-prev-draw img{
+    content: url(Images/debuggerStepOver.png);
+    -webkit-transform: scaleX(-1);
+}
+.canvas-replay-next-draw img{
+    content: url(Images/debuggerStepOver.png);
+}
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to