# Copyright 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import os from telemetry.core import util class SmoothnessMetrics(object): def __init__(self, tab): self._tab = tab with open( os.path.join(os.path.dirname(__file__), 'smoothness.js')) as f: js = f.read() tab.ExecuteJavaScript(js) def Start(self): self._tab.ExecuteJavaScript( 'window.__renderingStats = new __RenderingStats();' 'window.__renderingStats.start()') def SetNeedsDisplayOnAllLayersAndStart(self): self._tab.ExecuteJavaScript( 'chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers();' 'window.__renderingStats = new __RenderingStats();' 'window.__renderingStats.start()') def Stop(self): self._tab.ExecuteJavaScript('window.__renderingStats.stop()') def BindToAction(self, action): # Make the scroll test start and stop measurement automatically. self._tab.ExecuteJavaScript( 'window.__renderingStats = new __RenderingStats();') action.BindMeasurementJavaScript(self._tab, 'window.__renderingStats.start();', 'window.__renderingStats.stop();') @property def start_values(self): return self._tab.EvaluateJavaScript( 'window.__renderingStats.getStartValues()') @property def end_values(self): return self._tab.EvaluateJavaScript( 'window.__renderingStats.getEndValues()') @property def deltas(self): return self._tab.EvaluateJavaScript( 'window.__renderingStats.getDeltas()') def Average(numerator, denominator, scale = None, precision = None): if denominator == 0: return 0 avg = float(numerator) / float(denominator) if scale: avg *= scale if precision: avg = round(avg, precision) return avg def CalcFirstPaintTimeResults(results, tab): if tab.browser.is_content_shell: results.Add('first_paint', 'ms', 'unsupported') return tab.ExecuteJavaScript(""" window.__rafFired = false; window.webkitRequestAnimationFrame(function() { window.__rafFired = true; }); """) util.WaitFor(lambda: tab.EvaluateJavaScript('window.__rafFired'), 60) first_paint_secs = tab.EvaluateJavaScript( 'window.chrome.loadTimes().firstPaintTime - ' + 'window.chrome.loadTimes().startLoadTime') results.Add('first_paint', 'ms', round(first_paint_secs * 1000, 1)) def CalcResults(benchmark_stats, results): s = benchmark_stats # Scroll Results results.Add('mean_frame_time', 'ms', Average(s.total_time, s.screen_frame_count, 1000, 3)) results.Add('dropped_percent', '%', Average(s.dropped_frame_count, s.screen_frame_count, 100, 1), data_type='unimportant') results.Add('percent_impl_scrolled', '%', Average(s.impl_thread_scroll_count, s.impl_thread_scroll_count + s.main_thread_scroll_count, 100, 1), data_type='unimportant') results.Add('average_num_layers_drawn', '', Average(s.drawn_layers_count, s.screen_frame_count, 1, 1), data_type='unimportant') results.Add('average_num_missing_tiles', '', Average(s.missing_tile_count, s.screen_frame_count, 1, 1), data_type='unimportant') # Texture Upload Results results.Add('average_commit_time', 'ms', Average(s.commit_time, s.commit_count, 1000, 3), data_type='unimportant') results.Add('texture_upload_count', 'count', s.texture_upload_count) results.Add('total_texture_upload_time', 'seconds', s.texture_upload_time) # Image Decoding Results results.Add('total_deferred_image_decode_count', 'count', s.deferred_image_decode_count, data_type='unimportant') results.Add('total_image_cache_hit_count', 'count', s.deferred_image_cache_hits, data_type='unimportant') results.Add('average_image_gathering_time', 'ms', Average(s.image_gathering_time, s.image_gathering_count, 1000, 3), data_type='unimportant') results.Add('total_deferred_image_decoding_time', 'seconds', s.deferred_image_decode_time, data_type='unimportant') # Tile Analysis Results results.Add('total_tiles_analyzed', 'count', s.tile_analysis_count, data_type='unimportant') results.Add('solid_color_tiles_analyzed', 'count', s.solid_color_tile_analysis_count, data_type='unimportant') results.Add('average_tile_analysis_time', 'ms', Average(s.tile_analysis_time, s.tile_analysis_count, 1000, 3), data_type='unimportant') # Latency Results results.Add('average_latency', 'ms', Average(s.input_event_latency, s.input_event_count, 1000, 3), data_type='unimportant') results.Add('average_touch_ui_latency', 'ms', Average(s.touch_ui_latency, s.touch_ui_count, 1000, 3), data_type='unimportant') results.Add('average_touch_acked_latency', 'ms', Average(s.touch_acked_latency, s.touch_acked_count, 1000, 3), data_type='unimportant') results.Add('average_scroll_update_latency', 'ms', Average(s.scroll_update_latency, s.scroll_update_count, 1000, 3), data_type='unimportant')