Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: Source/devtools/front_end/TimelinePresentationModel.js

Issue 180273023: DevTools: encapsulate presentation model in timeline view. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Review comments addressed. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 if (this._textFilter === textFilter)
215 return;
216 this._textFilter = textFilter;
217 for (var i = 0; this._filteredRecords && i < this._filteredRecords.lengt h; ++i)
218 delete this._filteredRecords[i]._expandedOrCollapsedWhileFiltered;
219 },
220
303 invalidateFilteredRecords: function() 221 invalidateFilteredRecords: function()
304 { 222 {
305 delete this._filteredRecords; 223 delete this._filteredRecords;
306 }, 224 },
307 225
308 /** 226 /**
309 * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>} 227 * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>}
310 */ 228 */
311 filteredRecords: function() 229 filteredRecords: function()
312 { 230 {
313 if (this._filteredRecords) 231 if (this._filteredRecords)
314 return this._filteredRecords; 232 return this._filteredRecords;
315 233
316 var recordsInWindow = []; 234 var recordsInWindow = [];
caseq 2014/03/04 16:38:03 indent
317 var stack = [{children: this._rootRecord._presentationChildren, index: 0 , parentIsCollapsed: false, parentRecord: {}}]; 235
318 var revealedDepth = 0; 236 var stack = [{children: this._rootRecord._presentationChildren, index: 0, parentIsCollapsed: false, parentRecord: {}}];
237 var revealedDepth = 0;
caseq 2014/03/04 16:38:03 ditto
319 238
320 function revealRecordsInStack() { 239 function revealRecordsInStack() {
321 for (var depth = revealedDepth + 1; depth < stack.length; ++depth) { 240 for (var depth = revealedDepth + 1; depth < stack.length; ++depth) {
322 if (stack[depth - 1].parentIsCollapsed) { 241 if (stack[depth - 1].parentIsCollapsed) {
323 stack[depth].parentRecord._presentationParent._expandable = true; 242 stack[depth].parentRecord._presentationParent._expandable = true;
324 return; 243 return;
325 } 244 }
326 stack[depth - 1].parentRecord._collapsed = false; 245 stack[depth - 1].parentRecord._collapsed = false;
327 recordsInWindow.push(stack[depth].parentRecord); 246 recordsInWindow.push(stack[depth].parentRecord);
328 stack[depth].windowLengthBeforeChildrenTraversal = recordsInWind ow.length; 247 stack[depth].windowLengthBeforeChildrenTraversal = recordsInWind ow.length;
329 stack[depth].parentIsRevealed = true; 248 stack[depth].parentIsRevealed = true;
330 revealedDepth = depth; 249 revealedDepth = depth;
331 } 250 }
332 } 251 }
333 252
334 while (stack.length) { 253 while (stack.length) {
335 var entry = stack[stack.length - 1]; 254 var entry = stack[stack.length - 1];
336 var records = entry.children; 255 var records = entry.children;
337 if (records && entry.index < records.length) { 256 if (records && entry.index < records.length) {
338 var record = records[entry.index]; 257 var record = records[entry.index];
339 ++entry.index; 258 ++entry.index;
340 259
341 if (this.isVisible(record.record())) { 260 if (this._model.isVisible(record.record())) {
342 record._presentationParent._expandable = true; 261 record._presentationParent._expandable = true;
343 if (this._searchFilter) 262 if (this._textFilter)
344 revealRecordsInStack(); 263 revealRecordsInStack();
345 if (!entry.parentIsCollapsed) { 264 if (!entry.parentIsCollapsed) {
346 recordsInWindow.push(record); 265 recordsInWindow.push(record);
347 revealedDepth = stack.length; 266 revealedDepth = stack.length;
348 entry.parentRecord._collapsed = false; 267 entry.parentRecord._collapsed = false;
349 } 268 }
350 } 269 }
351 270
352 record._expandable = false; 271 record._expandable = false;
353 272
354 stack.push({children: record._presentationChildren, 273 stack.push({children: record._presentationChildren,
355 index: 0, 274 index: 0,
356 parentIsCollapsed: (entry.parentIsCollapsed || (reco rd._collapsed && (!this._searchFilter || record.clicked))), 275 parentIsCollapsed: entry.parentIsCollapsed || (recor d._collapsed && (!this._textFilter || record._expandedOrCollapsedWhileFiltered)) ,
357 parentRecord: record, 276 parentRecord: record,
358 windowLengthBeforeChildrenTraversal: recordsInWindow .length}); 277 windowLengthBeforeChildrenTraversal: recordsInWindow .length});
359 } else { 278 } else {
360 stack.pop(); 279 stack.pop();
361 revealedDepth = Math.min(revealedDepth, stack.length - 1); 280 revealedDepth = Math.min(revealedDepth, stack.length - 1);
362 entry.parentRecord._visibleChildrenCount = recordsInWindow.lengt h - entry.windowLengthBeforeChildrenTraversal; 281 entry.parentRecord._visibleChildrenCount = recordsInWindow.lengt h - entry.windowLengthBeforeChildrenTraversal;
363 } 282 }
364 } 283 }
365 284
366 this._filteredRecords = recordsInWindow; 285 this._filteredRecords = recordsInWindow;
367 return recordsInWindow; 286 return recordsInWindow;
368 }, 287 },
369 288
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 289 __proto__: WebInspector.Object.prototype
392 } 290 }
393 291
394 /** 292 /**
395 * @constructor 293 * @constructor
396 * @param {!WebInspector.TimelineModel.Record} record 294 * @param {!WebInspector.TimelineModel.Record} record
397 * @param {?WebInspector.TimelinePresentationModel.Record} parentRecord 295 * @param {?WebInspector.TimelinePresentationModel.Record} parentRecord
398 */ 296 */
399 WebInspector.TimelinePresentationModel.Record = function(record, parentRecord) 297 WebInspector.TimelinePresentationModel.Record = function(record, parentRecord)
400 { 298 {
(...skipping 20 matching lines...) Expand all
421 WebInspector.TimelinePresentationModel.Record.prototype = { 319 WebInspector.TimelinePresentationModel.Record.prototype = {
422 /** 320 /**
423 * @return {!WebInspector.TimelineModel.Record} 321 * @return {!WebInspector.TimelineModel.Record}
424 */ 322 */
425 record: function() 323 record: function()
426 { 324 {
427 return this._record; 325 return this._record;
428 }, 326 },
429 327
430 /** 328 /**
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>} 329 * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>}
440 */ 330 */
441 presentationChildren: function() 331 presentationChildren: function()
442 { 332 {
443 return this._presentationChildren; 333 return this._presentationChildren;
444 }, 334 },
445 335
446 /** 336 /**
447 * @return {boolean} 337 * @return {boolean}
448 */ 338 */
(...skipping 17 matching lines...) Expand all
466 { 356 {
467 return this._collapsed; 357 return this._collapsed;
468 }, 358 },
469 359
470 /** 360 /**
471 * @param {boolean} collapsed 361 * @param {boolean} collapsed
472 */ 362 */
473 setCollapsed: function(collapsed) 363 setCollapsed: function(collapsed)
474 { 364 {
475 this._collapsed = collapsed; 365 this._collapsed = collapsed;
366 this._expandedOrCollapsedWhileFiltered = true;
476 }, 367 },
477 368
478 /** 369 /**
479 * @return {?WebInspector.TimelinePresentationModel.Record} 370 * @return {?WebInspector.TimelinePresentationModel.Record}
480 */ 371 */
481 presentationParent: function() 372 presentationParent: function()
482 { 373 {
483 return this._presentationParent || null; 374 return this._presentationParent || null;
484 }, 375 },
485 376
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 }, 431 },
541 432
542 /** 433 /**
543 * @param {!WebInspector.TimelineRecordGraphRow} graphRow 434 * @param {!WebInspector.TimelineRecordGraphRow} graphRow
544 */ 435 */
545 setGraphRow: function(graphRow) 436 setGraphRow: function(graphRow)
546 { 437 {
547 this._graphRow = graphRow; 438 this._graphRow = graphRow;
548 } 439 }
549 } 440 }
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698