Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Side by Side Diff: build/android/pylib/perf/surface_stats_collector.py

Issue 71353006: Telemetry: Filter invalid frame lengths from SurfaceFlinger data. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: small fix. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | build/android/pylib/perf/surface_stats_collector_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import Queue 5 import Queue
6 import datetime 6 import datetime
7 import logging 7 import logging
8 import re 8 import re
9 import threading 9 import threading
10 10
11 11
12 # Log marker containing SurfaceTexture timestamps. 12 # Log marker containing SurfaceTexture timestamps.
13 _SURFACE_TEXTURE_TIMESTAMPS_MESSAGE = 'SurfaceTexture update timestamps' 13 _SURFACE_TEXTURE_TIMESTAMPS_MESSAGE = 'SurfaceTexture update timestamps'
14 _SURFACE_TEXTURE_TIMESTAMP_RE = '\d+' 14 _SURFACE_TEXTURE_TIMESTAMP_RE = '\d+'
15 15
16 _MIN_NORMALIZED_FRAME_LENGTH = 0.5
17
16 18
17 class SurfaceStatsCollector(object): 19 class SurfaceStatsCollector(object):
18 """Collects surface stats for a SurfaceView from the output of SurfaceFlinger. 20 """Collects surface stats for a SurfaceView from the output of SurfaceFlinger.
19 21
20 Args: 22 Args:
21 adb: the adb connection to use. 23 adb: the adb connection to use.
22 """ 24 """
23 class Result(object): 25 class Result(object):
24 def __init__(self, name, value, unit): 26 def __init__(self, name, value, unit):
25 self.name = name 27 self.name = name
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 def _GetEmptyResults(self): 74 def _GetEmptyResults(self):
73 return [ 75 return [
74 SurfaceStatsCollector.Result('refresh_period', None, 'seconds'), 76 SurfaceStatsCollector.Result('refresh_period', None, 'seconds'),
75 SurfaceStatsCollector.Result('jank_count', None, 'janks'), 77 SurfaceStatsCollector.Result('jank_count', None, 'janks'),
76 SurfaceStatsCollector.Result('max_frame_delay', None, 'vsyncs'), 78 SurfaceStatsCollector.Result('max_frame_delay', None, 'vsyncs'),
77 SurfaceStatsCollector.Result('frame_lengths', None, 'vsyncs'), 79 SurfaceStatsCollector.Result('frame_lengths', None, 'vsyncs'),
78 SurfaceStatsCollector.Result('avg_surface_fps', None, 'fps') 80 SurfaceStatsCollector.Result('avg_surface_fps', None, 'fps')
79 ] 81 ]
80 82
81 @staticmethod 83 @staticmethod
82 def _GetNormalizedDeltas(data, refresh_period): 84 def _GetNormalizedDeltas(data, refresh_period, min_normalized_delta=None):
83 deltas = [t2 - t1 for t1, t2 in zip(data, data[1:])] 85 deltas = [t2 - t1 for t1, t2 in zip(data, data[1:])]
86 if min_normalized_delta != None:
87 deltas = filter(lambda d: d / refresh_period >= min_normalized_delta,
88 deltas)
84 return (deltas, [delta / refresh_period for delta in deltas]) 89 return (deltas, [delta / refresh_period for delta in deltas])
85 90
86 @staticmethod 91 @staticmethod
87 def _CalculateResults(refresh_period, timestamps, result_suffix): 92 def _CalculateResults(refresh_period, timestamps, result_suffix):
88 """Returns a list of SurfaceStatsCollector.Result.""" 93 """Returns a list of SurfaceStatsCollector.Result."""
89 frame_count = len(timestamps) 94 frame_count = len(timestamps)
90 seconds = timestamps[-1] - timestamps[0] 95 seconds = timestamps[-1] - timestamps[0]
91 96
92 frame_lengths, normalized_frame_lengths = \ 97 frame_lengths, normalized_frame_lengths = \
93 SurfaceStatsCollector._GetNormalizedDeltas(timestamps, refresh_period) 98 SurfaceStatsCollector._GetNormalizedDeltas(
99 timestamps, refresh_period, _MIN_NORMALIZED_FRAME_LENGTH)
100 if len(frame_lengths) < frame_count - 1:
101 logging.warning('Skipping frame lengths that are too short.')
102 frame_count = len(frame_lengths) + 1
103 if len(frame_lengths) == 0:
104 raise Exception('No valid frames lengths found.')
94 length_changes, normalized_changes = \ 105 length_changes, normalized_changes = \
95 SurfaceStatsCollector._GetNormalizedDeltas( 106 SurfaceStatsCollector._GetNormalizedDeltas(
96 frame_lengths, refresh_period) 107 frame_lengths, refresh_period)
97 jankiness = [max(0, round(change)) for change in normalized_changes] 108 jankiness = [max(0, round(change)) for change in normalized_changes]
98 pause_threshold = 20 109 pause_threshold = 20
99 jank_count = sum(1 for change in jankiness 110 jank_count = sum(1 for change in jankiness
100 if change > 0 and change < pause_threshold) 111 if change > 0 and change < pause_threshold)
101 return [ 112 return [
102 SurfaceStatsCollector.Result( 113 SurfaceStatsCollector.Result(
103 'avg_surface_fps' + result_suffix, 114 'avg_surface_fps' + result_suffix,
104 int(round(frame_count / seconds)), 'fps'), 115 int(round((frame_count - 1) / seconds)), 'fps'),
105 SurfaceStatsCollector.Result( 116 SurfaceStatsCollector.Result(
106 'jank_count' + result_suffix, jank_count, 'janks'), 117 'jank_count' + result_suffix, jank_count, 'janks'),
107 SurfaceStatsCollector.Result( 118 SurfaceStatsCollector.Result(
108 'max_frame_delay' + result_suffix, 119 'max_frame_delay' + result_suffix,
109 round(max(normalized_frame_lengths)), 120 round(max(normalized_frame_lengths)),
110 'vsyncs'), 121 'vsyncs'),
111 SurfaceStatsCollector.Result( 122 SurfaceStatsCollector.Result(
112 'frame_lengths' + result_suffix, normalized_frame_lengths, 123 'frame_lengths' + result_suffix, normalized_frame_lengths,
113 'vsyncs'), 124 'vsyncs'),
114 ] 125 ]
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 try: 298 try:
288 cur_surface = int(match.group(1), 16) 299 cur_surface = int(match.group(1), 16)
289 except Exception: 300 except Exception:
290 logging.error('Failed to parse current surface from ' + match.group(1)) 301 logging.error('Failed to parse current surface from ' + match.group(1))
291 else: 302 else:
292 logging.warning('Failed to call SurfaceFlinger surface ' + results[0]) 303 logging.warning('Failed to call SurfaceFlinger surface ' + results[0])
293 return { 304 return {
294 'page_flip_count': cur_surface, 305 'page_flip_count': cur_surface,
295 'timestamp': datetime.datetime.now(), 306 'timestamp': datetime.datetime.now(),
296 } 307 }
OLDNEW
« no previous file with comments | « no previous file | build/android/pylib/perf/surface_stats_collector_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698