OLD | NEW |
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 12 matching lines...) Expand all Loading... |
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 | 30 |
31 /** | 31 /** |
32 * @constructor | 32 * @constructor |
33 * @param {!WebInspector.LayerTreeModel} model | 33 * @param {function(string=)} showImageCallback |
34 * @param {!WebInspector.Layers3DView} layers3DView | 34 * @extends {WebInspector.HBox} |
35 * @extends {WebInspector.SplitView} | |
36 */ | 35 */ |
37 WebInspector.PaintProfilerView = function(model, layers3DView) | 36 WebInspector.PaintProfilerView = function(showImageCallback) |
38 { | 37 { |
39 WebInspector.SplitView.call(this, true, false); | 38 WebInspector.View.call(this); |
40 this.element.classList.add("paint-profiler-view"); | 39 this.element.classList.add("paint-profiler-view"); |
41 this._logTreeView = new WebInspector.PaintProfilerCommandLogView(); | |
42 this._logTreeView.show(this.sidebarElement()); | |
43 this.addEventListener(WebInspector.SplitView.Events.SidebarSizeChanged, this
.onResize, this); | |
44 | 40 |
45 this._model = model; | 41 this._showImageCallback = showImageCallback; |
46 this._layers3DView = layers3DView; | |
47 | 42 |
48 this._canvas = this.mainElement().createChild("canvas", "fill"); | 43 this._canvas = this.element.createChild("canvas", "fill"); |
49 this._context = this._canvas.getContext("2d"); | 44 this._context = this._canvas.getContext("2d"); |
50 this._selectionWindow = new WebInspector.OverviewGrid.Window(this.mainElemen
t(), this.mainElement()); | 45 this._selectionWindow = new WebInspector.OverviewGrid.Window(this.element, t
his.element); |
51 this._selectionWindow.addEventListener(WebInspector.OverviewGrid.Events.Wind
owChanged, this._onWindowChanged, this); | 46 this._selectionWindow.addEventListener(WebInspector.OverviewGrid.Events.Wind
owChanged, this._onWindowChanged, this); |
52 | 47 |
53 this._innerBarWidth = 4 * window.devicePixelRatio; | 48 this._innerBarWidth = 4 * window.devicePixelRatio; |
54 this._minBarHeight = 4 * window.devicePixelRatio; | 49 this._minBarHeight = 4 * window.devicePixelRatio; |
55 this._barPaddingWidth = 2 * window.devicePixelRatio; | 50 this._barPaddingWidth = 2 * window.devicePixelRatio; |
56 this._outerBarWidth = this._innerBarWidth + this._barPaddingWidth; | 51 this._outerBarWidth = this._innerBarWidth + this._barPaddingWidth; |
57 | 52 |
58 this._reset(); | 53 this._reset(); |
59 } | 54 } |
60 | 55 |
| 56 WebInspector.PaintProfilerView.Events = { |
| 57 WindowChanged: "WindowChanged" |
| 58 }; |
| 59 |
61 WebInspector.PaintProfilerView.prototype = { | 60 WebInspector.PaintProfilerView.prototype = { |
62 onResize: function() | 61 onResize: function() |
63 { | 62 { |
64 this._update(); | 63 this._update(); |
65 }, | 64 }, |
66 | 65 |
| 66 /** |
| 67 * @param {?WebInspector.PaintProfilerSnapshot} snapshot |
| 68 */ |
| 69 setSnapshot: function(snapshot) |
| 70 { |
| 71 this._reset(); |
| 72 this._snapshot = snapshot; |
| 73 if (!this._snapshot) { |
| 74 this._update(); |
| 75 return; |
| 76 } |
| 77 snapshot.requestImage(null, null, this._showImageCallback); |
| 78 snapshot.profile(onProfileDone.bind(this)); |
| 79 /** |
| 80 * @param {!Array.<!LayerTreeAgent.PaintProfile>=} profiles |
| 81 * @this {WebInspector.PaintProfilerView} |
| 82 */ |
| 83 function onProfileDone(profiles) |
| 84 { |
| 85 this._profiles = profiles; |
| 86 this._update(); |
| 87 } |
| 88 }, |
| 89 |
67 _update: function() | 90 _update: function() |
68 { | 91 { |
69 this._canvas.width = this.mainElement().clientWidth * window.devicePixel
Ratio; | 92 this._canvas.width = this.element.clientWidth * window.devicePixelRatio; |
70 this._canvas.height = this.mainElement().clientHeight * window.devicePix
elRatio; | 93 this._canvas.height = this.element.clientHeight * window.devicePixelRati
o; |
71 this._samplesPerBar = 0; | 94 this._samplesPerBar = 0; |
72 if (!this._profiles || !this._profiles.length) | 95 if (!this._profiles || !this._profiles.length) |
73 return; | 96 return; |
74 | 97 |
75 var maxBars = Math.floor((this._canvas.width - 2 * this._barPaddingWidth
) / this._outerBarWidth); | 98 var maxBars = Math.floor((this._canvas.width - 2 * this._barPaddingWidth
) / this._outerBarWidth); |
76 var sampleCount = this._profiles[0].length; | 99 var sampleCount = this._profiles[0].length; |
77 this._samplesPerBar = Math.ceil(sampleCount / maxBars); | 100 this._samplesPerBar = Math.ceil(sampleCount / maxBars); |
78 var barCount = Math.floor(sampleCount / this._samplesPerBar); | 101 var barCount = Math.floor(sampleCount / this._samplesPerBar); |
79 | 102 |
80 var maxBarTime = 0; | 103 var maxBarTime = 0; |
(...skipping 28 matching lines...) Expand all Loading... |
109 var x = this._barPaddingWidth + index * this._outerBarWidth; | 132 var x = this._barPaddingWidth + index * this._outerBarWidth; |
110 var y = this._canvas.height - height; | 133 var y = this._canvas.height - height; |
111 this._context.fillRect(x, y, this._innerBarWidth, height); | 134 this._context.fillRect(x, y, this._innerBarWidth, height); |
112 }, | 135 }, |
113 | 136 |
114 _onWindowChanged: function() | 137 _onWindowChanged: function() |
115 { | 138 { |
116 if (this._updateImageTimer) | 139 if (this._updateImageTimer) |
117 return; | 140 return; |
118 this._updateImageTimer = setTimeout(this._updateImage.bind(this), 100); | 141 this._updateImageTimer = setTimeout(this._updateImage.bind(this), 100); |
| 142 this.dispatchEventToListeners(WebInspector.PaintProfilerView.Events.Wind
owChanged); |
| 143 }, |
| 144 |
| 145 /** |
| 146 * @return {{left: number, right: number}} |
| 147 */ |
| 148 windowBoundaries: function() |
| 149 { |
| 150 var screenLeft = this._selectionWindow.windowLeft * this._canvas.width; |
| 151 var screenRight = this._selectionWindow.windowRight * this._canvas.width
; |
| 152 var barLeft = Math.floor((screenLeft - this._barPaddingWidth) / this._ou
terBarWidth); |
| 153 var barRight = Math.floor((screenRight - this._barPaddingWidth + this._i
nnerBarWidth)/ this._outerBarWidth); |
| 154 var stepLeft = Math.max(0, barLeft * this._samplesPerBar); |
| 155 var stepRight = Math.min(barRight * this._samplesPerBar, this._profiles[
0].length); |
| 156 |
| 157 return {left: stepLeft, right: stepRight}; |
119 }, | 158 }, |
120 | 159 |
121 _updateImage: function() | 160 _updateImage: function() |
122 { | 161 { |
123 delete this._updateImageTimer; | 162 delete this._updateImageTimer; |
124 if (!this._profiles || !this._profiles.length) | 163 if (!this._profiles || !this._profiles.length) |
125 return; | 164 return; |
126 | 165 |
127 var screenLeft = this._selectionWindow.windowLeft * this._canvas.width; | 166 var window = this.windowBoundaries(); |
128 var screenRight = this._selectionWindow.windowRight * this._canvas.width
; | 167 this._snapshot.requestImage(window.left, window.right, this._showImageCa
llback); |
129 | |
130 var barLeft = Math.floor((screenLeft - this._barPaddingWidth) / this._ou
terBarWidth); | |
131 var barRight = Math.floor((screenRight - this._barPaddingWidth + this._i
nnerBarWidth)/ this._outerBarWidth); | |
132 | |
133 var stepLeft = Math.max(0, barLeft * this._samplesPerBar); | |
134 var stepRight = Math.min(barRight * this._samplesPerBar, this._profiles[
0].length); | |
135 this._snapshot.requestImage(stepLeft, stepRight, this._layers3DView.show
ImageForLayer.bind(this._layers3DView, this._layer)); | |
136 this._logTreeView.updateLog(stepLeft, stepRight); | |
137 }, | 168 }, |
138 | 169 |
139 _reset: function() | 170 _reset: function() |
140 { | 171 { |
141 this._snapshot = null; | 172 this._snapshot = null; |
142 this._profiles = null; | 173 this._profiles = null; |
143 this._selectionWindow.reset(); | 174 this._selectionWindow.reset(); |
144 }, | 175 }, |
145 | 176 |
146 /** | 177 __proto__: WebInspector.HBox.prototype |
147 * @param {!WebInspector.Layer} layer | |
148 */ | |
149 profile: function(layer) | |
150 { | |
151 this._reset(); | |
152 this._layer = layer; | |
153 this._layer.requestSnapshot(onSnapshotDone.bind(this)); | |
154 | |
155 /** | |
156 * @param {!WebInspector.PaintProfilerSnapshot=} snapshot | |
157 * @this {WebInspector.PaintProfilerView} | |
158 */ | |
159 function onSnapshotDone(snapshot) | |
160 { | |
161 this._snapshot = snapshot; | |
162 if (!snapshot) { | |
163 this._profiles = null; | |
164 this._update(); | |
165 return; | |
166 } | |
167 snapshot.requestImage(null, null, this._layers3DView.showImageForLay
er.bind(this._layers3DView, this._layer)); | |
168 var barrier = new CallbackBarrier(); | |
169 snapshot.profile(barrier.createCallback(onProfileDone.bind(this))); | |
170 snapshot.commandLog(barrier.createCallback(onCommandLogDone.bind(thi
s))); | |
171 barrier.callWhenDone(this._update.bind(this)); | |
172 } | |
173 | |
174 /** | |
175 * @param {!Array.<!LayerTreeAgent.PaintProfile>=} profiles | |
176 * @this {WebInspector.PaintProfilerView} | |
177 */ | |
178 function onProfileDone(profiles) | |
179 { | |
180 this._profiles = profiles; | |
181 } | |
182 | |
183 /** | |
184 * @param {!Array.<!Object>=} log | |
185 * @this {WebInspector.PaintProfilerView} | |
186 */ | |
187 function onCommandLogDone(log) | |
188 { | |
189 this._logTreeView.setLog(log); | |
190 this._logTreeView.updateLog(); | |
191 } | |
192 }, | |
193 | |
194 __proto__: WebInspector.SplitView.prototype | |
195 }; | 178 }; |
196 | 179 |
197 /** | 180 /** |
198 * @constructor | 181 * @constructor |
199 * @extends {WebInspector.VBox} | 182 * @extends {WebInspector.VBox} |
200 */ | 183 */ |
201 WebInspector.PaintProfilerCommandLogView = function() | 184 WebInspector.PaintProfilerCommandLogView = function() |
202 { | 185 { |
203 WebInspector.VBox.call(this); | 186 WebInspector.VBox.call(this); |
204 this.setMinimumSize(100, 25); | 187 this.setMinimumSize(100, 25); |
205 this.element.classList.add("outline-disclosure"); | 188 this.element.classList.add("outline-disclosure"); |
206 var sidebarTreeElement = this.element.createChild("ol", "sidebar-tree"); | 189 var sidebarTreeElement = this.element.createChild("ol", "sidebar-tree"); |
207 this.sidebarTree = new TreeOutline(sidebarTreeElement); | 190 this.sidebarTree = new TreeOutline(sidebarTreeElement); |
208 this._popoverHelper = new WebInspector.ObjectPopoverHelper(this.element, thi
s._getHoverAnchor.bind(this), this._resolveObjectForPopover.bind(this), undefine
d, true); | 191 this._popoverHelper = new WebInspector.ObjectPopoverHelper(this.element, thi
s._getHoverAnchor.bind(this), this._resolveObjectForPopover.bind(this), undefine
d, true); |
209 | 192 this._reset(); |
210 this._log = []; | |
211 } | 193 } |
212 | 194 |
213 WebInspector.PaintProfilerCommandLogView.prototype = { | 195 WebInspector.PaintProfilerCommandLogView.prototype = { |
214 setLog: function(log) | 196 /** |
| 197 * @param {?WebInspector.PaintProfilerSnapshot} snapshot |
| 198 */ |
| 199 setSnapshot: function(snapshot) |
215 { | 200 { |
216 this._log = log; | 201 this._reset(); |
| 202 if (!snapshot) { |
| 203 this.updateWindow(); |
| 204 return; |
| 205 } |
| 206 snapshot.commandLog(onCommandLogDone.bind(this)); |
| 207 |
| 208 /** |
| 209 * @param {!Array.<!Object>=} log |
| 210 * @this {WebInspector.PaintProfilerCommandLogView} |
| 211 */ |
| 212 function onCommandLogDone(log) |
| 213 { |
| 214 this._log = log; |
| 215 this.updateWindow(); |
| 216 } |
217 }, | 217 }, |
218 | 218 |
219 /** | 219 /** |
220 * @param {number=} stepLeft | 220 * @param {number=} stepLeft |
221 * @param {number=} stepRight | 221 * @param {number=} stepRight |
222 */ | 222 */ |
223 updateLog: function(stepLeft, stepRight) | 223 updateWindow: function(stepLeft, stepRight) |
224 { | 224 { |
225 var log = this._log; | 225 var log = this._log; |
226 stepLeft = stepLeft || 0; | 226 stepLeft = stepLeft || 0; |
227 stepRight = stepRight || log.length - 1; | 227 stepRight = stepRight || log.length - 1; |
228 this.sidebarTree.removeChildren(); | 228 this.sidebarTree.removeChildren(); |
229 for (var i = stepLeft; i <= stepRight; ++i) { | 229 for (var i = stepLeft; i <= stepRight; ++i) { |
230 var node = new WebInspector.LogTreeElement(log[i]); | 230 var node = new WebInspector.LogTreeElement(log[i]); |
231 this.sidebarTree.appendChild(node); | 231 this.sidebarTree.appendChild(node); |
232 } | 232 } |
233 }, | 233 }, |
234 | 234 |
| 235 _reset: function() |
| 236 { |
| 237 this._log = []; |
| 238 }, |
| 239 |
235 /** | 240 /** |
236 * @param {!Element} target | 241 * @param {!Element} target |
237 * @return {!Element} | 242 * @return {!Element} |
238 */ | 243 */ |
239 _getHoverAnchor: function(target) | 244 _getHoverAnchor: function(target) |
240 { | 245 { |
241 return /** @type {!Element} */ (target.enclosingNodeOrSelfWithNodeName("
span")); | 246 return /** @type {!Element} */ (target.enclosingNodeOrSelfWithNodeName("
span")); |
242 }, | 247 }, |
243 | 248 |
244 /** | 249 /** |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 /** | 327 /** |
323 * @param {boolean} hovered | 328 * @param {boolean} hovered |
324 */ | 329 */ |
325 setHovered: function(hovered) | 330 setHovered: function(hovered) |
326 { | 331 { |
327 this.listItemElement.classList.toggle("hovered", hovered); | 332 this.listItemElement.classList.toggle("hovered", hovered); |
328 }, | 333 }, |
329 | 334 |
330 __proto__: TreeElement.prototype | 335 __proto__: TreeElement.prototype |
331 }; | 336 }; |
OLD | NEW |