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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/timeline/TimelineIRModel.js

Issue 1729603002: DevTools: Extract SegmentedRange from TimelineIRModel to utilities.js (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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
« no previous file with comments | « third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @constructor 6 * @constructor
7 */ 7 */
8 WebInspector.TimelineIRModel = function() 8 WebInspector.TimelineIRModel = function()
9 { 9 {
10 this.reset(); 10 this.reset();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 75
76 var groups = WebInspector.TimelineUIUtils.asyncEventGroups(); 76 var groups = WebInspector.TimelineUIUtils.asyncEventGroups();
77 var asyncEventsByGroup = timelineModel.mainThreadAsyncEvents(); 77 var asyncEventsByGroup = timelineModel.mainThreadAsyncEvents();
78 var inputLatencies = asyncEventsByGroup.get(groups.input); 78 var inputLatencies = asyncEventsByGroup.get(groups.input);
79 if (!inputLatencies) 79 if (!inputLatencies)
80 return; 80 return;
81 this._processInputLatencies(inputLatencies); 81 this._processInputLatencies(inputLatencies);
82 var animations = asyncEventsByGroup.get(groups.animation); 82 var animations = asyncEventsByGroup.get(groups.animation);
83 if (animations) 83 if (animations)
84 this._processAnimations(animations); 84 this._processAnimations(animations);
85 var range = new WebInspector.SegmentedRange(); 85 var range = new SegmentedRange();
86 range.appendRange(this._drags); // Drags take lower precedence than anim ation, as we can't detect them reliably. 86 range.appendRange(this._drags); // Drags take lower precedence than anim ation, as we can't detect them reliably.
87 range.appendRange(this._cssAnimations); 87 range.appendRange(this._cssAnimations);
88 range.appendRange(this._scrolls); 88 range.appendRange(this._scrolls);
89 range.appendRange(this._responses); 89 range.appendRange(this._responses);
90 this._segments = range.segments(); 90 this._segments = range.segments();
91 }, 91 },
92 92
93 /** 93 /**
94 * @param {!Array<!WebInspector.TracingModel.AsyncEvent>} events 94 * @param {!Array<!WebInspector.TracingModel.AsyncEvent>} events
95 */ 95 */
(...skipping 26 matching lines...) Expand all
122 WebInspector.console.error(WebInspector.UIString("Two flings at the same time? %s vs %s", flingStart.startTime, event.startTime)); 122 WebInspector.console.error(WebInspector.UIString("Two flings at the same time? %s vs %s", flingStart.startTime, event.startTime));
123 break; 123 break;
124 } 124 }
125 flingStart = event; 125 flingStart = event;
126 break; 126 break;
127 127
128 case eventTypes.FlingCancel: 128 case eventTypes.FlingCancel:
129 // FIXME: also process renderer fling events. 129 // FIXME: also process renderer fling events.
130 if (!flingStart) 130 if (!flingStart)
131 break; 131 break;
132 this._scrolls.append(new WebInspector.Segment(flingStart.startTi me, event.endTime, phases.Fling)); 132 this._scrolls.append(new Segment(flingStart.startTime, event.end Time, phases.Fling));
133 flingStart = null; 133 flingStart = null;
134 break; 134 break;
135 135
136 case eventTypes.ImplSideFling: 136 case eventTypes.ImplSideFling:
137 this._scrolls.append(this._segmentForEvent(event, phases.Fling)) ; 137 this._scrolls.append(this._segmentForEvent(event, phases.Fling)) ;
138 break; 138 break;
139 139
140 case eventTypes.ShowPress: 140 case eventTypes.ShowPress:
141 case eventTypes.Tap: 141 case eventTypes.Tap:
142 case eventTypes.KeyDown: 142 case eventTypes.KeyDown:
(...skipping 18 matching lines...) Expand all
161 161
162 case eventTypes.TouchCancel: 162 case eventTypes.TouchCancel:
163 touchStart = null; 163 touchStart = null;
164 break; 164 break;
165 165
166 case eventTypes.TouchMove: 166 case eventTypes.TouchMove:
167 if (firstTouchMove) { 167 if (firstTouchMove) {
168 this._drags.append(this._segmentForEvent(event, phases.Drag) ); 168 this._drags.append(this._segmentForEvent(event, phases.Drag) );
169 } else if (touchStart) { 169 } else if (touchStart) {
170 firstTouchMove = event; 170 firstTouchMove = event;
171 this._responses.append(new WebInspector.Segment(touchStart.s tartTime, event.endTime, phases.Response)); 171 this._responses.append(new Segment(touchStart.startTime, eve nt.endTime, phases.Response));
172 } 172 }
173 break; 173 break;
174 174
175 case eventTypes.TouchEnd: 175 case eventTypes.TouchEnd:
176 touchStart = null; 176 touchStart = null;
177 break; 177 break;
178 178
179 case eventTypes.MouseDown: 179 case eventTypes.MouseDown:
180 mouseDown = event; 180 mouseDown = event;
181 mouseMove = null; 181 mouseMove = null;
(...skipping 10 matching lines...) Expand all
192 break; 192 break;
193 193
194 case eventTypes.MouseUp: 194 case eventTypes.MouseUp:
195 this._responses.append(this._segmentForEvent(event, phases.Respo nse)); 195 this._responses.append(this._segmentForEvent(event, phases.Respo nse));
196 mouseDown = null; 196 mouseDown = null;
197 break; 197 break;
198 198
199 case eventTypes.MouseWheel: 199 case eventTypes.MouseWheel:
200 // Do not consider first MouseWheel as trace viewer's implementa tion does -- in case of MouseWheel it's not really special. 200 // Do not consider first MouseWheel as trace viewer's implementa tion does -- in case of MouseWheel it's not really special.
201 if (mouseWheel && canMerge(thresholdsMs.mouse, mouseWheel, event )) 201 if (mouseWheel && canMerge(thresholdsMs.mouse, mouseWheel, event ))
202 this._scrolls.append(new WebInspector.Segment(mouseWheel.end Time, event.startTime, phases.Scroll)); 202 this._scrolls.append(new Segment(mouseWheel.endTime, event.s tartTime, phases.Scroll));
203 this._scrolls.append(this._segmentForEvent(event, phases.Scroll) ); 203 this._scrolls.append(this._segmentForEvent(event, phases.Scroll) );
204 mouseWheel = event; 204 mouseWheel = event;
205 break; 205 break;
206 } 206 }
207 } 207 }
208 208
209 /** 209 /**
210 * @param {number} threshold 210 * @param {number} threshold
211 * @param {!WebInspector.TracingModel.AsyncEvent} first 211 * @param {!WebInspector.TracingModel.AsyncEvent} first
212 * @param {!WebInspector.TracingModel.AsyncEvent} second 212 * @param {!WebInspector.TracingModel.AsyncEvent} second
(...skipping 10 matching lines...) Expand all
223 */ 223 */
224 _processAnimations: function(events) 224 _processAnimations: function(events)
225 { 225 {
226 for (var i = 0; i < events.length; ++i) 226 for (var i = 0; i < events.length; ++i)
227 this._cssAnimations.append(this._segmentForEvent(events[i], WebInspe ctor.TimelineIRModel.Phases.Animation)); 227 this._cssAnimations.append(this._segmentForEvent(events[i], WebInspe ctor.TimelineIRModel.Phases.Animation));
228 }, 228 },
229 229
230 /** 230 /**
231 * @param {!WebInspector.TracingModel.AsyncEvent} event 231 * @param {!WebInspector.TracingModel.AsyncEvent} event
232 * @param {!WebInspector.TimelineIRModel.Phases} phase 232 * @param {!WebInspector.TimelineIRModel.Phases} phase
233 * @return {!WebInspector.Segment} 233 * @return {!Segment}
234 */ 234 */
235 _segmentForEvent: function(event, phase) 235 _segmentForEvent: function(event, phase)
236 { 236 {
237 return new WebInspector.Segment(event.startTime, event.endTime, phase); 237 return new Segment(event.startTime, event.endTime, phase);
238 }, 238 },
239 239
240 /** 240 /**
241 * @return {!Array<!WebInspector.Segment>} 241 * @return {!Array<!Segment>}
242 */ 242 */
243 interactionRecords: function() 243 interactionRecords: function()
244 { 244 {
245 return this._segments; 245 return this._segments;
246 }, 246 },
247 247
248 reset: function() 248 reset: function()
249 { 249 {
250 var thresholdsMs = WebInspector.TimelineIRModel._mergeThresholdsMs; 250 var thresholdsMs = WebInspector.TimelineIRModel._mergeThresholdsMs;
251 251
252 this._segments = []; 252 this._segments = [];
253 this._drags = new WebInspector.SegmentedRange(merge.bind(null, threshold sMs.mouse)); 253 this._drags = new SegmentedRange(merge.bind(null, thresholdsMs.mouse));
254 this._cssAnimations = new WebInspector.SegmentedRange(merge.bind(null, t hresholdsMs.animation)); 254 this._cssAnimations = new SegmentedRange(merge.bind(null, thresholdsMs.a nimation));
255 this._responses = new WebInspector.SegmentedRange(merge.bind(null, 0)); 255 this._responses = new SegmentedRange(merge.bind(null, 0));
256 this._scrolls = new WebInspector.SegmentedRange(merge.bind(null, thresho ldsMs.animation)); 256 this._scrolls = new SegmentedRange(merge.bind(null, thresholdsMs.animati on));
257 257
258 /** 258 /**
259 * @param {number} threshold 259 * @param {number} threshold
260 * @param {!WebInspector.Segment} first 260 * @param {!Segment} first
261 * @param {!WebInspector.Segment} second 261 * @param {!Segment} second
262 */ 262 */
263 function merge(threshold, first, second) 263 function merge(threshold, first, second)
264 { 264 {
265 return first.end + threshold >= second.begin && first.data === secon d.data ? first : null; 265 return first.end + threshold >= second.begin && first.data === secon d.data ? first : null;
266 } 266 }
267 }, 267 },
268 268
269 /** 269 /**
270 * @param {string} eventName 270 * @param {string} eventName
271 * @return {?WebInspector.TimelineIRModel.InputEvents} 271 * @return {?WebInspector.TimelineIRModel.InputEvents}
272 */ 272 */
273 _inputEventType: function(eventName) 273 _inputEventType: function(eventName)
274 { 274 {
275 var prefix = "InputLatency::"; 275 var prefix = "InputLatency::";
276 if (!eventName.startsWith(prefix)) { 276 if (!eventName.startsWith(prefix)) {
277 if (eventName === WebInspector.TimelineIRModel.InputEvents.ImplSideF ling) 277 if (eventName === WebInspector.TimelineIRModel.InputEvents.ImplSideF ling)
278 return /** @type {!WebInspector.TimelineIRModel.InputEvents} */ (eventName); 278 return /** @type {!WebInspector.TimelineIRModel.InputEvents} */ (eventName);
279 console.error("Unrecognized input latency event: " + eventName); 279 console.error("Unrecognized input latency event: " + eventName);
280 return null; 280 return null;
281 } 281 }
282 return /** @type {!WebInspector.TimelineIRModel.InputEvents} */ (eventNa me.substr(prefix.length)); 282 return /** @type {!WebInspector.TimelineIRModel.InputEvents} */ (eventNa me.substr(prefix.length));
283 } 283 }
284 }; 284 };
285 285
286 /**
287 * @constructor
288 * @param {(function(!WebInspector.Segment, !WebInspector.Segment): ?WebInspecto r.Segment)=} mergeCallback
289 */
290 WebInspector.SegmentedRange = function(mergeCallback)
291 {
292 /** @type {!Array<!WebInspector.Segment>} */
293 this._segments = [];
294 this._mergeCallback = mergeCallback;
295 }
296
297 /**
298 * @constructor
299 * @param {number} begin
300 * @param {number} end
301 * @param {*} data
302 */
303 WebInspector.Segment = function(begin, end, data)
304 {
305 if (begin > end)
306 console.assert(false, "Invalid segment");
307 this.begin = begin;
308 this.end = end;
309 this.data = data;
310 }
311
312 WebInspector.Segment.prototype = {
313 /**
314 * @param {!WebInspector.Segment} that
315 * @return {boolean}
316 */
317 intersects: function(that)
318 {
319 return this.begin < that.end && that.begin < this.end;
320 }
321 };
322
323 WebInspector.SegmentedRange.prototype = {
324 /**
325 * @param {!WebInspector.Segment} newSegment
326 */
327 append: function(newSegment)
328 {
329 // 1. Find the proper insertion point for new segment
330 var startIndex = this._segments.lowerBound(newSegment, (a, b) => a.begin - b.begin);
331 var endIndex = startIndex;
332 var merged = null;
333 if (startIndex > 0) {
334 // 2. Try mering the preceding segment
335 var precedingSegment = this._segments[startIndex - 1];
336 merged = this._tryMerge(precedingSegment, newSegment);
337 if (merged) {
338 --startIndex;
339 newSegment = merged;
340 } else if (this._segments[startIndex - 1].end >= newSegment.begin) {
341 // 2a. If merge failed and segments overlap, adjust preceding se gment.
342 // If an old segment entirely contains new one, split it in two.
343 if (newSegment.end < precedingSegment.end)
344 this._segments.splice(startIndex, 0, new WebInspector.Segmen t(newSegment.end, precedingSegment.end, precedingSegment.data));
345 precedingSegment.end = newSegment.begin;
346 }
347 }
348 // 3. Consume all segments that are entirely covered by the new one.
349 while (endIndex < this._segments.length && this._segments[endIndex].end <= newSegment.end)
350 ++endIndex;
351 // 4. Merge or adjust the succeeding segment if it overlaps.
352 if (endIndex < this._segments.length) {
353 merged = this._tryMerge(newSegment, this._segments[endIndex]);
354 if (merged) {
355 endIndex++;
356 newSegment = merged;
357 } else if (newSegment.intersects(this._segments[endIndex]))
358 this._segments[endIndex].begin = newSegment.end;
359 }
360 this._segments.splice(startIndex, endIndex - startIndex, newSegment);
361 },
362
363 /**
364 * @param {!WebInspector.SegmentedRange} that
365 */
366 appendRange: function(that)
367 {
368 that.segments().forEach(segment => this.append(segment));
369 },
370
371 /**
372 * @return {!Array<!WebInspector.Segment>}
373 */
374 segments: function()
375 {
376 return this._segments;
377 },
378
379 /**
380 * @param {!WebInspector.Segment} first
381 * @param {!WebInspector.Segment} second
382 * @return {?WebInspector.Segment}
383 */
384 _tryMerge: function(first, second)
385 {
386 var merged = this._mergeCallback && this._mergeCallback(first, second);
387 if (!merged)
388 return null;
389 merged.begin = first.begin;
390 merged.end = Math.max(first.end, second.end);
391 return merged;
392 }
393 }
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698