| OLD | NEW |
| 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 from pylib import android_commands | 10 from pylib import android_commands |
| 11 from pylib.device import device_utils | 11 from pylib.device import device_utils |
| 12 | 12 |
| 13 | 13 |
| 14 # Log marker containing SurfaceTexture timestamps. | 14 # Log marker containing SurfaceTexture timestamps. |
| 15 _SURFACE_TEXTURE_TIMESTAMPS_MESSAGE = 'SurfaceTexture update timestamps' | 15 _SURFACE_TEXTURE_TIMESTAMPS_MESSAGE = 'SurfaceTexture update timestamps' |
| 16 _SURFACE_TEXTURE_TIMESTAMP_RE = '\d+' | 16 _SURFACE_TEXTURE_TIMESTAMP_RE = r'\d+' |
| 17 | 17 |
| 18 _MIN_NORMALIZED_FRAME_LENGTH = 0.5 | 18 _MIN_NORMALIZED_FRAME_LENGTH = 0.5 |
| 19 | 19 |
| 20 | 20 |
| 21 class SurfaceStatsCollector(object): | 21 class SurfaceStatsCollector(object): |
| 22 """Collects surface stats for a SurfaceView from the output of SurfaceFlinger. | 22 """Collects surface stats for a SurfaceView from the output of SurfaceFlinger. |
| 23 | 23 |
| 24 Args: | 24 Args: |
| 25 device: A DeviceUtils instance. | 25 device: A DeviceUtils instance. |
| 26 """ | 26 """ |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 SurfaceStatsCollector.Result('jank_count', None, 'janks'), | 83 SurfaceStatsCollector.Result('jank_count', None, 'janks'), |
| 84 SurfaceStatsCollector.Result('max_frame_delay', None, 'vsyncs'), | 84 SurfaceStatsCollector.Result('max_frame_delay', None, 'vsyncs'), |
| 85 SurfaceStatsCollector.Result('frame_lengths', None, 'vsyncs'), | 85 SurfaceStatsCollector.Result('frame_lengths', None, 'vsyncs'), |
| 86 SurfaceStatsCollector.Result('avg_surface_fps', None, 'fps') | 86 SurfaceStatsCollector.Result('avg_surface_fps', None, 'fps') |
| 87 ] | 87 ] |
| 88 | 88 |
| 89 @staticmethod | 89 @staticmethod |
| 90 def _GetNormalizedDeltas(data, refresh_period, min_normalized_delta=None): | 90 def _GetNormalizedDeltas(data, refresh_period, min_normalized_delta=None): |
| 91 deltas = [t2 - t1 for t1, t2 in zip(data, data[1:])] | 91 deltas = [t2 - t1 for t1, t2 in zip(data, data[1:])] |
| 92 if min_normalized_delta != None: | 92 if min_normalized_delta != None: |
| 93 deltas = filter(lambda d: d / refresh_period >= min_normalized_delta, | 93 deltas = [d for d in deltas |
| 94 deltas) | 94 if d / refresh_period >= min_normalized_delta] |
| 95 return (deltas, [delta / refresh_period for delta in deltas]) | 95 return (deltas, [delta / refresh_period for delta in deltas]) |
| 96 | 96 |
| 97 @staticmethod | 97 @staticmethod |
| 98 def _CalculateResults(refresh_period, timestamps, result_suffix): | 98 def _CalculateResults(refresh_period, timestamps, result_suffix): |
| 99 """Returns a list of SurfaceStatsCollector.Result.""" | 99 """Returns a list of SurfaceStatsCollector.Result.""" |
| 100 frame_count = len(timestamps) | 100 frame_count = len(timestamps) |
| 101 seconds = timestamps[-1] - timestamps[0] | 101 seconds = timestamps[-1] - timestamps[0] |
| 102 | 102 |
| 103 frame_lengths, normalized_frame_lengths = \ | 103 frame_lengths, normalized_frame_lengths = \ |
| 104 SurfaceStatsCollector._GetNormalizedDeltas( | 104 SurfaceStatsCollector._GetNormalizedDeltas( |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 and timestamp. | 290 and timestamp. |
| 291 | 291 |
| 292 Calculate FPS by measuring the difference of Surface index returned by | 292 Calculate FPS by measuring the difference of Surface index returned by |
| 293 SurfaceFlinger in a period of time. | 293 SurfaceFlinger in a period of time. |
| 294 | 294 |
| 295 Returns: | 295 Returns: |
| 296 Dict of {page_flip_count (or 0 if there was an error), timestamp}. | 296 Dict of {page_flip_count (or 0 if there was an error), timestamp}. |
| 297 """ | 297 """ |
| 298 results = self._device.RunShellCommand('service call SurfaceFlinger 1013') | 298 results = self._device.RunShellCommand('service call SurfaceFlinger 1013') |
| 299 assert len(results) == 1 | 299 assert len(results) == 1 |
| 300 match = re.search('^Result: Parcel\((\w+)', results[0]) | 300 match = re.search(r'^Result: Parcel\((\w+)', results[0]) |
| 301 cur_surface = 0 | 301 cur_surface = 0 |
| 302 if match: | 302 if match: |
| 303 try: | 303 try: |
| 304 cur_surface = int(match.group(1), 16) | 304 cur_surface = int(match.group(1), 16) |
| 305 except Exception: | 305 except Exception: |
| 306 logging.error('Failed to parse current surface from ' + match.group(1)) | 306 logging.error('Failed to parse current surface from ' + match.group(1)) |
| 307 else: | 307 else: |
| 308 logging.warning('Failed to call SurfaceFlinger surface ' + results[0]) | 308 logging.warning('Failed to call SurfaceFlinger surface ' + results[0]) |
| 309 return { | 309 return { |
| 310 'page_flip_count': cur_surface, | 310 'page_flip_count': cur_surface, |
| 311 'timestamp': datetime.datetime.now(), | 311 'timestamp': datetime.datetime.now(), |
| 312 } | 312 } |
| OLD | NEW |