• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 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
6# Recipe module for Skia Swarming perf.
7
8
9import calendar
10
11from recipe_engine import recipe_api
12
13
14def nanobench_flags(bot):
15  args = ['--pre_log']
16
17  if 'GPU' in bot:
18    args.append('--images')
19    args.extend(['--gpuStatsDump', 'true'])
20
21  if 'Android' in bot and 'GPU' in bot:
22    args.extend(['--useThermalManager', '1,1,10,1000'])
23
24  args.extend(['--scales', '1.0', '1.1'])
25
26  if 'iOS' in bot:
27    args.extend(['--skps', 'ignore_skps'])
28
29  config = ['8888', 'nonrendering', 'hwui' ]
30
31  if '-arm-' not in bot:
32    # For Android CPU tests, these take too long and cause the task to time out.
33    config += [ 'f16', 'srgb' ]
34  if '-GCE-' in bot:
35    config += [ '565' ]
36
37  gl_prefix = 'gl'
38  sample_count = '8'
39  if 'Android' in bot or 'iOS' in bot:
40    sample_count = '4'
41    # The NVIDIA_Shield has a regular OpenGL implementation. We bench that
42    # instead of ES.
43    if 'NVIDIA_Shield' not in bot:
44      gl_prefix = 'gles'
45    # The NP produces a long error stream when we run with MSAA.
46    # iOS crashes (skia:6399)
47    if 'NexusPlayer' in bot or 'iOS' in bot:
48      sample_count = ''
49  elif 'Intel' in bot:
50    sample_count = ''
51
52  config.append(gl_prefix)
53  if sample_count is not '':
54    config.extend([gl_prefix + 'msaa' + sample_count,
55      gl_prefix + 'nvpr' + sample_count,
56      gl_prefix + 'nvprdit' + sample_count])
57
58  # We want to test both the OpenGL config and the GLES config on Linux Intel:
59  # GL is used by Chrome, GLES is used by ChromeOS.
60  if 'Intel' in bot and 'Ubuntu' in bot:
61    config.append('gles')
62
63  # Bench instanced rendering on a limited number of platforms
64  inst_config = gl_prefix + 'inst'
65  if 'Nexus6' in bot:
66    config.append(inst_config) # msaa inst isn't working yet on Adreno.
67  elif 'PixelC' in bot or 'NVIDIA_Shield' in bot or 'MacMini6.2' in bot:
68    config.extend([inst_config, inst_config + sample_count])
69
70  if 'CommandBuffer' in bot:
71    config = ['commandbuffer']
72  if 'Vulkan' in bot:
73    config = ['vk']
74
75  if 'ANGLE' in bot:
76    config.extend(['angle_d3d11_es2'])
77    # The GL backend of ANGLE crashes on the perf bot currently.
78    if 'Win' not in bot:
79      config.extend(['angle_gl_es2'])
80
81  args.append('--config')
82  args.extend(config)
83
84  if 'Valgrind' in bot:
85    # Don't care about Valgrind performance.
86    args.extend(['--loops',   '1'])
87    args.extend(['--samples', '1'])
88    # Ensure that the bot framework does not think we have timed out.
89    args.extend(['--keepAlive', 'true'])
90
91  match = []
92  if 'Android' in bot:
93    # Segfaults when run as GPU bench. Very large texture?
94    match.append('~blurroundrect')
95    match.append('~patch_grid')  # skia:2847
96    match.append('~desk_carsvg')
97  if 'NexusPlayer' in bot:
98    match.append('~desk_unicodetable')
99  if 'Nexus5' in bot:
100    match.append('~keymobi_shop_mobileweb_ebay_com.skp')  # skia:5178
101  if 'iOS' in bot:
102    match.append('~blurroundrect')
103    match.append('~patch_grid')  # skia:2847
104    match.append('~desk_carsvg')
105    match.append('~keymobi')
106    match.append('~path_hairline')
107    match.append('~GLInstancedArraysBench') # skia:4714
108  if 'IntelIris540' in bot and 'ANGLE' in bot:
109    match.append('~tile_image_filter_tiled_64')  # skia:6082
110  if 'Intel' in bot and 'Ubuntu' in bot and not 'Vulkan' in bot:
111    match.append('~native_image_to_raster_surface')  # skia:6401
112  if 'Vulkan' in bot and 'IntelIris540' in bot and 'Win' in bot:
113    # skia:6398
114    match.append('~GM_varied_text_clipped_lcd')
115    match.append('~GM_varied_text_ignorable_clip_lcd')
116    match.append('~Xfermode_DstATop_aa')
117    match.append('~Xfermode_SrcIn_aa')
118    match.append('~Xfermode_SrcOut_aa')
119    match.append('~Xfermode_Src_aa')
120    match.append('~fontscaler_lcd')
121    match.append('~rotated_rects_aa_alternating_transparent_and_opaque_src')
122    match.append('~rotated_rects_aa_changing_transparent_src')
123    match.append('~rotated_rects_aa_same_transparent_src')
124    match.append('~shadermask_LCD_FF')
125    match.append('~srcmode_rects_1')
126    match.append('~text_16_LCD_88')
127    match.append('~text_16_LCD_BK')
128    match.append('~text_16_LCD_FF')
129    match.append('~text_16_LCD_WT')
130  if 'Vulkan' in bot and 'NexusPlayer' in bot:
131    match.append('~hardstop') # skia:6037
132
133  # We do not need or want to benchmark the decodes of incomplete images.
134  # In fact, in nanobench we assert that the full image decode succeeds.
135  match.append('~inc0.gif')
136  match.append('~inc1.gif')
137  match.append('~incInterlaced.gif')
138  match.append('~inc0.jpg')
139  match.append('~incGray.jpg')
140  match.append('~inc0.wbmp')
141  match.append('~inc1.wbmp')
142  match.append('~inc0.webp')
143  match.append('~inc1.webp')
144  match.append('~inc0.ico')
145  match.append('~inc1.ico')
146  match.append('~inc0.png')
147  match.append('~inc1.png')
148  match.append('~inc2.png')
149  match.append('~inc12.png')
150  match.append('~inc13.png')
151  match.append('~inc14.png')
152  match.append('~inc0.webp')
153  match.append('~inc1.webp')
154
155  if match:
156    args.append('--match')
157    args.extend(match)
158
159  return args
160
161
162def perf_steps(api):
163  """Run Skia benchmarks."""
164  if api.vars.upload_perf_results:
165    api.flavor.create_clean_device_dir(
166        api.flavor.device_dirs.perf_data_dir)
167
168  # Run nanobench.
169  properties = [
170    '--properties',
171    'gitHash',      api.vars.got_revision,
172    'build_number', api.vars.build_number,
173  ]
174  if api.vars.is_trybot:
175    properties.extend([
176      'issue',    api.vars.issue,
177      'patchset', api.vars.patchset,
178      'patch_storage', api.vars.patch_storage,
179    ])
180  if api.vars.no_buildbot:
181    properties.extend(['no_buildbot', 'True'])
182    properties.extend(['swarming_bot_id', api.vars.swarming_bot_id])
183    properties.extend(['swarming_task_id', api.vars.swarming_task_id])
184
185  target = 'nanobench'
186  args = [
187      target,
188      '--undefok',   # This helps branches that may not know new flags.
189      '-i',       api.flavor.device_dirs.resource_dir,
190      '--skps',   api.flavor.device_dirs.skp_dir,
191      '--images', api.flavor.device_path_join(
192          api.flavor.device_dirs.images_dir, 'nanobench'),
193  ]
194
195  # Do not run svgs on Valgrind.
196  if 'Valgrind' not in api.vars.builder_name:
197    if ('Vulkan' not in api.vars.builder_name or
198        'NexusPlayer' not in api.vars.builder_name):
199      args.extend(['--svgs',  api.flavor.device_dirs.svg_dir])
200
201  skip_flag = None
202  if api.vars.builder_cfg.get('cpu_or_gpu') == 'CPU':
203    skip_flag = '--nogpu'
204  elif api.vars.builder_cfg.get('cpu_or_gpu') == 'GPU':
205    skip_flag = '--nocpu'
206  if skip_flag:
207    args.append(skip_flag)
208  args.extend(nanobench_flags(api.vars.builder_name))
209
210  if 'Chromecast' in api.vars.builder_cfg.get('os', ''):
211    # Due to limited disk space, run a watered down perf run on Chromecast.
212    args = [
213      target,
214       '-i', api.flavor.device_dirs.resource_dir,
215       '--images', api.flavor.device_path_join(
216            api.flavor.device_dirs.resource_dir, 'color_wheel.jpg'),
217       '--svgs',  api.flavor.device_dirs.svg_dir,
218    ]
219
220  if api.vars.upload_perf_results:
221    now = api.time.utcnow()
222    ts = int(calendar.timegm(now.utctimetuple()))
223    json_path = api.flavor.device_path_join(
224        api.flavor.device_dirs.perf_data_dir,
225        'nanobench_%s_%d.json' % (api.vars.got_revision, ts))
226    args.extend(['--outResultsFile', json_path])
227    args.extend(properties)
228
229    keys_blacklist = ['configuration', 'role', 'is_trybot']
230    args.append('--key')
231    for k in sorted(api.vars.builder_cfg.keys()):
232      if not k in keys_blacklist:
233        args.extend([k, api.vars.builder_cfg[k]])
234
235  env = api.step.get_from_context('env', {})
236  if 'Ubuntu16' in api.vars.builder_name:
237    # The vulkan in this asset name simply means that the graphics driver
238    # supports Vulkan. It is also the driver used for GL code.
239    dri_path = api.vars.slave_dir.join('linux_vulkan_intel_driver_release')
240    if 'Debug' in api.vars.builder_name:
241      dri_path = api.vars.slave_dir.join('linux_vulkan_intel_driver_debug')
242
243    if 'Vulkan' in api.vars.builder_name:
244      sdk_path = api.vars.slave_dir.join('linux_vulkan_sdk', 'bin')
245      lib_path = api.vars.slave_dir.join('linux_vulkan_sdk', 'lib')
246      env.update({
247        'PATH':'%%(PATH)s:%s' % sdk_path,
248        'LD_LIBRARY_PATH': '%s:%s' % (lib_path, dri_path),
249        'LIBGL_DRIVERS_PATH': dri_path,
250        'VK_ICD_FILENAMES':'%s' % dri_path.join('intel_icd.x86_64.json'),
251      })
252    else:
253      # Even the non-vulkan NUC jobs could benefit from the newer drivers.
254      env.update({
255        'LD_LIBRARY_PATH': dri_path,
256        'LIBGL_DRIVERS_PATH': dri_path,
257      })
258
259  # See skia:2789.
260  if '_AbandonGpuContext' in api.vars.builder_cfg.get('extra_config', ''):
261    args.extend(['--abandonGpuContext', '--nocpu'])
262
263  with api.step.context({'env': env}):
264    api.run(api.flavor.step, target, cmd=args,
265            abort_on_failure=False)
266
267  # Copy results to swarming out dir.
268  if api.vars.upload_perf_results:
269    api.file.makedirs('perf_dir', api.vars.perf_data_dir)
270    api.flavor.copy_directory_contents_to_host(
271        api.flavor.device_dirs.perf_data_dir,
272        api.vars.perf_data_dir)
273
274class PerfApi(recipe_api.RecipeApi):
275  def run(self):
276    self.m.core.setup()
277    env = self.m.step.get_from_context('env', {})
278    if 'iOS' in self.m.vars.builder_name:
279      env['IOS_BUNDLE_ID'] = 'com.google.nanobench'
280    with self.m.step.context({'env': env}):
281      try:
282        if 'Chromecast' in self.m.vars.builder_name:
283          self.m.flavor.install(resources=True, skps=True)
284        else:
285          self.m.flavor.install_everything()
286        perf_steps(self.m)
287      finally:
288        self.m.flavor.cleanup_steps()
289      self.m.run.check_failure()
290