Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 1 | from devlib.instrument import (Instrument, CONTINUOUS, |
| 2 | MeasurementsCsv, MeasurementType) |
| 3 | from devlib.utils.rendering import (GfxinfoFrameCollector, |
Sergei Trofimov | 1d3b4c8 | 2017-06-06 17:34:59 +0100 | [diff] [blame] | 4 | SurfaceFlingerFrameCollector, |
| 5 | SurfaceFlingerFrame, |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 6 | read_gfxinfo_columns) |
| 7 | |
| 8 | |
Sergei Trofimov | 1d3b4c8 | 2017-06-06 17:34:59 +0100 | [diff] [blame] | 9 | class FramesInstrument(Instrument): |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 10 | |
| 11 | mode = CONTINUOUS |
Sergei Trofimov | 1d3b4c8 | 2017-06-06 17:34:59 +0100 | [diff] [blame] | 12 | collector_cls = None |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 13 | |
Sergei Trofimov | 1d3b4c8 | 2017-06-06 17:34:59 +0100 | [diff] [blame] | 14 | def __init__(self, target, collector_target, period=2, keep_raw=True): |
| 15 | super(FramesInstrument, self).__init__(target) |
| 16 | self.collector_target = collector_target |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 17 | self.period = period |
| 18 | self.keep_raw = keep_raw |
Marc Bonnici | 7dd934a | 2017-08-03 16:41:10 +0100 | [diff] [blame] | 19 | self.sample_rate_hz = 1 / self.period |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 20 | self.collector = None |
| 21 | self.header = None |
| 22 | self._need_reset = True |
Sergei Trofimov | 823ce71 | 2017-08-30 14:55:42 +0100 | [diff] [blame^] | 23 | self._raw_file = None |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 24 | self._init_channels() |
| 25 | |
| 26 | def reset(self, sites=None, kinds=None, channels=None): |
Sergei Trofimov | 1d3b4c8 | 2017-06-06 17:34:59 +0100 | [diff] [blame] | 27 | super(FramesInstrument, self).reset(sites, kinds, channels) |
| 28 | self.collector = self.collector_cls(self.target, self.period, |
| 29 | self.collector_target, self.header) |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 30 | self._need_reset = False |
Sergei Trofimov | 823ce71 | 2017-08-30 14:55:42 +0100 | [diff] [blame^] | 31 | self._raw_file = None |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 32 | |
| 33 | def start(self): |
| 34 | if self._need_reset: |
| 35 | self.reset() |
| 36 | self.collector.start() |
| 37 | |
| 38 | def stop(self): |
| 39 | self.collector.stop() |
| 40 | self._need_reset = True |
| 41 | |
| 42 | def get_data(self, outfile): |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 43 | if self.keep_raw: |
Sergei Trofimov | 823ce71 | 2017-08-30 14:55:42 +0100 | [diff] [blame^] | 44 | self._raw_file = outfile + '.raw' |
| 45 | self.collector.process_frames(self._raw_file) |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 46 | active_sites = [chan.label for chan in self.active_channels] |
| 47 | self.collector.write_frames(outfile, columns=active_sites) |
Marc Bonnici | 049b275 | 2017-08-03 16:43:32 +0100 | [diff] [blame] | 48 | return MeasurementsCsv(outfile, self.active_channels, self.sample_rate_hz) |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 49 | |
Sergei Trofimov | 823ce71 | 2017-08-30 14:55:42 +0100 | [diff] [blame^] | 50 | def get_raw(self): |
| 51 | return [self._raw_file] if self._raw_file else [] |
| 52 | |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 53 | def _init_channels(self): |
Sergei Trofimov | 1d3b4c8 | 2017-06-06 17:34:59 +0100 | [diff] [blame] | 54 | raise NotImplementedError() |
| 55 | |
| 56 | |
| 57 | class GfxInfoFramesInstrument(FramesInstrument): |
| 58 | |
| 59 | mode = CONTINUOUS |
| 60 | collector_cls = GfxinfoFrameCollector |
| 61 | |
| 62 | def _init_channels(self): |
Sergei Trofimov | 4adefec | 2017-06-06 14:26:50 +0100 | [diff] [blame] | 63 | columns = read_gfxinfo_columns(self.target) |
| 64 | for entry in columns: |
| 65 | if entry == 'Flags': |
| 66 | self.add_channel('Flags', MeasurementType('flags', 'flags')) |
| 67 | else: |
| 68 | self.add_channel(entry, 'time_us') |
| 69 | self.header = [chan.label for chan in self.channels.values()] |
| 70 | |
Sergei Trofimov | 1d3b4c8 | 2017-06-06 17:34:59 +0100 | [diff] [blame] | 71 | |
| 72 | class SurfaceFlingerFramesInstrument(FramesInstrument): |
| 73 | |
| 74 | mode = CONTINUOUS |
| 75 | collector_cls = SurfaceFlingerFrameCollector |
| 76 | |
| 77 | def _init_channels(self): |
| 78 | for field in SurfaceFlingerFrame._fields: |
| 79 | # remove the "_time" from filed names to avoid duplication |
| 80 | self.add_channel(field[:-5], 'time_us') |
| 81 | self.header = [chan.label for chan in self.channels.values()] |