Commit 1f903908 authored by caseq@chromium.org's avatar caseq@chromium.org

DevTools: process events from all threads in TimelineTraceEventBindings

We used to process only main thread events in both TraceEventBindings
and TimelineFrameModel. This drops the filtering by thread from TracingModel
and lets its clients process all events from the inspected target, performing
filtering on their own.
Also, this forks the enum for thread event names from that of timeline model --
they may occasionally overlap, but essentially these are two different enums.

BUG=361045

Review URL: https://codereview.chromium.org/301593002

git-svn-id: svn://svn.chromium.org/blink/trunk@174955 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 3a31d226
......@@ -32,7 +32,7 @@ function test()
function onTracingComplete()
{
var events = InspectorTest.tracingModel.frameLifecycleEvents();
var events = InspectorTest.tracingModel.inspectedTargetEvents();
for (var i = events.length - 1; i >= 0; --i) {
if (events[i].phase === WebInspector.TracingModel.Phase.SnapshotObject && events[i].name === "cc::LayerTreeHostImpl") {
var rootLayer = events[i].args["snapshot"]["active_tree"]["root_layer"];
......
......@@ -5,7 +5,6 @@ Applications outside of WebKit depend on the stability of the mapping of these t
{
ActivateLayerTree : "ActivateLayerTree"
BeginFrame : "BeginFrame"
CallStack : "CallStack"
CancelAnimationFrame : "CancelAnimationFrame"
CompositeLayers : "CompositeLayers"
ConsoleTime : "ConsoleTime"
......
......@@ -192,7 +192,7 @@ function test()
model.setSessionIdForTest(sessionId);
model._eventsCollected(rawTraceEvents);
model._tracingComplete();
var events = model.inspectedTargetMainThreadEvents();
var events = model.inspectedTargetEvents();
var bindings = new WebInspector.TimelineTraceEventBindings();
bindings.setEvents(events);
InspectorTest.assertEquals(8, events.length);
......
......@@ -6,6 +6,7 @@
<script>
function test()
{
WebInspector.inspectorView.showPanel("timeline");
InspectorTest.invokeWithTracing("-*," + WebInspector.TracingModel.DevToolsMetadataEventCategory, "(function(callback) { callback(); })", processTracingEvents);
function processTracingEvents()
......@@ -20,10 +21,14 @@ function test()
function processEvent(event)
{
if (event.category !== WebInspector.TracingModel.DevToolsMetadataEventCategory ||
Object.values(WebInspector.TracingModel.DevToolsMetadataEvent).indexOf(event.name) < 0) {
var metadataEvents = [
WebInspector.TimelineTraceEventBindings.RecordType.SetLayerTreeId,
WebInspector.TimelineTraceEventBindings.RecordType.TracingStartedInPage
];
if (event.category !== WebInspector.TracingModel.DevToolsMetadataEventCategory || metadataEvents.indexOf(event.name) < 0)
return;
}
InspectorTest.assertEquals(InspectorTest.tracingModel.sessionId(), event.args["sessionId"]);
InspectorTest.addResult("Got DevTools metadata event: " + event.name);
}
......
......@@ -553,9 +553,8 @@ WebInspector.TracingBasedTimelineFlameChartDataProvider.prototype = {
this._currentLevel = 0;
this._minimumBoundary = this._model.minimumRecordTime() || 0;
this._timeSpan = Math.max((this._model.maximumRecordTime() || 0) - this._minimumBoundary, 1000000);
var tracingModel = this._model;
this._appendHeaderRecord("CPU");
var events = tracingModel.inspectedTargetMainThreadEvents();
var events = this._traceEventBindings.mainThreadEvents();
var maxStackDepth = 0;
for (var eventIndex = 0; eventIndex < events.length; ++eventIndex) {
var event = events[eventIndex];
......
......@@ -142,13 +142,12 @@ WebInspector.TimelineFrameModel.prototype = {
},
/**
* @param {!WebInspector.TracingModel} tracingModel
* @param {!Array.<!WebInspector.TracingModel.Event>} events
* @param {string} sessionId
*/
addTraceEvents: function(tracingModel)
addTraceEvents: function(events, sessionId)
{
// FIXME: we also need to process main thread events, so we can assign time spent by categories
// to frames. However, this requires that we can map trace event names to Timeline categories.
var events = tracingModel.frameLifecycleEvents();
this._sessionId = sessionId;
for (var i = 0; i < events.length; ++i)
this._addTraceEvent(events[i]);
},
......@@ -158,9 +157,22 @@ WebInspector.TimelineFrameModel.prototype = {
*/
_addTraceEvent: function(event)
{
var timestamp = event.startTime / 1000;
var eventNames = WebInspector.TracingModel.TraceEventName;
var eventNames = WebInspector.TimelineTraceEventBindings.RecordType;
if (event.name === eventNames.SetLayerTreeId) {
if (this._sessionId === event.args["sessionId"])
this._layerTreeId = event.args["layerTreeId"];
return;
}
if (event.phase === WebInspector.TracingModel.Phase.SnapshotObject && event.name === eventNames.LayerTreeHostImplSnapshot && parseInt(event.id, 0) === this._layerTreeId) {
this.handleLayerTreeSnapshot(new WebInspector.DeferredTracingLayerTree(this.target(), event.args["snapshot"]["active_tree"]["root_layer"]));
return;
}
if (event.args["layerTreeId"] !== this._layerTreeId)
return;
var timestamp = event.startTime / 1000;
if (event.name === eventNames.BeginFrame)
this.handleBeginFrame(timestamp);
else if (event.name === eventNames.DrawFrame)
......@@ -171,8 +183,9 @@ WebInspector.TimelineFrameModel.prototype = {
this.handleRequestMainThreadFrame();
else if (event.name === eventNames.CompositeLayers)
this.handleCompositeLayers();
else if (event.name === eventNames.LayerTreeHostImplSnapshot)
this.handleLayerTreeSnapshot(new WebInspector.DeferredTracingLayerTree(this.target(), event.args["snapshot"]["active_tree"]["root_layer"]));
// FIXME: we also need to process main thread events, so we can assign time spent by categories
// to frames. However, this requires that we can map trace event names to Timeline categories.
},
/**
......
......@@ -111,9 +111,6 @@ WebInspector.TimelineModel.RecordType = {
WebSocketDestroy : "WebSocketDestroy",
EmbedderCallback : "EmbedderCallback",
// Event types used in tracing based timeline only.
CallStack: "CallStack",
}
WebInspector.TimelineModel.Events = {
......
......@@ -247,8 +247,12 @@ WebInspector.TimelinePanel.prototype = {
*/
_frameModel: function()
{
if (!this._lazyFrameModel)
if (!this._lazyFrameModel) {
this._lazyFrameModel = new WebInspector.TimelineFrameModel(this._model);
if (this._lazyTracingModel)
this._lazyFrameModel.addTraceEvents(this._lazyTracingModel.inspectedTargetEvents(), this._lazyTracingModel.sessionId());
}
return this._lazyFrameModel;
},
......@@ -272,7 +276,7 @@ WebInspector.TimelinePanel.prototype = {
if (!this._lazyTraceEventBindings) {
this._lazyTraceEventBindings = new WebInspector.TimelineTraceEventBindings();
if (this._lazyTracingModel)
this._lazyTraceEventBindings.setEvents(this._lazyTracingModel.inspectedTargetMainThreadEvents());
this._lazyTraceEventBindings.setEvents(this._lazyTracingModel.inspectedTargetEvents());
}
return this._lazyTraceEventBindings;
},
......@@ -696,11 +700,11 @@ WebInspector.TimelinePanel.prototype = {
{
if (this._lazyFrameModel) {
this._lazyFrameModel.reset();
this._lazyFrameModel.addTraceEvents(this._lazyTracingModel);
this._lazyFrameModel.addTraceEvents(this._lazyTracingModel.inspectedTargetEvents(), this._lazyTracingModel.sessionId());
this._overviewPane.update();
}
if (this._lazyTraceEventBindings)
this._lazyTraceEventBindings.setEvents(this._lazyTracingModel.inspectedTargetMainThreadEvents());
this._lazyTraceEventBindings.setEvents(this._lazyTracingModel.inspectedTargetEvents());
this._refreshViews();
},
......
......@@ -7,10 +7,96 @@
*/
WebInspector.TimelineTraceEventBindings = function()
{
this._resetProcessingState();
this._reset();
}
WebInspector.TimelineTraceEventBindings.RecordType = {
Program: "Program",
EventDispatch: "EventDispatch",
GPUTask: "GPUTask",
RequestMainThreadFrame: "RequestMainThreadFrame",
BeginFrame: "BeginFrame",
BeginMainThreadFrame: "BeginMainThreadFrame",
ActivateLayerTree: "ActivateLayerTree",
DrawFrame: "DrawFrame",
ScheduleStyleRecalculation: "ScheduleStyleRecalculation",
RecalculateStyles: "RecalculateStyles",
InvalidateLayout: "InvalidateLayout",
Layout: "Layout",
UpdateLayerTree: "UpdateLayerTree",
PaintSetup: "PaintSetup",
Paint: "Paint",
Rasterize: "Rasterize",
RasterTask: "RasterTask",
ScrollLayer: "ScrollLayer",
DecodeImage: "DecodeImage",
ResizeImage: "ResizeImage",
CompositeLayers: "CompositeLayers",
ParseHTML: "ParseHTML",
TimerInstall: "TimerInstall",
TimerRemove: "TimerRemove",
TimerFire: "TimerFire",
XHRReadyStateChange: "XHRReadyStateChange",
XHRLoad: "XHRLoad",
EvaluateScript: "EvaluateScript",
MarkLoad: "MarkLoad",
MarkDOMContent: "MarkDOMContent",
MarkFirstPaint: "MarkFirstPaint",
TimeStamp: "TimeStamp",
ConsoleTime: "ConsoleTime",
ResourceSendRequest: "ResourceSendRequest",
ResourceReceiveResponse: "ResourceReceiveResponse",
ResourceReceivedData: "ResourceReceivedData",
ResourceFinish: "ResourceFinish",
FunctionCall: "FunctionCall",
GCEvent: "GCEvent",
JSFrame: "JSFrame",
UpdateCounters: "UpdateCounters",
RequestAnimationFrame: "RequestAnimationFrame",
CancelAnimationFrame: "CancelAnimationFrame",
FireAnimationFrame: "FireAnimationFrame",
WebSocketCreate : "WebSocketCreate",
WebSocketSendHandshakeRequest : "WebSocketSendHandshakeRequest",
WebSocketReceiveHandshakeResponse : "WebSocketReceiveHandshakeResponse",
WebSocketDestroy : "WebSocketDestroy",
EmbedderCallback : "EmbedderCallback",
CallStack: "CallStack",
SetLayerTreeId: "SetLayerTreeId",
TracingStartedInPage: "TracingStartedInPage",
LayerTreeHostImplSnapshot: "cc::LayerTreeHostImpl"
};
WebInspector.TimelineTraceEventBindings.prototype = {
/**
* @return {!Array.<!WebInspector.TracingModel.Event>}
*/
mainThreadEvents: function()
{
return this._mainThreadEvents;
},
_reset: function()
{
this._resetProcessingState();
this._mainThreadEvents = [];
},
_resetProcessingState: function()
{
this._sendRequestEvents = {};
......@@ -22,7 +108,6 @@ WebInspector.TimelineTraceEventBindings.prototype = {
this._lastRecalculateStylesEvent = null;
this._currentScriptEvent = null;
this._lastMainThreadEvent = null;
this._eventStack = [];
},
......@@ -33,13 +118,16 @@ WebInspector.TimelineTraceEventBindings.prototype = {
{
this._resetProcessingState();
for (var i = 0, length = events.length; i < length; i++)
this._processMainThreadEvent(events[i]);
this._processEvent(events[i]);
this._resetProcessingState();
},
_processMainThreadEvent: function(event)
/**
* @param {!WebInspector.TracingModel.Event} event
*/
_processEvent: function(event)
{
var recordTypes = WebInspector.TimelineModel.RecordType;
var recordTypes = WebInspector.TimelineTraceEventBindings.RecordType;
var eventStack = this._eventStack;
while (eventStack.length && eventStack.peekLast().endTime < event.startTime)
......@@ -59,9 +147,10 @@ WebInspector.TimelineTraceEventBindings.prototype = {
switch (event.name) {
case recordTypes.CallStack:
if (this._lastMainThreadEvent)
this._lastMainThreadEvent.stackTrace = event.args.stack;
break
var lastMainThreadEvent = this._mainThreadEvents.peekLast();
if (lastMainThreadEvent)
lastMainThreadEvent.stackTrace = event.args.stack;
break;
case recordTypes.ResourceSendRequest:
this._sendRequestEvents[event.args.data["requestId"]] = event;
......@@ -126,13 +215,22 @@ WebInspector.TimelineTraceEventBindings.prototype = {
event.initiator = this._webSocketCreateEvents[event.args.data["identifier"]];
break;
case WebInspector.TimelineModel.RecordType.EvaluateScript:
case WebInspector.TimelineModel.RecordType.FunctionCall:
case recordTypes.EvaluateScript:
case recordTypes.FunctionCall:
if (!this._currentScriptEvent)
this._currentScriptEvent = event;
break;
case recordTypes.SetLayerTreeId:
this._inspectedTargetLayerTreeId = event.args["layerTreeId"];
break;
case recordTypes.TracingStartedInPage:
this._mainThread = event.thread;
break;
}
this._lastMainThreadEvent = event;
if (this._mainThread === event.thread)
this._mainThreadEvents.push(event);
}
}
......@@ -229,8 +229,8 @@ WebInspector.TraceViewFlameChartDataProvider = function(model, timelineModelForM
id: 0,
s: ""
}
this._processHeaderRecord = new WebInspector.TracingModel.Event(dummyEventPayload, 0);
this._threadHeaderRecord = new WebInspector.TracingModel.Event(dummyEventPayload, 0);
this._processHeaderRecord = new WebInspector.TracingModel.Event(dummyEventPayload, 0, null);
this._threadHeaderRecord = new WebInspector.TracingModel.Event(dummyEventPayload, 0, null);
}
WebInspector.TraceViewFlameChartDataProvider.prototype = {
......
......@@ -71,44 +71,15 @@ WebInspector.TracingModel.FrameLifecycleEventCategory = "cc,devtools";
WebInspector.TracingModel.DevToolsMetadataEvent = {
TracingStartedInPage: "TracingStartedInPage",
SetLayerTreeId: "SetLayerTreeId"
};
WebInspector.TracingModel.TraceEventName = {
ActivateLayerTree: "ActivateLayerTree",
BeginFrame: "BeginFrame",
BeginMainThreadFrame: "BeginMainThreadFrame",
CompositeLayers: "CompositeLayers",
DrawFrame: "DrawFrame",
PaintSetup: "PaintSetup",
RasterTask: "RasterTask",
RequestMainThreadFrame: "RequestMainThreadFrame",
LayerTreeHostImplSnapshot: "cc::LayerTreeHostImpl"
};
WebInspector.TracingModel.prototype = {
/**
* @return {!Array.<!WebInspector.TracingModel.Event>}
*/
inspectedTargetMainThreadEvents: function()
{
return this._inspectedTargetMainThreadEvents;
},
/**
* @return {!Array.<!WebInspector.TracingModel.Event>}
*/
frameLifecycleEvents: function()
inspectedTargetEvents: function()
{
/**
* @param {!WebInspector.TracingModel.Event} a
* @param {!WebInspector.TracingModel.Event} b
*/
function compareStartTime(a, b)
{
return a.startTime - b.startTime;
}
return this._frameLifecycleEvents.sort(compareStartTime);
return this._inspectedTargetEvents;
},
/**
......@@ -184,6 +155,17 @@ WebInspector.TracingModel.prototype = {
_tracingComplete: function()
{
this._active = false;
/**
* @param {!WebInspector.TracingModel.Event} a
* @param {!WebInspector.TracingModel.Event} b
*/
function compareStartTime(a, b)
{
return a.startTime - b.startTime;
}
this._inspectedTargetEvents.sort(compareStartTime);
if (!this._pendingStopCallback)
return;
this._pendingStopCallback();
......@@ -197,10 +179,7 @@ WebInspector.TracingModel.prototype = {
this._maximumRecordTime = null;
this._sessionId = null;
this._inspectedTargetProcessId = null;
this._inspectedTargetMainThread = null;
this._inspectedTargetMainThreadEvents = [];
this._inspectedTargetLayerTreeHostId = 0;
this._frameLifecycleEvents = [];
this._inspectedTargetEvents = [];
},
/**
......@@ -213,13 +192,14 @@ WebInspector.TracingModel.prototype = {
process = new WebInspector.TracingModel.Process(payload.pid);
this._processById[payload.pid] = process;
}
var thread = process.threadById(payload.tid);
if (payload.ph === WebInspector.TracingModel.Phase.SnapshotObject) {
process.addObject(payload);
if (payload.pid === this._inspectedTargetProcessId && payload.name === "cc::LayerTreeHostImpl" && parseInt(payload.id, 0) === this._inspectedTargetLayerTreeId)
this._frameLifecycleEvents.push(new WebInspector.TracingModel.Event(payload, 0));
var event = new WebInspector.TracingModel.Event(payload, 0, thread);
process.addObject(event);
if (payload.pid === this._inspectedTargetProcessId)
this._inspectedTargetEvents.push(event);
return;
}
var thread = process.threadById(payload.tid);
if (payload.ph !== WebInspector.TracingModel.Phase.Metadata) {
var timestamp = payload.ts;
// We do allow records for unrelated threads to arrive out-of-order,
......@@ -231,12 +211,8 @@ WebInspector.TracingModel.prototype = {
if (payload.cat === WebInspector.TracingModel.DevToolsMetadataEventCategory)
this._processDevToolsMetadataEvent(payload);
var event = thread.addEvent(payload);
if (!event)
return;
if (thread === this._inspectedTargetMainThread)
this._inspectedTargetMainThreadEvents.push(event);
if (payload.cat === WebInspector.TracingModel.FrameLifecycleEventCategory && payload.pid === this._inspectedTargetProcessId && payload.args && payload.args["layerTreeId"] === this._inspectedTargetLayerTreeId)
this._frameLifecycleEvents.push(event);
if (event && payload.pid === this._inspectedTargetProcessId)
this._inspectedTargetEvents.push(event);
return;
}
switch (payload.name) {
......@@ -260,16 +236,9 @@ WebInspector.TracingModel.prototype = {
*/
_processDevToolsMetadataEvent: function(payload)
{
if (payload.args["sessionId"] !== this._sessionId)
if (payload.args["sessionId"] !== this._sessionId || payload.name !== WebInspector.TracingModel.DevToolsMetadataEvent.TracingStartedInPage)
return;
if (payload.name === WebInspector.TracingModel.DevToolsMetadataEvent.TracingStartedInPage) {
var thread = this._processById[payload.pid].threadById(payload.tid)
this._inspectedTargetProcessId = payload.pid;
this._inspectedTargetMainThread = thread;
this._inspectedTargetMainThreadEvents = this._inspectedTargetMainThreadEvents.concat(thread.events());
} else if (payload.name === WebInspector.TracingModel.DevToolsMetadataEvent.SetLayerTreeId) {
this._inspectedTargetLayerTreeId = payload.args["layerTreeId"];
}
this._inspectedTargetProcessId = payload.pid;
},
/**
......@@ -303,8 +272,9 @@ WebInspector.TracingModel.prototype = {
* @constructor
* @param {!WebInspector.TracingModel.EventPayload} payload
* @param {number} level
* @param {?WebInspector.TracingModel.Thread} thread
*/
WebInspector.TracingModel.Event = function(payload, level)
WebInspector.TracingModel.Event = function(payload, level, thread)
{
this.name = payload.name;
this.category = payload.cat;
......@@ -313,6 +283,11 @@ WebInspector.TracingModel.Event = function(payload, level)
this.phase = payload.ph;
this.level = level;
if (payload.id)
this.id = payload.id;
this.thread = thread;
/** @type {?string} */
this.warning = null;
/** @type {?WebInspector.TracingModel.Event} */
......@@ -439,11 +414,11 @@ WebInspector.TracingModel.Process.prototype = {
},
/**
* @param {!WebInspector.TracingModel.EventPayload} event
* @param {!WebInspector.TracingModel.Event} event
*/
addObject: function(event)
{
this.objectsByName(event.name).push(new WebInspector.TracingModel.Event(event, 0));
this.objectsByName(event.name).push(event);
},
/**
......@@ -512,7 +487,7 @@ WebInspector.TracingModel.Thread.prototype = {
return null;
}
var event = new WebInspector.TracingModel.Event(payload, this._stack.length);
var event = new WebInspector.TracingModel.Event(payload, this._stack.length, this);
if (payload.ph === WebInspector.TracingModel.Phase.Begin || payload.ph === WebInspector.TracingModel.Phase.Complete) {
if (payload.ph === WebInspector.TracingModel.Phase.Complete)
event._setDuration(payload.dur);
......
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