blob: 74bfdcee4934ab3a4e76e1273c8aa8ef59ec8bb8 [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright (c) 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.
"""Command line tool for continuously printing Android graphics surface
statistics on the console.
"""
import collections
import optparse
import sys
import time
from pylib.device import device_utils
from pylib.perf import surface_stats_collector
from pylib.utils import run_tests_helper
_FIELD_FORMAT = {
'jank_count (janks)': '%d',
'max_frame_delay (vsyncs)': '%d',
'avg_surface_fps (fps)': '%.2f',
'frame_lengths (vsyncs)': '%.3f',
'refresh_period (seconds)': '%.6f',
}
def _MergeResults(results, fields):
merged_results = collections.defaultdict(list)
for result in results:
if ((fields != ['all'] and not result.name in fields) or
result.value is None):
continue
name = '%s (%s)' % (result.name, result.unit)
if isinstance(result.value, list):
value = result.value
else:
value = [result.value]
merged_results[name] += value
for name, values in merged_results.iteritems():
merged_results[name] = sum(values) / float(len(values))
return merged_results
def _GetTerminalHeight():
try:
import fcntl, termios, struct
except ImportError:
return 0, 0
height, _, _, _ = struct.unpack('HHHH',
fcntl.ioctl(0, termios.TIOCGWINSZ,
struct.pack('HHHH', 0, 0, 0, 0)))
return height
def _PrintColumnTitles(results):
for name in results.keys():
print '%s ' % name,
print
for name in results.keys():
print '%s ' % ('-' * len(name)),
print
def _PrintResults(results):
for name, value in results.iteritems():
value = _FIELD_FORMAT.get(name, '%s') % value
print value.rjust(len(name)) + ' ',
print
def main(argv):
parser = optparse.OptionParser(usage='Usage: %prog [options]',
description=__doc__)
parser.add_option('-v',
'--verbose',
dest='verbose_count',
default=0,
action='count',
help='Verbose level (multiple times for more)')
parser.add_option('--device',
help='Serial number of device we should use.')
parser.add_option('-f',
'--fields',
dest='fields',
default='jank_count,max_frame_delay,avg_surface_fps,'
'frame_lengths',
help='Comma separated list of fields to display or "all".')
parser.add_option('-d',
'--delay',
dest='delay',
default=1,
type='float',
help='Time in seconds to sleep between updates.')
options, _ = parser.parse_args(argv)
run_tests_helper.SetLogLevel(options.verbose_count)
device = device_utils.DeviceUtils(options.device)
collector = surface_stats_collector.SurfaceStatsCollector(device)
collector.DisableWarningAboutEmptyData()
fields = options.fields.split(',')
row_count = None
try:
collector.Start()
while True:
time.sleep(options.delay)
results = collector.SampleResults()
results = _MergeResults(results, fields)
if not results:
continue
terminal_height = _GetTerminalHeight()
if row_count is None or (terminal_height and
row_count >= terminal_height - 3):
_PrintColumnTitles(results)
row_count = 0
_PrintResults(results)
row_count += 1
except KeyboardInterrupt:
sys.exit(0)
finally:
collector.Stop()
if __name__ == '__main__':
main(sys.argv)