Home | History | Annotate | Download | only in android
      1 # SPDX-License-Identifier: Apache-2.0
      2 #
      3 # Copyright (C) 2017, ARM Limited and contributors.
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License"); you may
      6 # not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 # http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 # Parser for dumpsys gfxinfo output
     18 
     19 import ast, re
     20 
     21 def get_value(token):
     22     try:
     23         v = ast.literal_eval(token)
     24     except:
     25         return token
     26     return v
     27 
     28 class GfxInfo(object):
     29     """
     30     Class for parsing and accessing GfxInfo output
     31     """
     32     __properties = {}
     33 
     34     def __init__(self, path):
     35         """
     36         Initialize gfxinfo parser object
     37 
     38         :param path: Path to file containing output of gfxinfo
     39         """
     40         self.path = path
     41         self.parse_gfxinfo()
     42 
     43     def parse_gfxinfo(self):
     44         """
     45         Parser for gfxinfo output, creates a name/value pair
     46         """
     47         with open(self.path) as f:
     48             content = f.readlines()
     49 
     50         parsing_histogram = False
     51 
     52         # gfxinfo has several statistics of the format
     53         # <string>: <value>
     54         for line in content:
     55             line = line.rstrip()
     56             # Ignore any lines that aren't of this format
     57             if not ':' in line or line.endswith(':'):
     58                 continue
     59 
     60             tokens = line.split(':')
     61             # convert <string> into a key by replacing spaces with '_'
     62             tokens = [t.strip() for t in tokens]
     63             tokens[0] = tokens[0].replace(' ', '_').lower()
     64 
     65             # Parse janky_frames. Ex: "Janky frames: 44 (26.99%)"
     66             if tokens[0] == 'janky_frames':
     67                 (frames, pc) = tokens[1].split(' ')
     68                 self.__properties["janky_frames"] = get_value(frames)
     69                 pc = re.sub('[\(\)\%]', '', pc)
     70                 self.__properties["janky_frames_pc"] = get_value(pc)
     71                 continue
     72             # Parse 'nth_percentile: <int>ms' into nth_percentile_ms=<int>
     73             if tokens[1].endswith('ms'):
     74                 tokens[0] = tokens[0] + '_ms'
     75                 tokens[1] = tokens[1][:-2]
     76             # Begin parsing the histogram of frame times
     77             if tokens[0] == 'histogram':
     78                 parsing_histogram = True
     79                 self.__properties['histogram'] = []
     80                 line = line[11:]
     81             # Extracts the frame time data into an array of tuples
     82             # Ex: 5ms=50 6ms=60 7ms=70 ... -> [(5, 50), (6, 60), (7, 70), ...]
     83             if parsing_histogram:
     84                 h_tokens = [x.rstrip() for x in line.split(' ')]
     85                 if 'ms=' in line:
     86                     for h_value in [x.split('=') for x in h_tokens]:
     87                         self.__properties['histogram'].append((int(h_value[0][:-2]), int(h_value[1])))
     88                 else:
     89                     parsing_histogram = False
     90                 continue
     91 
     92             # Regular parsing
     93             self.__properties[tokens[0]] = get_value(tokens[1])
     94 
     95     def __dir__(self):
     96         """
     97         List all available attributes including ones parsed from
     98         gfxinfo output
     99         """
    100         return self.__properties.keys()
    101 
    102     def __getattr__(self, name):
    103         """
    104         Get the gfxinfo property using the period operator
    105         Ex: obj.number_missed_vsync
    106         """
    107         return self.__properties[name]
    108 
    109     def __getitem__(self, name):
    110         """
    111         Get the gfxinfo property using the [] opertator
    112         Useful for attributes like "50th_percentile" that can't
    113         be fetched with the period operator
    114         """
    115         return self.__properties[name]
    116