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

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

Issue 1174293006: DevTools: Add responsiveness strip to the 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 | Source/devtools/front_end/timeline/TimelineFrameModel.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 * 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 var categories = WebInspector.TimelineUIUtils.categories(); 45 var categories = WebInspector.TimelineUIUtils.categories();
46 for (var category in categories) { 46 for (var category in categories) {
47 this._fillStyles[category] = categories[category].fillColorStop1; 47 this._fillStyles[category] = categories[category].fillColorStop1;
48 categories[category].addEventListener(WebInspector.TimelineCategory.Even ts.VisibilityChanged, this._onCategoryVisibilityChanged, this); 48 categories[category].addEventListener(WebInspector.TimelineCategory.Even ts.VisibilityChanged, this._onCategoryVisibilityChanged, this);
49 } 49 }
50 50
51 this._disabledCategoryFillStyle = "hsl(0, 0%, 67%)"; 51 this._disabledCategoryFillStyle = "hsl(0, 0%, 67%)";
52 } 52 }
53 53
54 /** @const */ 54 /** @const */
55 WebInspector.TimelineEventOverview._fullStripHeight = 20; 55 WebInspector.TimelineEventOverview._fullStripHeight = 24;
56 /** @const */ 56 /** @const */
57 WebInspector.TimelineEventOverview._smallStripHeight = 8; 57 WebInspector.TimelineEventOverview._smallStripHeight = 8;
58 58
59 WebInspector.TimelineEventOverview.prototype = { 59 WebInspector.TimelineEventOverview.prototype = {
60 /** 60 /**
61 * @override 61 * @override
62 */ 62 */
63 dispose: function() 63 dispose: function()
64 { 64 {
65 WebInspector.TimelineOverviewBase.prototype.dispose.call(this); 65 WebInspector.TimelineOverviewBase.prototype.dispose.call(this);
66 var categories = WebInspector.TimelineUIUtils.categories(); 66 var categories = WebInspector.TimelineUIUtils.categories();
67 for (var category in categories) 67 for (var category in categories)
68 categories[category].removeEventListener(WebInspector.TimelineCatego ry.Events.VisibilityChanged, this._onCategoryVisibilityChanged, this); 68 categories[category].removeEventListener(WebInspector.TimelineCatego ry.Events.VisibilityChanged, this._onCategoryVisibilityChanged, this);
69 }, 69 },
70 70
71 /** 71 /**
72 * @override 72 * @override
73 */ 73 */
74 update: function() 74 update: function()
75 { 75 {
76 var /** @const */ fpsStripHeight = 20;
76 this.resetCanvas(); 77 this.resetCanvas();
77 var threads = this._model.virtualThreads(); 78 var threads = this._model.virtualThreads();
78 var mainThreadEvents = this._model.mainThreadEvents(); 79 var mainThreadEvents = this._model.mainThreadEvents();
79 var networkHeight = this._canvas.clientHeight 80 var networkHeight = this._canvas.clientHeight
80 - WebInspector.TimelineEventOverview._fullStripHeight 81 - WebInspector.TimelineEventOverview._fullStripHeight
81 - 2 * WebInspector.TimelineEventOverview._smallStripHeight; 82 - 2 * WebInspector.TimelineEventOverview._smallStripHeight;
82 var position = 0; 83 var position = 0;
83 if (Runtime.experiments.isEnabled("inputEventsOnTimelineOverview")) { 84 if (Runtime.experiments.isEnabled("inputEventsOnTimelineOverview")) {
84 var inputHeight = this._drawInputEvents(mainThreadEvents, position, WebInspector.TimelineEventOverview._smallStripHeight); 85 var inputHeight = this._drawInputEvents(mainThreadEvents, position, WebInspector.TimelineEventOverview._smallStripHeight);
85 position += inputHeight; 86 position += inputHeight;
86 networkHeight -= inputHeight; 87 networkHeight -= inputHeight;
87 } 88 }
88 if (Runtime.experiments.isEnabled("frameRateOnEventsOverview")) 89 if (Runtime.experiments.isEnabled("frameRateOnEventsOverview")) {
caseq 2015/06/17 12:56:13 nit: nuke { }
alph 2015/06/17 13:22:00 Done.
89 networkHeight -= WebInspector.TimelineEventOverview._fullStripHeight ; 90 networkHeight -= fpsStripHeight + WebInspector.TimelineEventOverview ._smallStripHeight;
91 }
90 position += this._drawNetwork(mainThreadEvents, position, networkHeight) ; 92 position += this._drawNetwork(mainThreadEvents, position, networkHeight) ;
91 position += this._drawStackedUtilizationChart(mainThreadEvents, position , WebInspector.TimelineEventOverview._fullStripHeight); 93 position += this._drawStackedUtilizationChart(mainThreadEvents, position , WebInspector.TimelineEventOverview._fullStripHeight);
92 for (var thread of threads.filter(function(thread) { return !thread.isWo rker(); })) 94 for (var thread of threads.filter(function(thread) { return !thread.isWo rker(); }))
93 this._drawEvents(thread.events, position, WebInspector.TimelineEvent Overview._smallStripHeight); 95 this._drawEvents(thread.events, position, WebInspector.TimelineEvent Overview._smallStripHeight);
94 position += WebInspector.TimelineEventOverview._smallStripHeight; 96 position += WebInspector.TimelineEventOverview._smallStripHeight;
95 for (var thread of threads.filter(function(thread) { return thread.isWor ker(); })) 97 for (var thread of threads.filter(function(thread) { return thread.isWor ker(); }))
96 this._drawEvents(thread.events, position, WebInspector.TimelineEvent Overview._smallStripHeight); 98 this._drawEvents(thread.events, position, WebInspector.TimelineEvent Overview._smallStripHeight);
97 position += WebInspector.TimelineEventOverview._smallStripHeight; 99 position += WebInspector.TimelineEventOverview._smallStripHeight;
98 if (Runtime.experiments.isEnabled("frameRateOnEventsOverview")) 100 if (Runtime.experiments.isEnabled("frameRateOnEventsOverview")) {
99 position += this._drawFrames(position, WebInspector.TimelineEventOve rview._fullStripHeight); 101 position += this._drawResponsivenessStrip(position, WebInspector.Tim elineEventOverview._smallStripHeight);
caseq 2015/06/17 12:56:12 Does the height of drawn strip ever vary?
alph 2015/06/17 13:22:00 No, but this way the call site code is simpler. So
102 position += this._drawFrames(position, fpsStripHeight);
caseq 2015/06/17 12:56:13 ditto.
alph 2015/06/17 13:22:00 ditto.
103 }
100 console.assert(position === this._canvas.clientHeight); 104 console.assert(position === this._canvas.clientHeight);
101 }, 105 },
102 106
103 /** 107 /**
104 * @param {!Array.<!WebInspector.TracingModel.Event>} events 108 * @param {!Array.<!WebInspector.TracingModel.Event>} events
105 * @param {number} position 109 * @param {number} position
106 * @param {number} height 110 * @param {number} height
107 * @return {number} 111 * @return {number}
108 */ 112 */
109 _drawInputEvents: function(events, position, height) 113 _drawInputEvents: function(events, position, height)
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 }, 192 },
189 193
190 /** 194 /**
191 * @param {!Array.<!WebInspector.TracingModel.Event>} events 195 * @param {!Array.<!WebInspector.TracingModel.Event>} events
192 * @param {number} position 196 * @param {number} position
193 * @param {number} height 197 * @param {number} height
194 * @return {number} 198 * @return {number}
195 */ 199 */
196 _drawStackedUtilizationChart: function(events, position, height) 200 _drawStackedUtilizationChart: function(events, position, height)
197 { 201 {
202 if (!events.length)
203 return height;
198 var /** @const */ quantSizePx = 4 * window.devicePixelRatio; 204 var /** @const */ quantSizePx = 4 * window.devicePixelRatio;
199 var /** @const */ padding = 1; 205 var /** @const */ padding = 1;
200 var visualHeight = (height - padding) * window.devicePixelRatio; 206 var visualHeight = (height - padding) * window.devicePixelRatio;
201 var baseLine = (position + height) * window.devicePixelRatio; 207 var baseLine = (position + height) * window.devicePixelRatio;
202 var timeOffset = this._model.minimumRecordTime(); 208 var timeOffset = this._model.minimumRecordTime();
203 var timeSpan = this._model.maximumRecordTime() - timeOffset; 209 var timeSpan = this._model.maximumRecordTime() - timeOffset;
204 var scale = this._canvas.width / timeSpan; 210 var scale = this._canvas.width / timeSpan;
205 var quantTime = quantSizePx / scale; 211 var quantTime = quantSizePx / scale;
206 var quantizer = new WebInspector.Quantizer(timeOffset, quantTime, drawSa mple.bind(this)); 212 var quantizer = new WebInspector.Quantizer(timeOffset, quantTime, drawSa mple.bind(this));
207 var ctx = this._context; 213 var ctx = this._context;
208 var x = 0; 214 var x = 0;
209 var categories = WebInspector.TimelineUIUtils.categories(); 215 var categories = WebInspector.TimelineUIUtils.categories();
210 var categoryOrder = ["idle", "scripting", "rendering", "painting", "load ing", "other"]; 216 var categoryOrder = ["idle", "scripting", "rendering", "painting", "load ing", "other"];
211 var otherIndex = categoryOrder.indexOf("other"); 217 var otherIndex = categoryOrder.indexOf("other");
212 var idleIndex = 0; 218 var idleIndex = 0;
213 console.assert(idleIndex === categoryOrder.indexOf("idle")); 219 console.assert(idleIndex === categoryOrder.indexOf("idle"));
214 for (var i = idleIndex + 1; i < categoryOrder.length; ++i) 220 for (var i = idleIndex + 1; i < categoryOrder.length; ++i)
215 categories[categoryOrder[i]]._overviewIndex = i; 221 categories[categoryOrder[i]]._overviewIndex = i;
216 var categoryIndexStack = []; 222 var categoryIndexStack = [];
217 223
224 this._drawHorizontalGuide(baseLine - visualHeight + 0.5, WebInspector.UI String("100%"));
225
218 /** 226 /**
219 * @param {!Array<number>} counters 227 * @param {!Array<number>} counters
220 * @this {WebInspector.TimelineEventOverview} 228 * @this {WebInspector.TimelineEventOverview}
221 */ 229 */
222 function drawSample(counters) 230 function drawSample(counters)
223 { 231 {
224 var y = baseLine; 232 var y = baseLine;
225 for (var i = idleIndex + 1; i < counters.length; ++i) { 233 for (var i = idleIndex + 1; i < counters.length; ++i) {
226 if (!counters[i]) 234 if (!counters[i])
227 continue; 235 continue;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 _categoryColor: function(category) 324 _categoryColor: function(category)
317 { 325 {
318 return category.hidden ? this._disabledCategoryFillStyle : this._fillSty les[category.name]; 326 return category.hidden ? this._disabledCategoryFillStyle : this._fillSty les[category.name];
319 }, 327 },
320 328
321 /** 329 /**
322 * @param {number} position 330 * @param {number} position
323 * @param {number} height 331 * @param {number} height
324 * @return {number} 332 * @return {number}
325 */ 333 */
334 _drawResponsivenessStrip: function(position, height)
335 {
336 var /** @const */ padding = 1;
337 var visualHeight = (height - padding) * window.devicePixelRatio;
338 var timeOffset = this._model.minimumRecordTime();
339 var timeSpan = this._model.maximumRecordTime() - timeOffset;
340 var scale = this._canvas.width / timeSpan;
341 var frames = this._frameModel.frames();
342 var ctx = this._context;
343 ctx.beginPath();
344 var responsivenessStripY = (position + padding) * window.devicePixelRati o;
345 for (var i = 0; i < frames.length; ++i) {
346 var frame = frames[i];
347 if (!frame.hasWarnings())
348 continue;
349 var x = scale * (frame.startTime - timeOffset);
350 var w = scale * frame.duration;
351 ctx.rect(x, responsivenessStripY, w, visualHeight);
352 }
353 ctx.fillStyle = "hsl(0, 80%, 70%)";
354 ctx.fill();
355 return height;
356 },
357
358 /**
359 * @param {number} position
360 * @param {number} height
361 * @return {number}
362 */
326 _drawFrames: function(position, height) 363 _drawFrames: function(position, height)
327 { 364 {
328 var /** @const */ padding = 2; 365 var /** @const */ padding = 2;
329 var /** @const */ baseFrameDurationMs = 1e3 / 60; 366 var /** @const */ baseFrameDurationMs = 1e3 / 60;
330 var visualHeight = (height - padding) * window.devicePixelRatio; 367 var visualHeight = (height - padding) * window.devicePixelRatio;
331 var timeOffset = this._model.minimumRecordTime(); 368 var timeOffset = this._model.minimumRecordTime();
332 var timeSpan = this._model.maximumRecordTime() - timeOffset; 369 var timeSpan = this._model.maximumRecordTime() - timeOffset;
333 var scale = this._canvas.width / timeSpan; 370 var scale = this._canvas.width / timeSpan;
334 var frames = this._frameModel.frames(); 371 var frames = this._frameModel.frames();
335 var baseY = (position + height) * window.devicePixelRatio; 372 var baseY = height * window.devicePixelRatio;
373 var ctx = this._context;
336 var y = baseY + 10; 374 var y = baseY + 10;
337 var ctx = this._context; 375 if (!frames.length)
376 return height;
377
338 ctx.save(); 378 ctx.save();
379 ctx.translate(0, position * window.devicePixelRatio);
339 ctx.beginPath(); 380 ctx.beginPath();
340 ctx.rect(0, position * window.devicePixelRatio, this._canvas.width, heig ht * window.devicePixelRatio); 381 ctx.rect(0, 0, this._canvas.width, height * window.devicePixelRatio);
341 ctx.clip(); 382 ctx.clip();
383 ctx.lineWidth = window.devicePixelRatio;
384
385 this._drawHorizontalGuide(baseY - visualHeight - 0.5, WebInspector.UIStr ing("60\u2009fps"));
386
342 ctx.beginPath(); 387 ctx.beginPath();
343 ctx.lineWidth = 1 * window.devicePixelRatio;
344 ctx.strokeStyle = "hsl(110, 50%, 60%)";
345 ctx.fillStyle = "hsl(110, 50%, 88%)";
346 ctx.moveTo(0, y); 388 ctx.moveTo(0, y);
347 for (var i = 0; i < frames.length; ++i) { 389 for (var i = 0; i < frames.length; ++i) {
348 var frame = frames[i]; 390 var frame = frames[i];
349 var x = Math.round((frame.startTime - timeOffset) * scale) + 0.5; 391 var x = Math.round((frame.startTime - timeOffset) * scale) + 0.5;
350 ctx.lineTo(x, y); 392 ctx.lineTo(x, y);
351 ctx.lineTo(x, y + 1.5); 393 ctx.lineTo(x, y + 1.5);
352 y = frame.idle ? baseY + 0.5 : Math.round(baseY - visualHeight * Mat h.min(baseFrameDurationMs / frame.duration, 1)) - 0.5; 394 y = frame.idle ? baseY + 0.5 : Math.round(baseY - visualHeight * Mat h.min(baseFrameDurationMs / frame.duration, 1)) - 0.5;
353 ctx.lineTo(x, y + 1.5); 395 ctx.lineTo(x, y + 1.5);
354 ctx.lineTo(x, y); 396 ctx.lineTo(x, y);
355 } 397 }
356 if (frames.length) { 398 if (frames.length) {
357 var lastFrame = frames.peekLast(); 399 var lastFrame = frames.peekLast();
358 var x = Math.round((lastFrame.startTime + lastFrame.duration - timeO ffset) * scale) + 0.5; 400 var x = Math.round((lastFrame.startTime + lastFrame.duration - timeO ffset) * scale) + 0.5;
359 ctx.lineTo(x, y); 401 ctx.lineTo(x, y);
360 } 402 }
361 ctx.lineTo(x, baseY + 10); 403 ctx.lineTo(x, baseY + 10);
362 ctx.closePath(); 404 ctx.fillStyle = "hsl(110, 50%, 88%)";
405 ctx.strokeStyle = "hsl(110, 50%, 60%)";
363 ctx.fill(); 406 ctx.fill();
364 ctx.stroke(); 407 ctx.stroke();
365 ctx.restore(); 408 ctx.restore();
366 return height; 409 return height;
367 }, 410 },
368 411
412 /**
413 * @param {number} y
414 * @param {string} label
415 */
416 _drawHorizontalGuide: function(y, label)
417 {
418 var ctx = this._context;
419 ctx.save();
420 ctx.beginPath();
421 ctx.moveTo(0, y);
422 ctx.lineTo(this._canvas.width, y);
423 ctx.strokeStyle = "hsl(0, 0%, 85%)";
424 ctx.setLineDash([3]);
425 ctx.stroke();
426 ctx.fillStyle = "hsl(0, 0%, 65%)";
427 ctx.font = "9px " + WebInspector.fontFamily();
428 ctx.fillText(label, 4, y + 8);
429 ctx.restore();
430 },
431
369 _onCategoryVisibilityChanged: function() 432 _onCategoryVisibilityChanged: function()
370 { 433 {
371 this.update(); 434 this.update();
372 }, 435 },
373 436
374 /** 437 /**
375 * @param {number} begin 438 * @param {number} begin
376 * @param {number} end 439 * @param {number} end
377 * @param {number} position 440 * @param {number} position
378 * @param {number} height 441 * @param {number} height
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 counters[group] = this._quantDuration; 601 counters[group] = this._quantDuration;
539 this._callback(counters); 602 this._callback(counters);
540 interval -= this._quantDuration; 603 interval -= this._quantDuration;
541 } 604 }
542 this._counters = []; 605 this._counters = [];
543 this._counters[group] = interval; 606 this._counters[group] = interval;
544 this._lastTime = time; 607 this._lastTime = time;
545 this._remainder = this._quantDuration - interval; 608 this._remainder = this._quantDuration - interval;
546 } 609 }
547 } 610 }
OLDNEW
« no previous file with comments | « no previous file | Source/devtools/front_end/timeline/TimelineFrameModel.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698