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 import os | 4 import os |
5 | 5 |
6 from telemetry.core import util | 6 from telemetry.core import util |
7 | 7 |
8 class SmoothnessMetrics(object): | 8 class SmoothnessMetrics(object): |
9 def __init__(self, tab): | 9 def __init__(self, tab): |
10 self._tab = tab | 10 self._tab = tab |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 @property | 44 @property |
45 def end_values(self): | 45 def end_values(self): |
46 return self._tab.EvaluateJavaScript( | 46 return self._tab.EvaluateJavaScript( |
47 'window.__renderingStats.getEndValues()') | 47 'window.__renderingStats.getEndValues()') |
48 | 48 |
49 @property | 49 @property |
50 def deltas(self): | 50 def deltas(self): |
51 return self._tab.EvaluateJavaScript( | 51 return self._tab.EvaluateJavaScript( |
52 'window.__renderingStats.getDeltas()') | 52 'window.__renderingStats.getDeltas()') |
53 | 53 |
54 | 54 def Average(numerator, denominator, scale = None, precision = None): |
55 def DivideIfPossibleOrZero(numerator, denominator): | |
56 if denominator == 0: | 55 if denominator == 0: |
57 return 0 | 56 return 0 |
58 return numerator / denominator | 57 avg = float(numerator) / float(denominator) |
59 | 58 if scale: |
60 def CalcScrollResults(rendering_stats_deltas, results): | 59 avg *= scale |
61 num_frames_sent_to_screen = rendering_stats_deltas['numFramesSentToScreen'] | 60 if precision: |
62 | 61 avg = round(avg, precision) |
63 mean_frame_time_seconds = ( | 62 return avg |
64 rendering_stats_deltas['totalTimeInSeconds'] / | |
65 float(num_frames_sent_to_screen)) | |
66 | |
67 dropped_percent = ( | |
68 rendering_stats_deltas['droppedFrameCount'] / | |
69 float(num_frames_sent_to_screen)) | |
70 | |
71 num_impl_thread_scrolls = rendering_stats_deltas.get( | |
72 'numImplThreadScrolls', 0) | |
73 num_main_thread_scrolls = rendering_stats_deltas.get( | |
74 'numMainThreadScrolls', 0) | |
75 | |
76 percent_impl_scrolled = DivideIfPossibleOrZero( | |
77 float(num_impl_thread_scrolls), | |
78 num_impl_thread_scrolls + num_main_thread_scrolls) | |
79 | |
80 num_layers = ( | |
81 rendering_stats_deltas.get('numLayersDrawn', 0) / | |
82 float(num_frames_sent_to_screen)) | |
83 | |
84 num_missing_tiles = ( | |
85 rendering_stats_deltas.get('numMissingTiles', 0) / | |
86 float(num_frames_sent_to_screen)) | |
87 | |
88 results.Add('mean_frame_time', 'ms', round(mean_frame_time_seconds * 1000, 3)) | |
89 results.Add('dropped_percent', '%', round(dropped_percent * 100, 1), | |
90 data_type='unimportant') | |
91 results.Add('percent_impl_scrolled', '%', | |
92 round(percent_impl_scrolled * 100, 1), | |
93 data_type='unimportant') | |
94 results.Add('average_num_layers_drawn', '', round(num_layers, 1), | |
95 data_type='unimportant') | |
96 results.Add('average_num_missing_tiles', '', round(num_missing_tiles, 1), | |
97 data_type='unimportant') | |
98 | |
99 def CalcTextureUploadResults(rendering_stats_deltas, results): | |
100 if (('totalCommitCount' not in rendering_stats_deltas) | |
101 or rendering_stats_deltas['totalCommitCount'] == 0) : | |
102 averageCommitTimeMs = 0 | |
103 else : | |
104 averageCommitTimeMs = ( | |
105 1000 * rendering_stats_deltas['totalCommitTimeInSeconds'] / | |
106 rendering_stats_deltas['totalCommitCount']) | |
107 | |
108 results.Add('texture_upload_count', 'count', | |
109 rendering_stats_deltas.get('textureUploadCount', 0)) | |
110 results.Add('total_texture_upload_time', 'seconds', | |
111 rendering_stats_deltas.get('totalTextureUploadTimeInSeconds', 0)) | |
112 results.Add('average_commit_time', 'ms', averageCommitTimeMs, | |
113 data_type='unimportant') | |
114 | 63 |
115 def CalcFirstPaintTimeResults(results, tab): | 64 def CalcFirstPaintTimeResults(results, tab): |
116 if tab.browser.is_content_shell: | 65 if tab.browser.is_content_shell: |
117 results.Add('first_paint', 'ms', 'unsupported') | 66 results.Add('first_paint', 'ms', 'unsupported') |
118 return | 67 return |
119 | 68 |
120 tab.ExecuteJavaScript(""" | 69 tab.ExecuteJavaScript(""" |
121 window.__rafFired = false; | 70 window.__rafFired = false; |
122 window.webkitRequestAnimationFrame(function() { | 71 window.webkitRequestAnimationFrame(function() { |
123 window.__rafFired = true; | 72 window.__rafFired = true; |
124 }); | 73 }); |
125 """) | 74 """) |
126 util.WaitFor(lambda: tab.EvaluateJavaScript('window.__rafFired'), 60) | 75 util.WaitFor(lambda: tab.EvaluateJavaScript('window.__rafFired'), 60) |
127 | 76 |
128 first_paint_secs = tab.EvaluateJavaScript( | 77 first_paint_secs = tab.EvaluateJavaScript( |
129 'window.chrome.loadTimes().firstPaintTime - ' + | 78 'window.chrome.loadTimes().firstPaintTime - ' + |
130 'window.chrome.loadTimes().startLoadTime') | 79 'window.chrome.loadTimes().startLoadTime') |
131 | 80 |
132 results.Add('first_paint', 'ms', round(first_paint_secs * 1000, 1)) | 81 results.Add('first_paint', 'ms', round(first_paint_secs * 1000, 1)) |
133 | 82 |
134 def CalcImageDecodingResults(rendering_stats_deltas, results): | 83 def CalcResults(benchmark_stats, results): |
135 totalDeferredImageDecodeCount = rendering_stats_deltas.get( | 84 s = benchmark_stats |
136 'totalDeferredImageDecodeCount', 0) | |
137 totalDeferredImageCacheHitCount = rendering_stats_deltas.get( | |
138 'totalDeferredImageCacheHitCount', 0) | |
139 totalImageGatheringCount = rendering_stats_deltas.get( | |
140 'totalImageGatheringCount', 0) | |
141 totalDeferredImageDecodeTimeInSeconds = rendering_stats_deltas.get( | |
142 'totalDeferredImageDecodeTimeInSeconds', 0) | |
143 totalImageGatheringTimeInSeconds = rendering_stats_deltas.get( | |
144 'totalImageGatheringTimeInSeconds', 0) | |
145 | 85 |
146 averageImageGatheringTime = DivideIfPossibleOrZero( | 86 # Scroll Results |
147 (totalImageGatheringTimeInSeconds * 1000), totalImageGatheringCount) | 87 results.Add('mean_frame_time', 'ms', |
| 88 Average(s.total_time, s.screen_frame_count, 1000, 3)) |
| 89 results.Add('dropped_percent', '%', |
| 90 Average(s.dropped_frame_count, s.screen_frame_count, |
| 91 100, 1), |
| 92 data_type='unimportant') |
| 93 results.Add('percent_impl_scrolled', '%', |
| 94 Average(s.impl_thread_scroll_count, |
| 95 s.impl_thread_scroll_count + |
| 96 s.main_thread_scroll_count, |
| 97 100, 1), |
| 98 data_type='unimportant') |
| 99 results.Add('average_num_layers_drawn', '', |
| 100 Average(s.drawn_layers_count, s.screen_frame_count, 1, 1), |
| 101 data_type='unimportant') |
| 102 results.Add('average_num_missing_tiles', '', |
| 103 Average(s.missing_tile_count, s.screen_frame_count, 1, 1), |
| 104 data_type='unimportant') |
148 | 105 |
| 106 # Texture Upload Results |
| 107 results.Add('average_commit_time', 'ms', |
| 108 Average(s.commit_time, s.commit_count, 1000, 3), |
| 109 data_type='unimportant') |
| 110 results.Add('texture_upload_count', 'count', |
| 111 s.texture_upload_count) |
| 112 results.Add('total_texture_upload_time', 'seconds', |
| 113 s.texture_upload_time) |
| 114 |
| 115 # Image Decoding Results |
149 results.Add('total_deferred_image_decode_count', 'count', | 116 results.Add('total_deferred_image_decode_count', 'count', |
150 totalDeferredImageDecodeCount, | 117 s.deferred_image_decode_count, |
151 data_type='unimportant') | 118 data_type='unimportant') |
152 results.Add('total_image_cache_hit_count', 'count', | 119 results.Add('total_image_cache_hit_count', 'count', |
153 totalDeferredImageCacheHitCount, | 120 s.deferred_image_cache_hits, |
154 data_type='unimportant') | 121 data_type='unimportant') |
155 results.Add('average_image_gathering_time', 'ms', averageImageGatheringTime, | 122 results.Add('average_image_gathering_time', 'ms', |
| 123 Average(s.image_gathering_time, s.image_gathering_count, |
| 124 1000, 3), |
156 data_type='unimportant') | 125 data_type='unimportant') |
157 results.Add('total_deferred_image_decoding_time', 'seconds', | 126 results.Add('total_deferred_image_decoding_time', 'seconds', |
158 totalDeferredImageDecodeTimeInSeconds, | 127 s.deferred_image_decode_time, |
159 data_type='unimportant') | 128 data_type='unimportant') |
160 | 129 |
161 def CalcAnalysisResults(rendering_stats_deltas, results): | 130 # Tile Analysis Results |
162 totalTilesAnalyzed = rendering_stats_deltas.get( | |
163 'totalTilesAnalyzed', 0) | |
164 solidColorTilesAnalyzed = rendering_stats_deltas.get( | |
165 'solidColorTilesAnalyzed', 0) | |
166 totalTileAnalysisTimeInSeconds = rendering_stats_deltas.get( | |
167 'totalTileAnalysisTimeInSeconds', 0) | |
168 | |
169 averageAnalysisTimeMS = \ | |
170 1000 * DivideIfPossibleOrZero(totalTileAnalysisTimeInSeconds, | |
171 totalTilesAnalyzed) | |
172 | |
173 results.Add('total_tiles_analyzed', 'count', | 131 results.Add('total_tiles_analyzed', 'count', |
174 totalTilesAnalyzed, | 132 s.tile_analysis_count, |
175 data_type='unimportant') | 133 data_type='unimportant') |
176 results.Add('solid_color_tiles_analyzed', 'count', | 134 results.Add('solid_color_tiles_analyzed', 'count', |
177 solidColorTilesAnalyzed, | 135 s.solid_color_tile_analysis_count, |
178 data_type='unimportant') | 136 data_type='unimportant') |
179 results.Add('average_tile_analysis_time', 'ms', | 137 results.Add('average_tile_analysis_time', 'ms', |
180 averageAnalysisTimeMS, | 138 Average(s.tile_analysis_time, s.tile_analysis_count, |
| 139 1000, 3), |
181 data_type='unimportant') | 140 data_type='unimportant') |
182 | 141 |
183 def CalcLatency(rendering_stats_deltas, count_name, total_latency_name, | 142 # Latency Results |
184 result_name, results): | 143 results.Add('average_latency', 'ms', |
185 eventCount = rendering_stats_deltas.get(count_name, 0) | 144 Average(s.input_event_latency, s.input_event_count, |
186 totalLatencyInSeconds = rendering_stats_deltas.get(total_latency_name, 0) | 145 1000, 3), |
187 averageLatency = DivideIfPossibleOrZero( | 146 data_type='unimportant') |
188 (totalLatencyInSeconds * 1000), eventCount) | 147 results.Add('average_touch_ui_latency', 'ms', |
189 results.Add(result_name, 'ms', averageLatency, data_type='unimportant') | 148 Average(s.touch_ui_latency, s.touch_ui_count, 1000, 3), |
190 | 149 data_type='unimportant') |
191 def CalcLatencyResults(rendering_stats_deltas, results): | 150 results.Add('average_touch_acked_latency', 'ms', |
192 CalcLatency(rendering_stats_deltas, 'inputEventCount', 'totalInputLatency', | 151 Average(s.touch_acked_latency, s.touch_acked_count, |
193 'average_latency', results) | 152 1000, 3), |
194 CalcLatency(rendering_stats_deltas, 'touchUICount', 'totalTouchUILatency', | 153 data_type='unimportant') |
195 'average_touch_ui_latency', results) | 154 results.Add('average_scroll_update_latency', 'ms', |
196 CalcLatency(rendering_stats_deltas, 'touchAckedCount', | 155 Average(s.scroll_update_latency, s.scroll_update_count, |
197 'totalTouchAckedLatency', | 156 1000, 3), |
198 'average_touch_acked_latency', | 157 data_type='unimportant') |
199 results) | |
200 CalcLatency(rendering_stats_deltas, 'scrollUpdateCount', | |
201 'totalScrollUpdateLatency', | |
202 'average_scroll_update_latency', results) | |
OLD | NEW |