OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 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 from operator import attrgetter | 5 from operator import attrgetter |
6 | 6 |
7 # These are LatencyInfo component names indicating the various components | 7 # These are LatencyInfo component names indicating the various components |
8 # that the input event has travelled through. | 8 # that the input event has travelled through. |
9 # This is when the input event first reaches chrome. | 9 # This is when the input event first reaches chrome. |
10 UI_COMP_NAME = 'INPUT_EVENT_LATENCY_UI_COMPONENT' | 10 UI_COMP_NAME = 'INPUT_EVENT_LATENCY_UI_COMPONENT' |
11 # This is when the input event was originally created by OS. | 11 # This is when the input event was originally created by OS. |
12 ORIGINAL_COMP_NAME = 'INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT' | 12 ORIGINAL_COMP_NAME = 'INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT' |
13 # This is when the input event was sent from browser to renderer. | 13 # This is when the input event was sent from browser to renderer. |
14 BEGIN_COMP_NAME = 'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT' | 14 BEGIN_COMP_NAME = 'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT' |
15 # This is when the input event has reached swap buffer. | 15 # This is when the input event has reached swap buffer. |
16 END_COMP_NAME = 'INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT' | 16 END_COMP_NAME = 'INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT' |
17 | 17 |
18 def GetScrollInputLatencyEvents(browser_process, timeline_range): | 18 def GetScrollInputLatencyEvents(scroll_type, browser_process, timeline_range): |
19 """Get scroll events' LatencyInfo from the browser process's trace buffer | 19 """Get scroll events' LatencyInfo from the browser process's trace buffer |
20 that are within the timeline_range. | 20 that are within the timeline_range. |
21 | 21 |
22 Scroll events (MouseWheel, GestureScrollUpdate or JS scroll on TouchMove) | 22 Scroll events (MouseWheel, GestureScrollUpdate or JS scroll on TouchMove) |
23 dump their LatencyInfo into trace buffer as async trace event with name | 23 dump their LatencyInfo into trace buffer as async trace event with name |
24 "InputLatency". The trace event has a memeber 'step' containing its event | 24 "InputLatency". The trace event has a memeber 'step' containing its event |
25 type and a memeber 'data' containing its latency history. | 25 type and a memeber 'data' containing its latency history. |
26 | 26 |
27 """ | 27 """ |
28 mouse_wheel_events = [] | 28 scroll_events = [] |
29 touch_scroll_events = [] | |
30 if not browser_process: | 29 if not browser_process: |
31 return (mouse_wheel_events, touch_scroll_events) | 30 return scroll_events |
32 for event in browser_process.IterAllAsyncSlicesOfName("InputLatency"): | 31 for event in browser_process.IterAllAsyncSlicesOfName("InputLatency"): |
33 if event.start >= timeline_range.min and event.end <= timeline_range.max: | 32 if event.start >= timeline_range.min and event.end <= timeline_range.max: |
34 for ss in event.sub_slices: | 33 for ss in event.sub_slices: |
35 if 'step' not in ss.args: | 34 if 'step' not in ss.args: |
36 continue | 35 continue |
37 if 'data' not in ss.args: | 36 if 'data' not in ss.args: |
38 continue | 37 continue |
39 if ss.args['step'] == 'MouseWheel': | 38 if ss.args['step'] == scroll_type: |
40 mouse_wheel_events.append(ss) | 39 scroll_events.append(ss) |
41 elif ss.args['step'] == 'GestureScrollUpdate': | 40 return scroll_events |
42 touch_scroll_events.append(ss) | |
43 elif ss.args['step'] == 'TouchMove': | |
44 touch_scroll_events.append(ss) | |
45 return (mouse_wheel_events, touch_scroll_events) | |
46 | 41 |
47 def ComputeMouseWheelScrollLatency(mouse_wheel_events): | 42 def ComputeMouseWheelScrollLatency(mouse_wheel_events): |
48 """ Compute the mouse wheel scroll latency. | 43 """ Compute the mouse wheel scroll latency. |
49 | 44 |
50 Mouse wheel scroll latency is the time from when mouse wheel event is sent | 45 Mouse wheel scroll latency is the time from when mouse wheel event is sent |
51 from browser RWH to renderer (the timestamp of component | 46 from browser RWH to renderer (the timestamp of component |
52 'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT') to when the scrolled page is | 47 'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT') to when the scrolled page is |
53 buffer swapped (the timestamp of component | 48 buffer swapped (the timestamp of component |
54 'INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT') | 49 'INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT') |
55 | 50 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 self.frame_times = [] | 102 self.frame_times = [] |
108 self.paint_times = [] | 103 self.paint_times = [] |
109 self.painted_pixel_counts = [] | 104 self.painted_pixel_counts = [] |
110 self.record_times = [] | 105 self.record_times = [] |
111 self.recorded_pixel_counts = [] | 106 self.recorded_pixel_counts = [] |
112 self.rasterize_times = [] | 107 self.rasterize_times = [] |
113 self.rasterized_pixel_counts = [] | 108 self.rasterized_pixel_counts = [] |
114 # End-to-end latency for MouseWheel scroll - from when mouse wheel event is | 109 # End-to-end latency for MouseWheel scroll - from when mouse wheel event is |
115 # generated to when the scrolled page is buffer swapped. | 110 # generated to when the scrolled page is buffer swapped. |
116 self.mouse_wheel_scroll_latency = [] | 111 self.mouse_wheel_scroll_latency = [] |
117 # End-to-end latency for touch scroll event - from when the touch event is | 112 # End-to-end latency for GestureScrollUpdate scroll - from when the touch |
118 # generated to the scrolled page is buffer swapped. | 113 # event is generated to the scrolled page is buffer swapped. |
119 self.touch_scroll_latency = [] | 114 self.touch_scroll_latency = [] |
| 115 # End-to-end latency for JS touch handler scrolling - from when the touch |
| 116 # event is generated to the scrolled page is buffer swapped. |
| 117 self.js_touch_scroll_latency = [] |
120 | 118 |
121 for timeline_range in timeline_ranges: | 119 for timeline_range in timeline_ranges: |
122 self.frame_timestamps.append([]) | 120 self.frame_timestamps.append([]) |
123 self.frame_times.append([]) | 121 self.frame_times.append([]) |
124 self.paint_times.append([]) | 122 self.paint_times.append([]) |
125 self.painted_pixel_counts.append([]) | 123 self.painted_pixel_counts.append([]) |
126 self.record_times.append([]) | 124 self.record_times.append([]) |
127 self.recorded_pixel_counts.append([]) | 125 self.recorded_pixel_counts.append([]) |
128 self.rasterize_times.append([]) | 126 self.rasterize_times.append([]) |
129 self.rasterized_pixel_counts.append([]) | 127 self.rasterized_pixel_counts.append([]) |
130 self.mouse_wheel_scroll_latency.append([]) | 128 self.mouse_wheel_scroll_latency.append([]) |
131 self.touch_scroll_latency.append([]) | 129 self.touch_scroll_latency.append([]) |
| 130 self.js_touch_scroll_latency.append([]) |
132 | 131 |
133 if timeline_range.is_empty: | 132 if timeline_range.is_empty: |
134 continue | 133 continue |
135 self.initMainThreadStatsFromTimeline(timeline_range) | 134 self.initMainThreadStatsFromTimeline(timeline_range) |
136 self.initImplThreadStatsFromTimeline(timeline_range) | 135 self.initImplThreadStatsFromTimeline(timeline_range) |
137 self.initScrollLatencyStatsFromTimeline(browser_process, timeline_range) | 136 self.initScrollLatencyStatsFromTimeline(browser_process, timeline_range) |
138 | 137 |
139 def initScrollLatencyStatsFromTimeline(self, browser_process, timeline_range): | 138 def initScrollLatencyStatsFromTimeline(self, browser_process, timeline_range): |
140 mouse_wheel_events, touch_scroll_events = GetScrollInputLatencyEvents( | 139 mouse_wheel_events = GetScrollInputLatencyEvents( |
141 browser_process, timeline_range) | 140 "MouseWheel", browser_process, timeline_range) |
142 self.mouse_wheel_scroll_latency = ComputeMouseWheelScrollLatency( | 141 self.mouse_wheel_scroll_latency = ComputeMouseWheelScrollLatency( |
143 mouse_wheel_events) | 142 mouse_wheel_events) |
| 143 |
| 144 touch_scroll_events = GetScrollInputLatencyEvents( |
| 145 "GestureScrollUpdate", browser_process, timeline_range) |
144 self.touch_scroll_latency = ComputeTouchScrollLatency(touch_scroll_events) | 146 self.touch_scroll_latency = ComputeTouchScrollLatency(touch_scroll_events) |
145 | 147 |
| 148 js_touch_scroll_events = GetScrollInputLatencyEvents( |
| 149 "TouchMove", browser_process, timeline_range) |
| 150 self.js_touch_scroll_latency = ComputeTouchScrollLatency( |
| 151 js_touch_scroll_events) |
| 152 |
146 def initMainThreadStatsFromTimeline(self, timeline_range): | 153 def initMainThreadStatsFromTimeline(self, timeline_range): |
147 event_name = 'BenchmarkInstrumentation::MainThreadRenderingStats' | 154 event_name = 'BenchmarkInstrumentation::MainThreadRenderingStats' |
148 events = [] | 155 events = [] |
149 for event in self.renderer_process.IterAllSlicesOfName(event_name): | 156 for event in self.renderer_process.IterAllSlicesOfName(event_name): |
150 if event.start >= timeline_range.min and event.end <= timeline_range.max: | 157 if event.start >= timeline_range.min and event.end <= timeline_range.max: |
151 if 'data' not in event.args: | 158 if 'data' not in event.args: |
152 continue | 159 continue |
153 events.append(event) | 160 events.append(event) |
154 events.sort(key=attrgetter('start')) | 161 events.sort(key=attrgetter('start')) |
155 | 162 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 self.frame_timestamps[-1].append( | 200 self.frame_timestamps[-1].append( |
194 event.start) | 201 event.start) |
195 if not first_frame: | 202 if not first_frame: |
196 self.frame_times[-1].append(round(self.frame_timestamps[-1][-1] - | 203 self.frame_times[-1].append(round(self.frame_timestamps[-1][-1] - |
197 self.frame_timestamps[-1][-2], 2)) | 204 self.frame_timestamps[-1][-2], 2)) |
198 first_frame = False | 205 first_frame = False |
199 self.rasterize_times[-1].append(1000.0 * | 206 self.rasterize_times[-1].append(1000.0 * |
200 event.args['data']['rasterize_time']) | 207 event.args['data']['rasterize_time']) |
201 self.rasterized_pixel_counts[-1].append( | 208 self.rasterized_pixel_counts[-1].append( |
202 event.args['data']['rasterized_pixel_count']) | 209 event.args['data']['rasterized_pixel_count']) |
OLD | NEW |