Пример #1
0
    def _process_without_pandas(self, measurements_csv):
        per_frame_fps = []
        start_vsync, end_vsync = None, None
        frame_count = 0

        for frame_data in measurements_csv.iter_values():
            if frame_data.Flags_flags != 0:
                continue
            frame_count += 1

            if start_vsync is None:
                start_vsync = frame_data.Vsync_time_us
            end_vsync = frame_data.Vsync_time_us

            frame_time = frame_data.FrameCompleted_time_us - frame_data.IntendedVsync_time_us
            pff = 1e9 / frame_time
            if pff > self.drop_threshold:
                per_frame_fps.append([pff])

        if frame_count:
            duration = end_vsync - start_vsync
            fps = (1e6 * frame_count) / float(duration)
        else:
            duration = 0
            fps = 0

        csv_file = self._get_csv_file_name(measurements_csv.path)
        with csvwriter(csv_file) as writer:
            writer.writerow(['fps'])
            writer.writerows(per_frame_fps)

        return [DerivedMetric('fps', fps, 'fps'),
                DerivedMetric('total_frames', frame_count, 'frames'),
                MeasurementsCsv(csv_file)]
Пример #2
0
    def get_data(self, outfile):
        if os.stat(self.raw_data_file).st_size == 0:
            self.logger.warning('"{}" appears to be empty'.format(
                self.raw_data_file))
            return

        all_channels = [c.label for c in self.list_channels()]
        active_channels = [c.label for c in self.active_channels]
        active_indexes = [all_channels.index(ac) for ac in active_channels]

        with csvreader(self.raw_data_file, skipinitialspace=True) as reader:
            with csvwriter(outfile) as writer:
                writer.writerow(active_channels)

                header = next(reader)
                ts_index = header.index('timestamp ms')

                for row in reader:
                    output_row = []
                    for i in active_indexes:
                        if i == ts_index:
                            # Leave time in ms
                            output_row.append(float(row[i]))
                        else:
                            # Convert rest into standard units.
                            output_row.append(float(row[i]) / 1000)
                    writer.writerow(output_row)
        return MeasurementsCsv(outfile, self.active_channels,
                               self.sample_rate_hz)
Пример #3
0
    def _process_with_pandas(self, measurements_csv):
        data = pd.read_csv(measurements_csv.path)
        data = data[data.Flags_flags == 0]
        frame_time = data.FrameCompleted_time_us - data.IntendedVsync_time_us
        per_frame_fps = (1e6 / frame_time)
        keep_filter = per_frame_fps > self.drop_threshold
        per_frame_fps = per_frame_fps[keep_filter]
        per_frame_fps.name = 'fps'

        frame_count = data.index.size
        if frame_count > 1:
            duration = data.Vsync_time_us.iloc[-1] - data.Vsync_time_us.iloc[0]
            fps = (1e9 * frame_count) / float(duration)
        else:
            duration = 0
            fps = 0

        csv_file = self._get_csv_file_name(measurements_csv.path)
        per_frame_fps.to_csv(csv_file, index=False, header=True)

        return [
            DerivedMetric('fps', fps, 'fps'),
            DerivedMetric('total_frames', frame_count, 'frames'),
            MeasurementsCsv(csv_file)
        ]
Пример #4
0
    def _process_with_pandas(self, measurements_csv):
        data = pd.read_csv(measurements_csv.path)

        # fiter out bogus frames.
        bogus_frames_filter = data.actual_present_time_us != 0x7fffffffffffffff
        actual_present_times = data.actual_present_time_us[bogus_frames_filter]
        actual_present_time_deltas = actual_present_times.diff().dropna()

        vsyncs_to_compose = actual_present_time_deltas.div(VSYNC_INTERVAL)
        vsyncs_to_compose.apply(lambda x: int(round(x, 0)))

        # drop values lower than drop_threshold FPS as real in-game frame
        # rate is unlikely to drop below that (except on loading screens
        # etc, which should not be factored in frame rate calculation).
        per_frame_fps = (1.0 /
                         (vsyncs_to_compose.multiply(VSYNC_INTERVAL / 1e9)))
        keep_filter = per_frame_fps > self.drop_threshold
        filtered_vsyncs_to_compose = vsyncs_to_compose[keep_filter]
        per_frame_fps.name = 'fps'

        csv_file = self._get_csv_file_name(measurements_csv.path)
        per_frame_fps.to_csv(csv_file, index=False, header=True)

        if not filtered_vsyncs_to_compose.empty:
            fps = 0
            total_vsyncs = filtered_vsyncs_to_compose.sum()
            frame_count = filtered_vsyncs_to_compose.size

            if total_vsyncs:
                fps = 1e9 * frame_count / (VSYNC_INTERVAL * total_vsyncs)

            janks = self._calc_janks(filtered_vsyncs_to_compose)
            not_at_vsync = self._calc_not_at_vsync(vsyncs_to_compose)
        else:
            fps = 0
            frame_count = 0
            janks = 0
            not_at_vsync = 0

        janks_pc = 0 if frame_count == 0 else janks * 100 / frame_count

        return [
            DerivedMetric('fps', fps, 'fps'),
            DerivedMetric('total_frames', frame_count, 'frames'),
            MeasurementsCsv(csv_file),
            DerivedMetric('janks', janks, 'count'),
            DerivedMetric('janks_pc', janks_pc, 'percent'),
            DerivedMetric('missed_vsync', not_at_vsync, 'count')
        ]
Пример #5
0
 def process(self, measurements_csv):
     if isinstance(measurements_csv, basestring):
         measurements_csv = MeasurementsCsv(measurements_csv)
     if pd is not None:
         return self._process_with_pandas(measurements_csv)
     return self._process_without_pandas(measurements_csv)
Пример #6
0
    def get_data(self, outfile=None, **to_csv_kwargs):
        if outfile is None:
            return self.data

        self.data.to_csv(outfile, **to_csv_kwargs)
        return MeasurementsCsv(outfile, self.active_channels)