OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * Copyright (C) 2012 Intel Inc. All rights reserved. | 3 * Copyright (C) 2012 Intel Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 27 matching lines...) Expand all Loading... |
38 { | 38 { |
39 this._model = model; | 39 this._model = model; |
40 this._filters = []; | 40 this._filters = []; |
41 /** | 41 /** |
42 * @type {!Map.<!WebInspector.TimelineModel.Record, !WebInspector.TimelinePr
esentationModel.Record>} | 42 * @type {!Map.<!WebInspector.TimelineModel.Record, !WebInspector.TimelinePr
esentationModel.Record>} |
43 */ | 43 */ |
44 this._recordToPresentationRecord = new Map(); | 44 this._recordToPresentationRecord = new Map(); |
45 this.reset(); | 45 this.reset(); |
46 } | 46 } |
47 | 47 |
48 WebInspector.TimelinePresentationModel._hiddenRecords = { }; | |
49 WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel
.RecordType.MarkDOMContent] = 1; | |
50 WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel
.RecordType.MarkLoad] = 1; | |
51 WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel
.RecordType.MarkFirstPaint] = 1; | |
52 WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel
.RecordType.GPUTask] = 1; | |
53 WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel
.RecordType.ScheduleStyleRecalculation] = 1; | |
54 WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel
.RecordType.InvalidateLayout] = 1; | |
55 WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel
.RecordType.RequestMainThreadFrame] = 1; | |
56 WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel
.RecordType.ActivateLayerTree] = 1; | |
57 WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel
.RecordType.DrawFrame] = 1; | |
58 WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel
.RecordType.BeginFrame] = 1; | |
59 | |
60 WebInspector.TimelinePresentationModel._coalescingRecords = { }; | 48 WebInspector.TimelinePresentationModel._coalescingRecords = { }; |
61 WebInspector.TimelinePresentationModel._coalescingRecords[WebInspector.TimelineM
odel.RecordType.Layout] = 1; | 49 WebInspector.TimelinePresentationModel._coalescingRecords[WebInspector.TimelineM
odel.RecordType.Layout] = 1; |
62 WebInspector.TimelinePresentationModel._coalescingRecords[WebInspector.TimelineM
odel.RecordType.Paint] = 1; | 50 WebInspector.TimelinePresentationModel._coalescingRecords[WebInspector.TimelineM
odel.RecordType.Paint] = 1; |
63 WebInspector.TimelinePresentationModel._coalescingRecords[WebInspector.TimelineM
odel.RecordType.Rasterize] = 1; | 51 WebInspector.TimelinePresentationModel._coalescingRecords[WebInspector.TimelineM
odel.RecordType.Rasterize] = 1; |
64 WebInspector.TimelinePresentationModel._coalescingRecords[WebInspector.TimelineM
odel.RecordType.DecodeImage] = 1; | 52 WebInspector.TimelinePresentationModel._coalescingRecords[WebInspector.TimelineM
odel.RecordType.DecodeImage] = 1; |
65 WebInspector.TimelinePresentationModel._coalescingRecords[WebInspector.TimelineM
odel.RecordType.ResizeImage] = 1; | 53 WebInspector.TimelinePresentationModel._coalescingRecords[WebInspector.TimelineM
odel.RecordType.ResizeImage] = 1; |
66 | 54 |
67 WebInspector.TimelinePresentationModel.prototype = { | 55 WebInspector.TimelinePresentationModel.prototype = { |
68 /** | 56 /** |
69 * @param {?WebInspector.TimelineModel.Record} record | 57 * @param {?WebInspector.TimelineModel.Record} record |
70 * @return {?WebInspector.TimelinePresentationModel.Record} | 58 * @return {?WebInspector.TimelinePresentationModel.Record} |
71 */ | 59 */ |
72 toPresentationRecord: function(record) | 60 toPresentationRecord: function(record) |
73 { | 61 { |
74 return record ? this._recordToPresentationRecord.get(record) || null : n
ull; | 62 return record ? this._recordToPresentationRecord.get(record) || null : n
ull; |
75 }, | 63 }, |
76 | 64 |
77 /** | 65 /** |
78 * @param {!WebInspector.TimelinePresentationModel.Filter} filter | |
79 */ | |
80 addFilter: function(filter) | |
81 { | |
82 this._filters.push(filter); | |
83 }, | |
84 | |
85 /** | |
86 * @param {?WebInspector.TimelinePresentationModel.Filter} filter | |
87 */ | |
88 setSearchFilter: function(filter) | |
89 { | |
90 if (!filter) { | |
91 var allRecords = this._recordToPresentationRecord.values(); | |
92 for (var i = 0; i < allRecords.length; ++i) | |
93 delete allRecords[i].clicked; | |
94 } | |
95 this._searchFilter = filter; | |
96 }, | |
97 | |
98 /** | |
99 * @return {!WebInspector.TimelinePresentationModel.Record} | 66 * @return {!WebInspector.TimelinePresentationModel.Record} |
100 */ | 67 */ |
101 rootRecord: function() | 68 rootRecord: function() |
102 { | 69 { |
103 return this._rootRecord; | 70 return this._rootRecord; |
104 }, | 71 }, |
105 | 72 |
106 reset: function() | 73 reset: function() |
107 { | 74 { |
108 this._recordToPresentationRecord.clear(); | 75 this._recordToPresentationRecord.clear(); |
109 var rootPayload = { type: WebInspector.TimelineModel.RecordType.Root }; | 76 var rootPayload = { type: WebInspector.TimelineModel.RecordType.Root }; |
110 var rootRecord = new WebInspector.TimelineModel.Record(this._model, /**
@type {!TimelineAgent.TimelineEvent} */ (rootPayload), null); | 77 var rootRecord = new WebInspector.TimelineModel.Record(this._model, /**
@type {!TimelineAgent.TimelineEvent} */ (rootPayload), null); |
111 this._rootRecord = new WebInspector.TimelinePresentationModel.Record(roo
tRecord, null); | 78 this._rootRecord = new WebInspector.TimelinePresentationModel.Record(roo
tRecord, null); |
112 this._eventDividerRecords = []; | |
113 this._minimumRecordTime = -1; | |
114 /** @type {!Object.<string, !WebInspector.TimelinePresentationModel.Reco
rd>} */ | 79 /** @type {!Object.<string, !WebInspector.TimelinePresentationModel.Reco
rd>} */ |
115 this._coalescingBuckets = {}; | 80 this._coalescingBuckets = {}; |
116 this._mergingBuffer = new WebInspector.TimelineMergingRecordBuffer(); | |
117 | |
118 /** @type {!Array.<!WebInspector.TimelineModel.Record>} */ | |
119 this._mainThreadTasks = ([]); | |
120 /** @type {!Array.<!WebInspector.TimelineModel.Record>} */ | |
121 this._gpuThreadTasks = ([]); | |
122 }, | 81 }, |
123 | 82 |
124 /** | 83 /** |
125 * @return {number} | |
126 */ | |
127 minimumRecordTime: function() | |
128 { | |
129 return this._minimumRecordTime; | |
130 }, | |
131 | |
132 /** | |
133 * @return {number} | |
134 */ | |
135 maximumRecordTime: function() | |
136 { | |
137 return this._maximumRecordTime; | |
138 }, | |
139 | |
140 /** | |
141 * @return {!Array.<!WebInspector.TimelineModel.Record>} | |
142 */ | |
143 mainThreadTasks: function() | |
144 { | |
145 return this._mainThreadTasks; | |
146 }, | |
147 | |
148 /** | |
149 * @return {!Array.<!WebInspector.TimelineModel.Record>} | |
150 */ | |
151 gpuThreadTasks: function() | |
152 { | |
153 return this._gpuThreadTasks; | |
154 }, | |
155 | |
156 /** | |
157 * @param {!WebInspector.TimelineModel.Record} record | 84 * @param {!WebInspector.TimelineModel.Record} record |
158 */ | 85 */ |
159 addRecord: function(record) | 86 addRecord: function(record) |
160 { | 87 { |
161 if (record.type === WebInspector.TimelineModel.RecordType.Program) | |
162 this._mainThreadTasks.push(record); | |
163 if (record.type === WebInspector.TimelineModel.RecordType.GPUTask) | |
164 this._gpuThreadTasks.push(record); | |
165 | |
166 var startTime = record.startTime; | |
167 var endTime = record.endTime; | |
168 if (this._minimumRecordTime === -1 || startTime < this._minimumRecordTim
e) | |
169 this._minimumRecordTime = startTime; | |
170 if (this._maximumRecordTime === -1 || endTime > this._maximumRecordTime) | |
171 this._maximumRecordTime = endTime; | |
172 | |
173 var records; | 88 var records; |
174 if (record.type === WebInspector.TimelineModel.RecordType.Program) | 89 if (record.type === WebInspector.TimelineModel.RecordType.Program) |
175 records = record.children; | 90 records = record.children; |
176 else | 91 else |
177 records = [record]; | 92 records = [record]; |
178 | 93 |
179 for (var i = 0; i < records.length; ++i) | 94 for (var i = 0; i < records.length; ++i) |
180 this._innerAddRecord(this._rootRecord, records[i]); | 95 this._innerAddRecord(this._rootRecord, records[i]); |
181 }, | 96 }, |
182 | 97 |
183 /** | 98 /** |
184 * @param {!WebInspector.TimelinePresentationModel.Record} parentRecord | 99 * @param {!WebInspector.TimelinePresentationModel.Record} parentRecord |
185 * @param {!WebInspector.TimelineModel.Record} record | 100 * @param {!WebInspector.TimelineModel.Record} record |
186 */ | 101 */ |
187 _innerAddRecord: function(parentRecord, record) | 102 _innerAddRecord: function(parentRecord, record) |
188 { | 103 { |
189 if (WebInspector.TimelineUIUtils.isEventDivider(record)) | |
190 this._eventDividerRecords.push(record); | |
191 | |
192 if (record.type in WebInspector.TimelinePresentationModel._hiddenRecords
) | |
193 return null; | |
194 | |
195 const recordTypes = WebInspector.TimelineModel.RecordType; | |
196 | |
197 var origin = parentRecord; | |
198 var coalescingBucket; | 104 var coalescingBucket; |
199 | 105 |
200 // On main thread, only coalesce if the last event is of same type. | 106 // On main thread, only coalesce if the last event is of same type. |
201 if (parentRecord === this._rootRecord) | 107 if (parentRecord === this._rootRecord) |
202 coalescingBucket = record.thread ? record.type : "mainThread"; | 108 coalescingBucket = record.thread ? record.type : "mainThread"; |
203 var coalescedRecord = this._findCoalescedParent(record, parentRecord, co
alescingBucket); | 109 var coalescedRecord = this._findCoalescedParent(record, parentRecord, co
alescingBucket); |
204 if (coalescedRecord) | 110 if (coalescedRecord) |
205 parentRecord = coalescedRecord; | 111 parentRecord = coalescedRecord; |
206 | 112 |
207 var formattedRecord = new WebInspector.TimelinePresentationModel.Record(
record, parentRecord); | 113 var formattedRecord = new WebInspector.TimelinePresentationModel.Record(
record, parentRecord); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 var parentRecord = presentationRecord._presentationParent.record(); | 199 var parentRecord = presentationRecord._presentationParent.record(); |
294 WebInspector.TimelineUIUtils.aggregateTimeByCategory(parentRecord.aggreg
atedStats, record.aggregatedStats); | 200 WebInspector.TimelineUIUtils.aggregateTimeByCategory(parentRecord.aggreg
atedStats, record.aggregatedStats); |
295 if (parentRecord.startTime > record.startTime) | 201 if (parentRecord.startTime > record.startTime) |
296 parentRecord.startTime = record.startTime; | 202 parentRecord.startTime = record.startTime; |
297 if (parentRecord.endTime < record.endTime) { | 203 if (parentRecord.endTime < record.endTime) { |
298 parentRecord.endTime = record.endTime; | 204 parentRecord.endTime = record.endTime; |
299 parentRecord.lastChildEndTime = parentRecord.endTime; | 205 parentRecord.lastChildEndTime = parentRecord.endTime; |
300 } | 206 } |
301 }, | 207 }, |
302 | 208 |
| 209 /** |
| 210 * @param {?RegExp} textFilter |
| 211 */ |
| 212 setTextFilter: function(textFilter) |
| 213 { |
| 214 this._textFilter = textFilter; |
| 215 }, |
| 216 |
303 invalidateFilteredRecords: function() | 217 invalidateFilteredRecords: function() |
304 { | 218 { |
305 delete this._filteredRecords; | 219 delete this._filteredRecords; |
306 }, | 220 }, |
307 | 221 |
308 /** | 222 /** |
309 * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>} | 223 * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>} |
310 */ | 224 */ |
311 filteredRecords: function() | 225 filteredRecords: function() |
312 { | 226 { |
313 if (this._filteredRecords) | 227 if (this._filteredRecords) |
314 return this._filteredRecords; | 228 return this._filteredRecords; |
315 | 229 |
316 var recordsInWindow = []; | 230 var recordsInWindow = []; |
| 231 |
317 var stack = [{children: this._rootRecord._presentationChildren, index: 0
, parentIsCollapsed: false, parentRecord: {}}]; | 232 var stack = [{children: this._rootRecord._presentationChildren, index: 0
, parentIsCollapsed: false, parentRecord: {}}]; |
318 var revealedDepth = 0; | 233 var revealedDepth = 0; |
319 | 234 |
320 function revealRecordsInStack() { | 235 function revealRecordsInStack() { |
321 for (var depth = revealedDepth + 1; depth < stack.length; ++depth) { | 236 for (var depth = revealedDepth + 1; depth < stack.length; ++depth) { |
322 if (stack[depth - 1].parentIsCollapsed) { | 237 if (stack[depth - 1].parentIsCollapsed) { |
323 stack[depth].parentRecord._presentationParent._expandable =
true; | 238 stack[depth].parentRecord._presentationParent._expandable =
true; |
324 return; | 239 return; |
325 } | 240 } |
326 stack[depth - 1].parentRecord._collapsed = false; | 241 stack[depth - 1].parentRecord._collapsed = false; |
327 recordsInWindow.push(stack[depth].parentRecord); | 242 recordsInWindow.push(stack[depth].parentRecord); |
328 stack[depth].windowLengthBeforeChildrenTraversal = recordsInWind
ow.length; | 243 stack[depth].windowLengthBeforeChildrenTraversal = recordsInWind
ow.length; |
329 stack[depth].parentIsRevealed = true; | 244 stack[depth].parentIsRevealed = true; |
330 revealedDepth = depth; | 245 revealedDepth = depth; |
331 } | 246 } |
332 } | 247 } |
333 | 248 |
334 while (stack.length) { | 249 while (stack.length) { |
335 var entry = stack[stack.length - 1]; | 250 var entry = stack[stack.length - 1]; |
336 var records = entry.children; | 251 var records = entry.children; |
337 if (records && entry.index < records.length) { | 252 if (records && entry.index < records.length) { |
338 var record = records[entry.index]; | 253 var record = records[entry.index]; |
339 ++entry.index; | 254 ++entry.index; |
340 | 255 |
341 if (this.isVisible(record.record())) { | 256 if (this._model.isVisible(record.record())) { |
342 record._presentationParent._expandable = true; | 257 record._presentationParent._expandable = true; |
343 if (this._searchFilter) | 258 if (this._textFilter) |
344 revealRecordsInStack(); | 259 revealRecordsInStack(); |
345 if (!entry.parentIsCollapsed) { | 260 if (!entry.parentIsCollapsed) { |
346 recordsInWindow.push(record); | 261 recordsInWindow.push(record); |
347 revealedDepth = stack.length; | 262 revealedDepth = stack.length; |
348 entry.parentRecord._collapsed = false; | 263 entry.parentRecord._collapsed = false; |
349 } | 264 } |
350 } | 265 } |
351 | 266 |
352 record._expandable = false; | 267 record._expandable = false; |
353 | 268 |
354 stack.push({children: record._presentationChildren, | 269 stack.push({children: record._presentationChildren, |
355 index: 0, | 270 index: 0, |
356 parentIsCollapsed: (entry.parentIsCollapsed || (reco
rd._collapsed && (!this._searchFilter || record.clicked))), | 271 parentIsCollapsed: entry.parentIsCollapsed || (recor
d._collapsed && (!this._textFilter || record._expandedOrCollapsedWhileFiltered))
, |
357 parentRecord: record, | 272 parentRecord: record, |
358 windowLengthBeforeChildrenTraversal: recordsInWindow
.length}); | 273 windowLengthBeforeChildrenTraversal: recordsInWindow
.length}); |
359 } else { | 274 } else { |
360 stack.pop(); | 275 stack.pop(); |
361 revealedDepth = Math.min(revealedDepth, stack.length - 1); | 276 revealedDepth = Math.min(revealedDepth, stack.length - 1); |
362 entry.parentRecord._visibleChildrenCount = recordsInWindow.lengt
h - entry.windowLengthBeforeChildrenTraversal; | 277 entry.parentRecord._visibleChildrenCount = recordsInWindow.lengt
h - entry.windowLengthBeforeChildrenTraversal; |
363 } | 278 } |
364 } | 279 } |
365 | 280 |
366 this._filteredRecords = recordsInWindow; | 281 this._filteredRecords = recordsInWindow; |
367 return recordsInWindow; | 282 return recordsInWindow; |
368 }, | 283 }, |
369 | 284 |
370 /** | |
371 * @return {!Array.<!WebInspector.TimelineModel.Record>} | |
372 */ | |
373 eventDividerRecords: function() | |
374 { | |
375 return this._eventDividerRecords; | |
376 }, | |
377 | |
378 /** | |
379 * @param {!WebInspector.TimelineModel.Record} record | |
380 * @return {boolean} | |
381 */ | |
382 isVisible: function(record) | |
383 { | |
384 for (var i = 0; i < this._filters.length; ++i) { | |
385 if (!this._filters[i].accept(record)) | |
386 return false; | |
387 } | |
388 return !this._searchFilter || this._searchFilter.accept(record); | |
389 }, | |
390 | |
391 __proto__: WebInspector.Object.prototype | 285 __proto__: WebInspector.Object.prototype |
392 } | 286 } |
393 | 287 |
394 /** | 288 /** |
395 * @constructor | 289 * @constructor |
396 * @param {!WebInspector.TimelineModel.Record} record | 290 * @param {!WebInspector.TimelineModel.Record} record |
397 * @param {?WebInspector.TimelinePresentationModel.Record} parentRecord | 291 * @param {?WebInspector.TimelinePresentationModel.Record} parentRecord |
398 */ | 292 */ |
399 WebInspector.TimelinePresentationModel.Record = function(record, parentRecord) | 293 WebInspector.TimelinePresentationModel.Record = function(record, parentRecord) |
400 { | 294 { |
(...skipping 20 matching lines...) Expand all Loading... |
421 WebInspector.TimelinePresentationModel.Record.prototype = { | 315 WebInspector.TimelinePresentationModel.Record.prototype = { |
422 /** | 316 /** |
423 * @return {!WebInspector.TimelineModel.Record} | 317 * @return {!WebInspector.TimelineModel.Record} |
424 */ | 318 */ |
425 record: function() | 319 record: function() |
426 { | 320 { |
427 return this._record; | 321 return this._record; |
428 }, | 322 }, |
429 | 323 |
430 /** | 324 /** |
431 * @return {boolean} | |
432 */ | |
433 isRoot: function() | |
434 { | |
435 return this.type === WebInspector.TimelineModel.RecordType.Root; | |
436 }, | |
437 | |
438 /** | |
439 * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>} | 325 * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>} |
440 */ | 326 */ |
441 presentationChildren: function() | 327 presentationChildren: function() |
442 { | 328 { |
443 return this._presentationChildren; | 329 return this._presentationChildren; |
444 }, | 330 }, |
445 | 331 |
446 /** | 332 /** |
447 * @return {boolean} | 333 * @return {boolean} |
448 */ | 334 */ |
(...skipping 17 matching lines...) Expand all Loading... |
466 { | 352 { |
467 return this._collapsed; | 353 return this._collapsed; |
468 }, | 354 }, |
469 | 355 |
470 /** | 356 /** |
471 * @param {boolean} collapsed | 357 * @param {boolean} collapsed |
472 */ | 358 */ |
473 setCollapsed: function(collapsed) | 359 setCollapsed: function(collapsed) |
474 { | 360 { |
475 this._collapsed = collapsed; | 361 this._collapsed = collapsed; |
| 362 this._expandedOrCollapsedWhileFiltered = true; |
476 }, | 363 }, |
477 | 364 |
478 /** | 365 /** |
479 * @return {?WebInspector.TimelinePresentationModel.Record} | 366 * @return {?WebInspector.TimelinePresentationModel.Record} |
480 */ | 367 */ |
481 presentationParent: function() | 368 presentationParent: function() |
482 { | 369 { |
483 return this._presentationParent || null; | 370 return this._presentationParent || null; |
484 }, | 371 }, |
485 | 372 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 }, | 427 }, |
541 | 428 |
542 /** | 429 /** |
543 * @param {!WebInspector.TimelineRecordGraphRow} graphRow | 430 * @param {!WebInspector.TimelineRecordGraphRow} graphRow |
544 */ | 431 */ |
545 setGraphRow: function(graphRow) | 432 setGraphRow: function(graphRow) |
546 { | 433 { |
547 this._graphRow = graphRow; | 434 this._graphRow = graphRow; |
548 } | 435 } |
549 } | 436 } |
550 | |
551 /** | |
552 * @interface | |
553 */ | |
554 WebInspector.TimelinePresentationModel.Filter = function() | |
555 { | |
556 } | |
557 | |
558 WebInspector.TimelinePresentationModel.Filter.prototype = { | |
559 /** | |
560 * @param {!WebInspector.TimelineModel.Record} record | |
561 * @return {boolean} | |
562 */ | |
563 accept: function(record) { return false; } | |
564 } | |
OLD | NEW |