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

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

Issue 180273023: DevTools: encapsulate presentation model in timeline view. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: 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) 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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698