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

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

Issue 980293002: DevTools: Show network requests on the timeline events overview. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Drop "Show" from the experiment name. Created 5 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
« no previous file with comments | « Source/devtools/front_end/main/Main.js ('k') | 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 for (var category in categories) { 43 for (var category in categories) {
44 this._fillStyles[category] = categories[category].fillColorStop1; 44 this._fillStyles[category] = categories[category].fillColorStop1;
45 categories[category].addEventListener(WebInspector.TimelineCategory.Even ts.VisibilityChanged, this._onCategoryVisibilityChanged, this); 45 categories[category].addEventListener(WebInspector.TimelineCategory.Even ts.VisibilityChanged, this._onCategoryVisibilityChanged, this);
46 } 46 }
47 47
48 this._disabledCategoryFillStyle = "hsl(0, 0%, 67%)"; 48 this._disabledCategoryFillStyle = "hsl(0, 0%, 67%)";
49 } 49 }
50 50
51 /** @const */ 51 /** @const */
52 WebInspector.TimelineEventOverview._stripHeight = 10; 52 WebInspector.TimelineEventOverview._stripHeight = 10;
53 /** @const */
54 WebInspector.TimelineEventOverview._maxNetworkStripHeight = 32;
53 55
54 WebInspector.TimelineEventOverview.prototype = { 56 WebInspector.TimelineEventOverview.prototype = {
55 /** 57 /**
56 * @override 58 * @override
57 */ 59 */
58 dispose: function() 60 dispose: function()
59 { 61 {
60 var categories = WebInspector.TimelineUIUtils.categories(); 62 var categories = WebInspector.TimelineUIUtils.categories();
61 for (var category in categories) 63 for (var category in categories)
62 categories[category].removeEventListener(WebInspector.TimelineCatego ry.Events.VisibilityChanged, this._onCategoryVisibilityChanged, this); 64 categories[category].removeEventListener(WebInspector.TimelineCatego ry.Events.VisibilityChanged, this._onCategoryVisibilityChanged, this);
63 }, 65 },
64 66
65 /** 67 /**
66 * @override 68 * @override
67 */ 69 */
68 update: function() 70 update: function()
69 { 71 {
70 var /** @const */ topPadding = 2; 72 var /** @const */ padding = 2;
71 this.resetCanvas(); 73 this.resetCanvas();
72 var threads = this._model.virtualThreads(); 74 var threads = this._model.virtualThreads();
73 var estimatedHeight = 3 * WebInspector.TimelineEventOverview._stripHeigh t; 75 var mainThreadEvents = this._model.mainThreadEvents();
76 var estimatedHeight = padding + 3 * WebInspector.TimelineEventOverview._ stripHeight;
77 estimatedHeight += padding + WebInspector.TimelineEventOverview._maxNetw orkStripHeight;
74 this._canvas.height = estimatedHeight * window.devicePixelRatio; 78 this._canvas.height = estimatedHeight * window.devicePixelRatio;
75 this._canvas.style.height = estimatedHeight + "px"; 79 this._canvas.style.height = estimatedHeight + "px";
76 var position = topPadding; 80 var position = padding;
77 position += this._drawEvents(this._model.mainThreadEvents(), position); 81 if (Runtime.experiments.isEnabled("networkRequestsOnTimeline")) {
82 position += this._drawNetwork(mainThreadEvents, position);
83 position += padding;
84 }
85 this._drawEvents(mainThreadEvents, position);
86 position += WebInspector.TimelineEventOverview._stripHeight;
78 for (var thread of threads.filter(function(thread) { return !thread.isWo rker(); })) 87 for (var thread of threads.filter(function(thread) { return !thread.isWo rker(); }))
79 this._drawEvents(thread.events, position); 88 this._drawEvents(thread.events, position);
80 position += WebInspector.TimelineEventOverview._stripHeight; 89 position += WebInspector.TimelineEventOverview._stripHeight;
81 var workersHeight = 0; 90 var workersHeight = 0;
82 for (var thread of threads.filter(function(thread) { return thread.isWor ker(); })) 91 for (var thread of threads.filter(function(thread) { return thread.isWor ker(); }))
83 workersHeight = Math.max(workersHeight, this._drawEvents(thread.even ts, position)); 92 workersHeight = Math.max(workersHeight, this._drawEvents(thread.even ts, position));
84 position += workersHeight; 93 position += workersHeight;
85 this.element.style.flexBasis = position + "px"; 94 this.element.style.flexBasis = position + "px";
86 }, 95 },
87 96
88 /** 97 /**
89 * @param {!Array.<!WebInspector.TracingModel.Event>} events 98 * @param {!Array.<!WebInspector.TracingModel.Event>} events
90 * @param {number} position 99 * @param {number} position
91 * @return {number} 100 * @return {number}
92 */ 101 */
102 _drawNetwork: function(events, position)
103 {
104 /**
105 * @param {!Array.<!WebInspector.TracingModel.Event>} events
106 * @return {number}
107 */
108 function calculateNetworkBandsCount(events)
109 {
110 var openBands = new Set();
111 var maxBands = 0;
112 for (var i = 0; i < events.length; ++i) {
113 var e = events[i];
114 switch (e.name) {
115 case WebInspector.TimelineModel.RecordType.ResourceSendRequest:
116 case WebInspector.TimelineModel.RecordType.ResourceReceiveRespon se:
117 case WebInspector.TimelineModel.RecordType.ResourceReceivedData:
118 var reqId = e.args["data"]["requestId"];
119 openBands.add(reqId);
120 maxBands = Math.max(maxBands, openBands.size);
121 break;
122 case WebInspector.TimelineModel.RecordType.ResourceFinish:
123 var reqId = e.args["data"]["requestId"];
124 if (!openBands.has(reqId))
125 ++maxBands;
126 else
127 openBands.delete(reqId);
128 break;
129 }
130 }
131 return maxBands;
132 }
133
134 var /** @const */ maxBandHeight = 4;
135 var bandsCount = calculateNetworkBandsCount(events);
136 var bandInterval = Math.min(maxBandHeight, WebInspector.TimelineEventOve rview._maxNetworkStripHeight / (bandsCount || 1));
137 var bandHeight = Math.ceil(bandInterval);
138 var timeOffset = this._model.minimumRecordTime();
139 var timeSpan = this._model.maximumRecordTime() - timeOffset;
140 var scale = this._canvas.width / timeSpan;
141 var loadingCategory = WebInspector.TimelineUIUtils.categories()["loading "];
142 var waitingColor = loadingCategory.fillColorStop0;
143 var processingColor = loadingCategory.fillColorStop1;
144
145 var bandsInUse = new Array(bandsCount);
146 var freeBandsCount = bandsCount;
147 var requestsInFlight = new Map();
148 var lastBand = 0;
149
150 /**
151 * @constructor
152 * @param {number} band
153 * @param {number} lastTime
154 * @param {boolean} gotResponse
155 */
156 function RequestInfo(band, lastTime, gotResponse)
157 {
158 this.band = band;
159 this.lastTime = lastTime;
160 this.gotResponse = gotResponse;
161 }
162
163 /**
164 * @return {number}
165 */
166 function seizeBand()
167 {
168 console.assert(freeBandsCount);
169 do {
170 lastBand = (lastBand + 1) % bandsInUse.length;
171 } while (bandsInUse[lastBand]);
172 bandsInUse[lastBand] = true;
173 --freeBandsCount;
174 return lastBand;
175 }
176
177 /**
178 * @param {number} band
179 */
180 function releaseBand(band)
181 {
182 bandsInUse[band] = false;
183 ++freeBandsCount;
184 }
185
186 /**
187 * @param {string} reqId
188 * @param {number=} time
189 * @return {!RequestInfo}
190 */
191 function getRequestInfo(reqId, time)
192 {
193 var reqInfo = requestsInFlight.get(reqId);
194 if (!reqInfo) {
195 reqInfo = new RequestInfo(seizeBand(), time || timeOffset, false );
196 requestsInFlight.set(reqId, reqInfo);
197 }
198 return reqInfo;
199 }
200
201 /**
202 * @param {string} reqId
203 * @param {!RequestInfo} reqInfo
204 * @param {number} time
205 * @param {boolean=} finish
206 * @this {WebInspector.TimelineEventOverview}
207 */
208 function advanceRequest(reqId, reqInfo, time, finish)
209 {
210 var band = reqInfo.band;
211 var start = (reqInfo.lastTime - timeOffset) * scale;
212 var end = (time - timeOffset) * scale;
213 var color = reqInfo.gotResponse ? processingColor : waitingColor;
214 if (finish) {
215 releaseBand(band);
216 requestsInFlight.delete(reqId);
217 } else {
218 reqInfo.lastTime = time;
219 reqInfo.gotResponse = true;
220 }
221 this._renderBar(Math.floor(start), Math.ceil(end), Math.floor(positi on + band * bandInterval), bandHeight, color);
222 }
223
224 for (var i = 0; i < events.length; ++i) {
225 var event = events[i];
226 switch (event.name) {
227 case WebInspector.TimelineModel.RecordType.ResourceSendRequest:
228 var reqId = event.args["data"]["requestId"];
229 getRequestInfo(reqId, event.startTime);
230 break;
231 case WebInspector.TimelineModel.RecordType.ResourceReceivedData:
232 case WebInspector.TimelineModel.RecordType.ResourceReceiveResponse:
233 case WebInspector.TimelineModel.RecordType.ResourceFinish:
234 var reqId = event.args["data"]["requestId"];
235 var reqInfo = getRequestInfo(reqId);
236 var finish = event.name === WebInspector.TimelineModel.RecordTyp e.ResourceFinish;
237 advanceRequest.call(this, reqId, reqInfo, event.startTime, finis h);
238 break;
239 }
240 }
241
242 for (var reqId of requestsInFlight.keys())
243 advanceRequest.call(this, reqId, requestsInFlight.get(reqId), timeOf fset + timeSpan);
244
245 return Math.ceil(bandInterval * bandsCount);
246 },
247
248 /**
249 * @param {!Array.<!WebInspector.TracingModel.Event>} events
250 * @param {number} position
251 * @return {number}
252 */
93 _drawEvents: function(events, position) 253 _drawEvents: function(events, position)
94 { 254 {
255 var /** @const */ padding = 1;
95 var stripHeight = WebInspector.TimelineEventOverview._stripHeight; 256 var stripHeight = WebInspector.TimelineEventOverview._stripHeight;
257 var visualHeight = stripHeight - padding;
96 var timeOffset = this._model.minimumRecordTime(); 258 var timeOffset = this._model.minimumRecordTime();
97 var timeSpan = this._model.maximumRecordTime() - timeOffset; 259 var timeSpan = this._model.maximumRecordTime() - timeOffset;
98 var scale = this._canvas.width / timeSpan; 260 var scale = this._canvas.width / timeSpan;
99 var ditherer = new WebInspector.Dithering(); 261 var ditherer = new WebInspector.Dithering();
100 var categoryStack = []; 262 var categoryStack = [];
101 var lastX = 0; 263 var lastX = 0;
102 var drawn = false; 264 var drawn = false;
103 265
104 /** 266 /**
267 * @param {!WebInspector.TimelineCategory} category
268 * @return {string}
269 * @this {WebInspector.TimelineEventOverview}
270 */
271 function categoryColor(category)
272 {
273 return category.hidden ? this._disabledCategoryFillStyle : this._fil lStyles[category.name];
274 }
275
276 /**
105 * @param {!WebInspector.TracingModel.Event} e 277 * @param {!WebInspector.TracingModel.Event} e
106 * @this {WebInspector.TimelineEventOverview} 278 * @this {WebInspector.TimelineEventOverview}
107 */ 279 */
108 function onEventStart(e) 280 function onEventStart(e)
109 { 281 {
110 var pos = (e.startTime - timeOffset) * scale; 282 var pos = (e.startTime - timeOffset) * scale;
111 if (categoryStack.length) { 283 if (categoryStack.length) {
112 var category = categoryStack.peekLast(); 284 var category = categoryStack.peekLast();
113 var bar = ditherer.appendInterval(category, lastX, pos); 285 var bar = ditherer.appendInterval(category, lastX, pos);
114 if (bar) { 286 if (bar) {
115 this._renderBar(bar.start, bar.end, position, stripHeight, c ategory); 287 this._renderBar(bar.start, bar.end, position, visualHeight, categoryColor.call(this, category));
116 drawn = true; 288 drawn = true;
117 } 289 }
118 } 290 }
119 categoryStack.push(WebInspector.TimelineUIUtils.eventStyle(e).catego ry); 291 categoryStack.push(WebInspector.TimelineUIUtils.eventStyle(e).catego ry);
120 lastX = pos; 292 lastX = pos;
121 } 293 }
122 294
123 /** 295 /**
124 * @param {!WebInspector.TracingModel.Event} e 296 * @param {!WebInspector.TracingModel.Event} e
125 * @this {WebInspector.TimelineEventOverview} 297 * @this {WebInspector.TimelineEventOverview}
126 */ 298 */
127 function onEventEnd(e) 299 function onEventEnd(e)
128 { 300 {
129 var category = categoryStack.pop(); 301 var category = categoryStack.pop();
130 var pos = (e.endTime - timeOffset) * scale; 302 var pos = (e.endTime - timeOffset) * scale;
131 var bar = ditherer.appendInterval(category, lastX, pos); 303 var bar = ditherer.appendInterval(category, lastX, pos);
132 if (bar) { 304 if (bar) {
133 this._renderBar(bar.start, bar.end, position, stripHeight, categ ory); 305 this._renderBar(bar.start, bar.end, position, visualHeight, cate goryColor.call(this, category));
134 drawn = true; 306 drawn = true;
135 } 307 }
136 lastX = pos; 308 lastX = pos;
137 } 309 }
138 310
139 WebInspector.TimelineModel.forEachEvent(events, onEventStart.bind(this), onEventEnd.bind(this)); 311 WebInspector.TimelineModel.forEachEvent(events, onEventStart.bind(this), onEventEnd.bind(this));
140 return drawn ? stripHeight : 0; 312 return drawn ? stripHeight : 0;
141 }, 313 },
142 314
143 _onCategoryVisibilityChanged: function() 315 _onCategoryVisibilityChanged: function()
144 { 316 {
145 this.update(); 317 this.update();
146 }, 318 },
147 319
148 /** 320 /**
149 * @param {number} begin 321 * @param {number} begin
150 * @param {number} end 322 * @param {number} end
151 * @param {number} position 323 * @param {number} position
152 * @param {number} height 324 * @param {number} height
153 * @param {!WebInspector.TimelineCategory} category 325 * @param {string} color
154 */ 326 */
155 _renderBar: function(begin, end, position, height, category) 327 _renderBar: function(begin, end, position, height, color)
156 { 328 {
157 var /** @const */ stripPadding = 1;
158 var innerStripHeight = (height - stripPadding) * window.devicePixelRatio ;
159 var x = begin; 329 var x = begin;
160 var y = position * window.devicePixelRatio; 330 var y = position * window.devicePixelRatio;
161 var width = end - begin; 331 var width = end - begin;
162 this._context.fillStyle = category.hidden ? this._disabledCategoryFillSt yle : this._fillStyles[category.name]; 332 this._context.fillStyle = color;
163 this._context.fillRect(x, y, width, innerStripHeight); 333 this._context.fillRect(x, y, width, height * window.devicePixelRatio);
164 }, 334 },
165 335
166 __proto__: WebInspector.TimelineOverviewBase.prototype 336 __proto__: WebInspector.TimelineOverviewBase.prototype
167 } 337 }
168 338
169 /** 339 /**
170 * @constructor 340 * @constructor
171 * @template T 341 * @template T
172 */ 342 */
173 WebInspector.Dithering = function() 343 WebInspector.Dithering = function()
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 for (var g of this._groupError.keys()) { 406 for (var g of this._groupError.keys()) {
237 if (!g) 407 if (!g)
238 continue; 408 continue;
239 var value = this._groupError.get(g); 409 var value = this._groupError.get(g);
240 value += (1 - value) * ratio; 410 value += (1 - value) * ratio;
241 this._groupError.set(g, value); 411 this._groupError.set(g, value);
242 } 412 }
243 return toDistribute; 413 return toDistribute;
244 } 414 }
245 } 415 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/main/Main.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698