OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 import random | 5 import random |
6 import unittest | 6 import unittest |
7 | 7 |
8 import telemetry.timeline.async_slice as tracing_async_slice | 8 import telemetry.timeline.async_slice as tracing_async_slice |
9 import telemetry.timeline.bounds as timeline_bounds | 9 import telemetry.timeline.bounds as timeline_bounds |
10 from telemetry.timeline import model | 10 from telemetry.timeline import model |
11 from telemetry.util.statistics import DivideIfPossibleOrZero | 11 from telemetry.util.statistics import DivideIfPossibleOrZero |
12 from telemetry.web_perf.metrics.rendering_stats import ( | 12 from telemetry.web_perf.metrics.rendering_stats import ( |
13 UI_COMP_NAME, BEGIN_COMP_NAME, ORIGINAL_COMP_NAME, | 13 BEGIN_COMP_NAME, |
14 BEGIN_SCROLL_UPDATE_COMP_NAME, FORWARD_SCROLL_UPDATE_COMP_NAME, | 14 BEGIN_SCROLL_UPDATE_COMP_NAME, |
15 END_COMP_NAME) | 15 END_COMP_NAME, |
| 16 FORWARD_SCROLL_UPDATE_COMP_NAME, |
| 17 GESTURE_SCROLL_UPDATE_EVENT_NAME, |
| 18 ORIGINAL_COMP_NAME, |
| 19 SCROLL_UPDATE_EVENT_NAME, |
| 20 UI_COMP_NAME) |
16 from telemetry.web_perf.metrics.rendering_stats import ( | 21 from telemetry.web_perf.metrics.rendering_stats import ( |
17 ComputeInputEventLatencies) | 22 ComputeInputEventLatencies) |
18 from telemetry.web_perf.metrics.rendering_stats import GetInputLatencyEvents | 23 from telemetry.web_perf.metrics.rendering_stats import GetInputLatencyEvents |
19 from telemetry.web_perf.metrics.rendering_stats import HasRenderingStats | 24 from telemetry.web_perf.metrics.rendering_stats import HasRenderingStats |
20 from telemetry.web_perf.metrics.rendering_stats import NotEnoughFramesError | 25 from telemetry.web_perf.metrics.rendering_stats import NotEnoughFramesError |
21 from telemetry.web_perf.metrics.rendering_stats import RenderingStats | 26 from telemetry.web_perf.metrics.rendering_stats import RenderingStats |
22 | 27 |
23 | 28 |
24 class MockTimer(object): | 29 class MockTimer(object): |
25 """A mock timer class which can generate random durations. | 30 """A mock timer class which can generate random durations. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 self.recorded_pixel_counts.append([]) | 67 self.recorded_pixel_counts.append([]) |
63 self.rasterize_times.append([]) | 68 self.rasterize_times.append([]) |
64 self.rasterized_pixel_counts.append([]) | 69 self.rasterized_pixel_counts.append([]) |
65 self.approximated_pixel_percentages.append([]) | 70 self.approximated_pixel_percentages.append([]) |
66 | 71 |
67 class ReferenceInputLatencyStats(object): | 72 class ReferenceInputLatencyStats(object): |
68 """ Stores expected data for comparison with actual input latency stats """ | 73 """ Stores expected data for comparison with actual input latency stats """ |
69 def __init__(self): | 74 def __init__(self): |
70 self.input_event_latency = [] | 75 self.input_event_latency = [] |
71 self.input_event = [] | 76 self.input_event = [] |
72 self.scroll_update_latency = [] | |
73 | 77 |
74 def AddMainThreadRenderingStats(mock_timer, thread, first_frame, | 78 def AddMainThreadRenderingStats(mock_timer, thread, first_frame, |
75 ref_stats = None): | 79 ref_stats = None): |
76 """ Adds a random main thread rendering stats event. | 80 """ Adds a random main thread rendering stats event. |
77 | 81 |
78 thread: The timeline model thread to which the event will be added. | 82 thread: The timeline model thread to which the event will be added. |
79 first_frame: Is this the first frame within the bounds of an action? | 83 first_frame: Is this the first frame within the bounds of an action? |
80 ref_stats: A ReferenceRenderingStats object to record expected values. | 84 ref_stats: A ReferenceRenderingStats object to record expected values. |
81 """ | 85 """ |
82 # Create randonm data and timestap for main thread rendering stats. | 86 # Create randonm data and timestap for main thread rendering stats. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 UI_COMP_NAME: {'time': ui_comp_time}, | 180 UI_COMP_NAME: {'time': ui_comp_time}, |
177 BEGIN_COMP_NAME: {'time': begin_comp_time}, | 181 BEGIN_COMP_NAME: {'time': begin_comp_time}, |
178 END_COMP_NAME: {'time': end_comp_time} } | 182 END_COMP_NAME: {'time': end_comp_time} } |
179 | 183 |
180 timestamp = mock_timer.Get() | 184 timestamp = mock_timer.Get() |
181 | 185 |
182 async_slice = tracing_async_slice.AsyncSlice( | 186 async_slice = tracing_async_slice.AsyncSlice( |
183 'benchmark', 'InputLatency', timestamp) | 187 'benchmark', 'InputLatency', timestamp) |
184 | 188 |
185 async_sub_slice = tracing_async_slice.AsyncSlice( | 189 async_sub_slice = tracing_async_slice.AsyncSlice( |
186 'benchmark', 'InputLatency', timestamp) | 190 'benchmark', GESTURE_SCROLL_UPDATE_EVENT_NAME, timestamp) |
187 async_sub_slice.args = {'data': data} | 191 async_sub_slice.args = {'data': data} |
188 async_sub_slice.parent_slice = async_slice | 192 async_sub_slice.parent_slice = async_slice |
189 async_sub_slice.start_thread = start_thread | 193 async_sub_slice.start_thread = start_thread |
190 async_sub_slice.end_thread = end_thread | 194 async_sub_slice.end_thread = end_thread |
191 | 195 |
192 async_slice.sub_slices.append(async_sub_slice) | 196 async_slice.sub_slices.append(async_sub_slice) |
193 async_slice.start_thread = start_thread | 197 async_slice.start_thread = start_thread |
194 async_slice.end_thread = end_thread | 198 async_slice.end_thread = end_thread |
195 start_thread.AddAsyncSlice(async_slice) | 199 start_thread.AddAsyncSlice(async_slice) |
196 | 200 |
197 # Add scroll update latency info. | 201 # Add scroll update latency info. |
198 scroll_update_data = { | 202 scroll_update_data = { |
199 BEGIN_SCROLL_UPDATE_COMP_NAME: {'time': begin_comp_time}, | 203 BEGIN_SCROLL_UPDATE_COMP_NAME: {'time': begin_comp_time}, |
200 FORWARD_SCROLL_UPDATE_COMP_NAME: {'time': forward_comp_time}, | 204 FORWARD_SCROLL_UPDATE_COMP_NAME: {'time': forward_comp_time}, |
201 END_COMP_NAME: {'time': end_comp_time} } | 205 END_COMP_NAME: {'time': end_comp_time} } |
202 | 206 |
203 scroll_async_slice = tracing_async_slice.AsyncSlice( | 207 scroll_async_slice = tracing_async_slice.AsyncSlice( |
204 'benchmark', 'InputLatency', timestamp) | 208 'benchmark', 'InputLatency', timestamp) |
205 | 209 |
206 scroll_async_sub_slice = tracing_async_slice.AsyncSlice( | 210 scroll_async_sub_slice = tracing_async_slice.AsyncSlice( |
207 'benchmark', 'InputLatency', timestamp) | 211 'benchmark', SCROLL_UPDATE_EVENT_NAME, timestamp) |
208 scroll_async_sub_slice.args = {'data': scroll_update_data} | 212 scroll_async_sub_slice.args = {'data': scroll_update_data} |
209 scroll_async_sub_slice.parent_slice = scroll_async_slice | 213 scroll_async_sub_slice.parent_slice = scroll_async_slice |
210 scroll_async_sub_slice.start_thread = start_thread | 214 scroll_async_sub_slice.start_thread = start_thread |
211 scroll_async_sub_slice.end_thread = end_thread | 215 scroll_async_sub_slice.end_thread = end_thread |
212 | 216 |
213 scroll_async_slice.sub_slices.append(scroll_async_sub_slice) | 217 scroll_async_slice.sub_slices.append(scroll_async_sub_slice) |
214 scroll_async_slice.start_thread = start_thread | 218 scroll_async_slice.start_thread = start_thread |
215 scroll_async_slice.end_thread = end_thread | 219 scroll_async_slice.end_thread = end_thread |
216 start_thread.AddAsyncSlice(scroll_async_slice) | 220 start_thread.AddAsyncSlice(scroll_async_slice) |
217 | 221 |
218 if not ref_latency_stats: | 222 if not ref_latency_stats: |
219 return | 223 return |
220 | 224 |
221 ref_latency_stats.input_event.append(async_sub_slice) | 225 ref_latency_stats.input_event.append(async_sub_slice) |
222 ref_latency_stats.input_event.append(scroll_async_sub_slice) | 226 ref_latency_stats.input_event.append(scroll_async_sub_slice) |
223 ref_latency_stats.input_event_latency.append( | 227 ref_latency_stats.input_event_latency.append(( |
224 (data[END_COMP_NAME]['time'] - data[ORIGINAL_COMP_NAME]['time']) / 1000.0) | 228 GESTURE_SCROLL_UPDATE_EVENT_NAME, |
225 ref_latency_stats.scroll_update_latency.append( | 229 (data[END_COMP_NAME]['time'] - |
| 230 data[ORIGINAL_COMP_NAME]['time']) / 1000.0)) |
| 231 ref_latency_stats.input_event_latency.append(( |
| 232 SCROLL_UPDATE_EVENT_NAME, |
226 (scroll_update_data[END_COMP_NAME]['time'] - | 233 (scroll_update_data[END_COMP_NAME]['time'] - |
227 scroll_update_data[BEGIN_SCROLL_UPDATE_COMP_NAME]['time']) / 1000.0) | 234 scroll_update_data[BEGIN_SCROLL_UPDATE_COMP_NAME]['time']) / 1000.0)) |
228 | 235 |
229 | 236 |
230 class RenderingStatsUnitTest(unittest.TestCase): | 237 class RenderingStatsUnitTest(unittest.TestCase): |
231 def testHasRenderingStats(self): | 238 def testHasRenderingStats(self): |
232 timeline = model.TimelineModel() | 239 timeline = model.TimelineModel() |
233 timer = MockTimer() | 240 timer = MockTimer() |
234 | 241 |
235 # A process without rendering stats | 242 # A process without rendering stats |
236 process_without_stats = timeline.GetOrCreateProcess(pid = 1) | 243 process_without_stats = timeline.GetOrCreateProcess(pid = 1) |
237 thread_without_stats = process_without_stats.GetOrCreateThread(tid = 11) | 244 thread_without_stats = process_without_stats.GetOrCreateThread(tid = 11) |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 | 450 |
444 timeline_markers = timeline.FindTimelineMarkers( | 451 timeline_markers = timeline.FindTimelineMarkers( |
445 ['ActionA', 'ActionB', 'ActionA']) | 452 ['ActionA', 'ActionB', 'ActionA']) |
446 for timeline_range in [ timeline_bounds.Bounds.CreateFromEvent(marker) | 453 for timeline_range in [ timeline_bounds.Bounds.CreateFromEvent(marker) |
447 for marker in timeline_markers ]: | 454 for marker in timeline_markers ]: |
448 if timeline_range.is_empty: | 455 if timeline_range.is_empty: |
449 continue | 456 continue |
450 input_events.extend(GetInputLatencyEvents(browser, timeline_range)) | 457 input_events.extend(GetInputLatencyEvents(browser, timeline_range)) |
451 | 458 |
452 self.assertEquals(input_events, ref_latency.input_event) | 459 self.assertEquals(input_events, ref_latency.input_event) |
453 input_event_latency_result, scroll_update_latency_result = ( | 460 input_event_latency_result = ComputeInputEventLatencies(input_events) |
454 ComputeInputEventLatencies(input_events)) | |
455 self.assertEquals(input_event_latency_result, | 461 self.assertEquals(input_event_latency_result, |
456 ref_latency.input_event_latency) | 462 ref_latency.input_event_latency) |
457 self.assertEquals(scroll_update_latency_result, | |
458 ref_latency.scroll_update_latency) | |
OLD | NEW |