summaryrefslogtreecommitdiffstats
path: root/build
diff options
context:
space:
mode:
authordominikg@chromium.org <dominikg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-18 08:53:07 +0000
committerdominikg@chromium.org <dominikg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-18 08:53:07 +0000
commit138cea3bb15c0057860bc0058f495d63de41f61a (patch)
tree24c84fa8a56f7479add50205365cb25442db77cd /build
parent05ac0f02fe6ec4a9820a68329209f3cb25353803 (diff)
downloadchromium_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.py17
-rw-r--r--build/android/pylib/perf/surface_stats_collector_unittest.py62
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()