X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftools%2Fperf%2Fmetrics%2Frendering_stats_unittest.py;h=11f82b5ad3f14721748e8ec05679bff47d557038;hb=ff3e2503a20db9193d323c1d19c38c68004dec4a;hp=6a225fcf8f838555d044fde189b7c29a80781e85;hpb=7338fba38ba696536d1cc9d389afd716a6ab2fe6;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/tools/perf/metrics/rendering_stats_unittest.py b/src/tools/perf/metrics/rendering_stats_unittest.py index 6a225fc..11f82b5 100644 --- a/src/tools/perf/metrics/rendering_stats_unittest.py +++ b/src/tools/perf/metrics/rendering_stats_unittest.py @@ -5,9 +5,14 @@ import random import unittest +from metrics.rendering_stats import UI_COMP_NAME, BEGIN_COMP_NAME, END_COMP_NAME +from metrics.rendering_stats import GetScrollInputLatencyEvents +from metrics.rendering_stats import ComputeMouseWheelScrollLatency +from metrics.rendering_stats import ComputeTouchScrollLatency from metrics.rendering_stats import RenderingStats import telemetry.core.timeline.bounds as timeline_bounds from telemetry.core.timeline import model +import telemetry.core.timeline.async_slice as tracing_async_slice class MockTimer(object): @@ -34,13 +39,32 @@ class ReferenceRenderingStats(object): def __init__(self): self.frame_timestamps = [] self.frame_times = [] - self.paint_time = [] - self.painted_pixel_count = [] - self.record_time = [] - self.recorded_pixel_count = [] - self.rasterize_time = [] - self.rasterized_pixel_count = [] - + self.paint_times = [] + self.painted_pixel_counts = [] + self.record_times = [] + self.recorded_pixel_counts = [] + self.rasterize_times = [] + self.rasterized_pixel_counts = [] + + def AppendNewRange(self): + self.frame_timestamps.append([]) + self.frame_times.append([]) + self.paint_times.append([]) + self.painted_pixel_counts.append([]) + self.record_times.append([]) + self.recorded_pixel_counts.append([]) + self.rasterize_times.append([]) + self.rasterized_pixel_counts.append([]) + +class ReferenceInputLatencyStats(object): + """ Stores expected data for comparison with actual input latency stats """ + def __init__(self): + self.mouse_wheel_scroll_latency = [] + self.touch_scroll_latency = [] + self.js_touch_scroll_latency = [] + self.mouse_wheel_scroll_events = [] + self.touch_scroll_events = [] + self.js_touch_scroll_events = [] def AddMainThreadRenderingStats(mock_timer, thread, first_frame, ref_stats = None): @@ -72,14 +96,14 @@ def AddMainThreadRenderingStats(mock_timer, thread, first_frame, if not first_frame: # Add frame_time if this is not the first frame in within the bounds of an # action. - prev_timestamp = ref_stats.frame_timestamps[-1] - ref_stats.frame_times.append(round(timestamp - prev_timestamp, 2)) - ref_stats.frame_timestamps.append(timestamp) + prev_timestamp = ref_stats.frame_timestamps[-1][-1] + ref_stats.frame_times[-1].append(round(timestamp - prev_timestamp, 2)) + ref_stats.frame_timestamps[-1].append(timestamp) - ref_stats.paint_time.append(data['paint_time'] * 1000.0) - ref_stats.painted_pixel_count.append(data['painted_pixel_count']) - ref_stats.record_time.append(data['record_time'] * 1000.0) - ref_stats.recorded_pixel_count.append(data['recorded_pixel_count']) + ref_stats.paint_times[-1].append(data['paint_time'] * 1000.0) + ref_stats.painted_pixel_counts[-1].append(data['painted_pixel_count']) + ref_stats.record_times[-1].append(data['record_time'] * 1000.0) + ref_stats.recorded_pixel_counts[-1].append(data['recorded_pixel_count']) def AddImplThreadRenderingStats(mock_timer, thread, first_frame, @@ -110,13 +134,69 @@ def AddImplThreadRenderingStats(mock_timer, thread, first_frame, if not first_frame: # Add frame_time if this is not the first frame in within the bounds of an # action. - prev_timestamp = ref_stats.frame_timestamps[-1] - ref_stats.frame_times.append(round(timestamp - prev_timestamp, 2)) - ref_stats.frame_timestamps.append(timestamp) + prev_timestamp = ref_stats.frame_timestamps[-1][-1] + ref_stats.frame_times[-1].append(round(timestamp - prev_timestamp, 2)) + ref_stats.frame_timestamps[-1].append(timestamp) + + ref_stats.rasterize_times[-1].append(data['rasterize_time'] * 1000.0) + ref_stats.rasterized_pixel_counts[-1].append(data['rasterized_pixel_count']) + + +def AddInputLatencyStats(mock_timer, input_type, start_thread, end_thread, + ref_latency_stats = None): + """ Adds a random input latency stats event. + + input_type: The input type for which the latency slice is generated. + start_thread: The start thread on which the async slice is added. + end_thread: The end thread on which the async slice is ended. + ref_latency_stats: A ReferenceInputLatencyStats object for expected values. + """ + + mock_timer.Advance() + ui_comp_time = mock_timer.Get() * 1000.0 + mock_timer.Advance() + begin_comp_time = mock_timer.Get() * 1000.0 + mock_timer.Advance(10, 20) + end_comp_time = mock_timer.Get() * 1000.0 + + data = { UI_COMP_NAME: {'time': ui_comp_time}, + BEGIN_COMP_NAME: {'time': begin_comp_time}, + END_COMP_NAME: {'time': end_comp_time} } + + timestamp = mock_timer.Get() - ref_stats.rasterize_time.append(data['rasterize_time'] * 1000.0) - ref_stats.rasterized_pixel_count.append(data['rasterized_pixel_count']) + async_slice = tracing_async_slice.AsyncSlice( + 'benchmark', 'InputLatency', timestamp) + async_sub_slice = tracing_async_slice.AsyncSlice( + 'benchmark', 'InputLatency', timestamp) + async_sub_slice.args = {'data': data, 'step': input_type} + async_sub_slice.parent_slice = async_slice + async_sub_slice.start_thread = start_thread + async_sub_slice.end_thread = end_thread + + async_slice.sub_slices.append(async_sub_slice) + async_slice.start_thread = start_thread + async_slice.end_thread = end_thread + start_thread.AddAsyncSlice(async_slice) + + if not ref_latency_stats: + return + + if input_type == 'MouseWheel': + ref_latency_stats.mouse_wheel_scroll_events.append(async_sub_slice) + ref_latency_stats.mouse_wheel_scroll_latency.append( + (data[END_COMP_NAME]['time'] - data[BEGIN_COMP_NAME]['time']) / 1000.0) + + if input_type == 'GestureScrollUpdate': + ref_latency_stats.touch_scroll_events.append(async_sub_slice) + ref_latency_stats.touch_scroll_latency.append( + (data[END_COMP_NAME]['time'] - data[UI_COMP_NAME]['time']) / 1000.0) + + if input_type == 'TouchMove': + ref_latency_stats.js_touch_scroll_events.append(async_sub_slice) + ref_latency_stats.js_touch_scroll_latency.append( + (data[END_COMP_NAME]['time'] - data[UI_COMP_NAME]['time']) / 1000.0) class RenderingStatsUnitTest(unittest.TestCase): def testFromTimeline(self): @@ -137,6 +217,7 @@ class RenderingStatsUnitTest(unittest.TestCase): # Create 10 main and impl rendering stats events for Action A. timer.Advance() renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') + ref_stats.AppendNewRange() for i in xrange(0, 10): first = (i == 0) AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) @@ -156,6 +237,7 @@ class RenderingStatsUnitTest(unittest.TestCase): # Create 10 main and impl rendering stats events for Action B. timer.Advance() renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '') + ref_stats.AppendNewRange() for i in xrange(0, 10): first = (i == 0) AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) @@ -167,6 +249,7 @@ class RenderingStatsUnitTest(unittest.TestCase): # Create 10 main and impl rendering stats events for Action A. timer.Advance() renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') + ref_stats.AppendNewRange() for i in xrange(0, 10): first = (i == 0) AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) @@ -182,16 +265,110 @@ class RenderingStatsUnitTest(unittest.TestCase): ['ActionA', 'ActionB', 'ActionA']) timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker) for marker in timeline_markers ] - stats = RenderingStats(renderer, timeline_ranges) + stats = RenderingStats(renderer, browser, timeline_ranges) # Compare rendering stats to reference. self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps) self.assertEquals(stats.frame_times, ref_stats.frame_times) - self.assertEquals(stats.rasterize_time, ref_stats.rasterize_time) - self.assertEquals(stats.rasterized_pixel_count, - ref_stats.rasterized_pixel_count) - self.assertEquals(stats.paint_time, ref_stats.paint_time) - self.assertEquals(stats.painted_pixel_count, ref_stats.painted_pixel_count) - self.assertEquals(stats.record_time, ref_stats.record_time) - self.assertEquals(stats.recorded_pixel_count, - ref_stats.recorded_pixel_count) + self.assertEquals(stats.rasterize_times, ref_stats.rasterize_times) + self.assertEquals(stats.rasterized_pixel_counts, + ref_stats.rasterized_pixel_counts) + self.assertEquals(stats.paint_times, ref_stats.paint_times) + self.assertEquals(stats.painted_pixel_counts, + ref_stats.painted_pixel_counts) + self.assertEquals(stats.record_times, ref_stats.record_times) + self.assertEquals(stats.recorded_pixel_counts, + ref_stats.recorded_pixel_counts) + + def testScrollLatencyFromTimeline(self): + timeline = model.TimelineModel() + + # Create a browser process and a renderer process. + browser = timeline.GetOrCreateProcess(pid = 1) + browser_main = browser.GetOrCreateThread(tid = 11) + renderer = timeline.GetOrCreateProcess(pid = 2) + renderer_main = renderer.GetOrCreateThread(tid = 21) + + timer = MockTimer() + ref_latency_stats = ReferenceInputLatencyStats() + + # Create 10 input latency stats events for Action A. + timer.Advance() + renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') + for _ in xrange(0, 10): + AddInputLatencyStats(timer, 'MouseWheel', browser_main, + renderer_main, ref_latency_stats) + AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, + renderer_main, ref_latency_stats) + AddInputLatencyStats(timer, 'TouchMove', browser_main, + renderer_main, ref_latency_stats) + renderer_main.EndSlice(timer.Get()) + + # Create 5 input latency stats events not within any action. + for _ in xrange(0, 5): + AddInputLatencyStats(timer, 'MouseWheel', browser_main, + renderer_main, None) + AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, + renderer_main, None) + AddInputLatencyStats(timer, 'TouchMove', browser_main, + renderer_main, None) + + # Create 10 input latency stats events for Action B. + timer.Advance() + renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '') + for _ in xrange(0, 10): + AddInputLatencyStats(timer, 'MouseWheel', browser_main, + renderer_main, ref_latency_stats) + AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, + renderer_main, ref_latency_stats) + AddInputLatencyStats(timer, 'TouchMove', browser_main, + renderer_main, ref_latency_stats) + renderer_main.EndSlice(timer.Get()) + + # Create 10 input latency stats events for Action A. + timer.Advance() + renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') + for _ in xrange(0, 10): + AddInputLatencyStats(timer, 'MouseWheel', browser_main, + renderer_main, ref_latency_stats) + AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, + renderer_main, ref_latency_stats) + AddInputLatencyStats(timer, 'TouchMove', browser_main, + renderer_main, ref_latency_stats) + renderer_main.EndSlice(timer.Get()) + + browser_main.FinalizeImport() + renderer_main.FinalizeImport() + + mouse_wheel_scroll_events = [] + touch_scroll_events = [] + js_touch_scroll_events = [] + + timeline_markers = timeline.FindTimelineMarkers( + ['ActionA', 'ActionB', 'ActionA']) + for timeline_range in [ timeline_bounds.Bounds.CreateFromEvent(marker) + for marker in timeline_markers ]: + if timeline_range.is_empty: + continue + tmp_mouse_events = GetScrollInputLatencyEvents( + 'MouseWheel', browser, timeline_range) + tmp_touch_scroll_events = GetScrollInputLatencyEvents( + 'GestureScrollUpdate', browser, timeline_range) + tmp_js_touch_scroll_events = GetScrollInputLatencyEvents( + 'TouchMove', browser, timeline_range) + mouse_wheel_scroll_events.extend(tmp_mouse_events) + touch_scroll_events.extend(tmp_touch_scroll_events) + js_touch_scroll_events.extend(tmp_js_touch_scroll_events) + + self.assertEquals(mouse_wheel_scroll_events, + ref_latency_stats.mouse_wheel_scroll_events) + self.assertEquals(touch_scroll_events, + ref_latency_stats.touch_scroll_events) + self.assertEquals(js_touch_scroll_events, + ref_latency_stats.js_touch_scroll_events) + self.assertEquals(ComputeMouseWheelScrollLatency(mouse_wheel_scroll_events), + ref_latency_stats.mouse_wheel_scroll_latency) + self.assertEquals(ComputeTouchScrollLatency(touch_scroll_events), + ref_latency_stats.touch_scroll_latency) + self.assertEquals(ComputeTouchScrollLatency(js_touch_scroll_events), + ref_latency_stats.js_touch_scroll_latency)