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

Side by Side Diff: Source/devtools/front_end/timeline/TimelineEventOverview.js

Issue 1163223002: DevTools: Show main thread as a stacked utilization chart on timeline overview. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 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 | « no previous file | no next file » | 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 * 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 var categories = WebInspector.TimelineUIUtils.categories(); 44 var categories = WebInspector.TimelineUIUtils.categories();
45 for (var category in categories) { 45 for (var category in categories) {
46 this._fillStyles[category] = categories[category].fillColorStop1; 46 this._fillStyles[category] = categories[category].fillColorStop1;
47 categories[category].addEventListener(WebInspector.TimelineCategory.Even ts.VisibilityChanged, this._onCategoryVisibilityChanged, this); 47 categories[category].addEventListener(WebInspector.TimelineCategory.Even ts.VisibilityChanged, this._onCategoryVisibilityChanged, this);
48 } 48 }
49 49
50 this._disabledCategoryFillStyle = "hsl(0, 0%, 67%)"; 50 this._disabledCategoryFillStyle = "hsl(0, 0%, 67%)";
51 } 51 }
52 52
53 /** @const */ 53 /** @const */
54 WebInspector.TimelineEventOverview._fullStripHeight = 16; 54 WebInspector.TimelineEventOverview._fullStripHeight = 20;
55 /** @const */ 55 /** @const */
56 WebInspector.TimelineEventOverview._smallStripHeight = 8; 56 WebInspector.TimelineEventOverview._smallStripHeight = 8;
57 57
58 WebInspector.TimelineEventOverview.prototype = { 58 WebInspector.TimelineEventOverview.prototype = {
59 /** 59 /**
60 * @override 60 * @override
61 */ 61 */
62 dispose: function() 62 dispose: function()
63 { 63 {
64 WebInspector.TimelineOverviewBase.prototype.dispose.call(this); 64 WebInspector.TimelineOverviewBase.prototype.dispose.call(this);
(...skipping 17 matching lines...) Expand all
82 if (Runtime.experiments.isEnabled("inputEventsOnTimelineOverview")) { 82 if (Runtime.experiments.isEnabled("inputEventsOnTimelineOverview")) {
83 var inputHeight = this._drawInputEvents(mainThreadEvents, position, WebInspector.TimelineEventOverview._smallStripHeight); 83 var inputHeight = this._drawInputEvents(mainThreadEvents, position, WebInspector.TimelineEventOverview._smallStripHeight);
84 position += inputHeight; 84 position += inputHeight;
85 networkHeight -= inputHeight; 85 networkHeight -= inputHeight;
86 } 86 }
87 if (Runtime.experiments.isEnabled("frameRateOnEventsOverview")) 87 if (Runtime.experiments.isEnabled("frameRateOnEventsOverview"))
88 networkHeight -= WebInspector.TimelineEventOverview._fullStripHeight ; 88 networkHeight -= WebInspector.TimelineEventOverview._fullStripHeight ;
89 position += this._drawNetwork(mainThreadEvents, position, networkHeight) ; 89 position += this._drawNetwork(mainThreadEvents, position, networkHeight) ;
90 if (Runtime.experiments.isEnabled("frameRateOnEventsOverview")) 90 if (Runtime.experiments.isEnabled("frameRateOnEventsOverview"))
91 position += this._drawFrames(position, WebInspector.TimelineEventOve rview._fullStripHeight); 91 position += this._drawFrames(position, WebInspector.TimelineEventOve rview._fullStripHeight);
92 position += this._drawEvents(mainThreadEvents, position, WebInspector.Ti melineEventOverview._fullStripHeight); 92 position += this._drawStackedUtilizationChart(mainThreadEvents, position , WebInspector.TimelineEventOverview._fullStripHeight);
93 for (var thread of threads.filter(function(thread) { return !thread.isWo rker(); })) 93 for (var thread of threads.filter(function(thread) { return !thread.isWo rker(); }))
94 this._drawEvents(thread.events, position, WebInspector.TimelineEvent Overview._smallStripHeight); 94 this._drawEvents(thread.events, position, WebInspector.TimelineEvent Overview._smallStripHeight);
95 position += WebInspector.TimelineEventOverview._smallStripHeight; 95 position += WebInspector.TimelineEventOverview._smallStripHeight;
96 for (var thread of threads.filter(function(thread) { return thread.isWor ker(); })) 96 for (var thread of threads.filter(function(thread) { return thread.isWor ker(); }))
97 this._drawEvents(thread.events, position, WebInspector.TimelineEvent Overview._smallStripHeight); 97 this._drawEvents(thread.events, position, WebInspector.TimelineEvent Overview._smallStripHeight);
98 position += WebInspector.TimelineEventOverview._smallStripHeight; 98 position += WebInspector.TimelineEventOverview._smallStripHeight;
99 console.assert(position === this._canvas.clientHeight); 99 console.assert(position === this._canvas.clientHeight);
100 }, 100 },
101 101
102 /** 102 /**
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 this._renderBar(Math.floor(start), Math.ceil(end), Math.floor(positi on + band * bandInterval), bandHeight, color); 182 this._renderBar(Math.floor(start), Math.ceil(end), Math.floor(positi on + band * bandInterval), bandHeight, color);
183 } 183 }
184 184
185 WebInspector.TimelineUIUtils.iterateNetworkRequestsInRoundRobin(events, bandsCount, drawBar.bind(this)); 185 WebInspector.TimelineUIUtils.iterateNetworkRequestsInRoundRobin(events, bandsCount, drawBar.bind(this));
186 return height; 186 return height;
187 }, 187 },
188 188
189 /** 189 /**
190 * @param {!Array.<!WebInspector.TracingModel.Event>} events 190 * @param {!Array.<!WebInspector.TracingModel.Event>} events
191 * @param {number} position 191 * @param {number} position
192 * @param {number} height
193 * @return {number}
194 */
195 _drawStackedUtilizationChart: function(events, position, height)
196 {
197 var /** @const */ quantSizePx = 4 * window.devicePixelRatio;
198 var /** @const */ padding = 1;
199 var visualHeight = (height - padding) * window.devicePixelRatio;
200 var baseLine = (position + height) * window.devicePixelRatio;
201 var timeOffset = this._model.minimumRecordTime();
202 var timeSpan = this._model.maximumRecordTime() - timeOffset;
203 var scale = this._canvas.width / timeSpan;
204 var quantTime = quantSizePx / scale;
205 var quantizer = new WebInspector.Quantizer(timeOffset, quantTime, drawSa mple.bind(this));
206 var ctx = this._context;
207 var x = 0;
208 var categories = WebInspector.TimelineUIUtils.categories();
209 var categoryOrder = ["idle", "scripting", "rendering", "painting", "load ing", "other"];
210 var idleIndex = categoryOrder.indexOf("idle");
yurys 2015/06/09 09:19:26 idleIndex = 0 and assert?
alph 2015/06/09 09:47:24 Done.
211 var otherIndex = categoryOrder.indexOf("other");
212 for (var i = 1; i < categoryOrder.length; ++i)
213 categories[categoryOrder[i]]._overviewIndex = i;
yurys 2015/06/09 09:19:26 Consider doing this once in the categories initial
alph 2015/06/09 09:47:24 The index is specific to this function, so I want
214 var indexStack = [];
215
216 /**
217 * @param {!Array<number>} counters
218 * @this {WebInspector.TimelineEventOverview}
219 */
220 function drawSample(counters)
221 {
222 var y = baseLine;
223 for (var i = idleIndex + 1; i < counters.length; ++i) {
224 if (!counters[i])
225 continue;
226 var h = counters[i] / quantTime * visualHeight;
227 ctx.fillStyle = this._categoryColor(categories[categoryOrder[i]] );
228 ctx.fillRect(x, y - h, quantSizePx, h);
229 y -= h;
230 }
231 x += quantSizePx;
232 }
233
234 /**
235 * @param {!WebInspector.TracingModel.Event} e
236 */
237 function onEventStart(e)
238 {
239 var index = indexStack.length ? indexStack.peekLast() : idleIndex;
yurys 2015/06/09 09:19:26 categoryIndexStack?
alph 2015/06/09 09:47:24 Done.
240 quantizer.appendInterval(e.startTime, index);
241 indexStack.push(WebInspector.TimelineUIUtils.eventStyle(e).category. _overviewIndex || otherIndex);
242 }
243
244 /**
245 * @param {!WebInspector.TracingModel.Event} e
246 */
247 function onEventEnd(e)
248 {
249 quantizer.appendInterval(e.endTime, indexStack.pop());
250 }
251
252 WebInspector.TimelineModel.forEachEvent(events, onEventStart, onEventEnd );
253 return height;
254 },
255
256 /**
257 * @param {!Array.<!WebInspector.TracingModel.Event>} events
258 * @param {number} position
192 * @param {number} stripHeight 259 * @param {number} stripHeight
193 * @return {number} 260 * @return {number}
194 */ 261 */
195 _drawEvents: function(events, position, stripHeight) 262 _drawEvents: function(events, position, stripHeight)
196 { 263 {
197 var /** @const */ padding = 1; 264 var /** @const */ padding = 1;
198 var visualHeight = stripHeight - padding; 265 var visualHeight = stripHeight - padding;
199 var timeOffset = this._model.minimumRecordTime(); 266 var timeOffset = this._model.minimumRecordTime();
200 var timeSpan = this._model.maximumRecordTime() - timeOffset; 267 var timeSpan = this._model.maximumRecordTime() - timeOffset;
201 var scale = this._canvas.width / timeSpan; 268 var scale = this._canvas.width / timeSpan;
202 var ditherer = new WebInspector.Dithering(); 269 var ditherer = new WebInspector.Dithering();
203 var categoryStack = []; 270 var categoryStack = [];
204 var lastX = 0; 271 var lastX = 0;
205 position += padding; 272 position += padding;
206 273
207 /** 274 /**
208 * @param {!WebInspector.TimelineCategory} category
209 * @return {string}
210 * @this {WebInspector.TimelineEventOverview}
211 */
212 function categoryColor(category)
213 {
214 return category.hidden ? this._disabledCategoryFillStyle : this._fil lStyles[category.name];
215 }
216
217 /**
218 * @param {!WebInspector.TracingModel.Event} e 275 * @param {!WebInspector.TracingModel.Event} e
219 * @this {WebInspector.TimelineEventOverview} 276 * @this {WebInspector.TimelineEventOverview}
220 */ 277 */
221 function onEventStart(e) 278 function onEventStart(e)
222 { 279 {
223 var pos = (e.startTime - timeOffset) * scale; 280 var pos = (e.startTime - timeOffset) * scale;
224 if (categoryStack.length) { 281 if (categoryStack.length) {
225 var category = categoryStack.peekLast(); 282 var category = categoryStack.peekLast();
226 var bar = ditherer.appendInterval(category, lastX, pos); 283 var bar = ditherer.appendInterval(category, lastX, pos);
227 if (bar) 284 if (bar)
228 this._renderBar(bar.start, bar.end, position, visualHeight, categoryColor.call(this, category)); 285 this._renderBar(bar.start, bar.end, position, visualHeight, this._categoryColor(category));
229 } 286 }
230 categoryStack.push(WebInspector.TimelineUIUtils.eventStyle(e).catego ry); 287 categoryStack.push(WebInspector.TimelineUIUtils.eventStyle(e).catego ry);
231 lastX = pos; 288 lastX = pos;
232 } 289 }
233 290
234 /** 291 /**
235 * @param {!WebInspector.TracingModel.Event} e 292 * @param {!WebInspector.TracingModel.Event} e
236 * @this {WebInspector.TimelineEventOverview} 293 * @this {WebInspector.TimelineEventOverview}
237 */ 294 */
238 function onEventEnd(e) 295 function onEventEnd(e)
239 { 296 {
240 var category = categoryStack.pop(); 297 var category = categoryStack.pop();
241 var pos = (e.endTime - timeOffset) * scale; 298 var pos = (e.endTime - timeOffset) * scale;
242 var bar = ditherer.appendInterval(category, lastX, pos); 299 var bar = ditherer.appendInterval(category, lastX, pos);
243 if (bar) 300 if (bar)
244 this._renderBar(bar.start, bar.end, position, visualHeight, cate goryColor.call(this, category)); 301 this._renderBar(bar.start, bar.end, position, visualHeight, this ._categoryColor(category));
245 lastX = pos; 302 lastX = pos;
246 } 303 }
247 304
248 WebInspector.TimelineModel.forEachEvent(events, onEventStart.bind(this), onEventEnd.bind(this)); 305 WebInspector.TimelineModel.forEachEvent(events, onEventStart.bind(this), onEventEnd.bind(this));
249 return stripHeight; 306 return stripHeight;
250 }, 307 },
251 308
252 /** 309 /**
310 * @param {!WebInspector.TimelineCategory} category
311 * @return {string}
312 */
313 _categoryColor: function(category)
314 {
315 return category.hidden ? this._disabledCategoryFillStyle : this._fillSty les[category.name];
316 },
317
318 /**
253 * @param {number} position 319 * @param {number} position
254 * @param {number} height 320 * @param {number} height
255 * @return {number} 321 * @return {number}
256 */ 322 */
257 _drawFrames: function(position, height) 323 _drawFrames: function(position, height)
258 { 324 {
259 var /** @const */ padding = 2; 325 var /** @const */ padding = 2;
260 var /** @const */ baseFrameDurationMs = 1e3 / 60; 326 var /** @const */ baseFrameDurationMs = 1e3 / 60;
261 var visualHeight = (height - padding) * window.devicePixelRatio; 327 var visualHeight = (height - padding) * window.devicePixelRatio;
262 var timeOffset = this._model.minimumRecordTime(); 328 var timeOffset = this._model.minimumRecordTime();
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 for (var g of this._groupError.keys()) { 451 for (var g of this._groupError.keys()) {
386 if (!g) 452 if (!g)
387 continue; 453 continue;
388 var value = this._groupError.get(g); 454 var value = this._groupError.get(g);
389 value += (1 - value) * ratio; 455 value += (1 - value) * ratio;
390 this._groupError.set(g, value); 456 this._groupError.set(g, value);
391 } 457 }
392 return toDistribute; 458 return toDistribute;
393 } 459 }
394 } 460 }
461
462 /**
463 * @constructor
464 * @param {number} startTime
465 * @param {number} quantDuration
466 * @param {function(!Array<number>)} callback
467 */
468 WebInspector.Quantizer = function(startTime, quantDuration, callback)
469 {
470 this._lastTime = startTime;
471 this._quantDuration = quantDuration;
472 this._callback = callback;
473 this._counters = [];
474 this._remainder = 0;
475 }
476
477 WebInspector.Quantizer.prototype = {
478 /**
479 * @param {number} time
480 * @param {number} group
481 */
482 appendInterval: function(time, group)
483 {
484 var interval = time - this._lastTime;
485 if (this._remainder + interval < this._quantDuration) {
486 this._counters[group] = (this._counters[group] || 0) + interval;
487 this._remainder += interval;
yurys 2015/06/09 09:19:26 _remainder -> _elapsed or _utilized ? Or better ma
alph 2015/06/09 09:47:24 Done.
488 this._lastTime = time;
489 return;
490 }
491 this._counters[group] = (this._counters[group] || 0) + this._quantDurati on - this._remainder;
492 this._callback(this._counters);
493 interval -= this._quantDuration - this._remainder;
494 while (interval >= this._quantDuration) {
495 var counters = [];
496 counters[group] = this._quantDuration;
497 this._callback(counters);
498 interval -= this._quantDuration;
499 }
500 this._counters = [];
501 this._counters[group] = interval;
502 this._lastTime = time;
503 this._remainder = interval;
504 }
505 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698