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 |