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

Side by Side Diff: tracing/tracing/extras/chrome/cc/input_latency_async_slice.html

Issue 2776653002: [ESLint] Fix violations when enabling curly rule in eslint. (Closed)
Patch Set: Fix test Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <!-- 2 <!--
3 Copyright (c) 2013 The Chromium Authors. All rights reserved. 3 Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be 4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file. 5 found in the LICENSE file.
6 --> 6 -->
7 7
8 <link rel="import" href="/tracing/model/async_slice.html"> 8 <link rel="import" href="/tracing/model/async_slice.html">
9 <link rel="import" href="/tracing/model/event_set.html"> 9 <link rel="import" href="/tracing/model/event_set.html">
10 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> 10 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html">
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 TOUCH_END: 'TouchEnd', 58 TOUCH_END: 'TouchEnd',
59 TOUCH_MOVE: 'TouchMove', 59 TOUCH_MOVE: 'TouchMove',
60 TOUCH_START: 'TouchStart', 60 TOUCH_START: 'TouchStart',
61 UNKNOWN: 'UNKNOWN' 61 UNKNOWN: 'UNKNOWN'
62 }; 62 };
63 63
64 function InputLatencyAsyncSlice() { 64 function InputLatencyAsyncSlice() {
65 AsyncSlice.apply(this, arguments); 65 AsyncSlice.apply(this, arguments);
66 this.associatedEvents_ = new EventSet(); 66 this.associatedEvents_ = new EventSet();
67 this.typeName_ = undefined; 67 this.typeName_ = undefined;
68 if (!this.isLegacyEvent) 68 if (!this.isLegacyEvent) {
69 this.determineModernTypeName_(); 69 this.determineModernTypeName_();
70 }
70 } 71 }
71 72
72 InputLatencyAsyncSlice.prototype = { 73 InputLatencyAsyncSlice.prototype = {
73 __proto__: AsyncSlice.prototype, 74 __proto__: AsyncSlice.prototype,
74 75
75 // Legacy InputLatencyAsyncSlices involve a top-level slice titled 76 // Legacy InputLatencyAsyncSlices involve a top-level slice titled
76 // "InputLatency" containing a subSlice whose title starts with 77 // "InputLatency" containing a subSlice whose title starts with
77 // "InputLatency:". Modern InputLatencyAsyncSlices involve a single 78 // "InputLatency:". Modern InputLatencyAsyncSlices involve a single
78 // top-level slice whose title starts with "InputLatency::". 79 // top-level slice whose title starts with "InputLatency::".
79 // Legacy subSlices are not available at construction time, so 80 // Legacy subSlices are not available at construction time, so
80 // determineLegacyTypeName_() must be called at get time. 81 // determineLegacyTypeName_() must be called at get time.
81 // So this returns false for the legacy subSlice events titled like 82 // So this returns false for the legacy subSlice events titled like
82 // "InputLatency:Foo" even though they are technically legacy events. 83 // "InputLatency:Foo" even though they are technically legacy events.
83 get isLegacyEvent() { 84 get isLegacyEvent() {
84 return this.title === 'InputLatency'; 85 return this.title === 'InputLatency';
85 }, 86 },
86 87
87 get typeName() { 88 get typeName() {
88 if (!this.typeName_) 89 if (!this.typeName_) {
89 this.determineLegacyTypeName_(); 90 this.determineLegacyTypeName_();
91 }
90 return this.typeName_; 92 return this.typeName_;
91 }, 93 },
92 94
93 checkTypeName_: function() { 95 checkTypeName_: function() {
94 if (!this.typeName_) 96 if (!this.typeName_) {
95 throw new Error('Unable to determine typeName'); 97 throw new Error('Unable to determine typeName');
98 }
96 var found = false; 99 var found = false;
97 for (var typeName in INPUT_EVENT_TYPE_NAMES) { 100 for (var typeName in INPUT_EVENT_TYPE_NAMES) {
98 if (this.typeName === INPUT_EVENT_TYPE_NAMES[typeName]) { 101 if (this.typeName === INPUT_EVENT_TYPE_NAMES[typeName]) {
99 found = true; 102 found = true;
100 break; 103 break;
101 } 104 }
102 } 105 }
103 if (!found) 106 if (!found) {
104 this.typeName_ = INPUT_EVENT_TYPE_NAMES.UNKNOWN; 107 this.typeName_ = INPUT_EVENT_TYPE_NAMES.UNKNOWN;
108 }
105 }, 109 },
106 110
107 determineModernTypeName_: function() { 111 determineModernTypeName_: function() {
108 // This method works both on modern events titled like 112 // This method works both on modern events titled like
109 // "InputLatency::Foo" and also on the legacy subSlices titled like 113 // "InputLatency::Foo" and also on the legacy subSlices titled like
110 // "InputLatency:Foo". Modern events' titles contain 2 colons, whereas the 114 // "InputLatency:Foo". Modern events' titles contain 2 colons, whereas the
111 // legacy subSlices events contain 1 colon. 115 // legacy subSlices events contain 1 colon.
112 116
113 var lastColonIndex = this.title.lastIndexOf(':'); 117 var lastColonIndex = this.title.lastIndexOf(':');
114 if (lastColonIndex < 0) 118 if (lastColonIndex < 0) return;
115 return;
116 119
117 var characterAfterLastColonIndex = lastColonIndex + 1; 120 var characterAfterLastColonIndex = lastColonIndex + 1;
118 this.typeName_ = this.title.slice(characterAfterLastColonIndex); 121 this.typeName_ = this.title.slice(characterAfterLastColonIndex);
119 122
120 // Check that the determined typeName is known. 123 // Check that the determined typeName is known.
121 this.checkTypeName_(); 124 this.checkTypeName_();
122 }, 125 },
123 126
124 determineLegacyTypeName_: function() { 127 determineLegacyTypeName_: function() {
125 // Iterate over all descendent subSlices. 128 // Iterate over all descendent subSlices.
126 for (var subSlice of this.enumerateAllDescendents()) { 129 for (var subSlice of this.enumerateAllDescendents()) {
127 // If |subSlice| is not an InputLatencyAsyncSlice, then ignore it. 130 // If |subSlice| is not an InputLatencyAsyncSlice, then ignore it.
128 var subSliceIsAInputLatencyAsyncSlice = ( 131 var subSliceIsAInputLatencyAsyncSlice = (
129 subSlice instanceof InputLatencyAsyncSlice); 132 subSlice instanceof InputLatencyAsyncSlice);
130 if (!subSliceIsAInputLatencyAsyncSlice) 133 if (!subSliceIsAInputLatencyAsyncSlice) continue;
131 continue;
132 134
133 // If |subSlice| does not have a typeName, then ignore it. 135 // If |subSlice| does not have a typeName, then ignore it.
134 if (!subSlice.typeName) 136 if (!subSlice.typeName) continue;
135 continue;
136 137
137 // If |this| already has a typeName and |subSlice| has a different 138 // If |this| already has a typeName and |subSlice| has a different
138 // typeName, then explode! 139 // typeName, then explode!
139 if (this.typeName_ && subSlice.typeName_) { 140 if (this.typeName_ && subSlice.typeName_) {
140 var subSliceHasDifferentTypeName = ( 141 var subSliceHasDifferentTypeName = (
141 this.typeName_ !== subSlice.typeName_); 142 this.typeName_ !== subSlice.typeName_);
142 if (subSliceHasDifferentTypeName) { 143 if (subSliceHasDifferentTypeName) {
143 throw new Error( 144 throw new Error(
144 'InputLatencyAsyncSlice.determineLegacyTypeName_() ' + 145 'InputLatencyAsyncSlice.determineLegacyTypeName_() ' +
145 ' found multiple typeNames'); 146 ' found multiple typeNames');
(...skipping 12 matching lines...) Expand all
158 } 159 }
159 160
160 // Check that the determined typeName is known. 161 // Check that the determined typeName is known.
161 this.checkTypeName_(); 162 this.checkTypeName_();
162 }, 163 },
163 164
164 getRendererHelper: function(sourceSlices) { 165 getRendererHelper: function(sourceSlices) {
165 var traceModel = this.startThread.parent.model; 166 var traceModel = this.startThread.parent.model;
166 var modelHelper = traceModel.getOrCreateHelper( 167 var modelHelper = traceModel.getOrCreateHelper(
167 tr.model.helpers.ChromeModelHelper); 168 tr.model.helpers.ChromeModelHelper);
168 if (!modelHelper) 169 if (!modelHelper) return undefined;
169 return undefined;
170 170
171 var mainThread = undefined; 171 var mainThread = undefined;
172 var compositorThread = undefined; 172 var compositorThread = undefined;
173 173
174 for (var i in sourceSlices) { 174 for (var i in sourceSlices) {
175 if (sourceSlices[i].parentContainer.name === 175 if (sourceSlices[i].parentContainer.name ===
176 MAIN_RENDERER_THREAD_NAME) 176 MAIN_RENDERER_THREAD_NAME) {
177 mainThread = sourceSlices[i].parentContainer; 177 mainThread = sourceSlices[i].parentContainer;
178 else if (sourceSlices[i].parentContainer.name === 178 } else if (sourceSlices[i].parentContainer.name ===
179 COMPOSITOR_THREAD_NAME) 179 COMPOSITOR_THREAD_NAME) {
180 compositorThread = sourceSlices[i].parentContainer; 180 compositorThread = sourceSlices[i].parentContainer;
181 }
181 182
182 if (mainThread && compositorThread) 183 if (mainThread && compositorThread) break;
183 break;
184 } 184 }
185 185
186 var rendererHelpers = modelHelper.rendererHelpers; 186 var rendererHelpers = modelHelper.rendererHelpers;
187 187
188 var pids = Object.keys(rendererHelpers); 188 var pids = Object.keys(rendererHelpers);
189 for (var i = 0; i < pids.length; i++) { 189 for (var i = 0; i < pids.length; i++) {
190 var pid = pids[i]; 190 var pid = pids[i];
191 var rendererHelper = rendererHelpers[pid]; 191 var rendererHelper = rendererHelpers[pid];
192 if (rendererHelper.mainThread === mainThread || 192 if (rendererHelper.mainThread === mainThread ||
193 rendererHelper.compositorThread === compositorThread) 193 rendererHelper.compositorThread === compositorThread) {
194 return rendererHelper; 194 return rendererHelper;
195 }
195 } 196 }
196 197
197 return undefined; 198 return undefined;
198 }, 199 },
199 200
200 addEntireSliceHierarchy: function(slice) { 201 addEntireSliceHierarchy: function(slice) {
201 this.associatedEvents_.push(slice); 202 this.associatedEvents_.push(slice);
202 slice.iterateAllSubsequentSlices(function(subsequentSlice) { 203 slice.iterateAllSubsequentSlices(function(subsequentSlice) {
203 this.associatedEvents_.push(subsequentSlice); 204 this.associatedEvents_.push(subsequentSlice);
204 }, this); 205 }, this);
205 }, 206 },
206 207
207 addDirectlyAssociatedEvents: function(flowEvents) { 208 addDirectlyAssociatedEvents: function(flowEvents) {
208 var slices = []; 209 var slices = [];
209 210
210 flowEvents.forEach(function(flowEvent) { 211 flowEvents.forEach(function(flowEvent) {
211 this.associatedEvents_.push(flowEvent); 212 this.associatedEvents_.push(flowEvent);
212 var newSource = flowEvent.startSlice.mostTopLevelSlice; 213 var newSource = flowEvent.startSlice.mostTopLevelSlice;
213 if (slices.indexOf(newSource) === -1) 214 if (slices.indexOf(newSource) === -1) {
214 slices.push(newSource); 215 slices.push(newSource);
216 }
215 }, this); 217 }, this);
216 218
217 var lastFlowEvent = flowEvents[flowEvents.length - 1]; 219 var lastFlowEvent = flowEvents[flowEvents.length - 1];
218 var lastSource = lastFlowEvent.endSlice.mostTopLevelSlice; 220 var lastSource = lastFlowEvent.endSlice.mostTopLevelSlice;
219 if (slices.indexOf(lastSource) === -1) 221 if (slices.indexOf(lastSource) === -1) {
220 slices.push(lastSource); 222 slices.push(lastSource);
223 }
221 224
222 return slices; 225 return slices;
223 }, 226 },
224 227
225 // Find the Latency::ScrollUpdate slice that corresponds to the 228 // Find the Latency::ScrollUpdate slice that corresponds to the
226 // InputLatency::GestureScrollUpdate slice. 229 // InputLatency::GestureScrollUpdate slice.
227 // The C++ CL that makes this connection is at: 230 // The C++ CL that makes this connection is at:
228 // https://codereview.chromium.org/1178963003 231 // https://codereview.chromium.org/1178963003
229 addScrollUpdateEvents: function(rendererHelper) { 232 addScrollUpdateEvents: function(rendererHelper) {
230 if (!rendererHelper || !rendererHelper.compositorThread) 233 if (!rendererHelper || !rendererHelper.compositorThread) {
231 return; 234 return;
235 }
232 236
233 var compositorThread = rendererHelper.compositorThread; 237 var compositorThread = rendererHelper.compositorThread;
234 var gestureScrollUpdateStart = this.start; 238 var gestureScrollUpdateStart = this.start;
235 var gestureScrollUpdateEnd = this.end; 239 var gestureScrollUpdateEnd = this.end;
236 240
237 var allCompositorAsyncSlices = 241 var allCompositorAsyncSlices =
238 compositorThread.asyncSliceGroup.slices; 242 compositorThread.asyncSliceGroup.slices;
239 243
240 for (var i in allCompositorAsyncSlices) { 244 for (var i in allCompositorAsyncSlices) {
241 var slice = allCompositorAsyncSlices[i]; 245 var slice = allCompositorAsyncSlices[i];
242 246
243 if (slice.title !== 'Latency::ScrollUpdate') 247 if (slice.title !== 'Latency::ScrollUpdate') continue;
244 continue;
245 248
246 var parentId = slice.args.data. 249 var parentId = slice.args.data.
247 INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT. 250 INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT.
248 sequence_number; 251 sequence_number;
249 252
250 if (parentId === undefined) { 253 if (parentId === undefined) {
251 // Old trace, we can only rely on the timestamp to find the slice 254 // Old trace, we can only rely on the timestamp to find the slice
252 if (slice.start < gestureScrollUpdateStart || 255 if (slice.start < gestureScrollUpdateStart ||
253 slice.start >= gestureScrollUpdateEnd) 256 slice.start >= gestureScrollUpdateEnd) {
254 continue; 257 continue;
258 }
255 } else { 259 } else {
256 // New trace, we can definitively find the latency slice by comparing 260 // New trace, we can definitively find the latency slice by comparing
257 // its sequence number with gesture id 261 // its sequence number with gesture id
258 if (parseInt(parentId) !== parseInt(this.id)) 262 if (parseInt(parentId) !== parseInt(this.id)) {
259 continue; 263 continue;
264 }
260 } 265 }
261 266
262 slice.associatedEvents.forEach(function(event) { 267 slice.associatedEvents.forEach(function(event) {
263 this.associatedEvents_.push(event); 268 this.associatedEvents_.push(event);
264 }, this); 269 }, this);
265 break; 270 break;
266 } 271 }
267 }, 272 },
268 273
269 // Return true if the slice hierarchy is tracked by LatencyInfo of other 274 // Return true if the slice hierarchy is tracked by LatencyInfo of other
270 // input latency events. If the slice hierarchy is tracked by both, this 275 // input latency events. If the slice hierarchy is tracked by both, this
271 // function still returns true. 276 // function still returns true.
272 belongToOtherInputs: function(slice, flowEvents) { 277 belongToOtherInputs: function(slice, flowEvents) {
273 var fromOtherInputs = false; 278 var fromOtherInputs = false;
274 279
275 slice.iterateEntireHierarchy(function(subsequentSlice) { 280 slice.iterateEntireHierarchy(function(subsequentSlice) {
276 if (fromOtherInputs) 281 if (fromOtherInputs) return;
277 return;
278 282
279 subsequentSlice.inFlowEvents.forEach(function(inflow) { 283 subsequentSlice.inFlowEvents.forEach(function(inflow) {
280 if (fromOtherInputs) 284 if (fromOtherInputs) return;
281 return;
282 285
283 if (inflow.category.indexOf('input') > -1) { 286 if (inflow.category.indexOf('input') > -1) {
284 if (flowEvents.indexOf(inflow) === -1) 287 if (flowEvents.indexOf(inflow) === -1) {
285 fromOtherInputs = true; 288 fromOtherInputs = true;
289 }
286 } 290 }
287 }, this); 291 }, this);
288 }, this); 292 }, this);
289 293
290 return fromOtherInputs; 294 return fromOtherInputs;
291 }, 295 },
292 296
293 // Return true if |event| triggers slices of other inputs. 297 // Return true if |event| triggers slices of other inputs.
294 triggerOtherInputs: function(event, flowEvents) { 298 triggerOtherInputs: function(event, flowEvents) {
295 if (event.outFlowEvents === undefined || 299 if (event.outFlowEvents === undefined ||
296 event.outFlowEvents.length === 0) 300 event.outFlowEvents.length === 0) {
297 return false; 301 return false;
302 }
298 303
299 // Once we fix the bug of flow event binding, there should exist one and 304 // Once we fix the bug of flow event binding, there should exist one and
300 // only one outgoing flow (PostTask) from ScheduleBeginImplFrameDeadline 305 // only one outgoing flow (PostTask) from ScheduleBeginImplFrameDeadline
301 // and PostComposite. 306 // and PostComposite.
302 var flow = event.outFlowEvents[0]; 307 var flow = event.outFlowEvents[0];
303 308
304 if (flow.category !== POSTTASK_FLOW_EVENT || 309 if (flow.category !== POSTTASK_FLOW_EVENT ||
305 !flow.endSlice) 310 !flow.endSlice) {
306 return false; 311 return false;
312 }
307 313
308 var endSlice = flow.endSlice; 314 var endSlice = flow.endSlice;
309 if (this.belongToOtherInputs(endSlice.mostTopLevelSlice, flowEvents)) 315 if (this.belongToOtherInputs(endSlice.mostTopLevelSlice, flowEvents)) {
310 return true; 316 return true;
317 }
311 318
312 return false; 319 return false;
313 }, 320 },
314 321
315 // Follow outgoing flow of subsequentSlices in the current hierarchy. 322 // Follow outgoing flow of subsequentSlices in the current hierarchy.
316 // We also handle cases where different inputs interfere with each other. 323 // We also handle cases where different inputs interfere with each other.
317 followSubsequentSlices: function(event, queue, visited, flowEvents) { 324 followSubsequentSlices: function(event, queue, visited, flowEvents) {
318 var stopFollowing = false; 325 var stopFollowing = false;
319 var inputAck = false; 326 var inputAck = false;
320 327
321 event.iterateAllSubsequentSlices(function(slice) { 328 event.iterateAllSubsequentSlices(function(slice) {
322 if (stopFollowing) 329 if (stopFollowing) return;
323 return;
324 330
325 // Do not follow TaskQueueManager::RunTask because it causes 331 // Do not follow TaskQueueManager::RunTask because it causes
326 // many false events to be included. 332 // many false events to be included.
327 if (slice.title === 'TaskQueueManager::RunTask') 333 if (slice.title === 'TaskQueueManager::RunTask') return;
328 return;
329 334
330 // Do not follow ScheduledActionSendBeginMainFrame because the real 335 // Do not follow ScheduledActionSendBeginMainFrame because the real
331 // main thread BeginMainFrame is already traced by LatencyInfo flow. 336 // main thread BeginMainFrame is already traced by LatencyInfo flow.
332 if (slice.title === 'ThreadProxy::ScheduledActionSendBeginMainFrame') 337 if (slice.title === 'ThreadProxy::ScheduledActionSendBeginMainFrame') {
333 return; 338 return;
339 }
334 340
335 // Do not follow ScheduleBeginImplFrameDeadline that triggers an 341 // Do not follow ScheduleBeginImplFrameDeadline that triggers an
336 // OnBeginImplFrameDeadline that is tracked by another LatencyInfo. 342 // OnBeginImplFrameDeadline that is tracked by another LatencyInfo.
337 if (slice.title === 'Scheduler::ScheduleBeginImplFrameDeadline') { 343 if (slice.title === 'Scheduler::ScheduleBeginImplFrameDeadline') {
338 if (this.triggerOtherInputs(slice, flowEvents)) 344 if (this.triggerOtherInputs(slice, flowEvents)) return;
339 return;
340 } 345 }
341 346
342 // Do not follow PostComposite that triggers CompositeImmediately 347 // Do not follow PostComposite that triggers CompositeImmediately
343 // that is tracked by another LatencyInfo. 348 // that is tracked by another LatencyInfo.
344 if (slice.title === 'CompositorImpl::PostComposite') { 349 if (slice.title === 'CompositorImpl::PostComposite') {
345 if (this.triggerOtherInputs(slice, flowEvents)) 350 if (this.triggerOtherInputs(slice, flowEvents)) return;
346 return;
347 } 351 }
348 352
349 // Stop following the rest of the current slice hierarchy if 353 // Stop following the rest of the current slice hierarchy if
350 // FilterAndSendWebInputEvent occurs after ProcessInputEventAck. 354 // FilterAndSendWebInputEvent occurs after ProcessInputEventAck.
351 if (slice.title === 'InputRouterImpl::ProcessInputEventAck') 355 if (slice.title === 'InputRouterImpl::ProcessInputEventAck') {
352 inputAck = true; 356 inputAck = true;
357 }
353 if (inputAck && 358 if (inputAck &&
354 slice.title === 'InputRouterImpl::FilterAndSendWebInputEvent') 359 slice.title === 'InputRouterImpl::FilterAndSendWebInputEvent') {
355 stopFollowing = true; 360 stopFollowing = true;
361 }
356 362
357 this.followCurrentSlice(slice, queue, visited); 363 this.followCurrentSlice(slice, queue, visited);
358 }, this); 364 }, this);
359 }, 365 },
360 366
361 // Follow outgoing flow events of the current slice. 367 // Follow outgoing flow events of the current slice.
362 followCurrentSlice: function(event, queue, visited) { 368 followCurrentSlice: function(event, queue, visited) {
363 event.outFlowEvents.forEach(function(outflow) { 369 event.outFlowEvents.forEach(function(outflow) {
364 if ((outflow.category === POSTTASK_FLOW_EVENT || 370 if ((outflow.category === POSTTASK_FLOW_EVENT ||
365 outflow.category === IPC_FLOW_EVENT) && 371 outflow.category === IPC_FLOW_EVENT) &&
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 }, 406 },
401 407
402 sortRasterizerSlices: function(rasterWorkerThreads, 408 sortRasterizerSlices: function(rasterWorkerThreads,
403 sortedRasterizerSlices) { 409 sortedRasterizerSlices) {
404 rasterWorkerThreads.forEach(function(rasterizer) { 410 rasterWorkerThreads.forEach(function(rasterizer) {
405 Array.prototype.push.apply(sortedRasterizerSlices, 411 Array.prototype.push.apply(sortedRasterizerSlices,
406 rasterizer.sliceGroup.slices); 412 rasterizer.sliceGroup.slices);
407 }, this); 413 }, this);
408 414
409 sortedRasterizerSlices.sort(function(a, b) { 415 sortedRasterizerSlices.sort(function(a, b) {
410 if (a.start !== b.start) 416 if (a.start !== b.start) {
411 return a.start - b.start; 417 return a.start - b.start;
418 }
412 return a.guid - b.guid; 419 return a.guid - b.guid;
413 }); 420 });
414 }, 421 },
415 422
416 // Find rasterization slices that have the source_prepare_tiles_id 423 // Find rasterization slices that have the source_prepare_tiles_id
417 // same as the prepare_tiles_id of TileManager::PrepareTiles 424 // same as the prepare_tiles_id of TileManager::PrepareTiles
418 // The C++ CL that makes this connection is at: 425 // The C++ CL that makes this connection is at:
419 // https://codereview.chromium.org/1208683002/ 426 // https://codereview.chromium.org/1208683002/
420 addRasterizationEvents: function(prepareTiles, rendererHelper, 427 addRasterizationEvents: function(prepareTiles, rendererHelper,
421 visited, flowEvents, sortedRasterizerSlices) { 428 visited, flowEvents, sortedRasterizerSlices) {
422 if (!prepareTiles.args.prepare_tiles_id) 429 if (!prepareTiles.args.prepare_tiles_id) return;
430
431 if (!rendererHelper || !rendererHelper.rasterWorkerThreads) {
423 return; 432 return;
424 433 }
425 if (!rendererHelper || !rendererHelper.rasterWorkerThreads)
426 return;
427 434
428 var rasterWorkerThreads = rendererHelper.rasterWorkerThreads; 435 var rasterWorkerThreads = rendererHelper.rasterWorkerThreads;
429 var prepareTileId = prepareTiles.args.prepare_tiles_id; 436 var prepareTileId = prepareTiles.args.prepare_tiles_id;
430 var pendingEventQueue = []; 437 var pendingEventQueue = [];
431 438
432 // Collect all the rasterizer tasks. Return the cached copy if possible. 439 // Collect all the rasterizer tasks. Return the cached copy if possible.
433 if (sortedRasterizerSlices.length === 0) 440 if (sortedRasterizerSlices.length === 0) {
434 this.sortRasterizerSlices(rasterWorkerThreads, sortedRasterizerSlices); 441 this.sortRasterizerSlices(rasterWorkerThreads, sortedRasterizerSlices);
442 }
435 443
436 // TODO(yuhao): Once TaskSetFinishedTaskImpl also get the prepareTileId 444 // TODO(yuhao): Once TaskSetFinishedTaskImpl also get the prepareTileId
437 // we can simply track by checking id rather than counting. 445 // we can simply track by checking id rather than counting.
438 var numFinishedTasks = 0; 446 var numFinishedTasks = 0;
439 var RASTER_TASK_TITLE = 'RasterizerTaskImpl::RunOnWorkerThread'; 447 var RASTER_TASK_TITLE = 'RasterizerTaskImpl::RunOnWorkerThread';
440 var IMAGEDECODE_TASK_TITLE = 'ImageDecodeTaskImpl::RunOnWorkerThread'; 448 var IMAGEDECODE_TASK_TITLE = 'ImageDecodeTaskImpl::RunOnWorkerThread';
441 var FINISHED_TASK_TITLE = 'TaskSetFinishedTaskImpl::RunOnWorkerThread'; 449 var FINISHED_TASK_TITLE = 'TaskSetFinishedTaskImpl::RunOnWorkerThread';
442 450
443 for (var i = 0; i < sortedRasterizerSlices.length; i++) { 451 for (var i = 0; i < sortedRasterizerSlices.length; i++) {
444 var task = sortedRasterizerSlices[i]; 452 var task = sortedRasterizerSlices[i];
445 453
446 if (task.title === RASTER_TASK_TITLE || 454 if (task.title === RASTER_TASK_TITLE ||
447 task.title === IMAGEDECODE_TASK_TITLE) { 455 task.title === IMAGEDECODE_TASK_TITLE) {
448 if (task.args.source_prepare_tiles_id === prepareTileId) 456 if (task.args.source_prepare_tiles_id === prepareTileId) {
449 this.addEntireSliceHierarchy(task.mostTopLevelSlice); 457 this.addEntireSliceHierarchy(task.mostTopLevelSlice);
458 }
450 } else if (task.title === FINISHED_TASK_TITLE) { 459 } else if (task.title === FINISHED_TASK_TITLE) {
451 if (task.start > prepareTiles.start) { 460 if (task.start > prepareTiles.start) {
452 pendingEventQueue.push(task.mostTopLevelSlice); 461 pendingEventQueue.push(task.mostTopLevelSlice);
453 if (++numFinishedTasks === 3) 462 if (++numFinishedTasks === 3) break;
454 break;
455 } 463 }
456 } 464 }
457 } 465 }
458 466
459 // Trace PostTask from rasterizer tasks. 467 // Trace PostTask from rasterizer tasks.
460 while (pendingEventQueue.length !== 0) { 468 while (pendingEventQueue.length !== 0) {
461 var event = pendingEventQueue.pop(); 469 var event = pendingEventQueue.pop();
462 470
463 this.addEntireSliceHierarchy(event); 471 this.addEntireSliceHierarchy(event);
464 this.followSubsequentSlices(event, pendingEventQueue, visited, 472 this.followSubsequentSlices(event, pendingEventQueue, visited,
(...skipping 26 matching lines...) Expand all
491 this.followCurrentSlice(event, pendingEventQueue, visitedEvents); 499 this.followCurrentSlice(event, pendingEventQueue, visitedEvents);
492 500
493 this.followSubsequentSlices(event, pendingEventQueue, visitedEvents, 501 this.followSubsequentSlices(event, pendingEventQueue, visitedEvents,
494 flowEvents); 502 flowEvents);
495 503
496 // The rasterization work (CompositorTileWorker thread) and the 504 // The rasterization work (CompositorTileWorker thread) and the
497 // Compositor tile manager are connect by the prepare_tiles_id 505 // Compositor tile manager are connect by the prepare_tiles_id
498 // instead of flow events. 506 // instead of flow events.
499 var COMPOSITOR_PREPARE_TILES = 'TileManager::PrepareTiles'; 507 var COMPOSITOR_PREPARE_TILES = 'TileManager::PrepareTiles';
500 prepareTiles = event.findDescendentSlice(COMPOSITOR_PREPARE_TILES); 508 prepareTiles = event.findDescendentSlice(COMPOSITOR_PREPARE_TILES);
501 if (prepareTiles) 509 if (prepareTiles) {
502 this.addRasterizationEvents(prepareTiles, rendererHelper, 510 this.addRasterizationEvents(prepareTiles, rendererHelper,
503 visitedEvents, flowEvents, sortedRasterizerSlices); 511 visitedEvents, flowEvents, sortedRasterizerSlices);
512 }
504 513
505 // OnBeginImplFrameDeadline could be triggered by other inputs. 514 // OnBeginImplFrameDeadline could be triggered by other inputs.
506 // For now, we backtrace from it. 515 // For now, we backtrace from it.
507 // TODO(yuhao): There are more such slices that we need to backtrace 516 // TODO(yuhao): There are more such slices that we need to backtrace
508 var COMPOSITOR_ON_BIFD = 'Scheduler::OnBeginImplFrameDeadline'; 517 var COMPOSITOR_ON_BIFD = 'Scheduler::OnBeginImplFrameDeadline';
509 beginImplFrame = event.findDescendentSlice(COMPOSITOR_ON_BIFD); 518 beginImplFrame = event.findDescendentSlice(COMPOSITOR_ON_BIFD);
510 if (beginImplFrame) 519 if (beginImplFrame) {
511 this.backtraceFromDraw(beginImplFrame, visitedEvents); 520 this.backtraceFromDraw(beginImplFrame, visitedEvents);
521 }
512 } 522 }
513 523
514 // A separate pass on GestureScrollUpdate. 524 // A separate pass on GestureScrollUpdate.
515 // Scroll update doesn't go through the main thread, but the compositor 525 // Scroll update doesn't go through the main thread, but the compositor
516 // may go back to the main thread if there is an onscroll event handler. 526 // may go back to the main thread if there is an onscroll event handler.
517 // This is captured by a different flow event, which does not have the 527 // This is captured by a different flow event, which does not have the
518 // same ID as the Input Latency Event, but it is technically causally 528 // same ID as the Input Latency Event, but it is technically causally
519 // related to the GestureScrollUpdate input. Add them manually for now. 529 // related to the GestureScrollUpdate input. Add them manually for now.
520 var INPUT_GSU = 'InputLatency::GestureScrollUpdate'; 530 var INPUT_GSU = 'InputLatency::GestureScrollUpdate';
521 if (this.title === INPUT_GSU) 531 if (this.title === INPUT_GSU) {
522 this.addScrollUpdateEvents(rendererHelper); 532 this.addScrollUpdateEvents(rendererHelper);
533 }
523 }, 534 },
524 535
525 get associatedEvents() { 536 get associatedEvents() {
526 if (this.associatedEvents_.length !== 0) 537 if (this.associatedEvents_.length !== 0) {
527 return this.associatedEvents_; 538 return this.associatedEvents_;
539 }
528 540
529 var modelIndices = this.startThread.parent.model.modelIndices; 541 var modelIndices = this.startThread.parent.model.modelIndices;
530 var flowEvents = modelIndices.getFlowEventsWithId(this.id); 542 var flowEvents = modelIndices.getFlowEventsWithId(this.id);
531 543
532 if (flowEvents.length === 0) 544 if (flowEvents.length === 0) {
533 return this.associatedEvents_; 545 return this.associatedEvents_;
546 }
534 547
535 // Step 1: Get events that are directly connected by the LatencyInfo 548 // Step 1: Get events that are directly connected by the LatencyInfo
536 // flow events. This gives us a small set of events that are guaranteed 549 // flow events. This gives us a small set of events that are guaranteed
537 // to be associated with the input, but are almost certain incomplete. 550 // to be associated with the input, but are almost certain incomplete.
538 // We call this set "source" event set. 551 // We call this set "source" event set.
539 // This step returns the "source" event set (sourceSlices), which is then 552 // This step returns the "source" event set (sourceSlices), which is then
540 // used in the second step. 553 // used in the second step.
541 var sourceSlices = this.addDirectlyAssociatedEvents(flowEvents); 554 var sourceSlices = this.addDirectlyAssociatedEvents(flowEvents);
542 555
543 // Step 2: Start from the previously constructed "source" event set, we 556 // Step 2: Start from the previously constructed "source" event set, we
544 // follow the toplevel (i.e., PostTask) and IPC flow events. Any slices 557 // follow the toplevel (i.e., PostTask) and IPC flow events. Any slices
545 // that are reachable from the "source" event set via PostTasks or IPCs 558 // that are reachable from the "source" event set via PostTasks or IPCs
546 // are conservatively considered associated with the input event. 559 // are conservatively considered associated with the input event.
547 // We then deal with specific cases where flow events either over include 560 // We then deal with specific cases where flow events either over include
548 // or miss capturing slices. 561 // or miss capturing slices.
549 var rendererHelper = this.getRendererHelper(sourceSlices); 562 var rendererHelper = this.getRendererHelper(sourceSlices);
550 this.addOtherCausallyRelatedEvents(rendererHelper, sourceSlices, 563 this.addOtherCausallyRelatedEvents(rendererHelper, sourceSlices,
551 flowEvents); 564 flowEvents);
552 565
553 return this.associatedEvents_; 566 return this.associatedEvents_;
554 }, 567 },
555 568
556 get inputLatency() { 569 get inputLatency() {
557 if (!('data' in this.args)) 570 if (!('data' in this.args)) return undefined;
558 return undefined;
559 571
560 var data = this.args.data; 572 var data = this.args.data;
561 if (!(END_COMP_NAME in data)) 573 if (!(END_COMP_NAME in data)) return undefined;
562 return undefined;
563 574
564 var latency = 0; 575 var latency = 0;
565 var endTime = data[END_COMP_NAME].time; 576 var endTime = data[END_COMP_NAME].time;
566 if (ORIGINAL_COMP_NAME in data) { 577 if (ORIGINAL_COMP_NAME in data) {
567 latency = endTime - data[ORIGINAL_COMP_NAME].time; 578 latency = endTime - data[ORIGINAL_COMP_NAME].time;
568 } else if (UI_COMP_NAME in data) { 579 } else if (UI_COMP_NAME in data) {
569 latency = endTime - data[UI_COMP_NAME].time; 580 latency = endTime - data[UI_COMP_NAME].time;
570 } else if (BEGIN_COMP_NAME in data) { 581 } else if (BEGIN_COMP_NAME in data) {
571 latency = endTime - data[BEGIN_COMP_NAME].time; 582 latency = endTime - data[BEGIN_COMP_NAME].time;
572 } else { 583 } else {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 typeNames: allTypeNames, 633 typeNames: allTypeNames,
623 categoryParts: ['latencyInfo'] 634 categoryParts: ['latencyInfo']
624 }); 635 });
625 636
626 return { 637 return {
627 InputLatencyAsyncSlice, 638 InputLatencyAsyncSlice,
628 INPUT_EVENT_TYPE_NAMES, 639 INPUT_EVENT_TYPE_NAMES,
629 }; 640 };
630 }); 641 });
631 </script> 642 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698