| 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 import random | 5 import random |
| 6 import unittest | 6 import unittest |
| 7 | 7 |
| 8 from metrics.rendering_stats import RenderingStats | 8 from metrics.rendering_stats import RenderingStats |
| 9 import telemetry.core.timeline.bounds as timeline_bounds | 9 import telemetry.core.timeline.bounds as timeline_bounds |
| 10 from telemetry.core.timeline import model | 10 from telemetry.core.timeline import model |
| 11 import telemetry.core.timeline.async_slice as tracing_async_slice |
| 11 | 12 |
| 12 | 13 |
| 13 class MockTimer(object): | 14 class MockTimer(object): |
| 14 """A mock timer class which can generate random durations. | 15 """A mock timer class which can generate random durations. |
| 15 | 16 |
| 16 An instance of this class is used as a global timer to generate random | 17 An instance of this class is used as a global timer to generate random |
| 17 durations for stats and consistent timestamps for all mock trace events. | 18 durations for stats and consistent timestamps for all mock trace events. |
| 18 The unit of time is milliseconds. | 19 The unit of time is milliseconds. |
| 19 """ | 20 """ |
| 20 def __init__(self): | 21 def __init__(self): |
| (...skipping 12 matching lines...) Expand all Loading... |
| 33 """ Stores expected data for comparison with actual RenderingStats """ | 34 """ Stores expected data for comparison with actual RenderingStats """ |
| 34 def __init__(self): | 35 def __init__(self): |
| 35 self.frame_timestamps = [] | 36 self.frame_timestamps = [] |
| 36 self.frame_times = [] | 37 self.frame_times = [] |
| 37 self.paint_time = [] | 38 self.paint_time = [] |
| 38 self.painted_pixel_count = [] | 39 self.painted_pixel_count = [] |
| 39 self.record_time = [] | 40 self.record_time = [] |
| 40 self.recorded_pixel_count = [] | 41 self.recorded_pixel_count = [] |
| 41 self.rasterize_time = [] | 42 self.rasterize_time = [] |
| 42 self.rasterized_pixel_count = [] | 43 self.rasterized_pixel_count = [] |
| 44 self.mouse_wheel_latency = [] |
| 45 self.gesture_scroll_latency = [] |
| 46 self.touch_scroll_latency = [] |
| 43 | 47 |
| 48 def AddBrowserInputLatencyStats(mock_timer, input_type, start_thread, |
| 49 end_thread, ref_stats = None): |
| 50 """ Adds a random browser process input latency stats event. |
| 51 |
| 52 input_type: The input type for which the latency slice is generated. |
| 53 start_thread: The start thread on which the async slice is added. |
| 54 end_thread: The end thread on which the async slice is ended. |
| 55 ref_stats: A ReferenceRenderingStats object to record expected values. |
| 56 """ |
| 57 ui_comp_name = 'INPUT_EVENT_LATENCY_UI_COMPONENT' |
| 58 begin_comp_name = 'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT' |
| 59 end_comp_name = 'INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT' |
| 60 |
| 61 mock_timer.Advance() |
| 62 ui_comp_time = mock_timer.Get() * 1000.0 |
| 63 mock_timer.Advance() |
| 64 begin_comp_time = mock_timer.Get() * 1000.0 |
| 65 mock_timer.Advance(10, 20) |
| 66 end_comp_time = mock_timer.Get() * 1000.0 |
| 67 |
| 68 data = { ui_comp_name: {'time': ui_comp_time}, |
| 69 begin_comp_name: {'time': begin_comp_time}, |
| 70 end_comp_name: {'time': end_comp_time} } |
| 71 |
| 72 timestamp = mock_timer.Get() |
| 73 |
| 74 async_slice = tracing_async_slice.AsyncSlice( |
| 75 'benchmark', 'InputLatency', timestamp) |
| 76 |
| 77 async_sub_slice = tracing_async_slice.AsyncSlice( |
| 78 'benchmark', 'InputLatency', timestamp) |
| 79 async_sub_slice.args = {'data': data, 'step': input_type} |
| 80 async_sub_slice.parent_slice = async_slice |
| 81 async_sub_slice.start_thread = start_thread |
| 82 async_sub_slice.end_thread = end_thread |
| 83 |
| 84 async_slice.sub_slices.append(async_sub_slice) |
| 85 async_slice.start_thread = start_thread |
| 86 async_slice.end_thread = end_thread |
| 87 start_thread.AddAsyncSlice(async_slice) |
| 88 |
| 89 if not ref_stats: |
| 90 return |
| 91 |
| 92 if input_type == 'MouseWheel': |
| 93 ref_stats.mouse_wheel_latency.append( |
| 94 (data[end_comp_name]['time'] - data[begin_comp_name]['time']) / 1000.0) |
| 95 elif input_type == 'GestureScrollUpdate': |
| 96 ref_stats.gesture_scroll_latency.append( |
| 97 (data[end_comp_name]['time'] - data[begin_comp_name]['time']) / 1000.0) |
| 98 ref_stats.touch_scroll_latency.append( |
| 99 (data[end_comp_name]['time'] - data[ui_comp_name]['time']) / 1000.0) |
| 44 | 100 |
| 45 def AddMainThreadRenderingStats(mock_timer, thread, first_frame, | 101 def AddMainThreadRenderingStats(mock_timer, thread, first_frame, |
| 46 ref_stats = None): | 102 ref_stats = None): |
| 47 """ Adds a random main thread rendering stats event. | 103 """ Adds a random main thread rendering stats event. |
| 48 | 104 |
| 49 thread: The timeline model thread to which the event will be added. | 105 thread: The timeline model thread to which the event will be added. |
| 50 first_frame: Is this the first frame within the bounds of an action? | 106 first_frame: Is this the first frame within the bounds of an action? |
| 51 ref_stats: A ReferenceRenderingStats object to record expected values. | 107 ref_stats: A ReferenceRenderingStats object to record expected values. |
| 52 """ | 108 """ |
| 53 # Create randonm data and timestap for main thread rendering stats. | 109 # Create randonm data and timestap for main thread rendering stats. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 | 192 |
| 137 # Create 10 main and impl rendering stats events for Action A. | 193 # Create 10 main and impl rendering stats events for Action A. |
| 138 timer.Advance() | 194 timer.Advance() |
| 139 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') | 195 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') |
| 140 for i in xrange(0, 10): | 196 for i in xrange(0, 10): |
| 141 first = (i == 0) | 197 first = (i == 0) |
| 142 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) | 198 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) |
| 143 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) | 199 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) |
| 144 AddMainThreadRenderingStats(timer, browser_main, first, None) | 200 AddMainThreadRenderingStats(timer, browser_main, first, None) |
| 145 AddImplThreadRenderingStats(timer, browser_compositor, first, None) | 201 AddImplThreadRenderingStats(timer, browser_compositor, first, None) |
| 202 AddBrowserInputLatencyStats(timer, 'MouseWheel', browser_main, |
| 203 renderer_main, ref_stats) |
| 204 AddBrowserInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, |
| 205 renderer_main, ref_stats) |
| 146 renderer_main.EndSlice(timer.Get()) | 206 renderer_main.EndSlice(timer.Get()) |
| 147 | 207 |
| 148 # Create 5 main and impl rendering stats events not within any action. | 208 # Create 5 main and impl rendering stats events not within any action. |
| 149 for i in xrange(0, 5): | 209 for i in xrange(0, 5): |
| 150 first = (i == 0) | 210 first = (i == 0) |
| 151 AddMainThreadRenderingStats(timer, renderer_main, first, None) | 211 AddMainThreadRenderingStats(timer, renderer_main, first, None) |
| 152 AddImplThreadRenderingStats(timer, renderer_compositor, first, None) | 212 AddImplThreadRenderingStats(timer, renderer_compositor, first, None) |
| 153 AddMainThreadRenderingStats(timer, browser_main, first, None) | 213 AddMainThreadRenderingStats(timer, browser_main, first, None) |
| 154 AddImplThreadRenderingStats(timer, browser_compositor, first, None) | 214 AddImplThreadRenderingStats(timer, browser_compositor, first, None) |
| 215 AddBrowserInputLatencyStats(timer, 'MouseWheel', browser_main, |
| 216 renderer_main, None) |
| 217 AddBrowserInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, |
| 218 renderer_main, None) |
| 155 | 219 |
| 156 # Create 10 main and impl rendering stats events for Action B. | 220 # Create 10 main and impl rendering stats events for Action B. |
| 157 timer.Advance() | 221 timer.Advance() |
| 158 renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '') | 222 renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '') |
| 159 for i in xrange(0, 10): | 223 for i in xrange(0, 10): |
| 160 first = (i == 0) | 224 first = (i == 0) |
| 161 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) | 225 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) |
| 162 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) | 226 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) |
| 163 AddMainThreadRenderingStats(timer, browser_main, first, None) | 227 AddMainThreadRenderingStats(timer, browser_main, first, None) |
| 164 AddImplThreadRenderingStats(timer, browser_compositor, first, None) | 228 AddImplThreadRenderingStats(timer, browser_compositor, first, None) |
| 229 AddBrowserInputLatencyStats(timer, 'MouseWheel', browser_main, |
| 230 renderer_main, ref_stats) |
| 231 AddBrowserInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, |
| 232 renderer_main, ref_stats) |
| 165 renderer_main.EndSlice(timer.Get()) | 233 renderer_main.EndSlice(timer.Get()) |
| 166 | 234 |
| 167 # Create 10 main and impl rendering stats events for Action A. | 235 # Create 10 main and impl rendering stats events for Action A. |
| 168 timer.Advance() | 236 timer.Advance() |
| 169 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') | 237 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') |
| 170 for i in xrange(0, 10): | 238 for i in xrange(0, 10): |
| 171 first = (i == 0) | 239 first = (i == 0) |
| 172 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) | 240 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) |
| 173 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) | 241 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) |
| 174 AddMainThreadRenderingStats(timer, browser_main, first, None) | 242 AddMainThreadRenderingStats(timer, browser_main, first, None) |
| 175 AddImplThreadRenderingStats(timer, browser_compositor, first, None) | 243 AddImplThreadRenderingStats(timer, browser_compositor, first, None) |
| 244 AddBrowserInputLatencyStats(timer, 'MouseWheel', browser_main, |
| 245 renderer_main, ref_stats) |
| 246 AddBrowserInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, |
| 247 renderer_main, ref_stats) |
| 176 renderer_main.EndSlice(timer.Get()) | 248 renderer_main.EndSlice(timer.Get()) |
| 177 | 249 |
| 178 renderer_main.FinalizeImport() | 250 renderer_main.FinalizeImport() |
| 179 renderer_compositor.FinalizeImport() | 251 renderer_compositor.FinalizeImport() |
| 180 | 252 |
| 181 timeline_markers = timeline.FindTimelineMarkers( | 253 timeline_markers = timeline.FindTimelineMarkers( |
| 182 ['ActionA', 'ActionB', 'ActionA']) | 254 ['ActionA', 'ActionB', 'ActionA']) |
| 183 timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker) | 255 timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker) |
| 184 for marker in timeline_markers ] | 256 for marker in timeline_markers ] |
| 185 stats = RenderingStats(renderer, timeline_ranges) | 257 stats = RenderingStats(renderer, browser_main, timeline_ranges) |
| 186 | 258 |
| 187 # Compare rendering stats to reference. | 259 # Compare rendering stats to reference. |
| 188 self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps) | 260 self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps) |
| 189 self.assertEquals(stats.frame_times, ref_stats.frame_times) | 261 self.assertEquals(stats.frame_times, ref_stats.frame_times) |
| 190 self.assertEquals(stats.rasterize_time, ref_stats.rasterize_time) | 262 self.assertEquals(stats.rasterize_time, ref_stats.rasterize_time) |
| 191 self.assertEquals(stats.rasterized_pixel_count, | 263 self.assertEquals(stats.rasterized_pixel_count, |
| 192 ref_stats.rasterized_pixel_count) | 264 ref_stats.rasterized_pixel_count) |
| 193 self.assertEquals(stats.paint_time, ref_stats.paint_time) | 265 self.assertEquals(stats.paint_time, ref_stats.paint_time) |
| 194 self.assertEquals(stats.painted_pixel_count, ref_stats.painted_pixel_count) | 266 self.assertEquals(stats.painted_pixel_count, ref_stats.painted_pixel_count) |
| 195 self.assertEquals(stats.record_time, ref_stats.record_time) | 267 self.assertEquals(stats.record_time, ref_stats.record_time) |
| 196 self.assertEquals(stats.recorded_pixel_count, | 268 self.assertEquals(stats.mouse_wheel_latency, |
| 197 ref_stats.recorded_pixel_count) | 269 ref_stats.mouse_wheel_latency) |
| 270 self.assertEquals(stats.gesture_scroll_latency, |
| 271 ref_stats.gesture_scroll_latency) |
| 272 self.assertEquals(stats.touch_scroll_latency, |
| 273 ref_stats.touch_scroll_latency) |
| OLD | NEW |