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

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: 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
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
123 * @return {boolean}
124 */ 124 */
125 WebInspector.TimelineModel.forAllRecords = function(recordsArray, preOrderCallba ck, postOrderCallback) 125 WebInspector.TimelineModel.forAllRecords = function(recordsArray, preOrderCallba ck, postOrderCallback)
126 { 126 {
127 if (!recordsArray) 127 /**
128 return; 128 * @param {!Array.<!WebInspector.TimelineModel.Record>} records
129 var stack = [{array: recordsArray, index: 0}]; 129 * @param {number} depth
130 while (stack.length) { 130 * @return {boolean}
131 var entry = stack[stack.length - 1]; 131 */
132 var records = entry.array; 132 function processRecords(records, depth)
133 if (entry.index < records.length) { 133 {
134 var record = records[entry.index]; 134 for (var i = 0; i < records.length; ++i) {
135 if (preOrderCallback && preOrderCallback(record, stack.length)) 135 var record = records[i];
136 return; 136 if (preOrderCallback && preOrderCallback(record, depth))
137 if (record.children) 137 return true;
138 stack.push({array: record.children, index: 0, record: record}); 138 if (processRecords(record.children, depth + 1))
139 else if (postOrderCallback && postOrderCallback(record, stack.lengt h)) 139 return true;
140 return; 140 if (postOrderCallback && postOrderCallback(record, depth))
141 ++entry.index; 141 return true;
142 } else {
143 if (entry.record && postOrderCallback && postOrderCallback(entry.rec ord, stack.length))
144 return;
145 stack.pop();
146 } 142 }
143 return false;
147 } 144 }
145 return processRecords(recordsArray, 0);
148 } 146 }
149 147
150 WebInspector.TimelineModel.prototype = { 148 WebInspector.TimelineModel.prototype = {
151 /** 149 /**
152 * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspe ctor.TimelineModel.Record,number)} preOrderCallback 150 * @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 151 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspect or.TimelineModel.Record,number)=} postOrderCallback
154 */ 152 */
155 forAllRecords: function(preOrderCallback, postOrderCallback) 153 forAllRecords: function(preOrderCallback, postOrderCallback)
156 { 154 {
157 WebInspector.TimelineModel.forAllRecords(this._records, preOrderCallback , postOrderCallback); 155 WebInspector.TimelineModel.forAllRecords(this._records, preOrderCallback , postOrderCallback);
158 }, 156 },
159 157
160 /** 158 /**
159 * @param {!WebInspector.TimelineModel.Filter} filter
160 */
161 addFilter: function(filter)
162 {
163 this._filters.push(filter);
164 filter._model = this;
165 },
166
167 /**
168 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspect or.TimelineModel.Record,number)} callback
169 */
170 forAllFilteredRecords: function(callback)
171 {
172 /**
173 * @param {!WebInspector.TimelineModel.Record} record
174 * @param {number} depth
175 * @this {WebInspector.TimelineModel}
176 * @return {boolean}
177 */
178 function processRecord(record, depth)
179 {
180 var visible = this.isVisible(record);
181 if (visible) {
182 if (callback(record, depth))
183 return true;
184 }
185
186 for (var i = 0; i < record.children.length; ++i) {
187 if (processRecord.call(this, record.children[i], visible ? depth + 1 : depth))
188 return true;
189 }
190 return false;
191 }
192
193 for (var i = 0; i < this._records.length; ++i)
194 processRecord.call(this, this._records[i], 0);
195 },
196
197 /**
198 * @param {!WebInspector.TimelineModel.Record} record
199 * @return {boolean}
200 */
201 isVisible: function(record)
202 {
203 for (var i = 0; i < this._filters.length; ++i) {
204 if (!this._filters[i].accept(record))
205 return false;
206 }
207 return true;
208 },
209
210 _filterChanged: function()
211 {
212 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordFi lterChanged);
213 },
214
215 /**
161 * @param {boolean=} includeCounters 216 * @param {boolean=} includeCounters
162 */ 217 */
163 startRecording: function(includeCounters) 218 startRecording: function(includeCounters)
164 { 219 {
165 this._clientInitiatedRecording = true; 220 this._clientInitiatedRecording = true;
166 this.reset(); 221 this.reset();
167 var maxStackFrames = WebInspector.settings.timelineCaptureStacks.get() ? 30 : 0; 222 var maxStackFrames = WebInspector.settings.timelineCaptureStacks.get() ? 30 : 0;
168 var includeGPUEvents = WebInspector.experimentsSettings.gpuTimeline.isEn abled(); 223 var includeGPUEvents = WebInspector.experimentsSettings.gpuTimeline.isEn abled();
169 WebInspector.timelineManager.start(maxStackFrames, includeCounters, incl udeGPUEvents, this._fireRecordingStarted.bind(this)); 224 WebInspector.timelineManager.start(maxStackFrames, includeCounters, incl udeGPUEvents, this._fireRecordingStarted.bind(this));
170 }, 225 },
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 * @param {!TimelineAgent.TimelineEvent} payload 300 * @param {!TimelineAgent.TimelineEvent} payload
246 */ 301 */
247 _addRecord: function(payload) 302 _addRecord: function(payload)
248 { 303 {
249 this._internStrings(payload); 304 this._internStrings(payload);
250 this._payloads.push(payload); 305 this._payloads.push(payload);
251 this._updateBoundaries(payload); 306 this._updateBoundaries(payload);
252 307
253 var record = this._innerAddRecord(payload, null); 308 var record = this._innerAddRecord(payload, null);
254 this._records.push(record); 309 this._records.push(record);
310 if (record.type === WebInspector.TimelineModel.RecordType.Program)
311 this._mainThreadTasks.push(record);
312 if (record.type === WebInspector.TimelineModel.RecordType.GPUTask)
313 this._gpuThreadTasks.push(record);
255 314
256 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd ded, record); 315 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd ded, record);
257 }, 316 },
258 317
259 /** 318 /**
260 * @param {!TimelineAgent.TimelineEvent} payload 319 * @param {!TimelineAgent.TimelineEvent} payload
261 * @param {?WebInspector.TimelineModel.Record} parentRecord 320 * @param {?WebInspector.TimelineModel.Record} parentRecord
262 * @return {!WebInspector.TimelineModel.Record} 321 * @return {!WebInspector.TimelineModel.Record}
263 * @this {!WebInspector.TimelineModel} 322 * @this {!WebInspector.TimelineModel}
264 */ 323 */
265 _innerAddRecord: function(payload, parentRecord) 324 _innerAddRecord: function(payload, parentRecord)
266 { 325 {
267 var record = new WebInspector.TimelineModel.Record(this, payload, parent Record); 326 var record = new WebInspector.TimelineModel.Record(this, payload, parent Record);
327 if (WebInspector.TimelineUIUtils.isEventDivider(record))
328 this._eventDividerRecords.push(record);
329
268 for (var i = 0; payload.children && i < payload.children.length; ++i) 330 for (var i = 0; payload.children && i < payload.children.length; ++i)
269 this._innerAddRecord.call(this, payload.children[i], record); 331 this._innerAddRecord.call(this, payload.children[i], record);
270 332
271 record.calculateAggregatedStats(); 333 record.calculateAggregatedStats();
272 if (parentRecord) 334 if (parentRecord)
273 parentRecord._selfTime -= record.endTime - record.startTime; 335 parentRecord._selfTime -= record.endTime - record.startTime;
274 return record; 336 return record;
275 }, 337 },
276 338
277 /** 339 /**
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 }, 390 },
329 391
330 reset: function() 392 reset: function()
331 { 393 {
332 this._records = []; 394 this._records = [];
333 this._payloads = []; 395 this._payloads = [];
334 this._stringPool = {}; 396 this._stringPool = {};
335 this._minimumRecordTime = -1; 397 this._minimumRecordTime = -1;
336 this._maximumRecordTime = -1; 398 this._maximumRecordTime = -1;
337 this._bindings._reset(); 399 this._bindings._reset();
400 /** @type {!Array.<!WebInspector.TimelineModel.Record>} */
401 this._mainThreadTasks = [];
402 /** @type {!Array.<!WebInspector.TimelineModel.Record>} */
403 this._gpuThreadTasks = [];
404 /** @type {!Array.<!WebInspector.TimelineModel.Record>} */
405 this._eventDividerRecords = [];
338 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordsC leared); 406 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordsC leared);
339 }, 407 },
340 408
341 /** 409 /**
342 * @return {number} 410 * @return {number}
343 */ 411 */
344 minimumRecordTime: function() 412 minimumRecordTime: function()
345 { 413 {
346 return this._minimumRecordTime; 414 return this._minimumRecordTime;
347 }, 415 },
(...skipping 14 matching lines...) Expand all
362 var startTime = record.startTime; 430 var startTime = record.startTime;
363 var endTime = record.endTime; 431 var endTime = record.endTime;
364 432
365 if (this._minimumRecordTime === -1 || startTime < this._minimumRecordTim e) 433 if (this._minimumRecordTime === -1 || startTime < this._minimumRecordTim e)
366 this._minimumRecordTime = startTime; 434 this._minimumRecordTime = startTime;
367 if ((this._maximumRecordTime === -1 && endTime) || endTime > this._maxim umRecordTime) 435 if ((this._maximumRecordTime === -1 && endTime) || endTime > this._maxim umRecordTime)
368 this._maximumRecordTime = endTime; 436 this._maximumRecordTime = endTime;
369 }, 437 },
370 438
371 /** 439 /**
372 * @param {!Object} rawRecord 440 * @return {!Array.<!WebInspector.TimelineModel.Record>}
373 * @return {number}
374 */ 441 */
375 recordOffsetInMillis: function(rawRecord) 442 mainThreadTasks: function()
376 { 443 {
377 return rawRecord.startTime - this._minimumRecordTime; 444 return this._mainThreadTasks;
378 }, 445 },
379 446
380 /** 447 /**
448 * @return {!Array.<!WebInspector.TimelineModel.Record>}
449 */
450 gpuThreadTasks: function()
451 {
452 return this._gpuThreadTasks;
453 },
454
455 /**
456 * @return {!Array.<!WebInspector.TimelineModel.Record>}
457 */
458 eventDividerRecords: function()
459 {
460 return this._eventDividerRecords;
461 },
462
463 /**
381 * @param {!TimelineAgent.TimelineEvent} record 464 * @param {!TimelineAgent.TimelineEvent} record
382 */ 465 */
383 _internStrings: function(record) 466 _internStrings: function(record)
384 { 467 {
385 for (var name in record) { 468 for (var name in record) {
386 var value = record[name]; 469 var value = record[name];
387 if (typeof value !== "string") 470 if (typeof value !== "string")
388 continue; 471 continue;
389 472
390 var interned = this._stringPool[value]; 473 var interned = this._stringPool[value];
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 */ 887 */
805 testContentMatching: function(regExp) 888 testContentMatching: function(regExp)
806 { 889 {
807 var tokens = [this.title()]; 890 var tokens = [this.title()];
808 for (var key in this._record.data) 891 for (var key in this._record.data)
809 tokens.push(this._record.data[key]) 892 tokens.push(this._record.data[key])
810 return regExp.test(tokens.join("|")); 893 return regExp.test(tokens.join("|"));
811 } 894 }
812 } 895 }
813 896
897
898 /**
899 * @constructor
900 */
901 WebInspector.TimelineModel.Filter = function()
902 {
903 /** @type {!WebInspector.TimelineModel} */
904 this._model;
905 }
906
907 WebInspector.TimelineModel.Filter.prototype = {
908 /**
909 * @param {!WebInspector.TimelineModel.Record} record
910 * @return {boolean}
911 */
912 accept: function(record)
913 {
914 return true;
915 },
916
917 notifyFilterChanged: function()
918 {
919 this._model._filterChanged();
920 }
921 }
922
814 /** 923 /**
815 * @constructor 924 * @constructor
816 * @implements {WebInspector.OutputStream} 925 * @implements {WebInspector.OutputStream}
817 * @param {!WebInspector.TimelineModel} model 926 * @param {!WebInspector.TimelineModel} model
818 * @param {!{cancel: function()}} reader 927 * @param {!{cancel: function()}} reader
819 * @param {!WebInspector.Progress} progress 928 * @param {!WebInspector.Progress} progress
820 */ 929 */
821 WebInspector.TimelineModelLoader = function(model, reader, progress) 930 WebInspector.TimelineModelLoader = function(model, reader, progress)
822 { 931 {
823 this._model = model; 932 this._model = model;
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 WebInspector.TimelineModel._quadFromRectData = function(data) 1148 WebInspector.TimelineModel._quadFromRectData = function(data)
1040 { 1149 {
1041 if (typeof data["x"] === "undefined" || typeof data["y"] === "undefined") 1150 if (typeof data["x"] === "undefined" || typeof data["y"] === "undefined")
1042 return null; 1151 return null;
1043 var x0 = data["x"]; 1152 var x0 = data["x"];
1044 var x1 = data["x"] + data["width"]; 1153 var x1 = data["x"] + data["width"];
1045 var y0 = data["y"]; 1154 var y0 = data["y"];
1046 var y1 = data["y"] + data["height"]; 1155 var y1 = data["y"] + data["height"];
1047 return [x0, y0, x1, y0, x1, y1, x0, y1]; 1156 return [x0, y0, x1, y0, x1, y1, x0, y1];
1048 } 1157 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/TimelineFrameModel.js ('k') | Source/devtools/front_end/TimelinePanel.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698