Upstream version 7.35.144.0
[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 time
7
8 from metrics import rendering_stats
9 from telemetry.page import page_measurement
10 from telemetry.page.perf_tests_helper import FlattenList
11 import telemetry.core.timeline.bounds as timeline_bounds
12 from telemetry.core.timeline.model import TimelineModel
13 from telemetry.core.timeline.model import MarkerMismatchError
14 from telemetry.core.timeline.model import MarkerOverlapError
15
16 TIMELINE_MARKER = 'RasterizeAndRecord'
17
18
19 class RasterizeAndRecord(page_measurement.PageMeasurement):
20   def __init__(self):
21     super(RasterizeAndRecord, self).__init__('', True)
22     self._metrics = None
23     self._compositing_features_enabled = False
24
25   @classmethod
26   def AddCommandLineArgs(cls, parser):
27     parser.add_option('--raster-record-repeat', type='int',
28                       default=20,
29                       help='Repetitions in raster and record loops.'
30                       'Higher values reduce variance, but can cause'
31                       'instability (timeouts, event buffer overflows, etc.).')
32     parser.add_option('--start-wait-time', type='float',
33                       default=5,
34                       help='Wait time before the benchmark is started '
35                       '(must be long enought to load all content)')
36     parser.add_option('--stop-wait-time', type='float',
37                       default=15,
38                       help='Wait time before measurement is taken '
39                       '(must be long enough to render one frame)')
40
41   def CustomizeBrowserOptions(self, options):
42     # Run each raster task N times. This allows us to report the time for the
43     # best run, effectively excluding cache effects and time when the thread is
44     # de-scheduled.
45     options.AppendExtraBrowserArgs([
46         '--enable-gpu-benchmarking',
47         '--slow-down-raster-scale-factor=%d' % options.raster_record_repeat,
48         # Enable impl-side-painting. Current version of benchmark only works for
49         # this mode.
50         '--enable-impl-side-painting',
51         '--force-compositing-mode',
52         '--enable-threaded-compositing'
53     ])
54
55   def DidStartBrowser(self, browser):
56     # Check if the we actually have threaded forced compositing enabled.
57     system_info = browser.GetSystemInfo()
58     if (system_info.gpu.feature_status
59         and system_info.gpu.feature_status.get(
60             'compositing', None) == 'enabled_force_threaded'):
61       self._compositing_features_enabled = True
62
63   def MeasurePage(self, page, tab, results):
64     if not self._compositing_features_enabled:
65       logging.warning('Warning: compositing feature status unknown or not '+
66                       'forced and threaded. Skipping measurement.')
67       return
68
69     # Rasterize only what's visible.
70     tab.ExecuteJavaScript(
71         'chrome.gpuBenchmarking.setRasterizeOnlyVisibleContent();')
72
73     # Wait until the page has loaded and come to a somewhat steady state.
74     # Needs to be adjusted for every device (~2 seconds for workstation).
75     time.sleep(self.options.start_wait_time)
76
77     # Render one frame before we start gathering a trace. On some pages, the
78     # first frame requested has more variance in the number of pixels
79     # rasterized.
80     tab.ExecuteJavaScript(
81         'window.__rafFired = false;'
82         'window.webkitRequestAnimationFrame(function() {'
83           'chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers();'
84           'window.__rafFired  = true;'
85         '});')
86
87     time.sleep(self.options.stop_wait_time)
88     tab.browser.StartTracing('webkit.console,benchmark', 60)
89
90     tab.ExecuteJavaScript(
91         'window.__rafFired = false;'
92         'window.webkitRequestAnimationFrame(function() {'
93           'chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers();'
94           'console.time("' + TIMELINE_MARKER + '");'
95           'window.__rafFired  = true;'
96         '});')
97     # Wait until the frame was drawn.
98     # Needs to be adjusted for every device and for different
99     # raster_record_repeat counts.
100     # TODO(ernstm): replace by call-back.
101     time.sleep(self.options.stop_wait_time)
102     tab.ExecuteJavaScript(
103         'console.timeEnd("' + TIMELINE_MARKER + '")')
104
105     tracing_timeline_data = tab.browser.StopTracing()
106     timeline = TimelineModel(timeline_data=tracing_timeline_data)
107     try:
108       timeline_markers = timeline.FindTimelineMarkers(TIMELINE_MARKER)
109     except (MarkerMismatchError, MarkerOverlapError) as e:
110       raise page_measurement.MeasurementFailure(str(e))
111     timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker)
112                         for marker in timeline_markers ]
113     renderer_process = timeline.GetRendererProcessFromTab(tab)
114
115     stats = rendering_stats.RenderingStats(
116         renderer_process, timeline.browser_process, timeline_ranges)
117
118     results.Add('rasterize_time', 'ms', max(FlattenList(stats.rasterize_times)))
119     results.Add('record_time', 'ms', max(FlattenList(stats.record_times)))
120     results.Add('rasterized_pixels', 'pixels',
121                 max(FlattenList(stats.rasterized_pixel_counts)))
122     results.Add('recorded_pixels', 'pixels',
123                 max(FlattenList(stats.recorded_pixel_counts)))
124
125   def CleanUpAfterPage(self, page, tab):
126     if tab.browser.is_tracing_running:
127       tab.browser.StopTracing()