- add sources.
[platform/framework/web/crosswalk.git] / src / build / android / surface_stats.py
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 """Command line tool for continuously printing Android graphics surface
8 statistics on the console.
9 """
10
11 import collections
12 import optparse
13 import sys
14 import time
15
16 from pylib import android_commands
17 from pylib.perf import surface_stats_collector
18 from pylib.utils import run_tests_helper
19
20
21 _FIELD_FORMAT = {
22   'jank_count (janks)': '%d',
23   'max_frame_delay (vsyncs)': '%d',
24   'avg_surface_fps (fps)': '%.2f',
25   'frame_lengths (vsyncs)': '%.3f',
26   'refresh_period (seconds)': '%.6f',
27 }
28
29
30 def _MergeResults(results, fields):
31   merged_results = collections.defaultdict(list)
32   for result in results:
33     if ((fields != ['all'] and not result.name in fields) or
34         result.value is None):
35       continue
36     name = '%s (%s)' % (result.name, result.unit)
37     if isinstance(result.value, list):
38       value = result.value
39     else:
40       value = [result.value]
41     merged_results[name] += value
42   for name, values in merged_results.iteritems():
43     merged_results[name] = sum(values) / float(len(values))
44   return merged_results
45
46
47 def _GetTerminalHeight():
48   try:
49     import fcntl, termios, struct
50   except ImportError:
51     return 0, 0
52   height, _, _, _ = struct.unpack('HHHH',
53       fcntl.ioctl(0, termios.TIOCGWINSZ,
54           struct.pack('HHHH', 0, 0, 0, 0)))
55   return height
56
57
58 def _PrintColumnTitles(results):
59   for name in results.keys():
60     print '%s ' % name,
61   print
62   for name in results.keys():
63     print '%s ' % ('-' * len(name)),
64   print
65
66
67 def _PrintResults(results):
68   for name, value in results.iteritems():
69     value = _FIELD_FORMAT.get(name, '%s') % value
70     print value.rjust(len(name)) + ' ',
71   print
72
73
74 def main(argv):
75   parser = optparse.OptionParser(usage='Usage: %prog [options]',
76                                  description=__doc__)
77   parser.add_option('-v',
78                     '--verbose',
79                     dest='verbose_count',
80                     default=0,
81                     action='count',
82                     help='Verbose level (multiple times for more)')
83   parser.add_option('--device',
84                     help='Serial number of device we should use.')
85   parser.add_option('-f',
86                     '--fields',
87                     dest='fields',
88                     default='jank_count,max_frame_delay,avg_surface_fps,'
89                         'frame_lengths',
90                     help='Comma separated list of fields to display or "all".')
91   parser.add_option('-d',
92                     '--delay',
93                     dest='delay',
94                     default=1,
95                     type='float',
96                     help='Time in seconds to sleep between updates.')
97
98   options, args = parser.parse_args(argv)
99   run_tests_helper.SetLogLevel(options.verbose_count)
100
101   adb = android_commands.AndroidCommands(options.device)
102   collector = surface_stats_collector.SurfaceStatsCollector(adb)
103   collector.DisableWarningAboutEmptyData()
104
105   fields = options.fields.split(',')
106   row_count = None
107
108   try:
109     collector.Start()
110     while True:
111       time.sleep(options.delay)
112       results = collector.SampleResults()
113       results = _MergeResults(results, fields)
114
115       if not results:
116         continue
117
118       terminal_height = _GetTerminalHeight()
119       if row_count is None or (terminal_height and
120           row_count >= terminal_height - 3):
121         _PrintColumnTitles(results)
122         row_count = 0
123
124       _PrintResults(results)
125       row_count += 1
126   except KeyboardInterrupt:
127     sys.exit(0)
128   finally:
129     collector.Stop()
130
131
132 if __name__ == '__main__':
133   main(sys.argv)