| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 def __init__(self, adb): | 31 def __init__(self, adb): |
| 32 self._adb = adb | 32 self._adb = adb |
| 33 self._collector_thread = None | 33 self._collector_thread = None |
| 34 self._use_legacy_method = False | 34 self._use_legacy_method = False |
| 35 self._surface_before = None | 35 self._surface_before = None |
| 36 self._get_data_event = None | 36 self._get_data_event = None |
| 37 self._data_queue = None | 37 self._data_queue = None |
| 38 self._stop_event = None | 38 self._stop_event = None |
| 39 self._results = [] | 39 self._results = [] |
| 40 self._warn_about_empty_data = True |
| 41 |
| 42 def DisableWarningAboutEmptyData(self): |
| 43 self._warn_about_empty_data = False |
| 40 | 44 |
| 41 def Start(self): | 45 def Start(self): |
| 42 assert not self._collector_thread | 46 assert not self._collector_thread |
| 43 | 47 |
| 44 if self._ClearSurfaceFlingerLatencyData(): | 48 if self._ClearSurfaceFlingerLatencyData(): |
| 45 self._get_data_event = threading.Event() | 49 self._get_data_event = threading.Event() |
| 46 self._stop_event = threading.Event() | 50 self._stop_event = threading.Event() |
| 47 self._data_queue = Queue.Queue() | 51 self._data_queue = Queue.Queue() |
| 48 self._collector_thread = threading.Thread(target=self._CollectorThread) | 52 self._collector_thread = threading.Thread(target=self._CollectorThread) |
| 49 self._collector_thread.start() | 53 self._collector_thread.start() |
| 50 else: | 54 else: |
| 51 self._use_legacy_method = True | 55 self._use_legacy_method = True |
| 52 self._surface_before = self._GetSurfaceStatsLegacy() | 56 self._surface_before = self._GetSurfaceStatsLegacy() |
| 53 | 57 |
| 54 def Stop(self): | 58 def Stop(self): |
| 55 self._StorePerfResults() | 59 self._StorePerfResults() |
| 56 if self._collector_thread: | 60 if self._collector_thread: |
| 57 self._stop_event.set() | 61 self._stop_event.set() |
| 58 self._collector_thread.join() | 62 self._collector_thread.join() |
| 59 self._collector_thread = None | 63 self._collector_thread = None |
| 60 | 64 |
| 65 def SampleResults(self): |
| 66 self._StorePerfResults() |
| 67 results = self._results |
| 68 self._results = [] |
| 69 return results |
| 70 |
| 61 def GetResults(self): | 71 def GetResults(self): |
| 62 return self._results | 72 return self._results |
| 63 | 73 |
| 64 @staticmethod | 74 @staticmethod |
| 65 def _GetNormalizedDeltas(data, refresh_period): | 75 def _GetNormalizedDeltas(data, refresh_period): |
| 66 deltas = [t2 - t1 for t1, t2 in zip(data, data[1:])] | 76 deltas = [t2 - t1 for t1, t2 in zip(data, data[1:])] |
| 67 return (deltas, [delta / refresh_period for delta in deltas]) | 77 return (deltas, [delta / refresh_period for delta in deltas]) |
| 68 | 78 |
| 69 def _StorePerfResults(self): | 79 def _StorePerfResults(self): |
| 70 if self._use_legacy_method: | 80 if self._use_legacy_method: |
| 71 surface_after = self._GetSurfaceStatsLegacy() | 81 surface_after = self._GetSurfaceStatsLegacy() |
| 72 td = surface_after['timestamp'] - self._surface_before['timestamp'] | 82 td = surface_after['timestamp'] - self._surface_before['timestamp'] |
| 73 seconds = td.seconds + td.microseconds / 1e6 | 83 seconds = td.seconds + td.microseconds / 1e6 |
| 74 frame_count = (surface_after['page_flip_count'] - | 84 frame_count = (surface_after['page_flip_count'] - |
| 75 self._surface_before['page_flip_count']) | 85 self._surface_before['page_flip_count']) |
| 76 else: | 86 else: |
| 77 assert self._collector_thread | 87 assert self._collector_thread |
| 78 (refresh_period, timestamps) = self._GetDataFromThread() | 88 (refresh_period, timestamps) = self._GetDataFromThread() |
| 79 if not refresh_period or not len(timestamps) >= 3: | 89 if not refresh_period or not len(timestamps) >= 3: |
| 80 logging.warning('Surface stat data is empty') | 90 if self._warn_about_empty_data: |
| 91 logging.warning('Surface stat data is empty') |
| 81 return | 92 return |
| 82 frame_count = len(timestamps) | 93 frame_count = len(timestamps) |
| 83 seconds = timestamps[-1] - timestamps[0] | 94 seconds = timestamps[-1] - timestamps[0] |
| 84 | 95 |
| 85 frame_lengths, normalized_frame_lengths = \ | 96 frame_lengths, normalized_frame_lengths = \ |
| 86 self._GetNormalizedDeltas(timestamps, refresh_period) | 97 self._GetNormalizedDeltas(timestamps, refresh_period) |
| 87 length_changes, normalized_changes = \ | 98 length_changes, normalized_changes = \ |
| 88 self._GetNormalizedDeltas(frame_lengths, refresh_period) | 99 self._GetNormalizedDeltas(frame_lengths, refresh_period) |
| 89 jankiness = [max(0, round(change)) for change in normalized_changes] | 100 jankiness = [max(0, round(change)) for change in normalized_changes] |
| 90 pause_threshold = 20 | 101 pause_threshold = 20 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 try: | 246 try: |
| 236 cur_surface = int(match.group(1), 16) | 247 cur_surface = int(match.group(1), 16) |
| 237 except Exception: | 248 except Exception: |
| 238 logging.error('Failed to parse current surface from ' + match.group(1)) | 249 logging.error('Failed to parse current surface from ' + match.group(1)) |
| 239 else: | 250 else: |
| 240 logging.warning('Failed to call SurfaceFlinger surface ' + results[0]) | 251 logging.warning('Failed to call SurfaceFlinger surface ' + results[0]) |
| 241 return { | 252 return { |
| 242 'page_flip_count': cur_surface, | 253 'page_flip_count': cur_surface, |
| 243 'timestamp': datetime.datetime.now(), | 254 'timestamp': datetime.datetime.now(), |
| 244 } | 255 } |
| OLD | NEW |