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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineFrameModel.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(!WebInspector.TracingModel.Event):string} categoryMapper
34 */ 32 */
35 WebInspector.TimelineFrameModel = function(categoryMapper) 33 WebInspector.TimelineFrameModel = class {
36 { 34 /**
35 * @param {function(!WebInspector.TracingModel.Event):string} categoryMapper
36 */
37 constructor(categoryMapper) {
37 this._categoryMapper = categoryMapper; 38 this._categoryMapper = categoryMapper;
38 this.reset(); 39 this.reset();
40 }
41
42 /**
43 * @return {!Array.<!WebInspector.TimelineFrame>}
44 */
45 frames() {
46 return this._frames;
47 }
48
49 /**
50 * @param {number} startTime
51 * @param {number} endTime
52 * @return {!Array.<!WebInspector.TimelineFrame>}
53 */
54 filteredFrames(startTime, endTime) {
55 /**
56 * @param {number} value
57 * @param {!WebInspector.TimelineFrame} object
58 * @return {number}
59 */
60 function compareStartTime(value, object) {
61 return value - object.startTime;
62 }
63 /**
64 * @param {number} value
65 * @param {!WebInspector.TimelineFrame} object
66 * @return {number}
67 */
68 function compareEndTime(value, object) {
69 return value - object.endTime;
70 }
71 var frames = this._frames;
72 var firstFrame = frames.lowerBound(startTime, compareEndTime);
73 var lastFrame = frames.lowerBound(endTime, compareStartTime);
74 return frames.slice(firstFrame, lastFrame);
75 }
76
77 /**
78 * @param {!WebInspector.TracingModel.Event} rasterTask
79 * @return {boolean}
80 */
81 hasRasterTile(rasterTask) {
82 var data = rasterTask.args['tileData'];
83 if (!data)
84 return false;
85 var frameId = data['sourceFrameNumber'];
86 var frame = frameId && this._frameById[frameId];
87 if (!frame || !frame.layerTree)
88 return false;
89 return true;
90 }
91
92 /**
93 * @param {!WebInspector.TracingModel.Event} rasterTask
94 * @return Promise<?{rect: !DOMAgent.Rect, snapshot: !WebInspector.PaintProfil erSnapshot}>}
95 */
96 rasterTilePromise(rasterTask) {
97 if (!this._target)
98 return Promise.resolve(null);
99 var data = rasterTask.args['tileData'];
100 var frameId = data['sourceFrameNumber'];
101 var tileId = data['tileId'] && data['tileId']['id_ref'];
102 var frame = frameId && this._frameById[frameId];
103 if (!frame || !frame.layerTree || !tileId)
104 return Promise.resolve(null);
105
106 return frame.layerTree.layerTreePromise().then(layerTree => layerTree && lay erTree.pictureForRasterTile(tileId));
107 }
108
109 reset() {
110 this._minimumRecordTime = Infinity;
111 this._frames = [];
112 this._frameById = {};
113 this._lastFrame = null;
114 this._lastLayerTree = null;
115 this._mainFrameCommitted = false;
116 this._mainFrameRequested = false;
117 this._framePendingCommit = null;
118 this._lastBeginFrame = null;
119 this._lastNeedsBeginFrame = null;
120 this._framePendingActivation = null;
121 this._lastTaskBeginTime = null;
122 this._target = null;
123 this._sessionId = null;
124 this._currentTaskTimeByCategory = {};
125 }
126
127 /**
128 * @param {number} startTime
129 */
130 handleBeginFrame(startTime) {
131 if (!this._lastFrame)
132 this._startFrame(startTime);
133 this._lastBeginFrame = startTime;
134 }
135
136 /**
137 * @param {number} startTime
138 */
139 handleDrawFrame(startTime) {
140 if (!this._lastFrame) {
141 this._startFrame(startTime);
142 return;
143 }
144
145 // - if it wasn't drawn, it didn't happen!
146 // - only show frames that either did not wait for the main thread frame or had one committed.
147 if (this._mainFrameCommitted || !this._mainFrameRequested) {
148 if (this._lastNeedsBeginFrame) {
149 var idleTimeEnd = this._framePendingActivation ? this._framePendingActiv ation.triggerTime :
150 (this._lastBeginFrame | | this._lastNeedsBeginFrame);
151 if (idleTimeEnd > this._lastFrame.startTime) {
152 this._lastFrame.idle = true;
153 this._startFrame(idleTimeEnd);
154 if (this._framePendingActivation)
155 this._commitPendingFrame();
156 this._lastBeginFrame = null;
157 }
158 this._lastNeedsBeginFrame = null;
159 }
160 this._startFrame(startTime);
161 }
162 this._mainFrameCommitted = false;
163 }
164
165 handleActivateLayerTree() {
166 if (!this._lastFrame)
167 return;
168 if (this._framePendingActivation && !this._lastNeedsBeginFrame)
169 this._commitPendingFrame();
170 }
171
172 handleRequestMainThreadFrame() {
173 if (!this._lastFrame)
174 return;
175 this._mainFrameRequested = true;
176 }
177
178 handleCompositeLayers() {
179 if (!this._framePendingCommit)
180 return;
181 this._framePendingActivation = this._framePendingCommit;
182 this._framePendingCommit = null;
183 this._mainFrameRequested = false;
184 this._mainFrameCommitted = true;
185 }
186
187 /**
188 * @param {!WebInspector.TracingFrameLayerTree} layerTree
189 */
190 handleLayerTreeSnapshot(layerTree) {
191 this._lastLayerTree = layerTree;
192 }
193
194 /**
195 * @param {number} startTime
196 * @param {boolean} needsBeginFrame
197 */
198 handleNeedFrameChanged(startTime, needsBeginFrame) {
199 if (needsBeginFrame)
200 this._lastNeedsBeginFrame = startTime;
201 }
202
203 /**
204 * @param {number} startTime
205 */
206 _startFrame(startTime) {
207 if (this._lastFrame)
208 this._flushFrame(this._lastFrame, startTime);
209 this._lastFrame = new WebInspector.TimelineFrame(startTime, startTime - this ._minimumRecordTime);
210 }
211
212 /**
213 * @param {!WebInspector.TimelineFrame} frame
214 * @param {number} endTime
215 */
216 _flushFrame(frame, endTime) {
217 frame._setLayerTree(this._lastLayerTree);
218 frame._setEndTime(endTime);
219 if (this._lastLayerTree)
220 this._lastLayerTree._setPaints(frame._paints);
221 if (this._frames.length && (frame.startTime !== this._frames.peekLast().endT ime || frame.startTime > frame.endTime))
222 console.assert(
223 false, `Inconsistent frame time for frame ${this._frames.length} (${fr ame.startTime} - ${frame.endTime})`);
224 this._frames.push(frame);
225 if (typeof frame._mainFrameId === 'number')
226 this._frameById[frame._mainFrameId] = frame;
227 }
228
229 _commitPendingFrame() {
230 this._lastFrame._addTimeForCategories(this._framePendingActivation.timeByCat egory);
231 this._lastFrame._paints = this._framePendingActivation.paints;
232 this._lastFrame._mainFrameId = this._framePendingActivation.mainFrameId;
233 this._framePendingActivation = null;
234 }
235
236 /**
237 * @param {!Array.<string>} types
238 * @param {!WebInspector.TimelineModel.Record} record
239 * @return {?WebInspector.TimelineModel.Record} record
240 */
241 _findRecordRecursively(types, record) {
242 if (types.indexOf(record.type()) >= 0)
243 return record;
244 if (!record.children())
245 return null;
246 for (var i = 0; i < record.children().length; ++i) {
247 var result = this._findRecordRecursively(types, record.children()[i]);
248 if (result)
249 return result;
250 }
251 return null;
252 }
253
254 /**
255 * @param {?WebInspector.Target} target
256 * @param {!Array.<!WebInspector.TracingModel.Event>} events
257 * @param {string} sessionId
258 */
259 addTraceEvents(target, events, sessionId) {
260 this._target = target;
261 this._sessionId = sessionId;
262 if (!events.length)
263 return;
264 if (events[0].startTime < this._minimumRecordTime)
265 this._minimumRecordTime = events[0].startTime;
266 for (var i = 0; i < events.length; ++i)
267 this._addTraceEvent(events[i]);
268 }
269
270 /**
271 * @param {!WebInspector.TracingModel.Event} event
272 */
273 _addTraceEvent(event) {
274 var eventNames = WebInspector.TimelineModel.RecordType;
275
276 if (event.name === eventNames.SetLayerTreeId) {
277 var sessionId = event.args['sessionId'] || event.args['data']['sessionId'] ;
278 if (this._sessionId === sessionId)
279 this._layerTreeId = event.args['layerTreeId'] || event.args['data']['lay erTreeId'];
280 } else if (event.name === eventNames.TracingStartedInPage) {
281 this._mainThread = event.thread;
282 } else if (
283 event.phase === WebInspector.TracingModel.Phase.SnapshotObject &&
284 event.name === eventNames.LayerTreeHostImplSnapshot && parseInt(event.id , 0) === this._layerTreeId) {
285 var snapshot = /** @type {!WebInspector.TracingModel.ObjectSnapshot} */ (e vent);
286 this.handleLayerTreeSnapshot(new WebInspector.TracingFrameLayerTree(this._ target, snapshot));
287 } else {
288 this._processCompositorEvents(event);
289 if (event.thread === this._mainThread)
290 this._addMainThreadTraceEvent(event);
291 else if (this._lastFrame && event.selfTime && !WebInspector.TracingModel.i sTopLevelEvent(event))
292 this._lastFrame._addTimeForCategory(this._categoryMapper(event), event.s elfTime);
293 }
294 }
295
296 /**
297 * @param {!WebInspector.TracingModel.Event} event
298 */
299 _processCompositorEvents(event) {
300 var eventNames = WebInspector.TimelineModel.RecordType;
301
302 if (event.args['layerTreeId'] !== this._layerTreeId)
303 return;
304
305 var timestamp = event.startTime;
306 if (event.name === eventNames.BeginFrame)
307 this.handleBeginFrame(timestamp);
308 else if (event.name === eventNames.DrawFrame)
309 this.handleDrawFrame(timestamp);
310 else if (event.name === eventNames.ActivateLayerTree)
311 this.handleActivateLayerTree();
312 else if (event.name === eventNames.RequestMainThreadFrame)
313 this.handleRequestMainThreadFrame();
314 else if (event.name === eventNames.NeedsBeginFrameChanged)
315 this.handleNeedFrameChanged(timestamp, event.args['data'] && event.args['d ata']['needsBeginFrame']);
316 }
317
318 /**
319 * @param {!WebInspector.TracingModel.Event} event
320 */
321 _addMainThreadTraceEvent(event) {
322 var eventNames = WebInspector.TimelineModel.RecordType;
323 var timestamp = event.startTime;
324 var selfTime = event.selfTime || 0;
325
326 if (WebInspector.TracingModel.isTopLevelEvent(event)) {
327 this._currentTaskTimeByCategory = {};
328 this._lastTaskBeginTime = event.startTime;
329 }
330 if (!this._framePendingCommit && WebInspector.TimelineFrameModel._mainFrameM arkers.indexOf(event.name) >= 0)
331 this._framePendingCommit =
332 new WebInspector.PendingFrame(this._lastTaskBeginTime || event.startTi me, this._currentTaskTimeByCategory);
333 if (!this._framePendingCommit) {
334 this._addTimeForCategory(this._currentTaskTimeByCategory, event);
335 return;
336 }
337 this._addTimeForCategory(this._framePendingCommit.timeByCategory, event);
338
339 if (event.name === eventNames.BeginMainThreadFrame && event.args['data'] && event.args['data']['frameId'])
340 this._framePendingCommit.mainFrameId = event.args['data']['frameId'];
341 if (event.name === eventNames.Paint && event.args['data']['layerId'] && even t.picture && this._target)
342 this._framePendingCommit.paints.push(new WebInspector.LayerPaintEvent(even t, this._target));
343 if (event.name === eventNames.CompositeLayers && event.args['layerTreeId'] = == this._layerTreeId)
344 this.handleCompositeLayers();
345 }
346
347 /**
348 * @param {!Object.<string, number>} timeByCategory
349 * @param {!WebInspector.TracingModel.Event} event
350 */
351 _addTimeForCategory(timeByCategory, event) {
352 if (!event.selfTime)
353 return;
354 var categoryName = this._categoryMapper(event);
355 timeByCategory[categoryName] = (timeByCategory[categoryName] || 0) + event.s elfTime;
356 }
39 }; 357 };
40 358
41 WebInspector.TimelineFrameModel._mainFrameMarkers = [ 359 WebInspector.TimelineFrameModel._mainFrameMarkers = [
42 WebInspector.TimelineModel.RecordType.ScheduleStyleRecalculation, 360 WebInspector.TimelineModel.RecordType.ScheduleStyleRecalculation,
43 WebInspector.TimelineModel.RecordType.InvalidateLayout, 361 WebInspector.TimelineModel.RecordType.InvalidateLayout, WebInspector.TimelineM odel.RecordType.BeginMainThreadFrame,
44 WebInspector.TimelineModel.RecordType.BeginMainThreadFrame, 362 WebInspector.TimelineModel.RecordType.ScrollLayer
45 WebInspector.TimelineModel.RecordType.ScrollLayer
46 ]; 363 ];
47 364
48 WebInspector.TimelineFrameModel.prototype = {
49 /**
50 * @return {!Array.<!WebInspector.TimelineFrame>}
51 */
52 frames: function()
53 {
54 return this._frames;
55 },
56
57 /**
58 * @param {number} startTime
59 * @param {number} endTime
60 * @return {!Array.<!WebInspector.TimelineFrame>}
61 */
62 filteredFrames: function(startTime, endTime)
63 {
64 /**
65 * @param {number} value
66 * @param {!WebInspector.TimelineFrame} object
67 * @return {number}
68 */
69 function compareStartTime(value, object)
70 {
71 return value - object.startTime;
72 }
73 /**
74 * @param {number} value
75 * @param {!WebInspector.TimelineFrame} object
76 * @return {number}
77 */
78 function compareEndTime(value, object)
79 {
80 return value - object.endTime;
81 }
82 var frames = this._frames;
83 var firstFrame = frames.lowerBound(startTime, compareEndTime);
84 var lastFrame = frames.lowerBound(endTime, compareStartTime);
85 return frames.slice(firstFrame, lastFrame);
86 },
87
88 /**
89 * @param {!WebInspector.TracingModel.Event} rasterTask
90 * @return {boolean}
91 */
92 hasRasterTile: function(rasterTask)
93 {
94 var data = rasterTask.args["tileData"];
95 if (!data)
96 return false;
97 var frameId = data["sourceFrameNumber"];
98 var frame = frameId && this._frameById[frameId];
99 if (!frame || !frame.layerTree)
100 return false;
101 return true;
102 },
103
104 /**
105 * @param {!WebInspector.TracingModel.Event} rasterTask
106 * @return Promise<?{rect: !DOMAgent.Rect, snapshot: !WebInspector.PaintProf ilerSnapshot}>}
107 */
108 rasterTilePromise: function(rasterTask)
109 {
110 if (!this._target)
111 return Promise.resolve(null);
112 var data = rasterTask.args["tileData"];
113 var frameId = data["sourceFrameNumber"];
114 var tileId = data["tileId"] && data["tileId"]["id_ref"];
115 var frame = frameId && this._frameById[frameId];
116 if (!frame || !frame.layerTree || !tileId)
117 return Promise.resolve(null);
118
119 return frame.layerTree.layerTreePromise().then(layerTree => layerTree && layerTree.pictureForRasterTile(tileId));
120 },
121
122 reset: function()
123 {
124 this._minimumRecordTime = Infinity;
125 this._frames = [];
126 this._frameById = {};
127 this._lastFrame = null;
128 this._lastLayerTree = null;
129 this._mainFrameCommitted = false;
130 this._mainFrameRequested = false;
131 this._framePendingCommit = null;
132 this._lastBeginFrame = null;
133 this._lastNeedsBeginFrame = null;
134 this._framePendingActivation = null;
135 this._lastTaskBeginTime = null;
136 this._target = null;
137 this._sessionId = null;
138 this._currentTaskTimeByCategory = {};
139 },
140
141 /**
142 * @param {number} startTime
143 */
144 handleBeginFrame: function(startTime)
145 {
146 if (!this._lastFrame)
147 this._startFrame(startTime);
148 this._lastBeginFrame = startTime;
149 },
150
151 /**
152 * @param {number} startTime
153 */
154 handleDrawFrame: function(startTime)
155 {
156 if (!this._lastFrame) {
157 this._startFrame(startTime);
158 return;
159 }
160
161 // - if it wasn't drawn, it didn't happen!
162 // - only show frames that either did not wait for the main thread frame or had one committed.
163 if (this._mainFrameCommitted || !this._mainFrameRequested) {
164 if (this._lastNeedsBeginFrame) {
165 var idleTimeEnd = this._framePendingActivation ? this._framePend ingActivation.triggerTime : (this._lastBeginFrame || this._lastNeedsBeginFrame);
166 if (idleTimeEnd > this._lastFrame.startTime) {
167 this._lastFrame.idle = true;
168 this._startFrame(idleTimeEnd);
169 if (this._framePendingActivation)
170 this._commitPendingFrame();
171 this._lastBeginFrame = null;
172 }
173 this._lastNeedsBeginFrame = null;
174 }
175 this._startFrame(startTime);
176 }
177 this._mainFrameCommitted = false;
178 },
179
180 handleActivateLayerTree: function()
181 {
182 if (!this._lastFrame)
183 return;
184 if (this._framePendingActivation && !this._lastNeedsBeginFrame)
185 this._commitPendingFrame();
186 },
187
188 handleRequestMainThreadFrame: function()
189 {
190 if (!this._lastFrame)
191 return;
192 this._mainFrameRequested = true;
193 },
194
195 handleCompositeLayers: function()
196 {
197 if (!this._framePendingCommit)
198 return;
199 this._framePendingActivation = this._framePendingCommit;
200 this._framePendingCommit = null;
201 this._mainFrameRequested = false;
202 this._mainFrameCommitted = true;
203 },
204
205 /**
206 * @param {!WebInspector.TracingFrameLayerTree} layerTree
207 */
208 handleLayerTreeSnapshot: function(layerTree)
209 {
210 this._lastLayerTree = layerTree;
211 },
212
213 /**
214 * @param {number} startTime
215 * @param {boolean} needsBeginFrame
216 */
217 handleNeedFrameChanged: function(startTime, needsBeginFrame)
218 {
219 if (needsBeginFrame)
220 this._lastNeedsBeginFrame = startTime;
221 },
222
223 /**
224 * @param {number} startTime
225 */
226 _startFrame: function(startTime)
227 {
228 if (this._lastFrame)
229 this._flushFrame(this._lastFrame, startTime);
230 this._lastFrame = new WebInspector.TimelineFrame(startTime, startTime - this._minimumRecordTime);
231 },
232
233 /**
234 * @param {!WebInspector.TimelineFrame} frame
235 * @param {number} endTime
236 */
237 _flushFrame: function(frame, endTime)
238 {
239 frame._setLayerTree(this._lastLayerTree);
240 frame._setEndTime(endTime);
241 if (this._lastLayerTree)
242 this._lastLayerTree._setPaints(frame._paints);
243 if (this._frames.length && (frame.startTime !== this._frames.peekLast(). endTime || frame.startTime > frame.endTime))
244 console.assert(false, `Inconsistent frame time for frame ${this._fra mes.length} (${frame.startTime} - ${frame.endTime})`);
245 this._frames.push(frame);
246 if (typeof frame._mainFrameId === "number")
247 this._frameById[frame._mainFrameId] = frame;
248 },
249
250 _commitPendingFrame: function()
251 {
252 this._lastFrame._addTimeForCategories(this._framePendingActivation.timeB yCategory);
253 this._lastFrame._paints = this._framePendingActivation.paints;
254 this._lastFrame._mainFrameId = this._framePendingActivation.mainFrameId;
255 this._framePendingActivation = null;
256 },
257
258 /**
259 * @param {!Array.<string>} types
260 * @param {!WebInspector.TimelineModel.Record} record
261 * @return {?WebInspector.TimelineModel.Record} record
262 */
263 _findRecordRecursively: function(types, record)
264 {
265 if (types.indexOf(record.type()) >= 0)
266 return record;
267 if (!record.children())
268 return null;
269 for (var i = 0; i < record.children().length; ++i) {
270 var result = this._findRecordRecursively(types, record.children()[i] );
271 if (result)
272 return result;
273 }
274 return null;
275 },
276
277 /**
278 * @param {?WebInspector.Target} target
279 * @param {!Array.<!WebInspector.TracingModel.Event>} events
280 * @param {string} sessionId
281 */
282 addTraceEvents: function(target, events, sessionId)
283 {
284 this._target = target;
285 this._sessionId = sessionId;
286 if (!events.length)
287 return;
288 if (events[0].startTime < this._minimumRecordTime)
289 this._minimumRecordTime = events[0].startTime;
290 for (var i = 0; i < events.length; ++i)
291 this._addTraceEvent(events[i]);
292 },
293
294 /**
295 * @param {!WebInspector.TracingModel.Event} event
296 */
297 _addTraceEvent: function(event)
298 {
299 var eventNames = WebInspector.TimelineModel.RecordType;
300
301 if (event.name === eventNames.SetLayerTreeId) {
302 var sessionId = event.args["sessionId"] || event.args["data"]["sessi onId"];
303 if (this._sessionId === sessionId)
304 this._layerTreeId = event.args["layerTreeId"] || event.args["dat a"]["layerTreeId"];
305 } else if (event.name === eventNames.TracingStartedInPage) {
306 this._mainThread = event.thread;
307 } else if (event.phase === WebInspector.TracingModel.Phase.SnapshotObjec t && event.name === eventNames.LayerTreeHostImplSnapshot && parseInt(event.id, 0 ) === this._layerTreeId) {
308 var snapshot = /** @type {!WebInspector.TracingModel.ObjectSnapshot} */ (event);
309 this.handleLayerTreeSnapshot(new WebInspector.TracingFrameLayerTree( this._target, snapshot));
310 } else {
311 this._processCompositorEvents(event);
312 if (event.thread === this._mainThread)
313 this._addMainThreadTraceEvent(event);
314 else if (this._lastFrame && event.selfTime && !WebInspector.TracingM odel.isTopLevelEvent(event))
315 this._lastFrame._addTimeForCategory(this._categoryMapper(event), event.selfTime);
316 }
317 },
318
319 /**
320 * @param {!WebInspector.TracingModel.Event} event
321 */
322 _processCompositorEvents: function(event)
323 {
324 var eventNames = WebInspector.TimelineModel.RecordType;
325
326 if (event.args["layerTreeId"] !== this._layerTreeId)
327 return;
328
329 var timestamp = event.startTime;
330 if (event.name === eventNames.BeginFrame)
331 this.handleBeginFrame(timestamp);
332 else if (event.name === eventNames.DrawFrame)
333 this.handleDrawFrame(timestamp);
334 else if (event.name === eventNames.ActivateLayerTree)
335 this.handleActivateLayerTree();
336 else if (event.name === eventNames.RequestMainThreadFrame)
337 this.handleRequestMainThreadFrame();
338 else if (event.name === eventNames.NeedsBeginFrameChanged)
339 this.handleNeedFrameChanged(timestamp, event.args["data"] && event.a rgs["data"]["needsBeginFrame"]);
340 },
341
342 /**
343 * @param {!WebInspector.TracingModel.Event} event
344 */
345 _addMainThreadTraceEvent: function(event)
346 {
347 var eventNames = WebInspector.TimelineModel.RecordType;
348 var timestamp = event.startTime;
349 var selfTime = event.selfTime || 0;
350
351 if (WebInspector.TracingModel.isTopLevelEvent(event)) {
352 this._currentTaskTimeByCategory = {};
353 this._lastTaskBeginTime = event.startTime;
354 }
355 if (!this._framePendingCommit && WebInspector.TimelineFrameModel._mainFr ameMarkers.indexOf(event.name) >= 0)
356 this._framePendingCommit = new WebInspector.PendingFrame(this._lastT askBeginTime || event.startTime, this._currentTaskTimeByCategory);
357 if (!this._framePendingCommit) {
358 this._addTimeForCategory(this._currentTaskTimeByCategory, event);
359 return;
360 }
361 this._addTimeForCategory(this._framePendingCommit.timeByCategory, event) ;
362
363 if (event.name === eventNames.BeginMainThreadFrame && event.args["data"] && event.args["data"]["frameId"])
364 this._framePendingCommit.mainFrameId = event.args["data"]["frameId"] ;
365 if (event.name === eventNames.Paint && event.args["data"]["layerId"] && event.picture && this._target)
366 this._framePendingCommit.paints.push(new WebInspector.LayerPaintEven t(event, this._target));
367 if (event.name === eventNames.CompositeLayers && event.args["layerTreeId "] === this._layerTreeId)
368 this.handleCompositeLayers();
369 },
370
371 /**
372 * @param {!Object.<string, number>} timeByCategory
373 * @param {!WebInspector.TracingModel.Event} event
374 */
375 _addTimeForCategory: function(timeByCategory, event)
376 {
377 if (!event.selfTime)
378 return;
379 var categoryName = this._categoryMapper(event);
380 timeByCategory[categoryName] = (timeByCategory[categoryName] || 0) + eve nt.selfTime;
381 },
382 };
383
384 /** 365 /**
385 * @constructor 366 * @unrestricted
386 * @param {!WebInspector.Target} target
387 * @param {!WebInspector.TracingModel.ObjectSnapshot} snapshot
388 */ 367 */
389 WebInspector.TracingFrameLayerTree = function(target, snapshot) 368 WebInspector.TracingFrameLayerTree = class {
390 { 369 /**
370 * @param {!WebInspector.Target} target
371 * @param {!WebInspector.TracingModel.ObjectSnapshot} snapshot
372 */
373 constructor(target, snapshot) {
391 this._target = target; 374 this._target = target;
392 this._snapshot = snapshot; 375 this._snapshot = snapshot;
393 /** @type {!Array<!WebInspector.LayerPaintEvent>|undefined} */ 376 /** @type {!Array<!WebInspector.LayerPaintEvent>|undefined} */
394 this._paints; 377 this._paints;
378 }
379
380 /**
381 * @return {!Promise<?WebInspector.TracingLayerTree>}
382 */
383 layerTreePromise() {
384 return this._snapshot.objectPromise().then(result => {
385 if (!result)
386 return null;
387 var viewport = result['device_viewport_size'];
388 var tiles = result['active_tiles'];
389 var rootLayer = result['active_tree']['root_layer'];
390 var layers = result['active_tree']['layers'];
391 var layerTree = new WebInspector.TracingLayerTree(this._target);
392 layerTree.setViewportSize(viewport);
393 layerTree.setTiles(tiles);
394 return new Promise(
395 resolve => layerTree.setLayers(rootLayer, layers, this._paints || [], () => resolve(layerTree)));
396 });
397 }
398
399 /**
400 * @return {!Array<!WebInspector.LayerPaintEvent>}
401 */
402 paints() {
403 return this._paints || [];
404 }
405
406 /**
407 * @param {!Array<!WebInspector.LayerPaintEvent>} paints
408 */
409 _setPaints(paints) {
410 this._paints = paints;
411 }
395 }; 412 };
396 413
397 WebInspector.TracingFrameLayerTree.prototype = {
398 /**
399 * @return {!Promise<?WebInspector.TracingLayerTree>}
400 */
401 layerTreePromise: function()
402 {
403 return this._snapshot.objectPromise().then(result => {
404 if (!result)
405 return null;
406 var viewport = result["device_viewport_size"];
407 var tiles = result["active_tiles"];
408 var rootLayer = result["active_tree"]["root_layer"];
409 var layers = result["active_tree"]["layers"];
410 var layerTree = new WebInspector.TracingLayerTree(this._target);
411 layerTree.setViewportSize(viewport);
412 layerTree.setTiles(tiles);
413 return new Promise(resolve => layerTree.setLayers(rootLayer, layers, this._paints || [], () => resolve(layerTree)));
414 });
415 },
416
417 /**
418 * @return {!Array<!WebInspector.LayerPaintEvent>}
419 */
420 paints: function()
421 {
422 return this._paints || [];
423 },
424
425 /**
426 * @param {!Array<!WebInspector.LayerPaintEvent>} paints
427 */
428 _setPaints: function(paints)
429 {
430 this._paints = paints;
431 }
432 };
433
434
435 /** 414 /**
436 * @constructor 415 * @unrestricted
437 * @param {number} startTime
438 * @param {number} startTimeOffset
439 */ 416 */
440 WebInspector.TimelineFrame = function(startTime, startTimeOffset) 417 WebInspector.TimelineFrame = class {
441 { 418 /**
419 * @param {number} startTime
420 * @param {number} startTimeOffset
421 */
422 constructor(startTime, startTimeOffset) {
442 this.startTime = startTime; 423 this.startTime = startTime;
443 this.startTimeOffset = startTimeOffset; 424 this.startTimeOffset = startTimeOffset;
444 this.endTime = this.startTime; 425 this.endTime = this.startTime;
445 this.duration = 0; 426 this.duration = 0;
446 this.timeByCategory = {}; 427 this.timeByCategory = {};
447 this.cpuTime = 0; 428 this.cpuTime = 0;
448 this.idle = false; 429 this.idle = false;
449 /** @type {?WebInspector.TracingFrameLayerTree} */ 430 /** @type {?WebInspector.TracingFrameLayerTree} */
450 this.layerTree = null; 431 this.layerTree = null;
451 /** @type {!Array.<!WebInspector.LayerPaintEvent>} */ 432 /** @type {!Array.<!WebInspector.LayerPaintEvent>} */
452 this._paints = []; 433 this._paints = [];
453 /** @type {number|undefined} */ 434 /** @type {number|undefined} */
454 this._mainFrameId = undefined; 435 this._mainFrameId = undefined;
455 }; 436 }
456 437
457 WebInspector.TimelineFrame.prototype = { 438 /**
458 /** 439 * @return {boolean}
459 * @return {boolean} 440 */
460 */ 441 hasWarnings() {
461 hasWarnings: function() 442 var /** @const */ longFrameDurationThresholdMs = 22;
462 { 443 return !this.idle && this.duration > longFrameDurationThresholdMs;
463 var /** @const */ longFrameDurationThresholdMs = 22; 444 }
464 return !this.idle && this.duration > longFrameDurationThresholdMs;
465 },
466 445
467 /** 446 /**
468 * @param {number} endTime 447 * @param {number} endTime
469 */ 448 */
470 _setEndTime: function(endTime) 449 _setEndTime(endTime) {
471 { 450 this.endTime = endTime;
472 this.endTime = endTime; 451 this.duration = this.endTime - this.startTime;
473 this.duration = this.endTime - this.startTime; 452 }
474 },
475 453
476 /** 454 /**
477 * @param {?WebInspector.TracingFrameLayerTree} layerTree 455 * @param {?WebInspector.TracingFrameLayerTree} layerTree
478 */ 456 */
479 _setLayerTree: function(layerTree) 457 _setLayerTree(layerTree) {
480 { 458 this.layerTree = layerTree;
481 this.layerTree = layerTree; 459 }
482 },
483 460
484 /** 461 /**
485 * @param {!Object} timeByCategory 462 * @param {!Object} timeByCategory
486 */ 463 */
487 _addTimeForCategories: function(timeByCategory) 464 _addTimeForCategories(timeByCategory) {
488 { 465 for (var category in timeByCategory)
489 for (var category in timeByCategory) 466 this._addTimeForCategory(category, timeByCategory[category]);
490 this._addTimeForCategory(category, timeByCategory[category]); 467 }
491 },
492 468
493 /** 469 /**
494 * @param {string} category 470 * @param {string} category
495 * @param {number} time 471 * @param {number} time
496 */ 472 */
497 _addTimeForCategory: function(category, time) 473 _addTimeForCategory(category, time) {
498 { 474 this.timeByCategory[category] = (this.timeByCategory[category] || 0) + time;
499 this.timeByCategory[category] = (this.timeByCategory[category] || 0) + t ime; 475 this.cpuTime += time;
500 this.cpuTime += time; 476 }
501 },
502 }; 477 };
503 478
504 /** 479 /**
505 * @constructor 480 * @unrestricted
506 * @param {!WebInspector.TracingModel.Event} event
507 * @param {?WebInspector.Target} target
508 */ 481 */
509 WebInspector.LayerPaintEvent = function(event, target) 482 WebInspector.LayerPaintEvent = class {
510 { 483 /**
484 * @param {!WebInspector.TracingModel.Event} event
485 * @param {?WebInspector.Target} target
486 */
487 constructor(event, target) {
511 this._event = event; 488 this._event = event;
512 this._target = target; 489 this._target = target;
513 }; 490 }
514 491
515 WebInspector.LayerPaintEvent.prototype = { 492 /**
516 /** 493 * @return {string}
517 * @return {string} 494 */
518 */ 495 layerId() {
519 layerId: function() 496 return this._event.args['data']['layerId'];
520 { 497 }
521 return this._event.args["data"]["layerId"];
522 },
523 498
524 /** 499 /**
525 * @return {!WebInspector.TracingModel.Event} 500 * @return {!WebInspector.TracingModel.Event}
526 */ 501 */
527 event: function() 502 event() {
528 { 503 return this._event;
529 return this._event; 504 }
530 },
531 505
532 /** 506 /**
533 * @return {!Promise<?{rect: !Array<number>, serializedPicture: string}>} 507 * @return {!Promise<?{rect: !Array<number>, serializedPicture: string}>}
534 */ 508 */
535 picturePromise: function() 509 picturePromise() {
536 { 510 return this._event.picture.objectPromise().then(result => {
537 return this._event.picture.objectPromise().then(result => { 511 if (!result)
538 if (!result) 512 return null;
539 return null; 513 var rect = result['params'] && result['params']['layer_rect'];
540 var rect = result["params"] && result["params"]["layer_rect"]; 514 var picture = result['skp64'];
541 var picture = result["skp64"]; 515 return rect && picture ? {rect: rect, serializedPicture: picture} : null;
542 return rect && picture ? {rect: rect, serializedPicture: picture} : null; 516 });
543 }); 517 }
544 },
545 518
546 /** 519 /**
547 * @return !Promise<?{rect: !Array<number>, snapshot: !WebInspector.PaintPro filerSnapshot}>} 520 * @return !Promise<?{rect: !Array<number>, snapshot: !WebInspector.PaintProfi lerSnapshot}>}
548 */ 521 */
549 snapshotPromise: function() 522 snapshotPromise() {
550 { 523 return this.picturePromise().then(picture => {
551 return this.picturePromise().then(picture => { 524 if (!picture || !this._target)
552 if (!picture || !this._target) 525 return null;
553 return null; 526 return WebInspector.PaintProfilerSnapshot.load(this._target, picture.seria lizedPicture)
554 return WebInspector.PaintProfilerSnapshot.load(this._target, picture .serializedPicture).then(snapshot => snapshot ? {rect: picture.rect, snapshot: s napshot} : null); 527 .then(snapshot => snapshot ? {rect: picture.rect, snapshot: snapshot} : null);
555 }); 528 });
556 } 529 }
557 }; 530 };
558 531
559 /** 532 /**
560 * @constructor 533 * @unrestricted
561 * @param {number} triggerTime
562 * @param {!Object.<string, number>} timeByCategory
563 */ 534 */
564 WebInspector.PendingFrame = function(triggerTime, timeByCategory) 535 WebInspector.PendingFrame = class {
565 { 536 /**
537 * @param {number} triggerTime
538 * @param {!Object.<string, number>} timeByCategory
539 */
540 constructor(triggerTime, timeByCategory) {
566 /** @type {!Object.<string, number>} */ 541 /** @type {!Object.<string, number>} */
567 this.timeByCategory = timeByCategory; 542 this.timeByCategory = timeByCategory;
568 /** @type {!Array.<!WebInspector.LayerPaintEvent>} */ 543 /** @type {!Array.<!WebInspector.LayerPaintEvent>} */
569 this.paints = []; 544 this.paints = [];
570 /** @type {number|undefined} */ 545 /** @type {number|undefined} */
571 this.mainFrameId = undefined; 546 this.mainFrameId = undefined;
572 this.triggerTime = triggerTime; 547 this.triggerTime = triggerTime;
548 }
573 }; 549 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698