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 3# found in the LICENSE file. 4 5import sys 6import time 7 8from telemetry.core.util import TimeoutException 9from telemetry.page import page_test 10from telemetry.value import scalar 11 12 13class RasterizeAndRecordMicro(page_test.PageTest): 14 def __init__(self): 15 super(RasterizeAndRecordMicro, self).__init__('') 16 self._chrome_branch_number = None 17 18 @classmethod 19 def AddCommandLineArgs(cls, parser): 20 parser.add_option('--start-wait-time', type='float', 21 default=2, 22 help='Wait time before the benchmark is started ' 23 '(must be long enought to load all content)') 24 parser.add_option('--rasterize-repeat', type='int', 25 default=100, 26 help='Repeat each raster this many times. Increase ' 27 'this value to reduce variance.') 28 parser.add_option('--record-repeat', type='int', 29 default=100, 30 help='Repeat each record this many times. Increase ' 31 'this value to reduce variance.') 32 parser.add_option('--timeout', type='int', 33 default=120, 34 help='The length of time to wait for the micro ' 35 'benchmark to finish, expressed in seconds.') 36 parser.add_option('--report-detailed-results', 37 action='store_true', 38 help='Whether to report additional detailed results.') 39 40 def CustomizeBrowserOptions(self, options): 41 options.AppendExtraBrowserArgs([ 42 '--enable-impl-side-painting', 43 '--enable-threaded-compositing', 44 '--enable-gpu-benchmarking' 45 ]) 46 47 def DidStartBrowser(self, browser): 48 # TODO(vmpstr): Remove this temporary workaround when reference build has 49 # been updated to branch 1713 or later. 50 backend = browser._browser_backend # pylint: disable=W0212 51 self._chrome_branch_number = getattr(backend, 'chrome_branch_number', None) 52 if (not self._chrome_branch_number or 53 (sys.platform != 'android' and self._chrome_branch_number < 1713)): 54 raise page_test.TestNotSupportedOnPlatformFailure( 55 'rasterize_and_record_micro requires Chrome branch 1713 ' 56 'or later. Skipping measurement.') 57 58 def ValidateAndMeasurePage(self, page, tab, results): 59 try: 60 tab.WaitForDocumentReadyStateToBeComplete() 61 except TimeoutException: 62 pass 63 time.sleep(self.options.start_wait_time) 64 65 record_repeat = self.options.record_repeat 66 rasterize_repeat = self.options.rasterize_repeat 67 # Enqueue benchmark 68 tab.ExecuteJavaScript(""" 69 window.benchmark_results = {}; 70 window.benchmark_results.done = false; 71 window.benchmark_results.id = 72 chrome.gpuBenchmarking.runMicroBenchmark( 73 "rasterize_and_record_benchmark", 74 function(value) { 75 window.benchmark_results.done = true; 76 window.benchmark_results.results = value; 77 }, { 78 "record_repeat_count": """ + str(record_repeat) + """, 79 "rasterize_repeat_count": """ + str(rasterize_repeat) + """ 80 }); 81 """) 82 83 benchmark_id = tab.EvaluateJavaScript('window.benchmark_results.id') 84 if (not benchmark_id): 85 raise page_test.MeasurementFailure( 86 'Failed to schedule rasterize_and_record_micro') 87 88 tab.WaitForJavaScriptExpression( 89 'window.benchmark_results.done', self.options.timeout) 90 91 data = tab.EvaluateJavaScript('window.benchmark_results.results') 92 93 pixels_recorded = data['pixels_recorded'] 94 record_time = data['record_time_ms'] 95 pixels_rasterized = data['pixels_rasterized'] 96 rasterize_time = data['rasterize_time_ms'] 97 98 results.AddValue(scalar.ScalarValue( 99 results.current_page, 'pixels_recorded', 'pixels', pixels_recorded)) 100 results.AddValue(scalar.ScalarValue( 101 results.current_page, 'record_time', 'ms', record_time)) 102 results.AddValue(scalar.ScalarValue( 103 results.current_page, 'pixels_rasterized', 'pixels', pixels_rasterized)) 104 results.AddValue(scalar.ScalarValue( 105 results.current_page, 'rasterize_time', 'ms', rasterize_time)) 106 107 # TODO(skyostil): Remove this temporary workaround when reference build has 108 # been updated to branch 1931 or later. 109 if ((self._chrome_branch_number and self._chrome_branch_number >= 1931) or 110 sys.platform == 'android'): 111 record_time_sk_null_canvas = data['record_time_sk_null_canvas_ms'] 112 record_time_painting_disabled = data['record_time_painting_disabled_ms'] 113 record_time_skrecord = data['record_time_skrecord_ms'] 114 results.AddValue(scalar.ScalarValue( 115 results.current_page, 'record_time_sk_null_canvas', 'ms', 116 record_time_sk_null_canvas)) 117 results.AddValue(scalar.ScalarValue( 118 results.current_page, 'record_time_painting_disabled', 'ms', 119 record_time_painting_disabled)) 120 results.AddValue(scalar.ScalarValue( 121 results.current_page, 'record_time_skrecord', 'ms', 122 record_time_skrecord)) 123 124 if self.options.report_detailed_results: 125 pixels_rasterized_with_non_solid_color = \ 126 data['pixels_rasterized_with_non_solid_color'] 127 pixels_rasterized_as_opaque = \ 128 data['pixels_rasterized_as_opaque'] 129 total_layers = data['total_layers'] 130 total_picture_layers = data['total_picture_layers'] 131 total_picture_layers_with_no_content = \ 132 data['total_picture_layers_with_no_content'] 133 total_picture_layers_off_screen = \ 134 data['total_picture_layers_off_screen'] 135 136 results.AddValue(scalar.ScalarValue( 137 results.current_page, 'pixels_rasterized_with_non_solid_color', 138 'pixels', pixels_rasterized_with_non_solid_color)) 139 results.AddValue(scalar.ScalarValue( 140 results.current_page, 'pixels_rasterized_as_opaque', 'pixels', 141 pixels_rasterized_as_opaque)) 142 results.AddValue(scalar.ScalarValue( 143 results.current_page, 'total_layers', 'count', total_layers)) 144 results.AddValue(scalar.ScalarValue( 145 results.current_page, 'total_picture_layers', 'count', 146 total_picture_layers)) 147 results.AddValue(scalar.ScalarValue( 148 results.current_page, 'total_picture_layers_with_no_content', 'count', 149 total_picture_layers_with_no_content)) 150 results.AddValue(scalar.ScalarValue( 151 results.current_page, 'total_picture_layers_off_screen', 'count', 152 total_picture_layers_off_screen)) 153