Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / tools / perf / perf_tools / smoothness_benchmark.py
blob1d469f3ad731270ba87c1a6455c440b3caf4b496
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
3 # found in the LICENSE file.
4 from perf_tools import smoothness_measurement
5 from telemetry.core import util
6 from telemetry.page import page_benchmark
8 class DidNotScrollException(page_benchmark.MeasurementFailure):
9 def __init__(self):
10 super(DidNotScrollException, self).__init__('Page did not scroll')
12 def DivideIfPossibleOrZero(numerator, denominator):
13 if denominator == 0:
14 return 0
15 return numerator / denominator
17 def CalcScrollResults(rendering_stats_deltas, results):
18 num_frames_sent_to_screen = rendering_stats_deltas['numFramesSentToScreen']
20 mean_frame_time_seconds = (
21 rendering_stats_deltas['totalTimeInSeconds'] /
22 float(num_frames_sent_to_screen))
24 dropped_percent = (
25 rendering_stats_deltas['droppedFrameCount'] /
26 float(num_frames_sent_to_screen))
28 num_impl_thread_scrolls = rendering_stats_deltas.get(
29 'numImplThreadScrolls', 0)
30 num_main_thread_scrolls = rendering_stats_deltas.get(
31 'numMainThreadScrolls', 0)
33 percent_impl_scrolled = DivideIfPossibleOrZero(
34 float(num_impl_thread_scrolls),
35 num_impl_thread_scrolls + num_main_thread_scrolls)
37 num_layers = (
38 rendering_stats_deltas.get('numLayersDrawn', 0) /
39 float(num_frames_sent_to_screen))
41 num_missing_tiles = (
42 rendering_stats_deltas.get('numMissingTiles', 0) /
43 float(num_frames_sent_to_screen))
45 results.Add('mean_frame_time', 'ms', round(mean_frame_time_seconds * 1000, 3))
46 results.Add('dropped_percent', '%', round(dropped_percent * 100, 1),
47 data_type='unimportant')
48 results.Add('percent_impl_scrolled', '%',
49 round(percent_impl_scrolled * 100, 1),
50 data_type='unimportant')
51 results.Add('average_num_layers_drawn', '', round(num_layers, 1),
52 data_type='unimportant')
53 results.Add('average_num_missing_tiles', '', round(num_missing_tiles, 1),
54 data_type='unimportant')
56 def CalcPaintingResults(rendering_stats_deltas, results):
57 totalPaintTime = rendering_stats_deltas.get('totalPaintTimeInSeconds', 0)
58 totalRasterizeTime = rendering_stats_deltas.get(
59 'totalRasterizeTimeInSeconds', 0)
60 totalPixelsPainted = rendering_stats_deltas.get('totalPixelsPainted', 0)
61 totalPixelsRasterized = rendering_stats_deltas.get('totalPixelsRasterized', 0)
63 megapixelsPaintedPerSecond = DivideIfPossibleOrZero(
64 (totalPixelsPainted / 1000000.0), totalPaintTime)
66 megapixelsRasterizedPerSecond = DivideIfPossibleOrZero(
67 (totalPixelsRasterized / 1000000.0), totalRasterizeTime)
69 results.Add('total_paint_time', 'seconds', totalPaintTime)
70 results.Add('total_rasterize_time', 'seconds', totalRasterizeTime,
71 data_type='unimportant')
72 results.Add('total_pixels_painted', '', totalPixelsPainted,
73 data_type='unimportant')
74 results.Add('total_pixels_rasterized', '', totalPixelsRasterized,
75 data_type='unimportant')
76 results.Add('megapixels_painted_per_second', '', megapixelsPaintedPerSecond,
77 data_type='unimportant')
78 results.Add('megapixels_rasterized_per_second', '',
79 megapixelsRasterizedPerSecond, data_type='unimportant')
80 results.Add('total_paint_and_rasterize_time', 'seconds', totalPaintTime +
81 totalRasterizeTime, data_type='unimportant')
83 def CalcTextureUploadResults(rendering_stats_deltas, results):
84 if (('totalCommitCount' not in rendering_stats_deltas)
85 or rendering_stats_deltas['totalCommitCount'] == 0) :
86 averageCommitTimeMs = 0
87 else :
88 averageCommitTimeMs = (
89 1000 * rendering_stats_deltas['totalCommitTimeInSeconds'] /
90 rendering_stats_deltas['totalCommitCount'])
92 results.Add('texture_upload_count', 'count',
93 rendering_stats_deltas.get('textureUploadCount', 0))
94 results.Add('total_texture_upload_time', 'seconds',
95 rendering_stats_deltas.get('totalTextureUploadTimeInSeconds', 0))
96 results.Add('average_commit_time', 'ms', averageCommitTimeMs,
97 data_type='unimportant')
99 def CalcFirstPaintTimeResults(results, tab):
100 if tab.browser.is_content_shell:
101 results.Add('first_paint', 'ms', 'unsupported')
102 return
104 tab.ExecuteJavaScript("""
105 window.__rafFired = false;
106 window.webkitRequestAnimationFrame(function() {
107 window.__rafFired = true;
109 """)
110 util.WaitFor(lambda: tab.EvaluateJavaScript('window.__rafFired'), 60)
112 first_paint_secs = tab.EvaluateJavaScript(
113 'window.chrome.loadTimes().firstPaintTime - ' +
114 'window.chrome.loadTimes().startLoadTime')
116 results.Add('first_paint', 'ms', round(first_paint_secs * 1000, 1))
118 def CalcImageDecodingResults(rendering_stats_deltas, results):
119 totalDeferredImageDecodeCount = rendering_stats_deltas.get(
120 'totalDeferredImageDecodeCount', 0)
121 totalDeferredImageCacheHitCount = rendering_stats_deltas.get(
122 'totalDeferredImageCacheHitCount', 0)
123 totalImageGatheringCount = rendering_stats_deltas.get(
124 'totalImageGatheringCount', 0)
125 totalDeferredImageDecodeTimeInSeconds = rendering_stats_deltas.get(
126 'totalDeferredImageDecodeTimeInSeconds', 0)
127 totalImageGatheringTimeInSeconds = rendering_stats_deltas.get(
128 'totalImageGatheringTimeInSeconds', 0)
130 averageImageGatheringTime = DivideIfPossibleOrZero(
131 (totalImageGatheringTimeInSeconds * 1000), totalImageGatheringCount)
133 results.Add('total_deferred_image_decode_count', 'count',
134 totalDeferredImageDecodeCount,
135 data_type='unimportant')
136 results.Add('total_image_cache_hit_count', 'count',
137 totalDeferredImageCacheHitCount,
138 data_type='unimportant')
139 results.Add('average_image_gathering_time', 'ms', averageImageGatheringTime,
140 data_type='unimportant')
141 results.Add('total_deferred_image_decoding_time', 'seconds',
142 totalDeferredImageDecodeTimeInSeconds,
143 data_type='unimportant')
145 class SmoothnessBenchmark(page_benchmark.PageBenchmark):
146 def __init__(self):
147 super(SmoothnessBenchmark, self).__init__('smoothness')
148 self.force_enable_threaded_compositing = False
149 self.use_gpu_benchmarking_extension = True
150 self._measurement = None
152 def AddCommandLineOptions(self, parser):
153 parser.add_option('--report-all-results', dest='report_all_results',
154 action='store_true',
155 help='Reports all data collected, not just FPS')
157 def CustomizeBrowserOptions(self, options):
158 if self.use_gpu_benchmarking_extension:
159 options.extra_browser_args.append('--enable-gpu-benchmarking')
160 if self.force_enable_threaded_compositing:
161 options.extra_browser_args.append('--enable-threaded-compositing')
163 def CanRunForPage(self, page):
164 return hasattr(page, 'smoothness')
166 def WillRunAction(self, page, tab, action):
167 if tab.browser.platform.IsRawDisplayFrameRateSupported():
168 tab.browser.platform.StartRawDisplayFrameRateMeasurement()
169 self._measurement = smoothness_measurement.SmoothnessMeasurement(tab)
170 if action.CanBeBound():
171 self._measurement.BindToAction(action)
172 else:
173 self._measurement.Start()
175 def DidRunAction(self, page, tab, action):
176 if tab.browser.platform.IsRawDisplayFrameRateSupported():
177 tab.browser.platform.StopRawDisplayFrameRateMeasurement()
178 if not action.CanBeBound():
179 self._measurement.Stop()
181 def MeasurePage(self, page, tab, results):
182 rendering_stats_deltas = self._measurement.deltas
184 if not (rendering_stats_deltas['numFramesSentToScreen'] > 0):
185 raise DidNotScrollException()
187 load_timings = tab.EvaluateJavaScript("window.performance.timing")
188 load_time_seconds = (
189 float(load_timings['loadEventStart']) -
190 load_timings['navigationStart']) / 1000
191 dom_content_loaded_time_seconds = (
192 float(load_timings['domContentLoadedEventStart']) -
193 load_timings['navigationStart']) / 1000
194 results.Add('load_time', 'seconds', load_time_seconds)
195 results.Add('dom_content_loaded_time', 'seconds',
196 dom_content_loaded_time_seconds)
198 CalcFirstPaintTimeResults(results, tab)
199 CalcScrollResults(rendering_stats_deltas, results)
200 CalcPaintingResults(rendering_stats_deltas, results)
201 CalcTextureUploadResults(rendering_stats_deltas, results)
202 CalcImageDecodingResults(rendering_stats_deltas, results)
204 if self.options.report_all_results:
205 for k, v in rendering_stats_deltas.iteritems():
206 results.Add(k, '', v)
208 if tab.browser.platform.IsRawDisplayFrameRateSupported():
209 for r in tab.browser.platform.GetRawDisplayFrameRateMeasurements():
210 results.Add(r.name, r.unit, r.value)