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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/layer_viewer/PaintProfilerView.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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
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
11 * copyright notice, this list of conditions and the following disclaimer 11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the 12 * in the documentation and/or other materials provided with the
13 * distribution. 13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its 14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from 15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission. 16 * this software without specific prior written permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
31 /** 30 /**
32 * @constructor 31 * @unrestricted
33 * @param {function(string=)} showImageCallback
34 * @extends {WebInspector.HBox}
35 */ 32 */
36 WebInspector.PaintProfilerView = function(showImageCallback) 33 WebInspector.PaintProfilerView = class extends WebInspector.HBox {
37 { 34 /**
38 WebInspector.HBox.call(this, true); 35 * @param {function(string=)} showImageCallback
39 this.registerRequiredCSS("layer_viewer/paintProfiler.css"); 36 */
40 this.contentElement.classList.add("paint-profiler-overview"); 37 constructor(showImageCallback) {
41 this._canvasContainer = this.contentElement.createChild("div", "paint-profil er-canvas-container"); 38 super(true);
42 this._progressBanner = this.contentElement.createChild("div", "full-widget-d immed-banner hidden"); 39 this.registerRequiredCSS('layer_viewer/paintProfiler.css');
43 this._progressBanner.textContent = WebInspector.UIString("Profiling\u2026"); 40 this.contentElement.classList.add('paint-profiler-overview');
41 this._canvasContainer = this.contentElement.createChild('div', 'paint-profil er-canvas-container');
42 this._progressBanner = this.contentElement.createChild('div', 'full-widget-d immed-banner hidden');
43 this._progressBanner.textContent = WebInspector.UIString('Profiling\u2026');
44 this._pieChart = new WebInspector.PieChart(55, this._formatPieChartTime.bind (this), true); 44 this._pieChart = new WebInspector.PieChart(55, this._formatPieChartTime.bind (this), true);
45 this._pieChart.element.classList.add("paint-profiler-pie-chart"); 45 this._pieChart.element.classList.add('paint-profiler-pie-chart');
46 this.contentElement.appendChild(this._pieChart.element); 46 this.contentElement.appendChild(this._pieChart.element);
47 47
48 this._showImageCallback = showImageCallback; 48 this._showImageCallback = showImageCallback;
49 49
50 this._canvas = this._canvasContainer.createChild("canvas", "fill"); 50 this._canvas = this._canvasContainer.createChild('canvas', 'fill');
51 this._context = this._canvas.getContext("2d"); 51 this._context = this._canvas.getContext('2d');
52 this._selectionWindow = new WebInspector.OverviewGrid.Window(this._canvasCon tainer); 52 this._selectionWindow = new WebInspector.OverviewGrid.Window(this._canvasCon tainer);
53 this._selectionWindow.addEventListener(WebInspector.OverviewGrid.Events.Wind owChanged, this._onWindowChanged, this); 53 this._selectionWindow.addEventListener(WebInspector.OverviewGrid.Events.Wind owChanged, this._onWindowChanged, this);
54 54
55 this._innerBarWidth = 4 * window.devicePixelRatio; 55 this._innerBarWidth = 4 * window.devicePixelRatio;
56 this._minBarHeight = window.devicePixelRatio; 56 this._minBarHeight = window.devicePixelRatio;
57 this._barPaddingWidth = 2 * window.devicePixelRatio; 57 this._barPaddingWidth = 2 * window.devicePixelRatio;
58 this._outerBarWidth = this._innerBarWidth + this._barPaddingWidth; 58 this._outerBarWidth = this._innerBarWidth + this._barPaddingWidth;
59 this._pendingScale = 1; 59 this._pendingScale = 1;
60 this._scale = this._pendingScale; 60 this._scale = this._pendingScale;
61 61
62 this._reset(); 62 this._reset();
63 }
64
65 /**
66 * @return {!Object.<string, !WebInspector.PaintProfilerCategory>}
67 */
68 static categories() {
69 if (WebInspector.PaintProfilerView._categories)
70 return WebInspector.PaintProfilerView._categories;
71 WebInspector.PaintProfilerView._categories = {
72 shapes: new WebInspector.PaintProfilerCategory('shapes', WebInspector.UISt ring('Shapes'), 'rgb(255, 161, 129)'),
73 bitmap: new WebInspector.PaintProfilerCategory('bitmap', WebInspector.UISt ring('Bitmap'), 'rgb(136, 196, 255)'),
74 text: new WebInspector.PaintProfilerCategory('text', WebInspector.UIString ('Text'), 'rgb(180, 255, 137)'),
75 misc: new WebInspector.PaintProfilerCategory('misc', WebInspector.UIString ('Misc'), 'rgb(206, 160, 255)')
76 };
77 return WebInspector.PaintProfilerView._categories;
78 }
79
80 /**
81 * @return {!Object.<string, !WebInspector.PaintProfilerCategory>}
82 */
83 static _initLogItemCategories() {
84 if (WebInspector.PaintProfilerView._logItemCategoriesMap)
85 return WebInspector.PaintProfilerView._logItemCategoriesMap;
86
87 var categories = WebInspector.PaintProfilerView.categories();
88
89 var logItemCategories = {};
90 logItemCategories['Clear'] = categories['misc'];
91 logItemCategories['DrawPaint'] = categories['misc'];
92 logItemCategories['DrawData'] = categories['misc'];
93 logItemCategories['SetMatrix'] = categories['misc'];
94 logItemCategories['PushCull'] = categories['misc'];
95 logItemCategories['PopCull'] = categories['misc'];
96 logItemCategories['Translate'] = categories['misc'];
97 logItemCategories['Scale'] = categories['misc'];
98 logItemCategories['Concat'] = categories['misc'];
99 logItemCategories['Restore'] = categories['misc'];
100 logItemCategories['SaveLayer'] = categories['misc'];
101 logItemCategories['Save'] = categories['misc'];
102 logItemCategories['BeginCommentGroup'] = categories['misc'];
103 logItemCategories['AddComment'] = categories['misc'];
104 logItemCategories['EndCommentGroup'] = categories['misc'];
105 logItemCategories['ClipRect'] = categories['misc'];
106 logItemCategories['ClipRRect'] = categories['misc'];
107 logItemCategories['ClipPath'] = categories['misc'];
108 logItemCategories['ClipRegion'] = categories['misc'];
109 logItemCategories['DrawPoints'] = categories['shapes'];
110 logItemCategories['DrawRect'] = categories['shapes'];
111 logItemCategories['DrawOval'] = categories['shapes'];
112 logItemCategories['DrawRRect'] = categories['shapes'];
113 logItemCategories['DrawPath'] = categories['shapes'];
114 logItemCategories['DrawVertices'] = categories['shapes'];
115 logItemCategories['DrawDRRect'] = categories['shapes'];
116 logItemCategories['DrawBitmap'] = categories['bitmap'];
117 logItemCategories['DrawBitmapRectToRect'] = categories['bitmap'];
118 logItemCategories['DrawBitmapMatrix'] = categories['bitmap'];
119 logItemCategories['DrawBitmapNine'] = categories['bitmap'];
120 logItemCategories['DrawSprite'] = categories['bitmap'];
121 logItemCategories['DrawPicture'] = categories['bitmap'];
122 logItemCategories['DrawText'] = categories['text'];
123 logItemCategories['DrawPosText'] = categories['text'];
124 logItemCategories['DrawPosTextH'] = categories['text'];
125 logItemCategories['DrawTextOnPath'] = categories['text'];
126
127 WebInspector.PaintProfilerView._logItemCategoriesMap = logItemCategories;
128 return logItemCategories;
129 }
130
131 /**
132 * @param {!Object} logItem
133 * @return {!WebInspector.PaintProfilerCategory}
134 */
135 static _categoryForLogItem(logItem) {
136 var method = logItem.method.toTitleCase();
137
138 var logItemCategories = WebInspector.PaintProfilerView._initLogItemCategorie s();
139 var result = logItemCategories[method];
140 if (!result) {
141 result = WebInspector.PaintProfilerView.categories()['misc'];
142 logItemCategories[method] = result;
143 }
144 return result;
145 }
146
147 /**
148 * @override
149 */
150 onResize() {
151 this._update();
152 }
153
154 /**
155 * @param {?WebInspector.PaintProfilerSnapshot} snapshot
156 * @param {!Array.<!WebInspector.PaintProfilerLogItem>} log
157 * @param {?DOMAgent.Rect} clipRect
158 */
159 setSnapshotAndLog(snapshot, log, clipRect) {
160 this._reset();
161 this._snapshot = snapshot;
162 if (this._snapshot)
163 this._snapshot.addReference();
164 this._log = log;
165 this._logCategories = this._log.map(WebInspector.PaintProfilerView._category ForLogItem);
166
167 if (!this._snapshot) {
168 this._update();
169 this._pieChart.setTotal(0);
170 this._selectionWindow.setEnabled(false);
171 return;
172 }
173 this._selectionWindow.setEnabled(true);
174 this._progressBanner.classList.remove('hidden');
175 this._updateImage();
176 snapshot.profile(clipRect, onProfileDone.bind(this));
177 /**
178 * @param {!Array.<!LayerTreeAgent.PaintProfile>=} profiles
179 * @this {WebInspector.PaintProfilerView}
180 */
181 function onProfileDone(profiles) {
182 this._progressBanner.classList.add('hidden');
183 this._profiles = profiles;
184 this._update();
185 this._updatePieChart();
186 }
187 }
188
189 /**
190 * @param {number} scale
191 */
192 setScale(scale) {
193 var needsUpdate = scale > this._scale;
194 var predictiveGrowthFactor = 2;
195 this._pendingScale = Math.min(1, scale * predictiveGrowthFactor);
196 if (needsUpdate && this._snapshot)
197 this._updateImage();
198 }
199
200 _update() {
201 this._canvas.width = this._canvasContainer.clientWidth * window.devicePixelR atio;
202 this._canvas.height = this._canvasContainer.clientHeight * window.devicePixe lRatio;
203 this._samplesPerBar = 0;
204 if (!this._profiles || !this._profiles.length)
205 return;
206
207 var maxBars = Math.floor((this._canvas.width - 2 * this._barPaddingWidth) / this._outerBarWidth);
208 var sampleCount = this._log.length;
209 this._samplesPerBar = Math.ceil(sampleCount / maxBars);
210
211 var maxBarTime = 0;
212 var barTimes = [];
213 var barHeightByCategory = [];
214 var heightByCategory = {};
215 for (var i = 0, lastBarIndex = 0, lastBarTime = 0; i < sampleCount;) {
216 var categoryName = (this._logCategories[i] && this._logCategories[i].name) || 'misc';
217 var sampleIndex = this._log[i].commandIndex;
218 for (var row = 0; row < this._profiles.length; row++) {
219 var sample = this._profiles[row][sampleIndex];
220 lastBarTime += sample;
221 heightByCategory[categoryName] = (heightByCategory[categoryName] || 0) + sample;
222 }
223 ++i;
224 if (i - lastBarIndex === this._samplesPerBar || i === sampleCount) {
225 // Normalize by total number of samples accumulated.
226 var factor = this._profiles.length * (i - lastBarIndex);
227 lastBarTime /= factor;
228 for (categoryName in heightByCategory)
229 heightByCategory[categoryName] /= factor;
230
231 barTimes.push(lastBarTime);
232 barHeightByCategory.push(heightByCategory);
233
234 if (lastBarTime > maxBarTime)
235 maxBarTime = lastBarTime;
236 lastBarTime = 0;
237 heightByCategory = {};
238 lastBarIndex = i;
239 }
240 }
241
242 const paddingHeight = 4 * window.devicePixelRatio;
243 var scale = (this._canvas.height - paddingHeight - this._minBarHeight) / max BarTime;
244 for (var i = 0; i < barTimes.length; ++i) {
245 for (var categoryName in barHeightByCategory[i])
246 barHeightByCategory[i][categoryName] *= (barTimes[i] * scale + this._min BarHeight) / barTimes[i];
247 this._renderBar(i, barHeightByCategory[i]);
248 }
249 }
250
251 /**
252 * @param {number} index
253 * @param {!Object.<string, number>} heightByCategory
254 */
255 _renderBar(index, heightByCategory) {
256 var categories = WebInspector.PaintProfilerView.categories();
257 var currentHeight = 0;
258 var x = this._barPaddingWidth + index * this._outerBarWidth;
259 for (var categoryName in categories) {
260 if (!heightByCategory[categoryName])
261 continue;
262 currentHeight += heightByCategory[categoryName];
263 var y = this._canvas.height - currentHeight;
264 this._context.fillStyle = categories[categoryName].color;
265 this._context.fillRect(x, y, this._innerBarWidth, heightByCategory[categor yName]);
266 }
267 }
268
269 _onWindowChanged() {
270 this.dispatchEventToListeners(WebInspector.PaintProfilerView.Events.WindowCh anged);
271 this._updatePieChart();
272 if (this._updateImageTimer)
273 return;
274 this._updateImageTimer = setTimeout(this._updateImage.bind(this), 100);
275 }
276
277 _updatePieChart() {
278 var window = this.selectionWindow();
279 if (!this._profiles || !this._profiles.length || !window)
280 return;
281 var totalTime = 0;
282 var timeByCategory = {};
283 for (var i = window.left; i < window.right; ++i) {
284 var logEntry = this._log[i];
285 var category = WebInspector.PaintProfilerView._categoryForLogItem(logEntry );
286 timeByCategory[category.color] = timeByCategory[category.color] || 0;
287 for (var j = 0; j < this._profiles.length; ++j) {
288 var time = this._profiles[j][logEntry.commandIndex];
289 totalTime += time;
290 timeByCategory[category.color] += time;
291 }
292 }
293 this._pieChart.setTotal(totalTime / this._profiles.length);
294 for (var color in timeByCategory)
295 this._pieChart.addSlice(timeByCategory[color] / this._profiles.length, col or);
296 }
297
298 /**
299 * @param {number} value
300 * @return {string}
301 */
302 _formatPieChartTime(value) {
303 return Number.millisToString(value * 1000, true);
304 }
305
306 /**
307 * @return {?{left: number, right: number}}
308 */
309 selectionWindow() {
310 if (!this._log)
311 return null;
312
313 var screenLeft = this._selectionWindow.windowLeft * this._canvas.width;
314 var screenRight = this._selectionWindow.windowRight * this._canvas.width;
315 var barLeft = Math.floor(screenLeft / this._outerBarWidth);
316 var barRight = Math.floor((screenRight + this._innerBarWidth - this._barPadd ingWidth / 2) / this._outerBarWidth);
317 var stepLeft = Number.constrain(barLeft * this._samplesPerBar, 0, this._log. length - 1);
318 var stepRight = Number.constrain(barRight * this._samplesPerBar, 0, this._lo g.length);
319
320 return {left: stepLeft, right: stepRight};
321 }
322
323 _updateImage() {
324 delete this._updateImageTimer;
325 var left = null;
326 var right = null;
327 var window = this.selectionWindow();
328 if (this._profiles && this._profiles.length && window) {
329 left = this._log[window.left].commandIndex;
330 right = this._log[window.right - 1].commandIndex;
331 }
332 var scale = this._pendingScale;
333 this._snapshot.replay(left, right, scale).then(image => {
334 if (!image)
335 return;
336 this._scale = scale;
337 this._showImageCallback(image);
338 });
339 }
340
341 _reset() {
342 if (this._snapshot)
343 this._snapshot.release();
344 this._snapshot = null;
345 this._profiles = null;
346 this._selectionWindow.reset();
347 this._selectionWindow.setEnabled(false);
348 }
63 }; 349 };
64 350
65 /** @enum {symbol} */ 351 /** @enum {symbol} */
66 WebInspector.PaintProfilerView.Events = { 352 WebInspector.PaintProfilerView.Events = {
67 WindowChanged: Symbol("WindowChanged") 353 WindowChanged: Symbol('WindowChanged')
68 }; 354 };
69 355
70 WebInspector.PaintProfilerView.prototype = {
71 onResize: function()
72 {
73 this._update();
74 },
75
76 /**
77 * @param {?WebInspector.PaintProfilerSnapshot} snapshot
78 * @param {!Array.<!WebInspector.PaintProfilerLogItem>} log
79 * @param {?DOMAgent.Rect} clipRect
80 */
81 setSnapshotAndLog: function(snapshot, log, clipRect)
82 {
83 this._reset();
84 this._snapshot = snapshot;
85 if (this._snapshot)
86 this._snapshot.addReference();
87 this._log = log;
88 this._logCategories = this._log.map(WebInspector.PaintProfilerView._cate goryForLogItem);
89
90 if (!this._snapshot) {
91 this._update();
92 this._pieChart.setTotal(0);
93 this._selectionWindow.setEnabled(false);
94 return;
95 }
96 this._selectionWindow.setEnabled(true);
97 this._progressBanner.classList.remove("hidden");
98 this._updateImage();
99 snapshot.profile(clipRect, onProfileDone.bind(this));
100 /**
101 * @param {!Array.<!LayerTreeAgent.PaintProfile>=} profiles
102 * @this {WebInspector.PaintProfilerView}
103 */
104 function onProfileDone(profiles)
105 {
106 this._progressBanner.classList.add("hidden");
107 this._profiles = profiles;
108 this._update();
109 this._updatePieChart();
110 }
111 },
112
113 /**
114 * @param {number} scale
115 */
116 setScale: function(scale)
117 {
118 var needsUpdate = scale > this._scale;
119 var predictiveGrowthFactor = 2;
120 this._pendingScale = Math.min(1, scale * predictiveGrowthFactor);
121 if (needsUpdate && this._snapshot)
122 this._updateImage();
123 },
124
125 _update: function()
126 {
127 this._canvas.width = this._canvasContainer.clientWidth * window.devicePi xelRatio;
128 this._canvas.height = this._canvasContainer.clientHeight * window.device PixelRatio;
129 this._samplesPerBar = 0;
130 if (!this._profiles || !this._profiles.length)
131 return;
132
133 var maxBars = Math.floor((this._canvas.width - 2 * this._barPaddingWidth ) / this._outerBarWidth);
134 var sampleCount = this._log.length;
135 this._samplesPerBar = Math.ceil(sampleCount / maxBars);
136
137 var maxBarTime = 0;
138 var barTimes = [];
139 var barHeightByCategory = [];
140 var heightByCategory = {};
141 for (var i = 0, lastBarIndex = 0, lastBarTime = 0; i < sampleCount;) {
142 var categoryName = (this._logCategories[i] && this._logCategories[i] .name) || "misc";
143 var sampleIndex = this._log[i].commandIndex;
144 for (var row = 0; row < this._profiles.length; row++) {
145 var sample = this._profiles[row][sampleIndex];
146 lastBarTime += sample;
147 heightByCategory[categoryName] = (heightByCategory[categoryName] || 0) + sample;
148 }
149 ++i;
150 if (i - lastBarIndex === this._samplesPerBar || i === sampleCount) {
151 // Normalize by total number of samples accumulated.
152 var factor = this._profiles.length * (i - lastBarIndex);
153 lastBarTime /= factor;
154 for (categoryName in heightByCategory)
155 heightByCategory[categoryName] /= factor;
156
157 barTimes.push(lastBarTime);
158 barHeightByCategory.push(heightByCategory);
159
160 if (lastBarTime > maxBarTime)
161 maxBarTime = lastBarTime;
162 lastBarTime = 0;
163 heightByCategory = {};
164 lastBarIndex = i;
165 }
166 }
167
168 const paddingHeight = 4 * window.devicePixelRatio;
169 var scale = (this._canvas.height - paddingHeight - this._minBarHeight) / maxBarTime;
170 for (var i = 0; i < barTimes.length; ++i) {
171 for (var categoryName in barHeightByCategory[i])
172 barHeightByCategory[i][categoryName] *= (barTimes[i] * scale + t his._minBarHeight) / barTimes[i];
173 this._renderBar(i, barHeightByCategory[i]);
174 }
175 },
176
177 /**
178 * @param {number} index
179 * @param {!Object.<string, number>} heightByCategory
180 */
181 _renderBar: function(index, heightByCategory)
182 {
183 var categories = WebInspector.PaintProfilerView.categories();
184 var currentHeight = 0;
185 var x = this._barPaddingWidth + index * this._outerBarWidth;
186 for (var categoryName in categories) {
187 if (!heightByCategory[categoryName])
188 continue;
189 currentHeight += heightByCategory[categoryName];
190 var y = this._canvas.height - currentHeight;
191 this._context.fillStyle = categories[categoryName].color;
192 this._context.fillRect(x, y, this._innerBarWidth, heightByCategory[c ategoryName]);
193 }
194 },
195
196 _onWindowChanged: function()
197 {
198 this.dispatchEventToListeners(WebInspector.PaintProfilerView.Events.Wind owChanged);
199 this._updatePieChart();
200 if (this._updateImageTimer)
201 return;
202 this._updateImageTimer = setTimeout(this._updateImage.bind(this), 100);
203 },
204
205 _updatePieChart: function()
206 {
207 var window = this.selectionWindow();
208 if (!this._profiles || !this._profiles.length || !window)
209 return;
210 var totalTime = 0;
211 var timeByCategory = {};
212 for (var i = window.left; i < window.right; ++i) {
213 var logEntry = this._log[i];
214 var category = WebInspector.PaintProfilerView._categoryForLogItem(lo gEntry);
215 timeByCategory[category.color] = timeByCategory[category.color] || 0 ;
216 for (var j = 0; j < this._profiles.length; ++j) {
217 var time = this._profiles[j][logEntry.commandIndex];
218 totalTime += time;
219 timeByCategory[category.color] += time;
220 }
221 }
222 this._pieChart.setTotal(totalTime / this._profiles.length);
223 for (var color in timeByCategory)
224 this._pieChart.addSlice(timeByCategory[color] / this._profiles.lengt h, color);
225 },
226
227 /**
228 * @param {number} value
229 * @return {string}
230 */
231 _formatPieChartTime: function(value)
232 {
233 return Number.millisToString(value * 1000, true);
234 },
235
236 /**
237 * @return {?{left: number, right: number}}
238 */
239 selectionWindow: function()
240 {
241 if (!this._log)
242 return null;
243
244 var screenLeft = this._selectionWindow.windowLeft * this._canvas.width;
245 var screenRight = this._selectionWindow.windowRight * this._canvas.width ;
246 var barLeft = Math.floor(screenLeft / this._outerBarWidth);
247 var barRight = Math.floor((screenRight + this._innerBarWidth - this._bar PaddingWidth / 2) / this._outerBarWidth);
248 var stepLeft = Number.constrain(barLeft * this._samplesPerBar, 0, this._ log.length - 1);
249 var stepRight = Number.constrain(barRight * this._samplesPerBar, 0, this ._log.length);
250
251 return { left: stepLeft, right: stepRight };
252 },
253
254 _updateImage: function()
255 {
256 delete this._updateImageTimer;
257 var left = null;
258 var right = null;
259 var window = this.selectionWindow();
260 if (this._profiles && this._profiles.length && window) {
261 left = this._log[window.left].commandIndex;
262 right = this._log[window.right - 1].commandIndex;
263 }
264 var scale = this._pendingScale;
265 this._snapshot.replay(left, right, scale).then(image => {
266 if (!image)
267 return;
268 this._scale = scale;
269 this._showImageCallback(image);
270 });
271 },
272
273 _reset: function()
274 {
275 if (this._snapshot)
276 this._snapshot.release();
277 this._snapshot = null;
278 this._profiles = null;
279 this._selectionWindow.reset();
280 this._selectionWindow.setEnabled(false);
281 },
282
283 __proto__: WebInspector.HBox.prototype
284 };
285
286 /** 356 /**
287 * @constructor 357 * @unrestricted
288 * @extends {WebInspector.ThrottledWidget}
289 */ 358 */
290 WebInspector.PaintProfilerCommandLogView = function() 359 WebInspector.PaintProfilerCommandLogView = class extends WebInspector.ThrottledW idget {
291 { 360 constructor() {
292 WebInspector.ThrottledWidget.call(this); 361 super();
293 this.setMinimumSize(100, 25); 362 this.setMinimumSize(100, 25);
294 this.element.classList.add("overflow-auto"); 363 this.element.classList.add('overflow-auto');
295 364
296 this._treeOutline = new TreeOutlineInShadow(); 365 this._treeOutline = new TreeOutlineInShadow();
297 this.element.appendChild(this._treeOutline.element); 366 this.element.appendChild(this._treeOutline.element);
298 367
299 this._log = []; 368 this._log = [];
369 }
370
371 /**
372 * @param {?WebInspector.Target} target
373 * @param {!Array.<!WebInspector.PaintProfilerLogItem>} log
374 */
375 setCommandLog(target, log) {
376 this._target = target;
377 this._log = log;
378 /** @type {!Map<!WebInspector.PaintProfilerLogItem>} */
379 this._treeItemCache = new Map();
380 this.updateWindow({left: 0, right: this._log.length});
381 }
382
383 /**
384 * @param {!WebInspector.PaintProfilerLogItem} logItem
385 */
386 _appendLogItem(logItem) {
387 var treeElement = this._treeItemCache.get(logItem);
388 if (!treeElement) {
389 treeElement = new WebInspector.LogTreeElement(this, logItem);
390 this._treeItemCache.set(logItem, treeElement);
391 } else if (treeElement.parent) {
392 return;
393 }
394 this._treeOutline.appendChild(treeElement);
395 }
396
397 /**
398 * @param {?{left: number, right: number}} selectionWindow
399 */
400 updateWindow(selectionWindow) {
401 this._selectionWindow = selectionWindow;
402 this.update();
403 }
404
405 /**
406 * @override
407 * @return {!Promise<*>}
408 */
409 doUpdate() {
410 if (!this._selectionWindow || !this._log.length) {
411 this._treeOutline.removeChildren();
412 return Promise.resolve();
413 }
414 var root = this._treeOutline.rootElement();
415 for (;;) {
416 var child = root.firstChild();
417 if (!child || child._logItem.commandIndex >= this._selectionWindow.left)
418 break;
419 root.removeChildAtIndex(0);
420 }
421 for (;;) {
422 var child = root.lastChild();
423 if (!child || child._logItem.commandIndex < this._selectionWindow.right)
424 break;
425 root.removeChildAtIndex(root.children().length - 1);
426 }
427 for (var i = this._selectionWindow.left, right = this._selectionWindow.right ; i < right; ++i)
428 this._appendLogItem(this._log[i]);
429 return Promise.resolve();
430 }
300 }; 431 };
301 432
302 WebInspector.PaintProfilerCommandLogView.prototype = {
303 /**
304 * @param {?WebInspector.Target} target
305 * @param {!Array.<!WebInspector.PaintProfilerLogItem>} log
306 */
307 setCommandLog: function(target, log)
308 {
309 this._target = target;
310 this._log = log;
311 /** @type {!Map<!WebInspector.PaintProfilerLogItem>} */
312 this._treeItemCache = new Map();
313 this.updateWindow({left: 0, right: this._log.length});
314 },
315
316 /**
317 * @param {!WebInspector.PaintProfilerLogItem} logItem
318 */
319 _appendLogItem: function(logItem)
320 {
321 var treeElement = this._treeItemCache.get(logItem);
322 if (!treeElement) {
323 treeElement = new WebInspector.LogTreeElement(this, logItem);
324 this._treeItemCache.set(logItem, treeElement);
325 } else if (treeElement.parent) {
326 return;
327 }
328 this._treeOutline.appendChild(treeElement);
329 },
330
331 /**
332 * @param {?{left: number, right: number}} selectionWindow
333 */
334 updateWindow: function(selectionWindow)
335 {
336 this._selectionWindow = selectionWindow;
337 this.update();
338 },
339
340 /**
341 * @override
342 * @return {!Promise<*>}
343 */
344 doUpdate: function()
345 {
346 if (!this._selectionWindow || !this._log.length) {
347 this._treeOutline.removeChildren();
348 return Promise.resolve();
349 }
350 var root = this._treeOutline.rootElement();
351 for (;;) {
352 var child = root.firstChild();
353 if (!child || child._logItem.commandIndex >= this._selectionWindow.l eft)
354 break;
355 root.removeChildAtIndex(0);
356 }
357 for (;;) {
358 var child = root.lastChild();
359 if (!child || child._logItem.commandIndex < this._selectionWindow.ri ght)
360 break;
361 root.removeChildAtIndex(root.children().length - 1);
362 }
363 for (var i = this._selectionWindow.left, right = this._selectionWindow.r ight; i < right; ++i)
364 this._appendLogItem(this._log[i]);
365 return Promise.resolve();
366 },
367
368 __proto__: WebInspector.ThrottledWidget.prototype
369 };
370
371 /** 433 /**
372 * @constructor 434 * @unrestricted
373 * @param {!WebInspector.PaintProfilerCommandLogView} ownerView 435 */
374 * @param {!WebInspector.PaintProfilerLogItem} logItem 436 WebInspector.LogTreeElement = class extends TreeElement {
375 * @extends {TreeElement} 437 /**
376 */ 438 * @param {!WebInspector.PaintProfilerCommandLogView} ownerView
377 WebInspector.LogTreeElement = function(ownerView, logItem) 439 * @param {!WebInspector.PaintProfilerLogItem} logItem
378 { 440 */
379 TreeElement.call(this, "", !!logItem.params); 441 constructor(ownerView, logItem) {
442 super('', !!logItem.params);
380 this._logItem = logItem; 443 this._logItem = logItem;
381 this._ownerView = ownerView; 444 this._ownerView = ownerView;
382 this._filled = false; 445 this._filled = false;
446 }
447
448 /**
449 * @override
450 */
451 onattach() {
452 this._update();
453 }
454
455 /**
456 * @override
457 */
458 onpopulate() {
459 for (var param in this._logItem.params)
460 WebInspector.LogPropertyTreeElement._appendLogPropertyItem(this, param, th is._logItem.params[param]);
461 }
462
463 /**
464 * @param {*} param
465 * @param {string} name
466 * @return {string}
467 */
468 _paramToString(param, name) {
469 if (typeof param !== 'object')
470 return typeof param === 'string' && param.length > 100 ? name : JSON.strin gify(param);
471 var str = '';
472 var keyCount = 0;
473 for (var key in param) {
474 if (++keyCount > 4 || typeof param[key] === 'object' ||
475 (typeof param[key] === 'string' && param[key].length > 100))
476 return name;
477 if (str)
478 str += ', ';
479 str += param[key];
480 }
481 return str;
482 }
483
484 /**
485 * @param {?Object<string, *>} params
486 * @return {string}
487 */
488 _paramsToString(params) {
489 var str = '';
490 for (var key in params) {
491 if (str)
492 str += ', ';
493 str += this._paramToString(params[key], key);
494 }
495 return str;
496 }
497
498 _update() {
499 var title = createDocumentFragment();
500 title.createTextChild(this._logItem.method + '(' + this._paramsToString(this ._logItem.params) + ')');
501 this.title = title;
502 }
383 }; 503 };
384 504
385 WebInspector.LogTreeElement.prototype = {
386 onattach: function()
387 {
388 this._update();
389 },
390
391 onpopulate: function()
392 {
393 for (var param in this._logItem.params)
394 WebInspector.LogPropertyTreeElement._appendLogPropertyItem(this, par am, this._logItem.params[param]);
395 },
396
397 /**
398 * @param {*} param
399 * @param {string} name
400 * @return {string}
401 */
402 _paramToString: function(param, name)
403 {
404 if (typeof param !== "object")
405 return typeof param === "string" && param.length > 100 ? name : JSON .stringify(param);
406 var str = "";
407 var keyCount = 0;
408 for (var key in param) {
409 if (++keyCount > 4 || typeof param[key] === "object" || (typeof para m[key] === "string" && param[key].length > 100))
410 return name;
411 if (str)
412 str += ", ";
413 str += param[key];
414 }
415 return str;
416 },
417
418 /**
419 * @param {?Object<string, *>} params
420 * @return {string}
421 */
422 _paramsToString: function(params)
423 {
424 var str = "";
425 for (var key in params) {
426 if (str)
427 str += ", ";
428 str += this._paramToString(params[key], key);
429 }
430 return str;
431 },
432
433 _update: function()
434 {
435 var title = createDocumentFragment();
436 title.createTextChild(this._logItem.method + "(" + this._paramsToString( this._logItem.params) + ")");
437 this.title = title;
438 },
439
440 __proto__: TreeElement.prototype
441 };
442
443 /** 505 /**
444 * @constructor 506 * @unrestricted
445 * @param {!{name: string, value}} property 507 */
446 * @extends {TreeElement} 508 WebInspector.LogPropertyTreeElement = class extends TreeElement {
447 */ 509 /**
448 WebInspector.LogPropertyTreeElement = function(property) 510 * @param {!{name: string, value}} property
449 { 511 */
450 TreeElement.call(this); 512 constructor(property) {
513 super();
451 this._property = property; 514 this._property = property;
452 }; 515 }
453 516
454 /** 517 /**
455 * @param {!TreeElement} element 518 * @param {!TreeElement} element
456 * @param {string} name 519 * @param {string} name
457 * @param {*} value 520 * @param {*} value
458 */ 521 */
459 WebInspector.LogPropertyTreeElement._appendLogPropertyItem = function(element, n ame, value) 522 static _appendLogPropertyItem(element, name, value) {
460 {
461 var treeElement = new WebInspector.LogPropertyTreeElement({name: name, value : value}); 523 var treeElement = new WebInspector.LogPropertyTreeElement({name: name, value : value});
462 element.appendChild(treeElement); 524 element.appendChild(treeElement);
463 if (value && typeof value === "object") { 525 if (value && typeof value === 'object') {
464 for (var property in value) 526 for (var property in value)
465 WebInspector.LogPropertyTreeElement._appendLogPropertyItem(treeEleme nt, property, value[property]); 527 WebInspector.LogPropertyTreeElement._appendLogPropertyItem(treeElement, property, value[property]);
466 } 528 }
529 }
530
531 /**
532 * @override
533 */
534 onattach() {
535 var title = createDocumentFragment();
536 var nameElement = title.createChild('span', 'name');
537 nameElement.textContent = this._property.name;
538 var separatorElement = title.createChild('span', 'separator');
539 separatorElement.textContent = ': ';
540 if (this._property.value === null || typeof this._property.value !== 'object ') {
541 var valueElement = title.createChild('span', 'value');
542 valueElement.textContent = JSON.stringify(this._property.value);
543 valueElement.classList.add('cm-js-' + (this._property.value === null ? 'nu ll' : typeof this._property.value));
544 }
545 this.title = title;
546 }
467 }; 547 };
468 548
469 WebInspector.LogPropertyTreeElement.prototype = {
470 onattach: function()
471 {
472 var title = createDocumentFragment();
473 var nameElement = title.createChild("span", "name");
474 nameElement.textContent = this._property.name;
475 var separatorElement = title.createChild("span", "separator");
476 separatorElement.textContent = ": ";
477 if (this._property.value === null || typeof this._property.value !== "ob ject") {
478 var valueElement = title.createChild("span", "value");
479 valueElement.textContent = JSON.stringify(this._property.value);
480 valueElement.classList.add("cm-js-" + (this._property.value === null ? "null" : typeof this._property.value));
481 }
482 this.title = title;
483 },
484
485 __proto__: TreeElement.prototype
486 };
487 549
488 /** 550 /**
489 * @return {!Object.<string, !WebInspector.PaintProfilerCategory>} 551 * @unrestricted
490 */ 552 */
491 WebInspector.PaintProfilerView.categories = function() 553 WebInspector.PaintProfilerCategory = class {
492 { 554 /**
493 if (WebInspector.PaintProfilerView._categories) 555 * @param {string} name
494 return WebInspector.PaintProfilerView._categories; 556 * @param {string} title
495 WebInspector.PaintProfilerView._categories = { 557 * @param {string} color
496 shapes: new WebInspector.PaintProfilerCategory("shapes", WebInspector.UI String("Shapes"), "rgb(255, 161, 129)"), 558 */
497 bitmap: new WebInspector.PaintProfilerCategory("bitmap", WebInspector.UI String("Bitmap"), "rgb(136, 196, 255)"), 559 constructor(name, title, color) {
498 text: new WebInspector.PaintProfilerCategory("text", WebInspector.UIStri ng("Text"), "rgb(180, 255, 137)"),
499 misc: new WebInspector.PaintProfilerCategory("misc", WebInspector.UIStri ng("Misc"), "rgb(206, 160, 255)")
500 };
501 return WebInspector.PaintProfilerView._categories;
502 };
503
504 /**
505 * @constructor
506 * @param {string} name
507 * @param {string} title
508 * @param {string} color
509 */
510 WebInspector.PaintProfilerCategory = function(name, title, color)
511 {
512 this.name = name; 560 this.name = name;
513 this.title = title; 561 this.title = title;
514 this.color = color; 562 this.color = color;
563 }
515 }; 564 };
516 565
517 /** 566
518 * @return {!Object.<string, !WebInspector.PaintProfilerCategory>}
519 */
520 WebInspector.PaintProfilerView._initLogItemCategories = function()
521 {
522 if (WebInspector.PaintProfilerView._logItemCategoriesMap)
523 return WebInspector.PaintProfilerView._logItemCategoriesMap;
524
525 var categories = WebInspector.PaintProfilerView.categories();
526
527 var logItemCategories = {};
528 logItemCategories["Clear"] = categories["misc"];
529 logItemCategories["DrawPaint"] = categories["misc"];
530 logItemCategories["DrawData"] = categories["misc"];
531 logItemCategories["SetMatrix"] = categories["misc"];
532 logItemCategories["PushCull"] = categories["misc"];
533 logItemCategories["PopCull"] = categories["misc"];
534 logItemCategories["Translate"] = categories["misc"];
535 logItemCategories["Scale"] = categories["misc"];
536 logItemCategories["Concat"] = categories["misc"];
537 logItemCategories["Restore"] = categories["misc"];
538 logItemCategories["SaveLayer"] = categories["misc"];
539 logItemCategories["Save"] = categories["misc"];
540 logItemCategories["BeginCommentGroup"] = categories["misc"];
541 logItemCategories["AddComment"] = categories["misc"];
542 logItemCategories["EndCommentGroup"] = categories["misc"];
543 logItemCategories["ClipRect"] = categories["misc"];
544 logItemCategories["ClipRRect"] = categories["misc"];
545 logItemCategories["ClipPath"] = categories["misc"];
546 logItemCategories["ClipRegion"] = categories["misc"];
547 logItemCategories["DrawPoints"] = categories["shapes"];
548 logItemCategories["DrawRect"] = categories["shapes"];
549 logItemCategories["DrawOval"] = categories["shapes"];
550 logItemCategories["DrawRRect"] = categories["shapes"];
551 logItemCategories["DrawPath"] = categories["shapes"];
552 logItemCategories["DrawVertices"] = categories["shapes"];
553 logItemCategories["DrawDRRect"] = categories["shapes"];
554 logItemCategories["DrawBitmap"] = categories["bitmap"];
555 logItemCategories["DrawBitmapRectToRect"] = categories["bitmap"];
556 logItemCategories["DrawBitmapMatrix"] = categories["bitmap"];
557 logItemCategories["DrawBitmapNine"] = categories["bitmap"];
558 logItemCategories["DrawSprite"] = categories["bitmap"];
559 logItemCategories["DrawPicture"] = categories["bitmap"];
560 logItemCategories["DrawText"] = categories["text"];
561 logItemCategories["DrawPosText"] = categories["text"];
562 logItemCategories["DrawPosTextH"] = categories["text"];
563 logItemCategories["DrawTextOnPath"] = categories["text"];
564
565 WebInspector.PaintProfilerView._logItemCategoriesMap = logItemCategories;
566 return logItemCategories;
567 };
568
569 /**
570 * @param {!Object} logItem
571 * @return {!WebInspector.PaintProfilerCategory}
572 */
573 WebInspector.PaintProfilerView._categoryForLogItem = function(logItem)
574 {
575 var method = logItem.method.toTitleCase();
576
577 var logItemCategories = WebInspector.PaintProfilerView._initLogItemCategorie s();
578 var result = logItemCategories[method];
579 if (!result) {
580 result = WebInspector.PaintProfilerView.categories()["misc"];
581 logItemCategories[method] = result;
582 }
583 return result;
584 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698