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.
9 from metrics import rendering_stats
10 from telemetry.page import page_measurement
11 from telemetry.core.timeline.model import MarkerMismatchError
12 from telemetry.core.timeline.model import MarkerOverlapError
15 class RasterizeAndRecord(page_measurement.PageMeasurement):
17 super(RasterizeAndRecord, self).__init__('', True)
19 self._compositing_features_enabled = False
21 def AddCommandLineOptions(self, parser):
22 parser.add_option('--raster-record-repeat', dest='raster_record_repeat',
24 help='Repetitions in raster and record loops.' +
25 'Higher values reduce variance, but can cause' +
26 'instability (timeouts, event buffer overflows, etc.).')
27 parser.add_option('--start-wait-time', dest='start_wait_time',
29 help='Wait time before the benchmark is started ' +
30 '(must be long enought to load all content)')
31 parser.add_option('--stop-wait-time', dest='stop_wait_time',
33 help='Wait time before measurement is taken ' +
34 '(must be long enough to render one frame)')
36 def CustomizeBrowserOptions(self, options):
37 # Run each raster task N times. This allows us to report the time for the
38 # best run, effectively excluding cache effects and time when the thread is
40 options.AppendExtraBrowserArgs([
41 '--enable-gpu-benchmarking',
42 '--slow-down-raster-scale-factor=%d' % int(
43 options.raster_record_repeat),
44 # Enable impl-side-painting. Current version of benchmark only works for
46 '--enable-impl-side-painting',
47 '--force-compositing-mode',
48 '--enable-threaded-compositing'
51 def DidStartBrowser(self, browser):
52 # Check if the we actually have threaded forced compositing enabled.
53 system_info = browser.GetSystemInfo()
54 if (system_info.gpu.feature_status
55 and system_info.gpu.feature_status.get(
56 'compositing', None) == 'enabled_force_threaded'):
57 self._compositing_features_enabled = True
59 def MeasurePage(self, page, tab, results):
60 # Exit if threaded forced compositing is not enabled.
61 if (not self._compositing_features_enabled):
62 logging.warning('Warning: compositing feature status unknown or not '+
63 'forced and threaded. Skipping measurement.')
66 # TODO(ernstm): Remove this temporary workaround when reference build has
67 # been updated to branch 1671 or later.
68 backend = tab.browser._browser_backend # pylint: disable=W0212
69 if (not hasattr(backend, 'chrome_branch_number') or
70 (sys.platform != 'android' and backend.chrome_branch_number < 1671)):
71 print ('Warning: rasterize_and_record requires Chrome branch 1671 or '
72 'later. Skipping measurement.')
75 # Rasterize only what's visible.
76 tab.ExecuteJavaScript(
77 'chrome.gpuBenchmarking.setRasterizeOnlyVisibleContent();')
79 # Wait until the page has loaded and come to a somewhat steady state.
80 # Needs to be adjusted for every device (~2 seconds for workstation).
81 time.sleep(float(self.options.start_wait_time))
83 # Render one frame before we start gathering a trace. On some pages, the
84 # first frame requested has more variance in the number of pixels
86 tab.ExecuteJavaScript(
87 'window.__rafFired = false;'
88 'window.webkitRequestAnimationFrame(function() {'
89 'chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers();'
90 'window.__rafFired = true;'
93 time.sleep(float(self.options.stop_wait_time))
94 tab.browser.StartTracing('webkit.console,benchmark', 60)
96 tab.ExecuteJavaScript(
97 'window.__rafFired = false;'
98 'window.webkitRequestAnimationFrame(function() {'
99 'chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers();'
100 'console.time("' + rendering_stats.RENDER_PROCESS_MARKER + '");'
101 'window.__rafFired = true;'
103 # Wait until the frame was drawn.
104 # Needs to be adjusted for every device and for different
105 # raster_record_repeat counts.
106 # TODO(ernstm): replace by call-back.
107 time.sleep(float(self.options.stop_wait_time))
108 tab.ExecuteJavaScript(
109 'console.timeEnd("' + rendering_stats.RENDER_PROCESS_MARKER + '")')
111 timeline = tab.browser.StopTracing().AsTimelineModel()
113 timeline_markers = timeline.FindTimelineMarkers(
114 rendering_stats.RENDER_PROCESS_MARKER)
115 except (MarkerMismatchError, MarkerOverlapError) as e:
116 raise page_measurement.MeasurementFailure(str(e))
117 stats = rendering_stats.RenderingStats(timeline_markers, timeline_markers)
119 results.Add('rasterize_time', 'ms',
120 max(stats.rasterize_time))
121 results.Add('record_time', 'ms',
122 max(stats.record_time))
123 results.Add('rasterized_pixels', 'pixels',
124 max(stats.rasterized_pixel_count))
125 results.Add('recorded_pixels', 'pixels',
126 max(stats.recorded_pixel_count))