summaryrefslogtreecommitdiff
path: root/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModuleSource.js
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModuleSource.js')
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModuleSource.js223
1 files changed, 131 insertions, 92 deletions
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModuleSource.js b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModuleSource.js
index 00d50cf82c8..c82ab2352ec 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModuleSource.js
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModuleSource.js
@@ -118,6 +118,14 @@ var TypeUtils = {
return result;
}
+ // Try to convert to a primitive value via valueOf().
+ if (typeof obj.valueOf === "function") {
+ var value = obj.valueOf();
+ var valueType = typeof value;
+ if (valueType !== "object" && valueType !== "function")
+ return value;
+ }
+
console.error("ASSERT_NOT_REACHED: failed to clone object: ", obj);
return obj;
},
@@ -260,8 +268,8 @@ function StackTraceV8(stackTraceLimit, topMostFunctionToIgnore)
/**
* @param {Object} error
- * @param {Array.<CallSite>} structuredStackTrace
- * @return {Array.<{sourceURL: string, lineNumber: number, columnNumber: number}>}
+ * @param {!Array.<CallSite>} structuredStackTrace
+ * @return {!Array.<{sourceURL: string, lineNumber: number, columnNumber: number}>}
*/
Error.prepareStackTrace = function(error, structuredStackTrace)
{
@@ -274,7 +282,7 @@ function StackTraceV8(stackTraceLimit, topMostFunctionToIgnore)
});
}
- var holder = /** @type {{stack: Array.<{sourceURL: string, lineNumber: number, columnNumber: number}>}} */ ({});
+ var holder = /** @type {{stack: !Array.<{sourceURL: string, lineNumber: number, columnNumber: number}>}} */ ({});
Error.captureStackTrace(holder, topMostFunctionToIgnore || arguments.callee);
this._stackTrace = holder.stack;
@@ -356,7 +364,7 @@ Cache.prototype = {
* @constructor
* @param {Resource|Object} thisObject
* @param {string} functionName
- * @param {Array|Arguments} args
+ * @param {!Array|Arguments} args
* @param {Resource|*=} result
* @param {StackTrace=} stackTrace
*/
@@ -531,11 +539,6 @@ Call.prototype = {
var attachments = replayableCall.attachments();
if (attachments)
this._attachments = TypeUtils.cloneObject(attachments);
-
- var thisResource = Resource.forObject(replayObject);
- if (thisResource)
- thisResource.onCallReplayed(this);
-
return this;
}
}
@@ -544,7 +547,7 @@ Call.prototype = {
* @constructor
* @param {ReplayableResource} thisObject
* @param {string} functionName
- * @param {Array.<ReplayableResource|*>} args
+ * @param {!Array.<ReplayableResource|*>} args
* @param {ReplayableResource|*} result
* @param {StackTrace} stackTrace
* @param {Object.<string, Object>} attachments
@@ -604,7 +607,7 @@ ReplayableCall.prototype = {
},
/**
- * @return {Array.<ReplayableResource|*>}
+ * @return {!Array.<ReplayableResource|*>}
*/
args: function()
{
@@ -979,7 +982,7 @@ Resource.prototype = {
var proxy = Object.create(wrappedObject.__proto__); // In order to emulate "instanceof".
var customWrapFunctions = this._customWrapFunctions();
- /** @type {Array.<string>} */
+ /** @type {!Array.<string>} */
this._proxyStatePropertyNames = [];
/**
@@ -1112,7 +1115,7 @@ Resource.prototype = {
* @param {Object} originalObject
* @param {Function} originalFunction
* @param {string} functionName
- * @param {Array|Arguments} args
+ * @param {!Array|Arguments} args
*/
Resource.WrapFunction = function(originalObject, originalFunction, functionName, args)
{
@@ -2750,6 +2753,7 @@ WebGLRenderingContextResource.prototype = {
var gl = this.wrappedObject();
var bindingParameter;
var bindMethodName;
+ target = +target; // Explicitly convert to a number.
var bindMethodTarget = target;
switch (target) {
case gl.ARRAY_BUFFER:
@@ -2835,36 +2839,6 @@ WebGLRenderingContextResource.prototype = {
wrapFunctions["createRenderbuffer"] = Resource.WrapFunction.resourceFactoryMethod(WebGLRenderbufferResource, "WebGLRenderbuffer");
wrapFunctions["getUniformLocation"] = Resource.WrapFunction.resourceFactoryMethod(WebGLUniformLocationResource, "WebGLUniformLocation");
- /**
- * @param {string} methodName
- * @param {function(this:Resource, !Call)=} pushCallFunc
- */
- function stateModifyingWrapFunction(methodName, pushCallFunc)
- {
- if (pushCallFunc) {
- /**
- * @param {Object|number} target
- * @this Resource.WrapFunction
- */
- wrapFunctions[methodName] = function(target)
- {
- var resource = this._resource.currentBinding(target);
- if (resource)
- pushCallFunc.call(resource, this.call());
- }
- } else {
- /**
- * @param {Object|number} target
- * @this Resource.WrapFunction
- */
- wrapFunctions[methodName] = function(target)
- {
- var resource = this._resource.currentBinding(target);
- if (resource)
- resource.pushCall(this.call());
- }
- }
- }
stateModifyingWrapFunction("bindAttribLocation");
stateModifyingWrapFunction("compileShader");
stateModifyingWrapFunction("detachShader");
@@ -2984,6 +2958,38 @@ WebGLRenderingContextResource.prototype = {
WebGLRenderingContextResource._wrapFunctions = wrapFunctions;
}
+
+ /**
+ * @param {string} methodName
+ * @param {function(this:Resource, !Call)=} pushCallFunc
+ */
+ function stateModifyingWrapFunction(methodName, pushCallFunc)
+ {
+ if (pushCallFunc) {
+ /**
+ * @param {Object|number} target
+ * @this Resource.WrapFunction
+ */
+ wrapFunctions[methodName] = function(target)
+ {
+ var resource = this._resource.currentBinding(target);
+ if (resource)
+ pushCallFunc.call(resource, this.call());
+ }
+ } else {
+ /**
+ * @param {Object|number} target
+ * @this Resource.WrapFunction
+ */
+ wrapFunctions[methodName] = function(target)
+ {
+ var resource = this._resource.currentBinding(target);
+ if (resource)
+ resource.pushCall(this.call());
+ }
+ }
+ }
+
return wrapFunctions;
},
@@ -3378,27 +3384,6 @@ CanvasRenderingContext2DResource.prototype = {
wrapFunctions["createRadialGradient"] = Resource.WrapFunction.resourceFactoryMethod(LogEverythingResource, "CanvasGradient");
wrapFunctions["createPattern"] = Resource.WrapFunction.resourceFactoryMethod(LogEverythingResource, "CanvasPattern");
- /**
- * @param {string} methodName
- * @param {function(this:Resource, !Call)=} func
- */
- function stateModifyingWrapFunction(methodName, func)
- {
- if (func) {
- /** @this Resource.WrapFunction */
- wrapFunctions[methodName] = function()
- {
- func.call(this._resource, this.call());
- }
- } else {
- /** @this Resource.WrapFunction */
- wrapFunctions[methodName] = function()
- {
- this._resource.pushCall(this.call());
- }
- }
- }
-
for (var i = 0, methodName; methodName = CanvasRenderingContext2DResource.TransformationMatrixMethods[i]; ++i)
stateModifyingWrapFunction(methodName, methodName === "setTransform" ? this.pushCall_setTransform : undefined);
for (var i = 0, methodName; methodName = CanvasRenderingContext2DResource.PathMethods[i]; ++i)
@@ -3410,6 +3395,28 @@ CanvasRenderingContext2DResource.prototype = {
CanvasRenderingContext2DResource._wrapFunctions = wrapFunctions;
}
+
+ /**
+ * @param {string} methodName
+ * @param {function(this:Resource, !Call)=} func
+ */
+ function stateModifyingWrapFunction(methodName, func)
+ {
+ if (func) {
+ /** @this Resource.WrapFunction */
+ wrapFunctions[methodName] = function()
+ {
+ func.call(this._resource, this.call());
+ }
+ } else {
+ /** @this Resource.WrapFunction */
+ wrapFunctions[methodName] = function()
+ {
+ this._resource.pushCall(this.call());
+ }
+ }
+ }
+
return wrapFunctions;
},
@@ -3897,12 +3904,14 @@ CallFormatter.register("WebGLRenderingContext", new WebGLCallFormatter(WebGLRend
*/
function TraceLog()
{
- /** @type {!Array.<ReplayableCall>} */
+ /** @type {!Array.<!ReplayableCall>} */
this._replayableCalls = [];
/** @type {!Cache.<ReplayableResource>} */
this._replayablesCache = new Cache();
/** @type {!Object.<number, boolean>} */
this._frameEndCallIndexes = {};
+ /** @type {!Object.<number, boolean>} */
+ this._resourcesCreatedInThisTraceLog = {};
}
TraceLog.prototype = {
@@ -3915,7 +3924,7 @@ TraceLog.prototype = {
},
/**
- * @return {!Array.<ReplayableCall>}
+ * @return {!Array.<!ReplayableCall>}
*/
replayableCalls: function()
{
@@ -3932,6 +3941,15 @@ TraceLog.prototype = {
},
/**
+ * @param {number} resourceId
+ * @return {boolean}
+ */
+ createdInThisTraceLog: function(resourceId)
+ {
+ return !!this._resourcesCreatedInThisTraceLog[resourceId];
+ },
+
+ /**
* @param {!Resource} resource
*/
captureResource: function(resource)
@@ -3944,6 +3962,9 @@ TraceLog.prototype = {
*/
addCall: function(call)
{
+ var resource = Resource.forObject(call.result());
+ if (resource && !this._replayablesCache.has(resource.id()))
+ this._resourcesCreatedInThisTraceLog[resource.id()] = true;
this._replayableCalls.push(call.toReplayable(this._replayablesCache));
},
@@ -4011,16 +4032,8 @@ TraceLogPlayer.prototype = {
},
/**
- * @return {Call}
- */
- step: function()
- {
- return this.stepTo(this._nextReplayStep);
- },
-
- /**
* @param {number} stepNum
- * @return {Call}
+ * @return {{replayTime:number, lastCall:(!Call)}}
*/
stepTo: function(stepNum)
{
@@ -4028,20 +4041,50 @@ TraceLogPlayer.prototype = {
console.assert(stepNum >= 0);
if (this._nextReplayStep > stepNum)
this.reset();
- // FIXME: Replay all the cached resources first to warm-up.
- var lastCall = null;
+
+ // Replay the calls' arguments first to warm-up, before measuring the actual replay time.
+ this._replayCallArguments(stepNum);
+
var replayableCalls = this._traceLog.replayableCalls();
- while (this._nextReplayStep <= stepNum)
- lastCall = replayableCalls[this._nextReplayStep++].replay(this._replayWorldCache);
- return lastCall;
+ var replayedCalls = [];
+ replayedCalls.length = stepNum - this._nextReplayStep + 1;
+
+ var beforeTime = TypeUtils.now();
+ for (var i = 0; this._nextReplayStep <= stepNum; ++this._nextReplayStep, ++i)
+ replayedCalls[i] = replayableCalls[this._nextReplayStep].replay(this._replayWorldCache);
+ var replayTime = Math.max(0, TypeUtils.now() - beforeTime);
+
+ for (var i = 0, call; call = replayedCalls[i]; ++i)
+ call.resource().onCallReplayed(call);
+
+ return {
+ replayTime: replayTime,
+ lastCall: replayedCalls[replayedCalls.length - 1]
+ };
},
/**
- * @return {Call}
+ * @param {number} stepNum
*/
- replay: function()
+ _replayCallArguments: function(stepNum)
{
- return this.stepTo(this._traceLog.size() - 1);
+ /**
+ * @param {*} obj
+ */
+ function replayIfNotCreatedInThisTraceLog(obj)
+ {
+ if (!(obj instanceof ReplayableResource))
+ return;
+ var replayableResource = /** @type {!ReplayableResource} */ (obj);
+ if (!this._traceLog.createdInThisTraceLog(replayableResource.id()))
+ replayableResource.replay(this._replayWorldCache)
+ }
+ var replayableCalls = this._traceLog.replayableCalls();
+ for (var i = this._nextReplayStep; i <= stepNum; ++i) {
+ replayIfNotCreatedInThisTraceLog.call(this, replayableCalls[i].replayableResource());
+ replayIfNotCreatedInThisTraceLog.call(this, replayableCalls[i].result());
+ replayableCalls[i].args().forEach(replayIfNotCreatedInThisTraceLog.bind(this));
+ }
}
}
@@ -4283,9 +4326,9 @@ InjectedCanvasModule.prototype = {
var alive = this._manager.capturing() && this._manager.lastTraceLog() === traceLog;
var result = {
id: id,
- /** @type {Array.<CanvasAgent.Call>} */
+ /** @type {!Array.<!CanvasAgent.Call>} */
calls: [],
- /** @type {Array.<CanvasAgent.CallArgument>} */
+ /** @type {!Array.<!CanvasAgent.CallArgument>} */
contexts: [],
alive: alive,
startOffset: fromIndex,
@@ -4325,14 +4368,10 @@ InjectedCanvasModule.prototype = {
if (!traceLog)
return "Error: Trace log with the given ID not found.";
this._traceLogPlayers[traceLogId] = this._traceLogPlayers[traceLogId] || new TraceLogPlayer(traceLog);
-
injectedScript.releaseObjectGroup(traceLogId);
- var beforeTime = TypeUtils.now();
- var lastCall = this._traceLogPlayers[traceLogId].stepTo(stepNo);
- var replayTime = Math.max(0, TypeUtils.now() - beforeTime);
-
- var resource = lastCall.resource();
+ var replayResult = this._traceLogPlayers[traceLogId].stepTo(stepNo);
+ var resource = replayResult.lastCall.resource();
var dataURL = resource.toDataURL();
if (!dataURL) {
resource = resource.contextResource();
@@ -4340,7 +4379,7 @@ InjectedCanvasModule.prototype = {
}
return {
resourceState: this._makeResourceState(resource.id(), traceLogId, resource, dataURL),
- replayTime: replayTime
+ replayTime: replayResult.replayTime
};
},