diff options
author | dominikg@chromium.org <dominikg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-18 08:53:07 +0000 |
---|---|---|
committer | dominikg@chromium.org <dominikg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-18 08:53:07 +0000 |
commit | 138cea3bb15c0057860bc0058f495d63de41f61a (patch) | |
tree | 24c84fa8a56f7479add50205365cb25442db77cd /build | |
parent | 05ac0f02fe6ec4a9820a68329209f3cb25353803 (diff) | |
download | chromium_src-138cea3bb15c0057860bc0058f495d63de41f61a.zip chromium_src-138cea3bb15c0057860bc0058f495d63de41f61a.tar.gz chromium_src-138cea3bb15c0057860bc0058f495d63de41f61a.tar.bz2 |
Telemetry: Filter invalid frame lengths from SurfaceFlinger data.
We use the SurfaceFlinger data to compute the lengths of the frames (normalized
to vsyncs). Sometimes the data is inconsistent and we get two frames that are
less than 1 vsync apart. Filter out these frame lengths (threshold length is
currently 0.5 vsyncs) and print a warning.
BUG=318093
Review URL: https://codereview.chromium.org/71353006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235675 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'build')
-rw-r--r-- | build/android/pylib/perf/surface_stats_collector.py | 17 | ||||
-rw-r--r-- | build/android/pylib/perf/surface_stats_collector_unittest.py | 62 |
2 files changed, 76 insertions, 3 deletions
diff --git a/build/android/pylib/perf/surface_stats_collector.py b/build/android/pylib/perf/surface_stats_collector.py index c38b1b4..9d92b43 100644 --- a/build/android/pylib/perf/surface_stats_collector.py +++ b/build/android/pylib/perf/surface_stats_collector.py @@ -13,6 +13,8 @@ import threading _SURFACE_TEXTURE_TIMESTAMPS_MESSAGE = 'SurfaceTexture update timestamps' _SURFACE_TEXTURE_TIMESTAMP_RE = '\d+' +_MIN_NORMALIZED_FRAME_LENGTH = 0.5 + class SurfaceStatsCollector(object): """Collects surface stats for a SurfaceView from the output of SurfaceFlinger. @@ -79,8 +81,11 @@ class SurfaceStatsCollector(object): ] @staticmethod - def _GetNormalizedDeltas(data, refresh_period): + def _GetNormalizedDeltas(data, refresh_period, min_normalized_delta=None): deltas = [t2 - t1 for t1, t2 in zip(data, data[1:])] + if min_normalized_delta != None: + deltas = filter(lambda d: d / refresh_period >= min_normalized_delta, + deltas) return (deltas, [delta / refresh_period for delta in deltas]) @staticmethod @@ -90,7 +95,13 @@ class SurfaceStatsCollector(object): seconds = timestamps[-1] - timestamps[0] frame_lengths, normalized_frame_lengths = \ - SurfaceStatsCollector._GetNormalizedDeltas(timestamps, refresh_period) + SurfaceStatsCollector._GetNormalizedDeltas( + timestamps, refresh_period, _MIN_NORMALIZED_FRAME_LENGTH) + if len(frame_lengths) < frame_count - 1: + logging.warning('Skipping frame lengths that are too short.') + frame_count = len(frame_lengths) + 1 + if len(frame_lengths) == 0: + raise Exception('No valid frames lengths found.') length_changes, normalized_changes = \ SurfaceStatsCollector._GetNormalizedDeltas( frame_lengths, refresh_period) @@ -101,7 +112,7 @@ class SurfaceStatsCollector(object): return [ SurfaceStatsCollector.Result( 'avg_surface_fps' + result_suffix, - int(round(frame_count / seconds)), 'fps'), + int(round((frame_count - 1) / seconds)), 'fps'), SurfaceStatsCollector.Result( 'jank_count' + result_suffix, jank_count, 'janks'), SurfaceStatsCollector.Result( diff --git a/build/android/pylib/perf/surface_stats_collector_unittest.py b/build/android/pylib/perf/surface_stats_collector_unittest.py new file mode 100644 index 0000000..982b55d --- /dev/null +++ b/build/android/pylib/perf/surface_stats_collector_unittest.py @@ -0,0 +1,62 @@ +# Copyright 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. + +"""Unittests for SurfaceStatsCollector.""" + +import unittest + +from surface_stats_collector import SurfaceStatsCollector + +class TestSurfaceStatsCollector(unittest.TestCase): + @staticmethod + def _CreateUniformTimestamps(base, num, delta): + return [base + i * delta for i in range(1, num + 1)] + + @staticmethod + def _CreateDictionaryFromResults(results): + dictionary = {} + for result in results: + dictionary[result.name] = result + return dictionary + + def setUp(self): + self.refresh_period = 0.1 + + def testOneFrameDelta(self): + timestamps = self._CreateUniformTimestamps(0, 10, self.refresh_period) + results = self._CreateDictionaryFromResults( + SurfaceStatsCollector._CalculateResults( + self.refresh_period, timestamps, '')) + + self.assertEquals(results['avg_surface_fps'].value, + int(round(1 / self.refresh_period))) + self.assertEquals(results['jank_count'].value, 0) + self.assertEquals(results['max_frame_delay'].value, 1) + self.assertEquals(len(results['frame_lengths'].value), len(timestamps) - 1) + + def testAllFramesTooShort(self): + timestamps = self._CreateUniformTimestamps(0, 10, self.refresh_period / 100) + self.assertRaises(Exception, + SurfaceStatsCollector._CalculateResults, + [self.refresh_period, timestamps, '']) + + def testSomeFramesTooShort(self): + timestamps = self._CreateUniformTimestamps(0, 5, self.refresh_period) + # The following timestamps should be skipped. + timestamps += self._CreateUniformTimestamps(timestamps[4], + 5, + self.refresh_period / 100) + timestamps += self._CreateUniformTimestamps(timestamps[4], + 5, + self.refresh_period) + + results = self._CreateDictionaryFromResults( + SurfaceStatsCollector._CalculateResults( + self.refresh_period, timestamps, '')) + + self.assertEquals(len(results['frame_lengths'].value), 9) + + +if __name__ == '__main__': + unittest.main() |