133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Copyright 2014 The Chromium Authors. All rights reserved. 233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Use of this source code is governed by a BSD-style license that can be 333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# found in the LICENSE file. 433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport random 633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport unittest 733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom telemetry.timeline import async_slice 933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom telemetry.timeline import bounds 1033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom telemetry.timeline import model 1133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom telemetry.util import perf_tests_helper 1233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom telemetry.util import statistics 1333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom telemetry.web_perf.metrics import rendering_stats 1433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 1533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 1633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass MockTimer(object): 1733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """A mock timer class which can generate random durations. 1833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 1933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck An instance of this class is used as a global timer to generate random 2033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck durations for stats and consistent timestamps for all mock trace events. 2133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck The unit of time is milliseconds. 2233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 2333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 2433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __init__(self): 2533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.milliseconds = 0 2633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 2733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def Advance(self, low=0.1, high=1): 2833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck delta = random.uniform(low, high) 2933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.milliseconds += delta 3033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return delta 3133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 3233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def AdvanceAndGet(self, low=0.1, high=1): 3333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.Advance(low, high) 3433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return self.milliseconds 3533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 3633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 37a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craikclass MockVblankTimer(object): 38a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik """A mock vblank timer class which can generate random durations. 39a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 40a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik An instance of this class is used as a vblank timer to generate random 41a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik durations for drm stats and consistent timeval for mock trace drm events. 42a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik The unit of time is microseconds. 43a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik """ 44a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 45a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik def __init__(self): 46a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik self.microseconds = 200000000 47a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 48a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik def TvAdvance(self, low=100, high=1000): 49a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik delta = random.randint(low, high) 50a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik self.microseconds += delta 51a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik return delta 52a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 53a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik def TvAdvanceAndGet(self, low=100, high=1000): 54a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik self.TvAdvance(low, high) 55a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik return self.microseconds 56a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 57a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 5833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass ReferenceRenderingStats(object): 5933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ Stores expected data for comparison with actual RenderingStats """ 6033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 6133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __init__(self): 6233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.frame_timestamps = [] 6333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.frame_times = [] 6433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.approximated_pixel_percentages = [] 6533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.checkerboarded_pixel_percentages = [] 6633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 6733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def AppendNewRange(self): 6833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.frame_timestamps.append([]) 6933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.frame_times.append([]) 7033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.approximated_pixel_percentages.append([]) 7133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.checkerboarded_pixel_percentages.append([]) 7233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 7333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 7433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass ReferenceInputLatencyStats(object): 7533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ Stores expected data for comparison with actual input latency stats """ 7633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 7733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __init__(self): 7833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.input_event_latency = [] 7933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.input_event = [] 8033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 8133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 8233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef AddSurfaceFlingerStats(mock_timer, thread, first_frame, 8333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats=None): 8433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ Adds a random surface flinger stats event. 8533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 8633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck thread: The timeline model thread to which the event will be added. 8733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first_frame: Is this the first frame within the bounds of an action? 8833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats: A ReferenceRenderingStats object to record expected values. 8933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 90a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # Create random data and timestamp for impl thread rendering stats. 9133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck data = {'frame_count': 1, 9233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'refresh_period': 16.6666} 9333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timestamp = mock_timer.AdvanceAndGet() 9433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 9533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Add a slice with the event data to the given thread. 9633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck thread.PushCompleteSlice( 9733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'SurfaceFlinger', 'vsync_before', 9833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timestamp, duration=0.0, thread_timestamp=None, thread_duration=None, 9933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck args={'data': data}) 10033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 10133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not ref_stats: 10233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return 10333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 10433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Add timestamp only if a frame was output 10533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if data['frame_count'] == 1: 10633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not first_frame: 10733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Add frame_time if this is not the first frame in within the bounds of an 10833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # action. 10933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck prev_timestamp = ref_stats.frame_timestamps[-1][-1] 11033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats.frame_times[-1].append(timestamp - prev_timestamp) 11133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats.frame_timestamps[-1].append(timestamp) 11233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 11333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 114a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craikdef AddDrmEventFlipStats(mock_timer, vblank_timer, thread, 115a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik first_frame, ref_stats=None): 116a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik """ Adds a random drm flip complete event. 117a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 118a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik thread: The timeline model thread to which the event will be added. 119a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik first_frame: Is this the first frame within the bounds of an action? 120a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik ref_stats: A ReferenceRenderingStats object to record expected values. 121a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik """ 122a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # Create random data and timestamp for drm thread flip complete stats. 123a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik vblank_timeval = vblank_timer.TvAdvanceAndGet() 124a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik vblank_tv_sec = vblank_timeval / 1000000 125a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik vblank_tv_usec = vblank_timeval % 1000000 126a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik data = {'frame_count': 1, 127a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 'vblank.tv_usec': vblank_tv_usec, 128a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 'vblank.tv_sec': vblank_tv_sec} 129a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik timestamp = mock_timer.AdvanceAndGet() 130a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 131a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # Add a slice with the event data to the given thread. 132a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik thread.PushCompleteSlice( 133a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 'benchmark,drm', 'DrmEventFlipComplete', 134a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik timestamp, duration=0.0, thread_timestamp=None, thread_duration=None, 135a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik args={'data': data}) 136a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 137a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik if not ref_stats: 138a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik return 139a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 140a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # Add vblank timeval only if a frame was output. 141a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik cur_timestamp = vblank_tv_sec * 1000.0 + vblank_tv_usec / 1000.0 142a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik if not first_frame: 143a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # Add frame_time if this is not the first frame in within the bounds of an 144a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # action. 145a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik prev_timestamp = ref_stats.frame_timestamps[-1][-1] 146a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik ref_stats.frame_times[-1].append(cur_timestamp - prev_timestamp) 147a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik ref_stats.frame_timestamps[-1].append(cur_timestamp) 148a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 149a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 15033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef AddDisplayRenderingStats(mock_timer, thread, first_frame, 15133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats=None): 15233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ Adds a random display rendering stats event. 15333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 15433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck thread: The timeline model thread to which the event will be added. 15533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first_frame: Is this the first frame within the bounds of an action? 15633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats: A ReferenceRenderingStats object to record expected values. 15733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 158a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # Create random data and timestamp for main thread rendering stats. 15933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck data = {'frame_count': 1} 16033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timestamp = mock_timer.AdvanceAndGet() 16133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 16233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Add a slice with the event data to the given thread. 16333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck thread.PushCompleteSlice( 16433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'benchmark', 'BenchmarkInstrumentation::DisplayRenderingStats', 16533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timestamp, duration=0.0, thread_timestamp=None, thread_duration=None, 16633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck args={'data': data}) 16733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 16833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not ref_stats: 16933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return 17033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 17133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Add timestamp only if a frame was output 17233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not first_frame: 17333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Add frame_time if this is not the first frame in within the bounds of an 17433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # action. 17533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck prev_timestamp = ref_stats.frame_timestamps[-1][-1] 17633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats.frame_times[-1].append(timestamp - prev_timestamp) 17733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats.frame_timestamps[-1].append(timestamp) 17833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 17933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 18033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef AddImplThreadRenderingStats(mock_timer, thread, first_frame, 18133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats=None): 18233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ Adds a random impl thread rendering stats event. 18333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 18433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck thread: The timeline model thread to which the event will be added. 18533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first_frame: Is this the first frame within the bounds of an action? 18633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats: A ReferenceRenderingStats object to record expected values. 18733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 188a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # Create random data and timestamp for impl thread rendering stats. 18933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck data = {'frame_count': 1, 19033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'visible_content_area': random.uniform(0, 100), 19133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'approximated_visible_content_area': random.uniform(0, 5), 19233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'checkerboarded_visible_content_area': random.uniform(0, 5)} 19333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timestamp = mock_timer.AdvanceAndGet() 19433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 19533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Add a slice with the event data to the given thread. 19633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck thread.PushCompleteSlice( 19733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'benchmark', 'BenchmarkInstrumentation::ImplThreadRenderingStats', 19833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timestamp, duration=0.0, thread_timestamp=None, thread_duration=None, 19933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck args={'data': data}) 20033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 20133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not ref_stats: 20233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return 20333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 20433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Add timestamp only if a frame was output 20533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if data['frame_count'] == 1: 20633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not first_frame: 20733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Add frame_time if this is not the first frame in within the bounds of an 20833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # action. 20933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck prev_timestamp = ref_stats.frame_timestamps[-1][-1] 21033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats.frame_times[-1].append(timestamp - prev_timestamp) 21133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats.frame_timestamps[-1].append(timestamp) 21233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 21333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats.approximated_pixel_percentages[-1].append( 21433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck round(statistics.DivideIfPossibleOrZero( 21533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck data['approximated_visible_content_area'], 21633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck data['visible_content_area']) * 100.0, 3)) 21733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 21833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats.checkerboarded_pixel_percentages[-1].append( 21933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck round(statistics.DivideIfPossibleOrZero( 22033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck data['checkerboarded_visible_content_area'], 22133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck data['visible_content_area']) * 100.0, 3)) 22233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 22333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef AddInputLatencyStats(mock_timer, start_thread, end_thread, 22433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_latency_stats=None): 22533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ Adds a random input latency stats event. 22633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 22733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck start_thread: The start thread on which the async slice is added. 22833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck end_thread: The end thread on which the async slice is ended. 22933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_latency_stats: A ReferenceInputLatencyStats object for expected values. 23033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 23133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 23233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck original_comp_time = mock_timer.AdvanceAndGet(2, 4) * 1000.0 23333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ui_comp_time = mock_timer.AdvanceAndGet(2, 4) * 1000.0 23433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck begin_comp_time = mock_timer.AdvanceAndGet(2, 4) * 1000.0 23533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck forward_comp_time = mock_timer.AdvanceAndGet(2, 4) * 1000.0 23633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck end_comp_time = mock_timer.AdvanceAndGet(10, 20) * 1000.0 23733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 23833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck data = {rendering_stats.ORIGINAL_COMP_NAME: {'time': original_comp_time}, 23933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rendering_stats.UI_COMP_NAME: {'time': ui_comp_time}, 24033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rendering_stats.BEGIN_COMP_NAME: {'time': begin_comp_time}, 24133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rendering_stats.END_COMP_NAME: {'time': end_comp_time}} 24233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 24333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timestamp = mock_timer.AdvanceAndGet(2, 4) 24433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 24533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck tracing_async_slice = async_slice.AsyncSlice( 24633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'benchmark', 'InputLatency', timestamp) 24733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 24833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck async_sub_slice = async_slice.AsyncSlice( 24933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'benchmark', rendering_stats.GESTURE_SCROLL_UPDATE_EVENT_NAME, timestamp) 25033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck async_sub_slice.args = {'data': data} 25133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck async_sub_slice.parent_slice = tracing_async_slice 25233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck async_sub_slice.start_thread = start_thread 25333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck async_sub_slice.end_thread = end_thread 25433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 25533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck tracing_async_slice.sub_slices.append(async_sub_slice) 25633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck tracing_async_slice.start_thread = start_thread 25733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck tracing_async_slice.end_thread = end_thread 25833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck start_thread.AddAsyncSlice(tracing_async_slice) 25933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 26033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Add scroll update latency info. 26133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_update_data = { 26233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rendering_stats.BEGIN_SCROLL_UPDATE_COMP_NAME: {'time': begin_comp_time}, 26333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rendering_stats.FORWARD_SCROLL_UPDATE_COMP_NAME: 26433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck {'time': forward_comp_time}, 26533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rendering_stats.END_COMP_NAME: {'time': end_comp_time} 26633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck } 26733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 26833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_async_slice = async_slice.AsyncSlice( 26933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'benchmark', 'InputLatency', timestamp) 27033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 27133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_async_sub_slice = async_slice.AsyncSlice( 27233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'benchmark', rendering_stats.MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME, 27333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timestamp) 27433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_async_sub_slice.args = {'data': scroll_update_data} 27533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_async_sub_slice.parent_slice = scroll_async_slice 27633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_async_sub_slice.start_thread = start_thread 27733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_async_sub_slice.end_thread = end_thread 27833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 27933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_async_slice.sub_slices.append(scroll_async_sub_slice) 28033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_async_slice.start_thread = start_thread 28133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_async_slice.end_thread = end_thread 28233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck start_thread.AddAsyncSlice(scroll_async_slice) 28333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 28433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Also add some dummy frame statistics so we can feed the resulting timeline 28533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # to RenderingStats. 28633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats(mock_timer, end_thread, False) 28733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 28833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not ref_latency_stats: 28933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return 29033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 29133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_latency_stats.input_event.append(async_sub_slice) 29233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_latency_stats.input_event.append(scroll_async_sub_slice) 29333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_latency_stats.input_event_latency.append(( 29433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rendering_stats.GESTURE_SCROLL_UPDATE_EVENT_NAME, 29533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck (data[rendering_stats.END_COMP_NAME]['time'] - 29633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck data[rendering_stats.ORIGINAL_COMP_NAME]['time']) / 1000.0)) 29733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_update_time = ( 29833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_update_data[rendering_stats.END_COMP_NAME]['time'] - 29933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_update_data[rendering_stats.BEGIN_SCROLL_UPDATE_COMP_NAME]['time']) 30033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_latency_stats.input_event_latency.append(( 30133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rendering_stats.MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME, 30233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck scroll_update_time / 1000.0)) 30333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 30433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 30533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass RenderingStatsUnitTest(unittest.TestCase): 30633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 30733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def testHasRenderingStats(self): 30833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline = model.TimelineModel() 30933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer = MockTimer() 31033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 31133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # A process without rendering stats 31233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck process_without_stats = timeline.GetOrCreateProcess(pid=1) 31333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck thread_without_stats = process_without_stats.GetOrCreateThread(tid=11) 31433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck process_without_stats.FinalizeImport() 31533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertFalse(rendering_stats.HasRenderingStats(thread_without_stats)) 31633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 31733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # A process with rendering stats, but no frames in them 31833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck process_without_frames = timeline.GetOrCreateProcess(pid=2) 31933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck thread_without_frames = process_without_frames.GetOrCreateThread(tid=21) 32033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck process_without_frames.FinalizeImport() 32133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertFalse(rendering_stats.HasRenderingStats(thread_without_frames)) 32233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 32333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # A process with rendering stats and frames in them 32433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck process_with_frames = timeline.GetOrCreateProcess(pid=3) 32533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck thread_with_frames = process_with_frames.GetOrCreateThread(tid=31) 32633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats(timer, thread_with_frames, True, None) 32733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck process_with_frames.FinalizeImport() 32833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertTrue(rendering_stats.HasRenderingStats(thread_with_frames)) 32933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 330a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik def testHasDrmStats(self): 331a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik timeline = model.TimelineModel() 332a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik timer = MockTimer() 333a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik vblank_timer = MockVblankTimer() 334a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 335a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # A process without drm stats 336a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik process_without_stats = timeline.GetOrCreateProcess(pid=5) 337a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik thread_without_stats = process_without_stats.GetOrCreateThread(tid=51) 338a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik process_without_stats.FinalizeImport() 339a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik self.assertFalse(rendering_stats.HasDrmStats(thread_without_stats)) 340a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 341a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # A process with drm stats and frames in them 342a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik process_with_frames = timeline.GetOrCreateProcess(pid=6) 343a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik thread_with_frames = process_with_frames.GetOrCreateThread(tid=61) 344a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik AddDrmEventFlipStats(timer, vblank_timer, thread_with_frames, True, None) 345a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik process_with_frames.FinalizeImport() 346a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik self.assertTrue(rendering_stats.HasDrmStats(thread_with_frames)) 347a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 34833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def testBothSurfaceFlingerAndDisplayStats(self): 34933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline = model.TimelineModel() 35033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer = MockTimer() 35133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 35233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats = ReferenceRenderingStats() 35333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats.AppendNewRange() 35433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck surface_flinger = timeline.GetOrCreateProcess(pid=4) 35533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck surface_flinger.name = 'SurfaceFlinger' 35633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck surface_flinger_thread = surface_flinger.GetOrCreateThread(tid=41) 35733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer = timeline.GetOrCreateProcess(pid=2) 35833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser = timeline.GetOrCreateProcess(pid=3) 35933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_main = browser.GetOrCreateThread(tid=31) 36033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_main.BeginSlice('webkit.console', 'ActionA', 36133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.AdvanceAndGet(2, 4), '') 36233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 36333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create SurfaceFlinger stats and display rendering stats. 36433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in xrange(0, 10): 36533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first = (i == 0) 36633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddSurfaceFlingerStats(timer, surface_flinger_thread, first, ref_stats) 36733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.Advance(2, 4) 36833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 36933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in xrange(0, 10): 37033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first = (i == 0) 37133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddDisplayRenderingStats(timer, browser_main, first, None) 37233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.Advance(5, 10) 37333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 37433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_main.EndSlice(timer.AdvanceAndGet()) 37533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.Advance(2, 4) 37633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 37733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser.FinalizeImport() 37833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer.FinalizeImport() 37933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline_markers = timeline.FindTimelineMarkers(['ActionA']) 38033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline_ranges = [bounds.Bounds.CreateFromEvent(marker) 38133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for marker in timeline_markers] 38233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck stats = rendering_stats.RenderingStats( 383a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik renderer, browser, surface_flinger, None, timeline_ranges) 38433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 38533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Compare rendering stats to reference - Only SurfaceFlinger stats should 38633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # count 38733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps) 38833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals(stats.frame_times, ref_stats.frame_times) 38933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 390a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik def testBothDrmAndDisplayStats(self): 391a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik timeline = model.TimelineModel() 392a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik timer = MockTimer() 393a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik vblank_timer = MockVblankTimer() 394a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 395a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik ref_stats = ReferenceRenderingStats() 396a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik ref_stats.AppendNewRange() 397a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik gpu = timeline.GetOrCreateProcess(pid=6) 398a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik gpu.name = 'GPU Process' 399a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik gpu_drm_thread = gpu.GetOrCreateThread(tid=61) 400a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik renderer = timeline.GetOrCreateProcess(pid=2) 401a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik browser = timeline.GetOrCreateProcess(pid=3) 402a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik browser_main = browser.GetOrCreateThread(tid=31) 403a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik browser_main.BeginSlice('webkit.console', 'ActionA', 404a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik timer.AdvanceAndGet(2, 4), '') 405a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik vblank_timer.TvAdvance(2000, 4000) 406a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 407a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # Create drm flip stats and display rendering stats. 408a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik for i in xrange(0, 10): 409a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik first = (i == 0) 410a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik AddDrmEventFlipStats(timer, vblank_timer, gpu_drm_thread, 411a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik first, ref_stats) 412a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik timer.Advance(2, 4) 413a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik vblank_timer.TvAdvance(2000, 4000) 414a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 415a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik for i in xrange(0, 10): 416a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik first = (i == 0) 417a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik AddDisplayRenderingStats(timer, browser_main, first, None) 418a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik timer.Advance(5, 10) 419a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik vblank_timer.TvAdvance(5000, 10000) 420a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 421a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik browser_main.EndSlice(timer.AdvanceAndGet()) 422a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik timer.Advance(2, 4) 423a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik vblank_timer.TvAdvance(2000, 4000) 424a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 425a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik browser.FinalizeImport() 426a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik renderer.FinalizeImport() 427a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik timeline_markers = timeline.FindTimelineMarkers(['ActionA']) 428a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik timeline_ranges = [bounds.Bounds.CreateFromEvent(marker) 429a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik for marker in timeline_markers] 430a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik stats = rendering_stats.RenderingStats( 431a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik renderer, browser, None, gpu, timeline_ranges) 432a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 433a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # Compare rendering stats to reference - Only drm flip stats should 434a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik # count 435a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps) 436a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik self.assertEquals(stats.frame_times, ref_stats.frame_times) 437a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik 43833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def testBothDisplayAndImplStats(self): 43933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline = model.TimelineModel() 44033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer = MockTimer() 44133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 44233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats = ReferenceRenderingStats() 44333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_stats.AppendNewRange() 44433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer = timeline.GetOrCreateProcess(pid=2) 44533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser = timeline.GetOrCreateProcess(pid=3) 44633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_main = browser.GetOrCreateThread(tid=31) 44733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_main.BeginSlice('webkit.console', 'ActionA', 44833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.AdvanceAndGet(2, 4), '') 44933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 45033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create main, impl, and display rendering stats. 45133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in xrange(0, 10): 45233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first = (i == 0) 45333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats(timer, browser_main, first, None) 45433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.Advance(2, 4) 45533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 45633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in xrange(0, 10): 45733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first = (i == 0) 45833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddDisplayRenderingStats(timer, browser_main, first, ref_stats) 45933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.Advance(5, 10) 46033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 46133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_main.EndSlice(timer.AdvanceAndGet()) 46233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.Advance(2, 4) 46333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 46433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser.FinalizeImport() 46533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer.FinalizeImport() 46633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline_markers = timeline.FindTimelineMarkers(['ActionA']) 46733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline_ranges = [bounds.Bounds.CreateFromEvent(marker) 46833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for marker in timeline_markers] 46933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck stats = rendering_stats.RenderingStats( 470a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik renderer, browser, None, None, timeline_ranges) 47133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 47233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Compare rendering stats to reference - Only display stats should count 47333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps) 47433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals(stats.frame_times, ref_stats.frame_times) 47533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 47633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def testRangeWithoutFrames(self): 47733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer = MockTimer() 47833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline = model.TimelineModel() 47933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 48033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create a renderer process, with a main thread and impl thread. 48133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer = timeline.GetOrCreateProcess(pid=2) 48233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main = renderer.GetOrCreateThread(tid=21) 48333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_compositor = renderer.GetOrCreateThread(tid=22) 48433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 48533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create 10 main and impl rendering stats events for Action A. 48633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.BeginSlice('webkit.console', 'ActionA', 48733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.AdvanceAndGet(2, 4), '') 48833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in xrange(0, 10): 48933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first = (i == 0) 49033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats(timer, renderer_compositor, first, None) 49133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.EndSlice(timer.AdvanceAndGet(2, 4)) 49233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.Advance(2, 4) 49333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 49433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create 5 main and impl rendering stats events not within any action. 49533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in xrange(0, 5): 49633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first = (i == 0) 49733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats(timer, renderer_compositor, first, None) 49833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 49933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create Action B without any frames. This should trigger 50033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # NotEnoughFramesError when the RenderingStats object is created. 50133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.BeginSlice('webkit.console', 'ActionB', 50233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.AdvanceAndGet(2, 4), '') 50333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.EndSlice(timer.AdvanceAndGet(2, 4)) 50433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 50533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer.FinalizeImport() 50633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 50733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline_markers = timeline.FindTimelineMarkers(['ActionA', 'ActionB']) 50833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline_ranges = [bounds.Bounds.CreateFromEvent(marker) 50933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for marker in timeline_markers] 51033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 51133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck stats = rendering_stats.RenderingStats( 512a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik renderer, None, None, None, timeline_ranges) 51333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals(0, len(stats.frame_timestamps[1])) 51433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 51533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def testFromTimeline(self): 51633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline = model.TimelineModel() 51733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 51833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create a browser process and a renderer process, and a main thread and 51933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # impl thread for each. 52033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser = timeline.GetOrCreateProcess(pid=1) 52133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_compositor = browser.GetOrCreateThread(tid=12) 52233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer = timeline.GetOrCreateProcess(pid=2) 52333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main = renderer.GetOrCreateThread(tid=21) 52433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_compositor = renderer.GetOrCreateThread(tid=22) 52533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 52633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer = MockTimer() 52733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_ref_stats = ReferenceRenderingStats() 52833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_ref_stats = ReferenceRenderingStats() 52933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 53033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create 10 main and impl rendering stats events for Action A. 53133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.BeginSlice('webkit.console', 'ActionA', 53233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.AdvanceAndGet(2, 4), '') 53333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_ref_stats.AppendNewRange() 53433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_ref_stats.AppendNewRange() 53533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in xrange(0, 10): 53633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first = (i == 0) 53733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats( 53833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer, renderer_compositor, first, renderer_ref_stats) 53933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats( 54033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer, browser_compositor, first, browser_ref_stats) 54133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.EndSlice(timer.AdvanceAndGet(2, 4)) 54233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 54333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create 5 main and impl rendering stats events not within any action. 54433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in xrange(0, 5): 54533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first = (i == 0) 54633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats(timer, renderer_compositor, first, None) 54733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats(timer, browser_compositor, first, None) 54833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 54933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create 10 main and impl rendering stats events for Action B. 55033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.BeginSlice('webkit.console', 'ActionB', 55133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.AdvanceAndGet(2, 4), '') 55233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_ref_stats.AppendNewRange() 55333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_ref_stats.AppendNewRange() 55433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in xrange(0, 10): 55533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first = (i == 0) 55633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats( 55733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer, renderer_compositor, first, renderer_ref_stats) 55833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats( 55933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer, browser_compositor, first, browser_ref_stats) 56033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.EndSlice(timer.AdvanceAndGet(2, 4)) 56133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 56233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create 10 main and impl rendering stats events for Action A. 56333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.BeginSlice('webkit.console', 'ActionA', 56433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.AdvanceAndGet(2, 4), '') 56533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_ref_stats.AppendNewRange() 56633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_ref_stats.AppendNewRange() 56733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in xrange(0, 10): 56833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck first = (i == 0) 56933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats( 57033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer, renderer_compositor, first, renderer_ref_stats) 57133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddImplThreadRenderingStats( 57233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer, browser_compositor, first, browser_ref_stats) 57333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.EndSlice(timer.AdvanceAndGet(2, 4)) 57433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.Advance(2, 4) 57533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 57633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser.FinalizeImport() 57733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer.FinalizeImport() 57833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 57933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline_markers = timeline.FindTimelineMarkers( 58033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ['ActionA', 'ActionB', 'ActionA']) 58133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline_ranges = [bounds.Bounds.CreateFromEvent(marker) 58233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for marker in timeline_markers] 58333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck stats = rendering_stats.RenderingStats( 584a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik renderer, browser, None, None, timeline_ranges) 58533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 58633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Compare rendering stats to reference. 58733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals(stats.frame_timestamps, 58833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_ref_stats.frame_timestamps) 58933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals(stats.frame_times, browser_ref_stats.frame_times) 59033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals(stats.approximated_pixel_percentages, 59133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_ref_stats.approximated_pixel_percentages) 59233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals(stats.checkerboarded_pixel_percentages, 59333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_ref_stats.checkerboarded_pixel_percentages) 59433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 59533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def testInputLatencyFromTimeline(self): 59633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline = model.TimelineModel() 59733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 59833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create a browser process and a renderer process. 59933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser = timeline.GetOrCreateProcess(pid=1) 60033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser_main = browser.GetOrCreateThread(tid=11) 60133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer = timeline.GetOrCreateProcess(pid=2) 60233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main = renderer.GetOrCreateThread(tid=21) 60333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 60433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer = MockTimer() 60533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_latency = ReferenceInputLatencyStats() 60633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 60733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create 10 input latency stats events for Action A. 60833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.BeginSlice('webkit.console', 'ActionA', 60933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.AdvanceAndGet(2, 4), '') 61033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for _ in xrange(0, 10): 61133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddInputLatencyStats(timer, browser_main, renderer_main, ref_latency) 61233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.EndSlice(timer.AdvanceAndGet(2, 4)) 61333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 61433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create 5 input latency stats events not within any action. 61533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.Advance(2, 4) 61633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for _ in xrange(0, 5): 61733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddInputLatencyStats(timer, browser_main, renderer_main, None) 61833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 61933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create 10 input latency stats events for Action B. 62033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.BeginSlice('webkit.console', 'ActionB', 62133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.AdvanceAndGet(2, 4), '') 62233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for _ in xrange(0, 10): 62333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddInputLatencyStats(timer, browser_main, renderer_main, ref_latency) 62433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.EndSlice(timer.AdvanceAndGet(2, 4)) 62533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 62633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Create 10 input latency stats events for Action A. 62733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.BeginSlice('webkit.console', 'ActionA', 62833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timer.AdvanceAndGet(2, 4), '') 62933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for _ in xrange(0, 10): 63033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck AddInputLatencyStats(timer, browser_main, renderer_main, ref_latency) 63133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer_main.EndSlice(timer.AdvanceAndGet(2, 4)) 63233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 63333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser.FinalizeImport() 63433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck renderer.FinalizeImport() 63533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 63633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck latency_events = [] 63733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 63833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline_markers = timeline.FindTimelineMarkers( 63933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ['ActionA', 'ActionB', 'ActionA']) 64033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck timeline_ranges = [bounds.Bounds.CreateFromEvent(marker) 64133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for marker in timeline_markers] 64233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for timeline_range in timeline_ranges: 64333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if timeline_range.is_empty: 64433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck continue 64533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck latency_events.extend(rendering_stats.GetLatencyEvents( 64633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck browser, timeline_range)) 64733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 64833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals(latency_events, ref_latency.input_event) 64933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck event_latency_result = rendering_stats.ComputeEventLatencies(latency_events) 65033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals(event_latency_result, 65133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ref_latency.input_event_latency) 65233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 65333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck stats = rendering_stats.RenderingStats( 654a0e5c0de428e9dea6d07dd57c5594fb1f1c17c20Chris Craik renderer, browser, None, None, timeline_ranges) 65533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals( 65633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck perf_tests_helper.FlattenList(stats.input_event_latency), 65733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck [latency for name, latency in ref_latency.input_event_latency 65833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if name != rendering_stats.MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME]) 65933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals( 66033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck perf_tests_helper.FlattenList(stats.main_thread_scroll_latency), 66133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck [latency for name, latency in ref_latency.input_event_latency 66233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if name == rendering_stats.MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME]) 66333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.assertEquals( 66433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck perf_tests_helper.FlattenList(stats.gesture_scroll_update_latency), 66533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck [latency for name, latency in ref_latency.input_event_latency 66633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if name == rendering_stats.GESTURE_SCROLL_UPDATE_EVENT_NAME]) 667