Home | History | Annotate | Download | only in metrics
      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
      3 # found in the LICENSE file.
      4 import os
      5 
      6 from telemetry.core import util
      7 
      8 class SmoothnessMetrics(object):
      9   def __init__(self, tab):
     10     self._tab = tab
     11     with open(
     12       os.path.join(os.path.dirname(__file__),
     13                    'smoothness.js')) as f:
     14       js = f.read()
     15       tab.ExecuteJavaScript(js)
     16 
     17   def Start(self):
     18     self._tab.ExecuteJavaScript(
     19         'window.__renderingStats = new __RenderingStats();'
     20         'window.__renderingStats.start()')
     21 
     22   def SetNeedsDisplayOnAllLayersAndStart(self):
     23     self._tab.ExecuteJavaScript(
     24         'chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers();'
     25         'window.__renderingStats = new __RenderingStats();'
     26         'window.__renderingStats.start()')
     27 
     28   def Stop(self):
     29     self._tab.ExecuteJavaScript('window.__renderingStats.stop()')
     30 
     31   def BindToAction(self, action):
     32     # Make the scroll test start and stop measurement automatically.
     33     self._tab.ExecuteJavaScript(
     34         'window.__renderingStats = new __RenderingStats();')
     35     action.BindMeasurementJavaScript(self._tab,
     36                                      'window.__renderingStats.start();',
     37                                      'window.__renderingStats.stop();')
     38 
     39   @property
     40   def start_values(self):
     41     return self._tab.EvaluateJavaScript(
     42       'window.__renderingStats.getStartValues()')
     43 
     44   @property
     45   def end_values(self):
     46     return self._tab.EvaluateJavaScript(
     47       'window.__renderingStats.getEndValues()')
     48 
     49   @property
     50   def deltas(self):
     51     return self._tab.EvaluateJavaScript(
     52       'window.__renderingStats.getDeltas()')
     53 
     54 def Average(numerator, denominator, scale = None, precision = None):
     55   if denominator == 0:
     56     return 0
     57   avg = float(numerator) / float(denominator)
     58   if scale:
     59     avg *= scale
     60   if precision:
     61     avg = round(avg, precision)
     62   return avg
     63 
     64 def CalcFirstPaintTimeResults(results, tab):
     65   if tab.browser.is_content_shell:
     66     results.Add('first_paint', 'ms', 'unsupported')
     67     return
     68 
     69   tab.ExecuteJavaScript("""
     70       window.__rafFired = false;
     71       window.webkitRequestAnimationFrame(function() {
     72           window.__rafFired  = true;
     73       });
     74   """)
     75   util.WaitFor(lambda: tab.EvaluateJavaScript('window.__rafFired'), 60)
     76 
     77   first_paint_secs = tab.EvaluateJavaScript(
     78       'window.chrome.loadTimes().firstPaintTime - ' +
     79       'window.chrome.loadTimes().startLoadTime')
     80 
     81   results.Add('first_paint', 'ms', round(first_paint_secs * 1000, 1))
     82 
     83 def CalcResults(benchmark_stats, results):
     84   s = benchmark_stats
     85 
     86   # Scroll Results
     87   results.Add('mean_frame_time', 'ms',
     88               Average(s.total_time, s.screen_frame_count, 1000, 3))
     89   results.Add('dropped_percent', '%',
     90               Average(s.dropped_frame_count, s.screen_frame_count,
     91                       100, 1),
     92               data_type='unimportant')
     93   results.Add('percent_impl_scrolled', '%',
     94               Average(s.impl_thread_scroll_count,
     95                       s.impl_thread_scroll_count +
     96                       s.main_thread_scroll_count,
     97                       100, 1),
     98               data_type='unimportant')
     99   results.Add('average_num_layers_drawn', '',
    100               Average(s.drawn_layers_count, s.screen_frame_count, 1, 1),
    101               data_type='unimportant')
    102   results.Add('average_num_missing_tiles', '',
    103               Average(s.missing_tile_count, s.screen_frame_count, 1, 1),
    104               data_type='unimportant')
    105 
    106   # Texture Upload Results
    107   results.Add('average_commit_time', 'ms',
    108               Average(s.commit_time, s.commit_count, 1000, 3),
    109               data_type='unimportant')
    110   results.Add('texture_upload_count', 'count',
    111               s.texture_upload_count)
    112   results.Add('total_texture_upload_time', 'seconds',
    113               s.texture_upload_time)
    114 
    115   # Image Decoding Results
    116   results.Add('total_deferred_image_decode_count', 'count',
    117               s.deferred_image_decode_count,
    118               data_type='unimportant')
    119   results.Add('total_image_cache_hit_count', 'count',
    120               s.deferred_image_cache_hits,
    121               data_type='unimportant')
    122   results.Add('average_image_gathering_time', 'ms',
    123               Average(s.image_gathering_time, s.image_gathering_count,
    124                       1000, 3),
    125               data_type='unimportant')
    126   results.Add('total_deferred_image_decoding_time', 'seconds',
    127               s.deferred_image_decode_time,
    128               data_type='unimportant')
    129 
    130   # Tile Analysis Results
    131   results.Add('total_tiles_analyzed', 'count',
    132               s.tile_analysis_count,
    133               data_type='unimportant')
    134   results.Add('solid_color_tiles_analyzed', 'count',
    135               s.solid_color_tile_analysis_count,
    136               data_type='unimportant')
    137   results.Add('average_tile_analysis_time', 'ms',
    138               Average(s.tile_analysis_time, s.tile_analysis_count,
    139                       1000, 3),
    140               data_type='unimportant')
    141 
    142   # Latency Results
    143   results.Add('average_latency', 'ms',
    144               Average(s.input_event_latency, s.input_event_count,
    145                       1000, 3),
    146               data_type='unimportant')
    147   results.Add('average_touch_ui_latency', 'ms',
    148               Average(s.touch_ui_latency, s.touch_ui_count, 1000, 3),
    149               data_type='unimportant')
    150   results.Add('average_touch_acked_latency', 'ms',
    151               Average(s.touch_acked_latency, s.touch_acked_count,
    152                       1000, 3),
    153               data_type='unimportant')
    154   results.Add('average_scroll_update_latency', 'ms',
    155               Average(s.scroll_update_latency, s.scroll_update_count,
    156                       1000, 3),
    157               data_type='unimportant')
    158