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