Index: Source/devtools/front_end/TimelineModel.js |
diff --git a/Source/devtools/front_end/TimelineModel.js b/Source/devtools/front_end/TimelineModel.js |
index 65c852780ca4c75c689834c6bec8a20c7fe8bca6..8ce8b1f9a99c30c12f5120392477e99240575895 100644 |
--- a/Source/devtools/front_end/TimelineModel.js |
+++ b/Source/devtools/front_end/TimelineModel.js |
@@ -34,13 +34,11 @@ |
*/ |
WebInspector.TimelineModel = function() |
{ |
- this._payloads = []; |
- this._records = []; |
- this._minimumRecordTime = -1; |
- this._maximumRecordTime = -1; |
- this._stringPool = {}; |
+ this._filters = []; |
this._bindings = new WebInspector.TimelineModel.InterRecordBindings(); |
+ this.reset(); |
+ |
WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, this._onRecordAdded, this); |
WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineStarted, this._onStarted, this); |
WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineStopped, this._onStopped, this); |
@@ -114,7 +112,8 @@ WebInspector.TimelineModel.Events = { |
RecordAdded: "RecordAdded", |
RecordsCleared: "RecordsCleared", |
RecordingStarted: "RecordingStarted", |
- RecordingStopped: "RecordingStopped" |
+ RecordingStopped: "RecordingStopped", |
+ RecordFilterChanged: "RecordFilterChanged" |
} |
/** |
@@ -124,27 +123,25 @@ WebInspector.TimelineModel.Events = { |
*/ |
WebInspector.TimelineModel.forAllRecords = function(recordsArray, preOrderCallback, postOrderCallback) |
{ |
- if (!recordsArray) |
- return; |
- var stack = [{array: recordsArray, index: 0}]; |
- while (stack.length) { |
- var entry = stack[stack.length - 1]; |
- var records = entry.array; |
- if (entry.index < records.length) { |
- var record = records[entry.index]; |
- if (preOrderCallback && preOrderCallback(record, stack.length)) |
- return; |
- if (record.children) |
- stack.push({array: record.children, index: 0, record: record}); |
- else if (postOrderCallback && postOrderCallback(record, stack.length)) |
- return; |
- ++entry.index; |
- } else { |
- if (entry.record && postOrderCallback && postOrderCallback(entry.record, stack.length)) |
- return; |
- stack.pop(); |
+ /** |
+ * @param {!Array.<!WebInspector.TimelineModel.Record>} records |
+ * @param {number} depth |
+ * @return {boolean} |
+ */ |
+ function processRecords(records, depth) |
+ { |
+ for (var i = 0; i < records.length; ++i) { |
+ var record = records[i]; |
+ if (preOrderCallback && preOrderCallback(record, depth)) |
+ return true; |
+ if (processRecords(record.children, depth + 1)) |
+ return true; |
+ if (postOrderCallback && postOrderCallback(record, depth)) |
+ return true; |
} |
+ return false; |
} |
+ processRecords(recordsArray, 0); |
} |
WebInspector.TimelineModel.prototype = { |
@@ -158,6 +155,63 @@ WebInspector.TimelineModel.prototype = { |
}, |
/** |
+ * @param {!WebInspector.TimelineModel.Filter} filter |
+ */ |
+ addFilter: function(filter) |
+ { |
+ this._filters.push(filter); |
+ filter._model = this; |
+ }, |
+ |
+ /** |
+ * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.TimelineModel.Record,number)} callback |
+ */ |
+ forAllFilteredRecords: function(callback) |
+ { |
+ /** |
+ * @param {!WebInspector.TimelineModel.Record} record |
+ * @param {number} depth |
+ * @this {WebInspector.TimelineModel} |
+ * @return {boolean} |
+ */ |
+ function processRecord(record, depth) |
+ { |
+ var visible = this.isVisible(record); |
+ if (visible) { |
+ if (callback(record, depth)) |
+ return true; |
+ } |
+ |
+ for (var i = 0; i < record.children.length; ++i) { |
+ if (processRecord.call(this, record.children[i], visible ? depth + 1 : depth)) |
+ return true; |
+ } |
+ return false; |
+ } |
+ |
+ for (var i = 0; i < this._records.length; ++i) |
+ processRecord.call(this, this._records[i], 0); |
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.TimelineModel.Record} record |
+ * @return {boolean} |
+ */ |
+ isVisible: function(record) |
+ { |
+ for (var i = 0; i < this._filters.length; ++i) { |
+ if (!this._filters[i].accept(record)) |
+ return false; |
+ } |
+ return true; |
+ }, |
+ |
+ _filterChanged: function() |
+ { |
+ this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordFilterChanged); |
+ }, |
+ |
+ /** |
* @param {boolean=} includeCounters |
*/ |
startRecording: function(includeCounters) |
@@ -252,6 +306,10 @@ WebInspector.TimelineModel.prototype = { |
var record = this._innerAddRecord(payload, null); |
this._records.push(record); |
+ if (record.type === WebInspector.TimelineModel.RecordType.Program) |
+ this._mainThreadTasks.push(record); |
+ if (record.type === WebInspector.TimelineModel.RecordType.GPUTask) |
+ this._gpuThreadTasks.push(record); |
this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAdded, record); |
}, |
@@ -265,6 +323,9 @@ WebInspector.TimelineModel.prototype = { |
_innerAddRecord: function(payload, parentRecord) |
{ |
var record = new WebInspector.TimelineModel.Record(this, payload, parentRecord); |
+ if (WebInspector.TimelineUIUtils.isEventDivider(record)) |
+ this._eventDividerRecords.push(record); |
+ |
for (var i = 0; payload.children && i < payload.children.length; ++i) |
this._innerAddRecord.call(this, payload.children[i], record); |
@@ -335,6 +396,12 @@ WebInspector.TimelineModel.prototype = { |
this._minimumRecordTime = -1; |
this._maximumRecordTime = -1; |
this._bindings._reset(); |
+ /** @type {!Array.<!WebInspector.TimelineModel.Record>} */ |
+ this._mainThreadTasks = []; |
+ /** @type {!Array.<!WebInspector.TimelineModel.Record>} */ |
+ this._gpuThreadTasks = []; |
+ /** @type {!Array.<!WebInspector.TimelineModel.Record>} */ |
+ this._eventDividerRecords = []; |
this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordsCleared); |
}, |
@@ -369,12 +436,27 @@ WebInspector.TimelineModel.prototype = { |
}, |
/** |
- * @param {!Object} rawRecord |
- * @return {number} |
+ * @return {!Array.<!WebInspector.TimelineModel.Record>} |
+ */ |
+ mainThreadTasks: function() |
+ { |
+ return this._mainThreadTasks; |
+ }, |
+ |
+ /** |
+ * @return {!Array.<!WebInspector.TimelineModel.Record>} |
+ */ |
+ gpuThreadTasks: function() |
+ { |
+ return this._gpuThreadTasks; |
+ }, |
+ |
+ /** |
+ * @return {!Array.<!WebInspector.TimelineModel.Record>} |
*/ |
- recordOffsetInMillis: function(rawRecord) |
+ eventDividerRecords: function() |
{ |
- return rawRecord.startTime - this._minimumRecordTime; |
+ return this._eventDividerRecords; |
}, |
/** |
@@ -811,6 +893,32 @@ WebInspector.TimelineModel.Record.prototype = { |
} |
} |
+ |
+/** |
+ * @constructor |
+ */ |
+WebInspector.TimelineModel.Filter = function() |
+{ |
+ /** @type {!WebInspector.TimelineModel} */ |
+ this._model; |
+} |
+ |
+WebInspector.TimelineModel.Filter.prototype = { |
+ /** |
+ * @param {!WebInspector.TimelineModel.Record} record |
+ * @return {boolean} |
+ */ |
+ accept: function(record) |
+ { |
+ return true; |
+ }, |
+ |
+ notifyFilterChanged: function() |
+ { |
+ this._model._filterChanged(); |
+ } |
+} |
+ |
/** |
* @constructor |
* @implements {WebInspector.OutputStream} |