| 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 |