SurfaceStats / Telemetry: calculate FPS in different frame buckets.
Instead of just calculating FPS over all frames returned by SurfaceFlinger, use the last 90% and the last 50% as well. This allow us to have a better representation and skip the "setup" stage. BUG=256340 Review URL: https://chromiumcodereview.appspot.com/18341006 git-svn-id: http://src.chromium.org/svn/trunk/src/build@210583 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
This commit is contained in:
Родитель
2cc0715a54
Коммит
d3ea847751
|
@ -85,6 +85,45 @@ class SurfaceStatsCollector(object):
|
|||
deltas = [t2 - t1 for t1, t2 in zip(data, data[1:])]
|
||||
return (deltas, [delta / refresh_period for delta in deltas])
|
||||
|
||||
@staticmethod
|
||||
def _CalculateResults(refresh_period, timestamps, result_suffix):
|
||||
"""Returns a list of SurfaceStatsCollector.Result."""
|
||||
frame_count = len(timestamps)
|
||||
seconds = timestamps[-1] - timestamps[0]
|
||||
|
||||
frame_lengths, normalized_frame_lengths = \
|
||||
SurfaceStatsCollector._GetNormalizedDeltas(timestamps, refresh_period)
|
||||
length_changes, normalized_changes = \
|
||||
SurfaceStatsCollector._GetNormalizedDeltas(
|
||||
frame_lengths, refresh_period)
|
||||
jankiness = [max(0, round(change)) for change in normalized_changes]
|
||||
pause_threshold = 20
|
||||
jank_count = sum(1 for change in jankiness
|
||||
if change > 0 and change < pause_threshold)
|
||||
return [
|
||||
SurfaceStatsCollector.Result(
|
||||
'avg_surface_fps' + result_suffix,
|
||||
int(round(frame_count / seconds)), 'fps'),
|
||||
SurfaceStatsCollector.Result(
|
||||
'jank_count' + result_suffix, jank_count, 'janks'),
|
||||
SurfaceStatsCollector.Result(
|
||||
'max_frame_delay' + result_suffix,
|
||||
round(max(normalized_frame_lengths)),
|
||||
'vsyncs'),
|
||||
SurfaceStatsCollector.Result(
|
||||
'frame_lengths' + result_suffix, normalized_frame_lengths,
|
||||
'vsyncs'),
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def _CalculateBuckets(refresh_period, timestamps):
|
||||
results = []
|
||||
for pct in [0.99, 0.5]:
|
||||
sliced = timestamps[int(-pct * len(timestamps)) + 3 : ]
|
||||
results += SurfaceStatsCollector._CalculateResults(
|
||||
refresh_period, sliced, '_' + str(int(pct * 100)))
|
||||
return results
|
||||
|
||||
def _StorePerfResults(self):
|
||||
if self._use_legacy_method:
|
||||
surface_after = self._GetSurfaceStatsLegacy()
|
||||
|
@ -92,36 +131,21 @@ class SurfaceStatsCollector(object):
|
|||
seconds = td.seconds + td.microseconds / 1e6
|
||||
frame_count = (surface_after['page_flip_count'] -
|
||||
self._surface_before['page_flip_count'])
|
||||
else:
|
||||
assert self._collector_thread
|
||||
(refresh_period, timestamps) = self._GetDataFromThread()
|
||||
if not refresh_period or not len(timestamps) >= 3:
|
||||
if self._warn_about_empty_data:
|
||||
logging.warning('Surface stat data is empty')
|
||||
return
|
||||
frame_count = len(timestamps)
|
||||
seconds = timestamps[-1] - timestamps[0]
|
||||
self._results.append(SurfaceStatsCollector.Result(
|
||||
'avg_surface_fps', int(round(frame_count / seconds)), 'fps'))
|
||||
return
|
||||
|
||||
frame_lengths, normalized_frame_lengths = \
|
||||
self._GetNormalizedDeltas(timestamps, refresh_period)
|
||||
length_changes, normalized_changes = \
|
||||
self._GetNormalizedDeltas(frame_lengths, refresh_period)
|
||||
jankiness = [max(0, round(change)) for change in normalized_changes]
|
||||
pause_threshold = 20
|
||||
jank_count = sum(1 for change in jankiness
|
||||
if change > 0 and change < pause_threshold)
|
||||
|
||||
self._results.append(SurfaceStatsCollector.Result(
|
||||
'refresh_period', refresh_period, 'seconds'))
|
||||
self._results.append(SurfaceStatsCollector.Result(
|
||||
'jank_count', jank_count, 'janks'))
|
||||
self._results.append(SurfaceStatsCollector.Result(
|
||||
'max_frame_delay', round(max(normalized_frame_lengths)),
|
||||
'vsyncs'))
|
||||
self._results.append(SurfaceStatsCollector.Result(
|
||||
'frame_lengths', normalized_frame_lengths, 'vsyncs'))
|
||||
# Non-legacy method.
|
||||
assert self._collector_thread
|
||||
(refresh_period, timestamps) = self._GetDataFromThread()
|
||||
if not refresh_period or not len(timestamps) >= 3:
|
||||
if self._warn_about_empty_data:
|
||||
logging.warning('Surface stat data is empty')
|
||||
return
|
||||
self._results.append(SurfaceStatsCollector.Result(
|
||||
'avg_surface_fps', int(round(frame_count / seconds)), 'fps'))
|
||||
'refresh_period', refresh_period, 'seconds'))
|
||||
self._results += self._CalculateResults(refresh_period, timestamps, '')
|
||||
self._results += self._CalculateBuckets(refresh_period, timestamps)
|
||||
|
||||
def _CollectorThread(self):
|
||||
last_timestamp = 0
|
||||
|
|
Загрузка…
Ссылка в новой задаче