OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 16 matching lines...) Expand all Loading... |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 /** | 31 /** |
32 * @constructor | 32 * @constructor |
33 * @extends {WebInspector.Object} | 33 * @extends {WebInspector.Object} |
34 */ | 34 */ |
35 WebInspector.TimelineModel = function() | 35 WebInspector.TimelineModel = function() |
36 { | 36 { |
37 this._payloads = []; | 37 this._filters = []; |
38 this._records = []; | |
39 this._minimumRecordTime = -1; | |
40 this._maximumRecordTime = -1; | |
41 this._stringPool = {}; | |
42 this._bindings = new WebInspector.TimelineModel.InterRecordBindings(); | 38 this._bindings = new WebInspector.TimelineModel.InterRecordBindings(); |
43 | 39 |
| 40 this.reset(); |
| 41 |
44 WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.E
ventTypes.TimelineEventRecorded, this._onRecordAdded, this); | 42 WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.E
ventTypes.TimelineEventRecorded, this._onRecordAdded, this); |
45 WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.E
ventTypes.TimelineStarted, this._onStarted, this); | 43 WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.E
ventTypes.TimelineStarted, this._onStarted, this); |
46 WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.E
ventTypes.TimelineStopped, this._onStopped, this); | 44 WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.E
ventTypes.TimelineStopped, this._onStopped, this); |
47 } | 45 } |
48 | 46 |
49 WebInspector.TimelineModel.TransferChunkLengthBytes = 5000000; | 47 WebInspector.TimelineModel.TransferChunkLengthBytes = 5000000; |
50 | 48 |
51 WebInspector.TimelineModel.RecordType = { | 49 WebInspector.TimelineModel.RecordType = { |
52 Root: "Root", | 50 Root: "Root", |
53 Program: "Program", | 51 Program: "Program", |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 WebSocketReceiveHandshakeResponse : "WebSocketReceiveHandshakeResponse", | 105 WebSocketReceiveHandshakeResponse : "WebSocketReceiveHandshakeResponse", |
108 WebSocketDestroy : "WebSocketDestroy", | 106 WebSocketDestroy : "WebSocketDestroy", |
109 | 107 |
110 EmbedderCallback : "EmbedderCallback", | 108 EmbedderCallback : "EmbedderCallback", |
111 } | 109 } |
112 | 110 |
113 WebInspector.TimelineModel.Events = { | 111 WebInspector.TimelineModel.Events = { |
114 RecordAdded: "RecordAdded", | 112 RecordAdded: "RecordAdded", |
115 RecordsCleared: "RecordsCleared", | 113 RecordsCleared: "RecordsCleared", |
116 RecordingStarted: "RecordingStarted", | 114 RecordingStarted: "RecordingStarted", |
117 RecordingStopped: "RecordingStopped" | 115 RecordingStopped: "RecordingStopped", |
| 116 RecordFilterChanged: "RecordFilterChanged" |
118 } | 117 } |
119 | 118 |
120 /** | 119 /** |
121 * @param {!Array.<!WebInspector.TimelineModel.Record>} recordsArray | 120 * @param {!Array.<!WebInspector.TimelineModel.Record>} recordsArray |
122 * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspector
.TimelineModel.Record,number)} preOrderCallback | 121 * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspector
.TimelineModel.Record,number)} preOrderCallback |
123 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.T
imelineModel.Record,number)=} postOrderCallback | 122 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.T
imelineModel.Record,number)=} postOrderCallback |
124 */ | 123 */ |
125 WebInspector.TimelineModel.forAllRecords = function(recordsArray, preOrderCallba
ck, postOrderCallback) | 124 WebInspector.TimelineModel.forAllRecords = function(recordsArray, preOrderCallba
ck, postOrderCallback) |
126 { | 125 { |
127 if (!recordsArray) | 126 /** |
128 return; | 127 * @param {!Array.<!WebInspector.TimelineModel.Record>} records |
129 var stack = [{array: recordsArray, index: 0}]; | 128 * @param {number} depth |
130 while (stack.length) { | 129 * @return {boolean} |
131 var entry = stack[stack.length - 1]; | 130 */ |
132 var records = entry.array; | 131 function processRecords(records, depth) |
133 if (entry.index < records.length) { | 132 { |
134 var record = records[entry.index]; | 133 for (var i = 0; i < records.length; ++i) { |
135 if (preOrderCallback && preOrderCallback(record, stack.length)) | 134 var record = records[i]; |
136 return; | 135 if (preOrderCallback && preOrderCallback(record, depth)) |
137 if (record.children) | 136 return true; |
138 stack.push({array: record.children, index: 0, record: record}); | 137 if (processRecords(record.children, depth + 1)) |
139 else if (postOrderCallback && postOrderCallback(record, stack.lengt
h)) | 138 return true; |
140 return; | 139 if (postOrderCallback && postOrderCallback(record, depth)) |
141 ++entry.index; | 140 return true; |
142 } else { | |
143 if (entry.record && postOrderCallback && postOrderCallback(entry.rec
ord, stack.length)) | |
144 return; | |
145 stack.pop(); | |
146 } | 141 } |
| 142 return false; |
147 } | 143 } |
| 144 processRecords(recordsArray, 0); |
148 } | 145 } |
149 | 146 |
150 WebInspector.TimelineModel.prototype = { | 147 WebInspector.TimelineModel.prototype = { |
151 /** | 148 /** |
152 * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspe
ctor.TimelineModel.Record,number)} preOrderCallback | 149 * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspe
ctor.TimelineModel.Record,number)} preOrderCallback |
153 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspect
or.TimelineModel.Record,number)=} postOrderCallback | 150 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspect
or.TimelineModel.Record,number)=} postOrderCallback |
154 */ | 151 */ |
155 forAllRecords: function(preOrderCallback, postOrderCallback) | 152 forAllRecords: function(preOrderCallback, postOrderCallback) |
156 { | 153 { |
157 WebInspector.TimelineModel.forAllRecords(this._records, preOrderCallback
, postOrderCallback); | 154 WebInspector.TimelineModel.forAllRecords(this._records, preOrderCallback
, postOrderCallback); |
158 }, | 155 }, |
159 | 156 |
160 /** | 157 /** |
| 158 * @param {!WebInspector.TimelineModel.Filter} filter |
| 159 */ |
| 160 addFilter: function(filter) |
| 161 { |
| 162 this._filters.push(filter); |
| 163 filter._model = this; |
| 164 }, |
| 165 |
| 166 /** |
| 167 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspect
or.TimelineModel.Record,number)} callback |
| 168 */ |
| 169 forAllFilteredRecords: function(callback) |
| 170 { |
| 171 /** |
| 172 * @param {!WebInspector.TimelineModel.Record} record |
| 173 * @param {number} depth |
| 174 * @this {WebInspector.TimelineModel} |
| 175 * @return {boolean} |
| 176 */ |
| 177 function processRecord(record, depth) |
| 178 { |
| 179 var visible = this.isVisible(record); |
| 180 if (visible) { |
| 181 if (callback(record, depth)) |
| 182 return true; |
| 183 } |
| 184 |
| 185 for (var i = 0; i < record.children.length; ++i) { |
| 186 if (processRecord.call(this, record.children[i], visible ? depth
+ 1 : depth)) |
| 187 return true; |
| 188 } |
| 189 return false; |
| 190 } |
| 191 |
| 192 for (var i = 0; i < this._records.length; ++i) |
| 193 processRecord.call(this, this._records[i], 0); |
| 194 }, |
| 195 |
| 196 /** |
| 197 * @param {!WebInspector.TimelineModel.Record} record |
| 198 * @return {boolean} |
| 199 */ |
| 200 isVisible: function(record) |
| 201 { |
| 202 for (var i = 0; i < this._filters.length; ++i) { |
| 203 if (!this._filters[i].accept(record)) |
| 204 return false; |
| 205 } |
| 206 return true; |
| 207 }, |
| 208 |
| 209 _filterChanged: function() |
| 210 { |
| 211 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordFi
lterChanged); |
| 212 }, |
| 213 |
| 214 /** |
161 * @param {boolean=} includeCounters | 215 * @param {boolean=} includeCounters |
162 */ | 216 */ |
163 startRecording: function(includeCounters) | 217 startRecording: function(includeCounters) |
164 { | 218 { |
165 this._clientInitiatedRecording = true; | 219 this._clientInitiatedRecording = true; |
166 this.reset(); | 220 this.reset(); |
167 var maxStackFrames = WebInspector.settings.timelineCaptureStacks.get() ?
30 : 0; | 221 var maxStackFrames = WebInspector.settings.timelineCaptureStacks.get() ?
30 : 0; |
168 var includeGPUEvents = WebInspector.experimentsSettings.gpuTimeline.isEn
abled(); | 222 var includeGPUEvents = WebInspector.experimentsSettings.gpuTimeline.isEn
abled(); |
169 WebInspector.timelineManager.start(maxStackFrames, includeCounters, incl
udeGPUEvents, this._fireRecordingStarted.bind(this)); | 223 WebInspector.timelineManager.start(maxStackFrames, includeCounters, incl
udeGPUEvents, this._fireRecordingStarted.bind(this)); |
170 }, | 224 }, |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 * @param {!TimelineAgent.TimelineEvent} payload | 299 * @param {!TimelineAgent.TimelineEvent} payload |
246 */ | 300 */ |
247 _addRecord: function(payload) | 301 _addRecord: function(payload) |
248 { | 302 { |
249 this._internStrings(payload); | 303 this._internStrings(payload); |
250 this._payloads.push(payload); | 304 this._payloads.push(payload); |
251 this._updateBoundaries(payload); | 305 this._updateBoundaries(payload); |
252 | 306 |
253 var record = this._innerAddRecord(payload, null); | 307 var record = this._innerAddRecord(payload, null); |
254 this._records.push(record); | 308 this._records.push(record); |
| 309 if (record.type === WebInspector.TimelineModel.RecordType.Program) |
| 310 this._mainThreadTasks.push(record); |
| 311 if (record.type === WebInspector.TimelineModel.RecordType.GPUTask) |
| 312 this._gpuThreadTasks.push(record); |
255 | 313 |
256 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd
ded, record); | 314 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd
ded, record); |
257 }, | 315 }, |
258 | 316 |
259 /** | 317 /** |
260 * @param {!TimelineAgent.TimelineEvent} payload | 318 * @param {!TimelineAgent.TimelineEvent} payload |
261 * @param {?WebInspector.TimelineModel.Record} parentRecord | 319 * @param {?WebInspector.TimelineModel.Record} parentRecord |
262 * @return {!WebInspector.TimelineModel.Record} | 320 * @return {!WebInspector.TimelineModel.Record} |
263 * @this {!WebInspector.TimelineModel} | 321 * @this {!WebInspector.TimelineModel} |
264 */ | 322 */ |
265 _innerAddRecord: function(payload, parentRecord) | 323 _innerAddRecord: function(payload, parentRecord) |
266 { | 324 { |
267 var record = new WebInspector.TimelineModel.Record(this, payload, parent
Record); | 325 var record = new WebInspector.TimelineModel.Record(this, payload, parent
Record); |
| 326 if (WebInspector.TimelineUIUtils.isEventDivider(record)) |
| 327 this._eventDividerRecords.push(record); |
| 328 |
268 for (var i = 0; payload.children && i < payload.children.length; ++i) | 329 for (var i = 0; payload.children && i < payload.children.length; ++i) |
269 this._innerAddRecord.call(this, payload.children[i], record); | 330 this._innerAddRecord.call(this, payload.children[i], record); |
270 | 331 |
271 record.calculateAggregatedStats(); | 332 record.calculateAggregatedStats(); |
272 if (parentRecord) | 333 if (parentRecord) |
273 parentRecord._selfTime -= record.endTime - record.startTime; | 334 parentRecord._selfTime -= record.endTime - record.startTime; |
274 return record; | 335 return record; |
275 }, | 336 }, |
276 | 337 |
277 /** | 338 /** |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 }, | 389 }, |
329 | 390 |
330 reset: function() | 391 reset: function() |
331 { | 392 { |
332 this._records = []; | 393 this._records = []; |
333 this._payloads = []; | 394 this._payloads = []; |
334 this._stringPool = {}; | 395 this._stringPool = {}; |
335 this._minimumRecordTime = -1; | 396 this._minimumRecordTime = -1; |
336 this._maximumRecordTime = -1; | 397 this._maximumRecordTime = -1; |
337 this._bindings._reset(); | 398 this._bindings._reset(); |
| 399 /** @type {!Array.<!WebInspector.TimelineModel.Record>} */ |
| 400 this._mainThreadTasks = []; |
| 401 /** @type {!Array.<!WebInspector.TimelineModel.Record>} */ |
| 402 this._gpuThreadTasks = []; |
| 403 /** @type {!Array.<!WebInspector.TimelineModel.Record>} */ |
| 404 this._eventDividerRecords = []; |
338 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordsC
leared); | 405 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordsC
leared); |
339 }, | 406 }, |
340 | 407 |
341 /** | 408 /** |
342 * @return {number} | 409 * @return {number} |
343 */ | 410 */ |
344 minimumRecordTime: function() | 411 minimumRecordTime: function() |
345 { | 412 { |
346 return this._minimumRecordTime; | 413 return this._minimumRecordTime; |
347 }, | 414 }, |
(...skipping 14 matching lines...) Expand all Loading... |
362 var startTime = record.startTime; | 429 var startTime = record.startTime; |
363 var endTime = record.endTime; | 430 var endTime = record.endTime; |
364 | 431 |
365 if (this._minimumRecordTime === -1 || startTime < this._minimumRecordTim
e) | 432 if (this._minimumRecordTime === -1 || startTime < this._minimumRecordTim
e) |
366 this._minimumRecordTime = startTime; | 433 this._minimumRecordTime = startTime; |
367 if ((this._maximumRecordTime === -1 && endTime) || endTime > this._maxim
umRecordTime) | 434 if ((this._maximumRecordTime === -1 && endTime) || endTime > this._maxim
umRecordTime) |
368 this._maximumRecordTime = endTime; | 435 this._maximumRecordTime = endTime; |
369 }, | 436 }, |
370 | 437 |
371 /** | 438 /** |
372 * @param {!Object} rawRecord | 439 * @return {!Array.<!WebInspector.TimelineModel.Record>} |
373 * @return {number} | |
374 */ | 440 */ |
375 recordOffsetInMillis: function(rawRecord) | 441 mainThreadTasks: function() |
376 { | 442 { |
377 return rawRecord.startTime - this._minimumRecordTime; | 443 return this._mainThreadTasks; |
378 }, | 444 }, |
379 | 445 |
380 /** | 446 /** |
| 447 * @return {!Array.<!WebInspector.TimelineModel.Record>} |
| 448 */ |
| 449 gpuThreadTasks: function() |
| 450 { |
| 451 return this._gpuThreadTasks; |
| 452 }, |
| 453 |
| 454 /** |
| 455 * @return {!Array.<!WebInspector.TimelineModel.Record>} |
| 456 */ |
| 457 eventDividerRecords: function() |
| 458 { |
| 459 return this._eventDividerRecords; |
| 460 }, |
| 461 |
| 462 /** |
381 * @param {!TimelineAgent.TimelineEvent} record | 463 * @param {!TimelineAgent.TimelineEvent} record |
382 */ | 464 */ |
383 _internStrings: function(record) | 465 _internStrings: function(record) |
384 { | 466 { |
385 for (var name in record) { | 467 for (var name in record) { |
386 var value = record[name]; | 468 var value = record[name]; |
387 if (typeof value !== "string") | 469 if (typeof value !== "string") |
388 continue; | 470 continue; |
389 | 471 |
390 var interned = this._stringPool[value]; | 472 var interned = this._stringPool[value]; |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 */ | 886 */ |
805 testContentMatching: function(regExp) | 887 testContentMatching: function(regExp) |
806 { | 888 { |
807 var tokens = [this.title()]; | 889 var tokens = [this.title()]; |
808 for (var key in this._record.data) | 890 for (var key in this._record.data) |
809 tokens.push(this._record.data[key]) | 891 tokens.push(this._record.data[key]) |
810 return regExp.test(tokens.join("|")); | 892 return regExp.test(tokens.join("|")); |
811 } | 893 } |
812 } | 894 } |
813 | 895 |
| 896 |
| 897 /** |
| 898 * @constructor |
| 899 */ |
| 900 WebInspector.TimelineModel.Filter = function() |
| 901 { |
| 902 /** @type {!WebInspector.TimelineModel} */ |
| 903 this._model; |
| 904 } |
| 905 |
| 906 WebInspector.TimelineModel.Filter.prototype = { |
| 907 /** |
| 908 * @param {!WebInspector.TimelineModel.Record} record |
| 909 * @return {boolean} |
| 910 */ |
| 911 accept: function(record) |
| 912 { |
| 913 return true; |
| 914 }, |
| 915 |
| 916 notifyFilterChanged: function() |
| 917 { |
| 918 this._model._filterChanged(); |
| 919 } |
| 920 } |
| 921 |
814 /** | 922 /** |
815 * @constructor | 923 * @constructor |
816 * @implements {WebInspector.OutputStream} | 924 * @implements {WebInspector.OutputStream} |
817 * @param {!WebInspector.TimelineModel} model | 925 * @param {!WebInspector.TimelineModel} model |
818 * @param {!{cancel: function()}} reader | 926 * @param {!{cancel: function()}} reader |
819 * @param {!WebInspector.Progress} progress | 927 * @param {!WebInspector.Progress} progress |
820 */ | 928 */ |
821 WebInspector.TimelineModelLoader = function(model, reader, progress) | 929 WebInspector.TimelineModelLoader = function(model, reader, progress) |
822 { | 930 { |
823 this._model = model; | 931 this._model = model; |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 WebInspector.TimelineModel._quadFromRectData = function(data) | 1147 WebInspector.TimelineModel._quadFromRectData = function(data) |
1040 { | 1148 { |
1041 if (typeof data["x"] === "undefined" || typeof data["y"] === "undefined") | 1149 if (typeof data["x"] === "undefined" || typeof data["y"] === "undefined") |
1042 return null; | 1150 return null; |
1043 var x0 = data["x"]; | 1151 var x0 = data["x"]; |
1044 var x1 = data["x"] + data["width"]; | 1152 var x1 = data["x"] + data["width"]; |
1045 var y0 = data["y"]; | 1153 var y0 = data["y"]; |
1046 var y1 = data["y"] + data["height"]; | 1154 var y1 = data["y"] + data["height"]; |
1047 return [x0, y0, x1, y0, x1, y1, x0, y1]; | 1155 return [x0, y0, x1, y0, x1, y1, x0, y1]; |
1048 } | 1156 } |
OLD | NEW |