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

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: For landing 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
« no previous file with comments | « Source/devtools/front_end/TimelinePanel.js ('k') | Source/devtools/front_end/TimelineView.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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
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
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
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 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/TimelinePanel.js ('k') | Source/devtools/front_end/TimelineView.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698