| 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 UI_COMP_NAME, BEGIN_COMP_NAME, END_COMP_NAME | 8 from metrics.rendering_stats import UI_COMP_NAME, BEGIN_COMP_NAME, END_COMP_NAME |
| 9 from metrics.rendering_stats import GetScrollInputLatencyEvents | 9 from metrics.rendering_stats import GetScrollInputLatencyEvents |
| 10 from metrics.rendering_stats import ComputeMouseWheelScrollLatency | 10 from metrics.rendering_stats import ComputeMouseWheelScrollLatency |
| 11 from metrics.rendering_stats import ComputeTouchScrollLatency | 11 from metrics.rendering_stats import ComputeTouchScrollLatency |
| 12 from metrics.rendering_stats import HasRenderingStats | |
| 13 from metrics.rendering_stats import RenderingStats | 12 from metrics.rendering_stats import RenderingStats |
| 14 import telemetry.core.timeline.bounds as timeline_bounds | 13 import telemetry.core.timeline.bounds as timeline_bounds |
| 15 from telemetry.core.timeline import model | 14 from telemetry.core.timeline import model |
| 16 import telemetry.core.timeline.async_slice as tracing_async_slice | 15 import telemetry.core.timeline.async_slice as tracing_async_slice |
| 17 | 16 |
| 18 | 17 |
| 19 class MockTimer(object): | 18 class MockTimer(object): |
| 20 """A mock timer class which can generate random durations. | 19 """A mock timer class which can generate random durations. |
| 21 | 20 |
| 22 An instance of this class is used as a global timer to generate random | 21 An instance of this class is used as a global timer to generate random |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 ref_latency_stats.touch_scroll_events.append(async_sub_slice) | 192 ref_latency_stats.touch_scroll_events.append(async_sub_slice) |
| 194 ref_latency_stats.touch_scroll_latency.append( | 193 ref_latency_stats.touch_scroll_latency.append( |
| 195 (data[END_COMP_NAME]['time'] - data[UI_COMP_NAME]['time']) / 1000.0) | 194 (data[END_COMP_NAME]['time'] - data[UI_COMP_NAME]['time']) / 1000.0) |
| 196 | 195 |
| 197 if input_type == 'TouchMove': | 196 if input_type == 'TouchMove': |
| 198 ref_latency_stats.js_touch_scroll_events.append(async_sub_slice) | 197 ref_latency_stats.js_touch_scroll_events.append(async_sub_slice) |
| 199 ref_latency_stats.js_touch_scroll_latency.append( | 198 ref_latency_stats.js_touch_scroll_latency.append( |
| 200 (data[END_COMP_NAME]['time'] - data[UI_COMP_NAME]['time']) / 1000.0) | 199 (data[END_COMP_NAME]['time'] - data[UI_COMP_NAME]['time']) / 1000.0) |
| 201 | 200 |
| 202 class RenderingStatsUnitTest(unittest.TestCase): | 201 class RenderingStatsUnitTest(unittest.TestCase): |
| 203 def testHasRenderingStats(self): | |
| 204 timeline = model.TimelineModel() | |
| 205 timer = MockTimer() | |
| 206 | |
| 207 # A process without rendering stats | |
| 208 process_without_stats = timeline.GetOrCreateProcess(pid = 1) | |
| 209 thread_without_stats = process_without_stats.GetOrCreateThread(tid = 11) | |
| 210 process_without_stats.FinalizeImport() | |
| 211 self.assertFalse(HasRenderingStats(thread_without_stats)) | |
| 212 | |
| 213 # A process with rendering stats, but no frames in them | |
| 214 process_without_frames = timeline.GetOrCreateProcess(pid = 2) | |
| 215 thread_without_frames = process_without_frames.GetOrCreateThread(tid = 21) | |
| 216 AddMainThreadRenderingStats(timer, thread_without_frames, True, None) | |
| 217 process_without_frames.FinalizeImport() | |
| 218 self.assertFalse(HasRenderingStats(thread_without_frames)) | |
| 219 | |
| 220 # A process with rendering stats and frames in them | |
| 221 process_with_frames = timeline.GetOrCreateProcess(pid = 3) | |
| 222 thread_with_frames = process_with_frames.GetOrCreateThread(tid = 31) | |
| 223 AddImplThreadRenderingStats(timer, thread_with_frames, True, None) | |
| 224 process_with_frames.FinalizeImport() | |
| 225 self.assertTrue(HasRenderingStats(thread_with_frames)) | |
| 226 | |
| 227 def testFromTimeline(self): | 202 def testFromTimeline(self): |
| 228 timeline = model.TimelineModel() | 203 timeline = model.TimelineModel() |
| 229 | 204 |
| 230 # Create a browser process and a renderer process, and a main thread and | 205 # Create a browser process and a renderer process, and a main thread and |
| 231 # impl thread for each. | 206 # impl thread for each. |
| 232 browser = timeline.GetOrCreateProcess(pid = 1) | 207 browser = timeline.GetOrCreateProcess(pid = 1) |
| 233 browser_main = browser.GetOrCreateThread(tid = 11) | 208 browser_main = browser.GetOrCreateThread(tid = 11) |
| 234 browser_compositor = browser.GetOrCreateThread(tid = 12) | 209 browser_compositor = browser.GetOrCreateThread(tid = 12) |
| 235 renderer = timeline.GetOrCreateProcess(pid = 2) | 210 renderer = timeline.GetOrCreateProcess(pid = 2) |
| 236 renderer_main = renderer.GetOrCreateThread(tid = 21) | 211 renderer_main = renderer.GetOrCreateThread(tid = 21) |
| 237 renderer_compositor = renderer.GetOrCreateThread(tid = 22) | 212 renderer_compositor = renderer.GetOrCreateThread(tid = 22) |
| 238 | 213 |
| 239 timer = MockTimer() | 214 timer = MockTimer() |
| 240 ref_stats = ReferenceRenderingStats() | 215 ref_stats = ReferenceRenderingStats() |
| 241 | 216 |
| 242 # Create 10 main and impl rendering stats events for Action A. | 217 # Create 10 main and impl rendering stats events for Action A. |
| 243 timer.Advance() | 218 timer.Advance() |
| 244 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') | 219 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') |
| 245 ref_stats.AppendNewRange() | 220 ref_stats.AppendNewRange() |
| 246 for i in xrange(0, 10): | 221 for i in xrange(0, 10): |
| 247 first = (i == 0) | 222 first = (i == 0) |
| 248 AddMainThreadRenderingStats(timer, renderer_main, first, None) | 223 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) |
| 249 AddImplThreadRenderingStats(timer, renderer_compositor, first, None) | 224 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) |
| 250 AddMainThreadRenderingStats(timer, browser_main, first, ref_stats) | 225 AddMainThreadRenderingStats(timer, browser_main, first, None) |
| 251 AddImplThreadRenderingStats(timer, browser_compositor, first, ref_stats) | 226 AddImplThreadRenderingStats(timer, browser_compositor, first, None) |
| 252 renderer_main.EndSlice(timer.Get()) | 227 renderer_main.EndSlice(timer.Get()) |
| 253 | 228 |
| 254 # Create 5 main and impl rendering stats events not within any action. | 229 # Create 5 main and impl rendering stats events not within any action. |
| 255 for i in xrange(0, 5): | 230 for i in xrange(0, 5): |
| 256 first = (i == 0) | 231 first = (i == 0) |
| 257 AddMainThreadRenderingStats(timer, renderer_main, first, None) | 232 AddMainThreadRenderingStats(timer, renderer_main, first, None) |
| 258 AddImplThreadRenderingStats(timer, renderer_compositor, first, None) | 233 AddImplThreadRenderingStats(timer, renderer_compositor, first, None) |
| 259 AddMainThreadRenderingStats(timer, browser_main, first, None) | 234 AddMainThreadRenderingStats(timer, browser_main, first, None) |
| 260 AddImplThreadRenderingStats(timer, browser_compositor, first, None) | 235 AddImplThreadRenderingStats(timer, browser_compositor, first, None) |
| 261 | 236 |
| 262 # Create 10 main and impl rendering stats events for Action B. | 237 # Create 10 main and impl rendering stats events for Action B. |
| 263 timer.Advance() | 238 timer.Advance() |
| 264 renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '') | 239 renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '') |
| 265 ref_stats.AppendNewRange() | 240 ref_stats.AppendNewRange() |
| 266 for i in xrange(0, 10): | 241 for i in xrange(0, 10): |
| 267 first = (i == 0) | 242 first = (i == 0) |
| 268 AddMainThreadRenderingStats(timer, renderer_main, first, None) | 243 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) |
| 269 AddImplThreadRenderingStats(timer, renderer_compositor, first, None) | 244 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) |
| 270 AddMainThreadRenderingStats(timer, browser_main, first, ref_stats) | 245 AddMainThreadRenderingStats(timer, browser_main, first, None) |
| 271 AddImplThreadRenderingStats(timer, browser_compositor, first, ref_stats) | 246 AddImplThreadRenderingStats(timer, browser_compositor, first, None) |
| 272 renderer_main.EndSlice(timer.Get()) | 247 renderer_main.EndSlice(timer.Get()) |
| 273 | 248 |
| 274 # Create 10 main and impl rendering stats events for Action A. | 249 # Create 10 main and impl rendering stats events for Action A. |
| 275 timer.Advance() | 250 timer.Advance() |
| 276 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') | 251 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') |
| 277 ref_stats.AppendNewRange() | 252 ref_stats.AppendNewRange() |
| 278 for i in xrange(0, 10): | 253 for i in xrange(0, 10): |
| 279 first = (i == 0) | 254 first = (i == 0) |
| 280 AddMainThreadRenderingStats(timer, renderer_main, first, None) | 255 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) |
| 281 AddImplThreadRenderingStats(timer, renderer_compositor, first, None) | 256 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) |
| 282 AddMainThreadRenderingStats(timer, browser_main, first, ref_stats) | 257 AddMainThreadRenderingStats(timer, browser_main, first, None) |
| 283 AddImplThreadRenderingStats(timer, browser_compositor, first, ref_stats) | 258 AddImplThreadRenderingStats(timer, browser_compositor, first, None) |
| 284 renderer_main.EndSlice(timer.Get()) | 259 renderer_main.EndSlice(timer.Get()) |
| 285 | 260 |
| 286 browser.FinalizeImport() | 261 renderer_main.FinalizeImport() |
| 287 renderer.FinalizeImport() | 262 renderer_compositor.FinalizeImport() |
| 288 | 263 |
| 289 timeline_markers = timeline.FindTimelineMarkers( | 264 timeline_markers = timeline.FindTimelineMarkers( |
| 290 ['ActionA', 'ActionB', 'ActionA']) | 265 ['ActionA', 'ActionB', 'ActionA']) |
| 291 timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker) | 266 timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker) |
| 292 for marker in timeline_markers ] | 267 for marker in timeline_markers ] |
| 293 stats = RenderingStats(renderer, browser, timeline_ranges) | 268 stats = RenderingStats(renderer, browser, timeline_ranges) |
| 294 | 269 |
| 295 # Check if we are using the browser compositor's stats | |
| 296 self.assertEquals(stats.top_level_process, browser) | |
| 297 | |
| 298 # Compare rendering stats to reference. | 270 # Compare rendering stats to reference. |
| 299 self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps) | 271 self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps) |
| 300 self.assertEquals(stats.frame_times, ref_stats.frame_times) | 272 self.assertEquals(stats.frame_times, ref_stats.frame_times) |
| 301 self.assertEquals(stats.rasterize_times, ref_stats.rasterize_times) | 273 self.assertEquals(stats.rasterize_times, ref_stats.rasterize_times) |
| 302 self.assertEquals(stats.rasterized_pixel_counts, | 274 self.assertEquals(stats.rasterized_pixel_counts, |
| 303 ref_stats.rasterized_pixel_counts) | 275 ref_stats.rasterized_pixel_counts) |
| 304 self.assertEquals(stats.paint_times, ref_stats.paint_times) | 276 self.assertEquals(stats.paint_times, ref_stats.paint_times) |
| 305 self.assertEquals(stats.painted_pixel_counts, | 277 self.assertEquals(stats.painted_pixel_counts, |
| 306 ref_stats.painted_pixel_counts) | 278 ref_stats.painted_pixel_counts) |
| 307 self.assertEquals(stats.record_times, ref_stats.record_times) | 279 self.assertEquals(stats.record_times, ref_stats.record_times) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') | 330 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') |
| 359 for _ in xrange(0, 10): | 331 for _ in xrange(0, 10): |
| 360 AddInputLatencyStats(timer, 'MouseWheel', browser_main, | 332 AddInputLatencyStats(timer, 'MouseWheel', browser_main, |
| 361 renderer_main, ref_latency_stats) | 333 renderer_main, ref_latency_stats) |
| 362 AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, | 334 AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, |
| 363 renderer_main, ref_latency_stats) | 335 renderer_main, ref_latency_stats) |
| 364 AddInputLatencyStats(timer, 'TouchMove', browser_main, | 336 AddInputLatencyStats(timer, 'TouchMove', browser_main, |
| 365 renderer_main, ref_latency_stats) | 337 renderer_main, ref_latency_stats) |
| 366 renderer_main.EndSlice(timer.Get()) | 338 renderer_main.EndSlice(timer.Get()) |
| 367 | 339 |
| 368 browser.FinalizeImport() | 340 browser_main.FinalizeImport() |
| 369 renderer.FinalizeImport() | 341 renderer_main.FinalizeImport() |
| 370 | 342 |
| 371 mouse_wheel_scroll_events = [] | 343 mouse_wheel_scroll_events = [] |
| 372 touch_scroll_events = [] | 344 touch_scroll_events = [] |
| 373 js_touch_scroll_events = [] | 345 js_touch_scroll_events = [] |
| 374 | 346 |
| 375 timeline_markers = timeline.FindTimelineMarkers( | 347 timeline_markers = timeline.FindTimelineMarkers( |
| 376 ['ActionA', 'ActionB', 'ActionA']) | 348 ['ActionA', 'ActionB', 'ActionA']) |
| 377 for timeline_range in [ timeline_bounds.Bounds.CreateFromEvent(marker) | 349 for timeline_range in [ timeline_bounds.Bounds.CreateFromEvent(marker) |
| 378 for marker in timeline_markers ]: | 350 for marker in timeline_markers ]: |
| 379 if timeline_range.is_empty: | 351 if timeline_range.is_empty: |
| (...skipping 13 matching lines...) Expand all Loading... |
| 393 self.assertEquals(touch_scroll_events, | 365 self.assertEquals(touch_scroll_events, |
| 394 ref_latency_stats.touch_scroll_events) | 366 ref_latency_stats.touch_scroll_events) |
| 395 self.assertEquals(js_touch_scroll_events, | 367 self.assertEquals(js_touch_scroll_events, |
| 396 ref_latency_stats.js_touch_scroll_events) | 368 ref_latency_stats.js_touch_scroll_events) |
| 397 self.assertEquals(ComputeMouseWheelScrollLatency(mouse_wheel_scroll_events), | 369 self.assertEquals(ComputeMouseWheelScrollLatency(mouse_wheel_scroll_events), |
| 398 ref_latency_stats.mouse_wheel_scroll_latency) | 370 ref_latency_stats.mouse_wheel_scroll_latency) |
| 399 self.assertEquals(ComputeTouchScrollLatency(touch_scroll_events), | 371 self.assertEquals(ComputeTouchScrollLatency(touch_scroll_events), |
| 400 ref_latency_stats.touch_scroll_latency) | 372 ref_latency_stats.touch_scroll_latency) |
| 401 self.assertEquals(ComputeTouchScrollLatency(js_touch_scroll_events), | 373 self.assertEquals(ComputeTouchScrollLatency(js_touch_scroll_events), |
| 402 ref_latency_stats.js_touch_scroll_latency) | 374 ref_latency_stats.js_touch_scroll_latency) |
| OLD | NEW |