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

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: addressing comments 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 | Source/devtools/front_end/timeline/timelinePanel.css » ('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 * 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 otherIndex = categoryOrder.indexOf("other");
211 var idleIndex = 0;
212 console.assert(idleIndex === categoryOrder.indexOf("idle"));
213 for (var i = idleIndex + 1; i < categoryOrder.length; ++i)
214 categories[categoryOrder[i]]._overviewIndex = i;
215 var categoryIndexStack = [];
216
217 /**
218 * @param {!Array<number>} counters
219 * @this {WebInspector.TimelineEventOverview}
220 */
221 function drawSample(counters)
222 {
223 var y = baseLine;
224 for (var i = idleIndex + 1; i < counters.length; ++i) {
225 if (!counters[i])
226 continue;
227 var h = counters[i] / quantTime * visualHeight;
228 ctx.fillStyle = this._categoryColor(categories[categoryOrder[i]] );
229 ctx.fillRect(x, y - h, quantSizePx, h);
230 y -= h;
231 }
232 x += quantSizePx;
233 }
234
235 /**
236 * @param {!WebInspector.TracingModel.Event} e
237 */
238 function onEventStart(e)
239 {
240 var index = categoryIndexStack.length ? categoryIndexStack.peekLast( ) : idleIndex;
241 quantizer.appendInterval(e.startTime, index);
242 categoryIndexStack.push(WebInspector.TimelineUIUtils.eventStyle(e).c ategory._overviewIndex || otherIndex);
243 }
244
245 /**
246 * @param {!WebInspector.TracingModel.Event} e
247 */
248 function onEventEnd(e)
249 {
250 quantizer.appendInterval(e.endTime, categoryIndexStack.pop());
251 }
252
253 WebInspector.TimelineModel.forEachEvent(events, onEventStart, onEventEnd );
254 return height;
255 },
256
257 /**
258 * @param {!Array.<!WebInspector.TracingModel.Event>} events
259 * @param {number} position
192 * @param {number} stripHeight 260 * @param {number} stripHeight
193 * @return {number} 261 * @return {number}
194 */ 262 */
195 _drawEvents: function(events, position, stripHeight) 263 _drawEvents: function(events, position, stripHeight)
196 { 264 {
197 var /** @const */ padding = 1; 265 var /** @const */ padding = 1;
198 var visualHeight = stripHeight - padding; 266 var visualHeight = stripHeight - padding;
199 var timeOffset = this._model.minimumRecordTime(); 267 var timeOffset = this._model.minimumRecordTime();
200 var timeSpan = this._model.maximumRecordTime() - timeOffset; 268 var timeSpan = this._model.maximumRecordTime() - timeOffset;
201 var scale = this._canvas.width / timeSpan; 269 var scale = this._canvas.width / timeSpan;
202 var ditherer = new WebInspector.Dithering(); 270 var ditherer = new WebInspector.Dithering();
203 var categoryStack = []; 271 var categoryStack = [];
204 var lastX = 0; 272 var lastX = 0;
205 position += padding; 273 position += padding;
206 274
207 /** 275 /**
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 276 * @param {!WebInspector.TracingModel.Event} e
219 * @this {WebInspector.TimelineEventOverview} 277 * @this {WebInspector.TimelineEventOverview}
220 */ 278 */
221 function onEventStart(e) 279 function onEventStart(e)
222 { 280 {
223 var pos = (e.startTime - timeOffset) * scale; 281 var pos = (e.startTime - timeOffset) * scale;
224 if (categoryStack.length) { 282 if (categoryStack.length) {
225 var category = categoryStack.peekLast(); 283 var category = categoryStack.peekLast();
226 var bar = ditherer.appendInterval(category, lastX, pos); 284 var bar = ditherer.appendInterval(category, lastX, pos);
227 if (bar) 285 if (bar)
228 this._renderBar(bar.start, bar.end, position, visualHeight, categoryColor.call(this, category)); 286 this._renderBar(bar.start, bar.end, position, visualHeight, this._categoryColor(category));
229 } 287 }
230 categoryStack.push(WebInspector.TimelineUIUtils.eventStyle(e).catego ry); 288 categoryStack.push(WebInspector.TimelineUIUtils.eventStyle(e).catego ry);
231 lastX = pos; 289 lastX = pos;
232 } 290 }
233 291
234 /** 292 /**
235 * @param {!WebInspector.TracingModel.Event} e 293 * @param {!WebInspector.TracingModel.Event} e
236 * @this {WebInspector.TimelineEventOverview} 294 * @this {WebInspector.TimelineEventOverview}
237 */ 295 */
238 function onEventEnd(e) 296 function onEventEnd(e)
239 { 297 {
240 var category = categoryStack.pop(); 298 var category = categoryStack.pop();
241 var pos = (e.endTime - timeOffset) * scale; 299 var pos = (e.endTime - timeOffset) * scale;
242 var bar = ditherer.appendInterval(category, lastX, pos); 300 var bar = ditherer.appendInterval(category, lastX, pos);
243 if (bar) 301 if (bar)
244 this._renderBar(bar.start, bar.end, position, visualHeight, cate goryColor.call(this, category)); 302 this._renderBar(bar.start, bar.end, position, visualHeight, this ._categoryColor(category));
245 lastX = pos; 303 lastX = pos;
246 } 304 }
247 305
248 WebInspector.TimelineModel.forEachEvent(events, onEventStart.bind(this), onEventEnd.bind(this)); 306 WebInspector.TimelineModel.forEachEvent(events, onEventStart.bind(this), onEventEnd.bind(this));
249 return stripHeight; 307 return stripHeight;
250 }, 308 },
251 309
252 /** 310 /**
311 * @param {!WebInspector.TimelineCategory} category
312 * @return {string}
313 */
314 _categoryColor: function(category)
315 {
316 return category.hidden ? this._disabledCategoryFillStyle : this._fillSty les[category.name];
317 },
318
319 /**
253 * @param {number} position 320 * @param {number} position
254 * @param {number} height 321 * @param {number} height
255 * @return {number} 322 * @return {number}
256 */ 323 */
257 _drawFrames: function(position, height) 324 _drawFrames: function(position, height)
258 { 325 {
259 var /** @const */ padding = 2; 326 var /** @const */ padding = 2;
260 var /** @const */ baseFrameDurationMs = 1e3 / 60; 327 var /** @const */ baseFrameDurationMs = 1e3 / 60;
261 var visualHeight = (height - padding) * window.devicePixelRatio; 328 var visualHeight = (height - padding) * window.devicePixelRatio;
262 var timeOffset = this._model.minimumRecordTime(); 329 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()) { 452 for (var g of this._groupError.keys()) {
386 if (!g) 453 if (!g)
387 continue; 454 continue;
388 var value = this._groupError.get(g); 455 var value = this._groupError.get(g);
389 value += (1 - value) * ratio; 456 value += (1 - value) * ratio;
390 this._groupError.set(g, value); 457 this._groupError.set(g, value);
391 } 458 }
392 return toDistribute; 459 return toDistribute;
393 } 460 }
394 } 461 }
462
463 /**
464 * @constructor
465 * @param {number} startTime
466 * @param {number} quantDuration
467 * @param {function(!Array<number>)} callback
468 */
469 WebInspector.Quantizer = function(startTime, quantDuration, callback)
470 {
471 this._lastTime = startTime;
472 this._quantDuration = quantDuration;
473 this._callback = callback;
474 this._counters = [];
475 this._remainder = quantDuration;
476 }
477
478 WebInspector.Quantizer.prototype = {
479 /**
480 * @param {number} time
481 * @param {number} group
482 */
483 appendInterval: function(time, group)
484 {
485 var interval = time - this._lastTime;
486 if (interval <= this._remainder) {
yurys 2015/06/09 09:57:20 It may happen that the last interval won't be draw
alph 2015/06/09 10:36:32 Done.
487 this._counters[group] = (this._counters[group] || 0) + interval;
488 this._remainder -= interval;
489 this._lastTime = time;
490 return;
491 }
492 this._counters[group] = (this._counters[group] || 0) + this._remainder;
493 this._callback(this._counters);
494 interval -= this._remainder;
495 while (interval >= this._quantDuration) {
496 var counters = [];
497 counters[group] = this._quantDuration;
498 this._callback(counters);
499 interval -= this._quantDuration;
500 }
501 this._counters = [];
502 this._counters[group] = interval;
503 this._lastTime = time;
504 this._remainder = this._quantDuration - interval;
505 }
506 }
OLDNEW
« no previous file with comments | « no previous file | Source/devtools/front_end/timeline/timelinePanel.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698