blob: c4ec7bc57eb529449731f315190bc471a6701b08 [file] [log] [blame]
# 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')