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);
+}