Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 from telemetry.perf_tests_helper import FlattenList | 5 from telemetry.perf_tests_helper import FlattenList |
| 6 from telemetry.util import statistics | 6 from telemetry.util import statistics |
| 7 from telemetry.value import list_of_scalar_values | 7 from telemetry.value import list_of_scalar_values |
| 8 from telemetry.value import scalar | 8 from telemetry.value import scalar |
| 9 from telemetry.web_perf.metrics import rendering_stats | 9 from telemetry.web_perf.metrics import rendering_stats |
| 10 from telemetry.web_perf.metrics import timeline_based_metric | 10 from telemetry.web_perf.metrics import timeline_based_metric |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 class SmoothnessMetric(timeline_based_metric.TimelineBasedMetric): | 23 class SmoothnessMetric(timeline_based_metric.TimelineBasedMetric): |
| 24 """Computes metrics that measure smoothness of animations over given ranges. | 24 """Computes metrics that measure smoothness of animations over given ranges. |
| 25 | 25 |
| 26 Animations are typically considered smooth if the frame rates are close to | 26 Animations are typically considered smooth if the frame rates are close to |
| 27 60 frames per second (fps) and uniformly distributed over the sequence. To | 27 60 frames per second (fps) and uniformly distributed over the sequence. To |
| 28 determine if a timeline range contains a smooth animation, we update the | 28 determine if a timeline range contains a smooth animation, we update the |
| 29 results object with several representative metrics: | 29 results object with several representative metrics: |
| 30 | 30 |
| 31 frame_times: A list of raw frame times | 31 frame_times: A list of raw frame times |
| 32 mean_frame_time: The arithmetic mean of frame times | 32 mean_frame_time: The arithmetic mean of frame times |
| 33 mostly_smooth: Whether we hit 60 fps for 95% of all frames | 33 percentage_smooth: Percentage of frames that were hitting 60 FPS. |
| 34 jank: The absolute discrepancy of frame timestamps | 34 jank: The absolute discrepancy of frame timestamps |
| 35 mean_pixels_approximated: The mean percentage of pixels approximated | 35 mean_pixels_approximated: The mean percentage of pixels approximated |
| 36 queueing_durations: The queueing delay between compositor & main threads | 36 queueing_durations: The queueing delay between compositor & main threads |
| 37 | 37 |
| 38 Note that if any of the interaction records provided to AddResults have less | 38 Note that if any of the interaction records provided to AddResults have less |
| 39 than 2 frames, we will return telemetry values with None values for each of | 39 than 2 frames, we will return telemetry values with None values for each of |
| 40 the smoothness metrics. Similarly, older browsers without support for | 40 the smoothness metrics. Similarly, older browsers without support for |
| 41 tracking the BeginMainFrame events will report a ListOfScalarValues with a | 41 tracking the BeginMainFrame events will report a ListOfScalarValues with a |
| 42 None value for the queueing duration metric. | 42 None value for the queueing duration metric. |
| 43 """ | 43 """ |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 139 'the compositor and renderer threads are. It is the amount ' | 139 'the compositor and renderer threads are. It is the amount ' |
| 140 'of wall time that elapses between a ' | 140 'of wall time that elapses between a ' |
| 141 'ScheduledActionSendBeginMainFrame event in the compositor ' | 141 'ScheduledActionSendBeginMainFrame event in the compositor ' |
| 142 'thread and the corresponding BeginMainFrame event in the ' | 142 'thread and the corresponding BeginMainFrame event in the ' |
| 143 'main thread.', | 143 'main thread.', |
| 144 none_value_reason=none_value_reason) | 144 none_value_reason=none_value_reason) |
| 145 | 145 |
| 146 def _ComputeFrameTimeMetric(self, page, stats): | 146 def _ComputeFrameTimeMetric(self, page, stats): |
| 147 """Returns Values for the frame time metrics. | 147 """Returns Values for the frame time metrics. |
| 148 | 148 |
| 149 This includes the raw and mean frame times, as well as the mostly_smooth | 149 This includes the raw and mean frame times, as well as the percentage of |
| 150 metric which tracks whether we hit 60 fps for 95% of the frames. | 150 frames that were hitting 60 fps. |
|
qyearsley
2014/10/10 04:02:21
Since smooth_threshold below is 19.0, is this actu
ernstm
2014/10/10 20:13:08
I lowered the threshold to 17.0ms. We will be able
| |
| 151 """ | 151 """ |
| 152 frame_times = None | 152 frame_times = None |
| 153 mean_frame_time = None | 153 mean_frame_time = None |
| 154 mostly_smooth = None | 154 percentage_smooth = None |
| 155 none_value_reason = None | 155 none_value_reason = None |
| 156 if self._HasEnoughFrames(stats.frame_timestamps): | 156 if self._HasEnoughFrames(stats.frame_timestamps): |
| 157 frame_times = FlattenList(stats.frame_times) | 157 frame_times = FlattenList(stats.frame_times) |
| 158 mean_frame_time = round(statistics.ArithmeticMean(frame_times), 3) | 158 mean_frame_time = round(statistics.ArithmeticMean(frame_times), 3) |
| 159 # We use 19ms as a somewhat looser threshold, instead of 1000.0/60.0. | 159 # We use 19ms as a somewhat looser threshold, instead of 1000.0/60.0. |
| 160 percentile_95 = statistics.Percentile(frame_times, 95.0) | 160 smooth_threshold = 19.0 |
| 161 mostly_smooth = 1.0 if percentile_95 < 19.0 else 0.0 | 161 smooth_count = sum(1 for t in frame_times if t < smooth_threshold) |
| 162 percentage_smooth = float(smooth_count) / len(frame_times) * 100.0 | |
| 162 else: | 163 else: |
| 163 none_value_reason = NOT_ENOUGH_FRAMES_MESSAGE | 164 none_value_reason = NOT_ENOUGH_FRAMES_MESSAGE |
| 164 return ( | 165 return ( |
| 165 list_of_scalar_values.ListOfScalarValues( | 166 list_of_scalar_values.ListOfScalarValues( |
| 166 page, 'frame_times', 'ms', frame_times, | 167 page, 'frame_times', 'ms', frame_times, |
| 167 description='List of raw frame times, helpful to understand the ' | 168 description='List of raw frame times, helpful to understand the ' |
| 168 'other metrics.', | 169 'other metrics.', |
| 169 none_value_reason=none_value_reason), | 170 none_value_reason=none_value_reason), |
| 170 scalar.ScalarValue( | 171 scalar.ScalarValue( |
| 171 page, 'mean_frame_time', 'ms', mean_frame_time, | 172 page, 'mean_frame_time', 'ms', mean_frame_time, |
| 172 description='Arithmetic mean of frame times.', | 173 description='Arithmetic mean of frame times.', |
| 173 none_value_reason=none_value_reason), | 174 none_value_reason=none_value_reason), |
| 174 scalar.ScalarValue( | 175 scalar.ScalarValue( |
| 175 page, 'mostly_smooth', 'score', mostly_smooth, | 176 page, 'percentage_smooth', 'score', percentage_smooth, |
| 176 description='Were 95 percent of the frames hitting 60 fps?' | 177 description='Percentage of frames that were hitting 60 fps.', |
| 177 'boolean value (1/0).', | |
| 178 none_value_reason=none_value_reason) | 178 none_value_reason=none_value_reason) |
| 179 ) | 179 ) |
| 180 | 180 |
| 181 def _ComputeFrameTimeDiscrepancy(self, page, stats): | 181 def _ComputeFrameTimeDiscrepancy(self, page, stats): |
| 182 """Returns a Value for the absolute discrepancy of frame time stamps.""" | 182 """Returns a Value for the absolute discrepancy of frame time stamps.""" |
| 183 | 183 |
| 184 frame_discrepancy = None | 184 frame_discrepancy = None |
| 185 none_value_reason = None | 185 none_value_reason = None |
| 186 if self._HasEnoughFrames(stats.frame_timestamps): | 186 if self._HasEnoughFrames(stats.frame_timestamps): |
| 187 frame_discrepancy = round(statistics.TimestampsDiscrepancy( | 187 frame_discrepancy = round(statistics.TimestampsDiscrepancy( |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 210 if self._HasEnoughFrames(stats.frame_timestamps): | 210 if self._HasEnoughFrames(stats.frame_timestamps): |
| 211 mean_pixels_approximated = round(statistics.ArithmeticMean( | 211 mean_pixels_approximated = round(statistics.ArithmeticMean( |
| 212 FlattenList(stats.approximated_pixel_percentages)), 3) | 212 FlattenList(stats.approximated_pixel_percentages)), 3) |
| 213 else: | 213 else: |
| 214 none_value_reason = NOT_ENOUGH_FRAMES_MESSAGE | 214 none_value_reason = NOT_ENOUGH_FRAMES_MESSAGE |
| 215 return scalar.ScalarValue( | 215 return scalar.ScalarValue( |
| 216 page, 'mean_pixels_approximated', 'percent', mean_pixels_approximated, | 216 page, 'mean_pixels_approximated', 'percent', mean_pixels_approximated, |
| 217 description='Percentage of pixels that were approximated ' | 217 description='Percentage of pixels that were approximated ' |
| 218 '(checkerboarding, low-resolution tiles, etc.).', | 218 '(checkerboarding, low-resolution tiles, etc.).', |
| 219 none_value_reason=none_value_reason) | 219 none_value_reason=none_value_reason) |
| OLD | NEW |