- add sources.
[platform/framework/web/crosswalk.git] / src / tools / perf / measurements / rasterize_and_record.py
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
5 import logging
6 import sys
7 import time
8
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
13
14
15 class RasterizeAndRecord(page_measurement.PageMeasurement):
16   def __init__(self):
17     super(RasterizeAndRecord, self).__init__('', True)
18     self._metrics = None
19     self._compositing_features_enabled = False
20
21   def AddCommandLineOptions(self, parser):
22     parser.add_option('--raster-record-repeat', dest='raster_record_repeat',
23                       default=20,
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',
28                       default=5,
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',
32                       default=10,
33                       help='Wait time before measurement is taken ' +
34                       '(must be long enough to render one frame)')
35
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
39     # de-scheduled.
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
45         # this mode.
46         '--enable-impl-side-painting',
47         '--force-compositing-mode',
48         '--enable-threaded-compositing'
49     ])
50
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
58
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.')
64       sys.exit(0)
65
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.')
73       sys.exit(0)
74
75     # Rasterize only what's visible.
76     tab.ExecuteJavaScript(
77         'chrome.gpuBenchmarking.setRasterizeOnlyVisibleContent();')
78
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))
82
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
85     # rasterized.
86     tab.ExecuteJavaScript(
87         'window.__rafFired = false;'
88         'window.webkitRequestAnimationFrame(function() {'
89           'chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers();'
90           'window.__rafFired  = true;'
91         '});')
92
93     time.sleep(float(self.options.stop_wait_time))
94     tab.browser.StartTracing('webkit.console,benchmark', 60)
95
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;'
102         '});')
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 + '")')
110
111     timeline = tab.browser.StopTracing().AsTimelineModel()
112     try:
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)
118
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))