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# This is more akin to a .pyl/JSON file, so it's expected to be long.
6# pylint: disable=too-many-lines
7
8import os
9
10from gpu_tests import common_browser_args as cba
11from gpu_tests import skia_gold_matching_algorithms as algo
12from gpu_tests import path_util
13
14CRASH_TYPE_GPU = 'gpu'
15
16# These tests attempt to use test rects that are larger than the small screen
17# on some Fuchsia devices, so we need to use a less-desirable screenshot capture
18# method to get the entire page contents instead of just the visible portion.
19PROBLEMATIC_FUCHSIA_TESTS = [
20    'Maps_maps',
21    'Pixel_BackgroundImage',
22    'Pixel_PrecisionRoundedCorner',
23    'Pixel_SolidColorBackground',
24]
25
26# Meant to be used when we know a test is going to be noisy, and we want any
27# images it generates to be auto-triaged until we have enough data to calculate
28# more suitable/less permissive parameters.
29VERY_PERMISSIVE_SOBEL_ALGO = algo.SobelMatchingAlgorithm(
30    max_different_pixels=100000000,
31    pixel_delta_threshold=255,
32    edge_threshold=0,
33    ignored_border_thickness=1)
34
35
36class PixelTestPage(object):
37  """A wrapper class mimicking the functionality of the PixelTestsStorySet
38  from the old-style GPU tests.
39  """
40
41  def __init__(  # pylint: disable=too-many-arguments
42      self,
43      url,
44      name,
45      test_rect,
46      browser_args=None,
47      gpu_process_disabled=False,
48      optional_action=None,
49      restart_browser_after_test=False,
50      other_args=None,
51      grace_period_end=None,
52      expected_per_process_crashes=None,
53      matching_algorithm=None):
54    super(PixelTestPage, self).__init__()
55    self.url = url
56    self.name = name
57    self.test_rect = test_rect
58    self.browser_args = browser_args
59    # Only a couple of tests run with the GPU process completely
60    # disabled. To prevent regressions, only allow the GPU information
61    # to be incomplete in these cases.
62    self.gpu_process_disabled = gpu_process_disabled
63    # Some of the tests require custom actions to be run. These are
64    # specified as a string which is the name of a method to call in
65    # PixelIntegrationTest. For example if the action here is
66    # "CrashGpuProcess" then it would be defined in a
67    # "_CrashGpuProcess" method in PixelIntegrationTest.
68    self.optional_action = optional_action
69    # Whether the browser should be forcibly restarted after the test
70    # runs. The browser is always restarted after running tests with
71    # optional_actions.
72    self.restart_browser_after_test = restart_browser_after_test
73    # These are used to pass additional arguments to the test harness.
74    # VideoPathTraceTest and OverlayModeTest support the following boolean
75    # arguments: pixel_format, zero_copy, no_overlay, and presentation_mode.
76    self.other_args = other_args
77    # This allows a newly added test to be exempted from failures for a
78    # (hopefully) short period after being added. This is so that any slightly
79    # different but valid images that get produced by the waterfall bots can
80    # be triaged without turning the bots red.
81    # This should be a datetime.date object.
82    self.grace_period_end = grace_period_end
83    # This lets the test runner know that one or more crashes are expected as
84    # part of the test. Should be a map of process type (str) to expected number
85    # of crashes (int).
86    self.expected_per_process_crashes = expected_per_process_crashes or {}
87    # This should be a child of
88    # skia_gold_matching_algorithms.SkiaGoldMatchingAlgorithm. This specifies
89    # which matching algorithm Skia Gold should use for the test.
90    self.matching_algorithm = (matching_algorithm
91                               or algo.ExactMatchingAlgorithm())
92
93  def CopyWithNewBrowserArgsAndSuffix(self, browser_args, suffix):
94    return PixelTestPage(self.url, self.name + suffix, self.test_rect,
95                         browser_args)
96
97  def CopyWithNewBrowserArgsAndPrefix(self, browser_args, prefix):
98    # Assuming the test name is 'Pixel'.
99    split = self.name.split('_', 1)
100    return PixelTestPage(self.url, split[0] + '_' + prefix + split[1],
101                         self.test_rect, browser_args)
102
103
104def CopyPagesWithNewBrowserArgsAndSuffix(pages, browser_args, suffix):
105  return [
106      p.CopyWithNewBrowserArgsAndSuffix(browser_args, suffix) for p in pages
107  ]
108
109
110def CopyPagesWithNewBrowserArgsAndPrefix(pages, browser_args, prefix):
111  return [
112      p.CopyWithNewBrowserArgsAndPrefix(browser_args, prefix) for p in pages
113  ]
114
115
116def GetMediaStreamTestBrowserArgs(media_stream_source_relpath):
117  return [
118      '--use-fake-device-for-media-stream', '--use-fake-ui-for-media-stream',
119      '--use-file-for-fake-video-capture=' +
120      os.path.join(path_util.GetChromiumSrcDir(), media_stream_source_relpath)
121  ]
122
123
124class PixelTestPages(object):
125  @staticmethod
126  def DefaultPages(base_name):
127    sw_compositing_args = [cba.DISABLE_GPU_COMPOSITING]
128
129    # The optimizer script spat out pretty similar values for most MP4 tests, so
130    # combine into a single set of parameters.
131    general_mp4_algo = algo.SobelMatchingAlgorithm(max_different_pixels=56300,
132                                                   pixel_delta_threshold=35,
133                                                   edge_threshold=80,
134                                                   ignored_border_thickness=1)
135
136    return [
137        PixelTestPage('pixel_background_image.html',
138                      base_name + '_BackgroundImage',
139                      test_rect=[20, 20, 370, 370]),
140        PixelTestPage('pixel_reflected_div.html',
141                      base_name + '_ReflectedDiv',
142                      test_rect=[0, 0, 100, 300]),
143        PixelTestPage('pixel_canvas2d.html',
144                      base_name + '_Canvas2DRedBox',
145                      test_rect=[0, 0, 300, 300]),
146        PixelTestPage('pixel_canvas2d_untagged.html',
147                      base_name + '_Canvas2DUntagged',
148                      test_rect=[0, 0, 257, 257]),
149        PixelTestPage('pixel_css3d.html',
150                      base_name + '_CSS3DBlueBox',
151                      test_rect=[0, 0, 300, 300],
152                      matching_algorithm=algo.SobelMatchingAlgorithm(
153                          max_different_pixels=0,
154                          pixel_delta_threshold=0,
155                          edge_threshold=100)),
156        PixelTestPage('pixel_webgl_aa_alpha.html',
157                      base_name + '_WebGLGreenTriangle_AA_Alpha',
158                      test_rect=[0, 0, 300, 300]),
159        PixelTestPage('pixel_webgl_noaa_alpha.html',
160                      base_name + '_WebGLGreenTriangle_NoAA_Alpha',
161                      test_rect=[0, 0, 300, 300]),
162        PixelTestPage('pixel_webgl_aa_noalpha.html',
163                      base_name + '_WebGLGreenTriangle_AA_NoAlpha',
164                      test_rect=[0, 0, 300, 300]),
165        PixelTestPage('pixel_webgl_noaa_noalpha.html',
166                      base_name + '_WebGLGreenTriangle_NoAA_NoAlpha',
167                      test_rect=[0, 0, 300, 300]),
168        PixelTestPage('pixel_webgl_noalpha_implicit_clear.html',
169                      base_name +
170                      '_WebGLTransparentGreenTriangle_NoAlpha_ImplicitClear',
171                      test_rect=[0, 0, 300, 300]),
172        PixelTestPage('pixel_webgl_sad_canvas.html',
173                      base_name + '_WebGLSadCanvas',
174                      test_rect=[0, 0, 300, 300],
175                      optional_action='CrashGpuProcess'),
176        PixelTestPage('pixel_scissor.html',
177                      base_name + '_ScissorTestWithPreserveDrawingBuffer',
178                      test_rect=[0, 0, 300, 300]),
179        PixelTestPage('pixel_canvas2d_webgl.html',
180                      base_name + '_2DCanvasWebGL',
181                      test_rect=[0, 0, 300, 300]),
182        PixelTestPage('pixel_background.html',
183                      base_name + '_SolidColorBackground',
184                      test_rect=[500, 500, 100, 100]),
185        PixelTestPage(
186            'pixel_video_mp4.html',
187            base_name + '_Video_MP4',
188            test_rect=[0, 0, 240, 135],
189            # Most images are actually very similar, but Pixel 2
190            # tends to produce images with all colors shifted by a
191            # small amount.
192            matching_algorithm=general_mp4_algo),
193        # Surprisingly stable, does not appear to require inexact matching.
194        PixelTestPage('pixel_video_mp4.html',
195                      base_name + '_Video_MP4_DXVA',
196                      browser_args=[cba.DISABLE_FEATURES_D3D11_VIDEO_DECODER],
197                      test_rect=[0, 0, 240, 135]),
198        PixelTestPage('pixel_video_mp4_four_colors_aspect_4x3.html',
199                      base_name + '_Video_MP4_FourColors_Aspect_4x3',
200                      test_rect=[0, 0, 240, 135],
201                      matching_algorithm=algo.SobelMatchingAlgorithm(
202                          max_different_pixels=41700,
203                          pixel_delta_threshold=15,
204                          edge_threshold=40,
205                          ignored_border_thickness=1)),
206        PixelTestPage('pixel_video_mp4_four_colors_rot_90.html',
207                      base_name + '_Video_MP4_FourColors_Rot_90',
208                      test_rect=[0, 0, 270, 240],
209                      matching_algorithm=general_mp4_algo),
210        PixelTestPage('pixel_video_mp4_four_colors_rot_180.html',
211                      base_name + '_Video_MP4_FourColors_Rot_180',
212                      test_rect=[0, 0, 240, 135],
213                      matching_algorithm=general_mp4_algo),
214        PixelTestPage('pixel_video_mp4_four_colors_rot_270.html',
215                      base_name + '_Video_MP4_FourColors_Rot_270',
216                      test_rect=[0, 0, 270, 240],
217                      matching_algorithm=general_mp4_algo),
218        PixelTestPage('pixel_video_mp4_rounded_corner.html',
219                      base_name + '_Video_MP4_Rounded_Corner',
220                      test_rect=[0, 0, 240, 135],
221                      matching_algorithm=algo.SobelMatchingAlgorithm(
222                          max_different_pixels=30500,
223                          pixel_delta_threshold=15,
224                          edge_threshold=70,
225                          ignored_border_thickness=1)),
226        PixelTestPage('pixel_video_vp9.html',
227                      base_name + '_Video_VP9',
228                      test_rect=[0, 0, 240, 135],
229                      matching_algorithm=algo.SobelMatchingAlgorithm(
230                          max_different_pixels=114000,
231                          pixel_delta_threshold=30,
232                          edge_threshold=20,
233                          ignored_border_thickness=1)),
234        PixelTestPage('pixel_video_vp9.html',
235                      base_name + '_Video_VP9_DXVA',
236                      browser_args=[cba.DISABLE_FEATURES_D3D11_VIDEO_DECODER],
237                      test_rect=[0, 0, 240, 135],
238                      matching_algorithm=algo.SobelMatchingAlgorithm(
239                          max_different_pixels=31100,
240                          pixel_delta_threshold=30,
241                          edge_threshold=250,
242                          ignored_border_thickness=1)),
243        PixelTestPage(
244            'pixel_video_media_stream_incompatible_stride.html',
245            base_name + '_Video_Media_Stream_Incompatible_Stride',
246            browser_args=GetMediaStreamTestBrowserArgs(
247                'media/test/data/four-colors-incompatible-stride.y4m'),
248            test_rect=[0, 0, 240, 135],
249            matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO),
250
251        # The MP4 contains H.264 which is primarily hardware decoded on bots.
252        PixelTestPage(
253            'pixel_video_context_loss.html?src='
254            '/media/test/data/four-colors.mp4',
255            base_name + '_Video_Context_Loss_MP4',
256            test_rect=[0, 0, 240, 135],
257            # Optimizer script spat out a value of 255 for the Sobel edge
258            # threshold, so use fuzzy for now since it's slightly more
259            # efficient.
260            matching_algorithm=algo.FuzzyMatchingAlgorithm(
261                max_different_pixels=31700, pixel_delta_threshold=20),
262            expected_per_process_crashes={
263                CRASH_TYPE_GPU: 1,
264            }),
265
266        # The VP9 test clip is primarily software decoded on bots.
267        PixelTestPage(('pixel_video_context_loss.html'
268                       '?src=/media/test/data/four-colors-vp9.webm'),
269                      base_name + '_Video_Context_Loss_VP9',
270                      test_rect=[0, 0, 240, 135],
271                      matching_algorithm=algo.SobelMatchingAlgorithm(
272                          max_different_pixels=54400,
273                          pixel_delta_threshold=30,
274                          edge_threshold=250,
275                          ignored_border_thickness=1),
276                      expected_per_process_crashes={
277                          CRASH_TYPE_GPU: 1,
278                      }),
279        PixelTestPage('pixel_video_backdrop_filter.html',
280                      base_name + '_Video_BackdropFilter',
281                      test_rect=[0, 0, 240, 135],
282                      matching_algorithm=algo.SobelMatchingAlgorithm(
283                          max_different_pixels=1000,
284                          pixel_delta_threshold=20,
285                          edge_threshold=40,
286                          ignored_border_thickness=1)),
287        PixelTestPage('pixel_webgl_premultiplied_alpha_false.html',
288                      base_name + '_WebGL_PremultipliedAlpha_False',
289                      test_rect=[0, 0, 150, 150]),
290        PixelTestPage('pixel_webgl2_blitframebuffer_result_displayed.html',
291                      base_name + '_WebGL2_BlitFramebuffer_Result_Displayed',
292                      test_rect=[0, 0, 200, 200]),
293        PixelTestPage('pixel_webgl2_clearbufferfv_result_displayed.html',
294                      base_name + '_WebGL2_ClearBufferfv_Result_Displayed',
295                      test_rect=[0, 0, 200, 200]),
296        PixelTestPage('pixel_repeated_webgl_to_2d.html',
297                      base_name + '_RepeatedWebGLTo2D',
298                      test_rect=[0, 0, 256, 256]),
299        PixelTestPage('pixel_repeated_webgl_to_2d.html',
300                      base_name + '_RepeatedWebGLTo2D_SoftwareCompositing',
301                      test_rect=[0, 0, 256, 256],
302                      browser_args=sw_compositing_args),
303        PixelTestPage('pixel_canvas2d_tab_switch.html',
304                      base_name + '_Canvas2DTabSwitch',
305                      test_rect=[0, 0, 100, 100],
306                      optional_action='SwitchTabs'),
307        PixelTestPage('pixel_canvas2d_tab_switch.html',
308                      base_name + '_Canvas2DTabSwitch_SoftwareCompositing',
309                      test_rect=[0, 0, 100, 100],
310                      browser_args=sw_compositing_args,
311                      optional_action='SwitchTabs'),
312        PixelTestPage('pixel_webgl_copy_image.html',
313                      base_name + '_WebGLCopyImage',
314                      test_rect=[0, 0, 200, 100]),
315        PixelTestPage('pixel_webgl_read_pixels_tab_switch.html',
316                      base_name + '_WebGLReadPixelsTabSwitch',
317                      test_rect=[0, 0, 100, 100],
318                      optional_action='SwitchTabs'),
319        PixelTestPage('pixel_webgl_read_pixels_tab_switch.html',
320                      base_name +
321                      '_WebGLReadPixelsTabSwitch_SoftwareCompositing',
322                      test_rect=[0, 0, 100, 100],
323                      browser_args=sw_compositing_args,
324                      optional_action='SwitchTabs'),
325        PixelTestPage('pixel_offscreen_canvas_ibrc_webgl_main.html',
326                      base_name + '_OffscreenCanvasIBRCWebGLMain',
327                      test_rect=[0, 0, 300, 300],
328                      optional_action='RunOffscreenCanvasIBRCWebGLTest'),
329        PixelTestPage('pixel_offscreen_canvas_ibrc_webgl_worker.html',
330                      base_name + '_OffscreenCanvasIBRCWebGLWorker',
331                      test_rect=[0, 0, 300, 300],
332                      optional_action='RunOffscreenCanvasIBRCWebGLTest'),
333    ]
334
335  # Pages that should be run with GPU rasterization enabled.
336  @staticmethod
337  def GpuRasterizationPages(base_name):
338    browser_args = [
339        cba.ENABLE_GPU_RASTERIZATION,
340        cba.DISABLE_SOFTWARE_COMPOSITING_FALLBACK,
341    ]
342    return [
343        PixelTestPage('pixel_background.html',
344                      base_name + '_GpuRasterization_BlueBox',
345                      test_rect=[0, 0, 220, 220],
346                      browser_args=browser_args),
347        PixelTestPage('concave_paths.html',
348                      base_name + '_GpuRasterization_ConcavePaths',
349                      test_rect=[0, 0, 100, 100],
350                      browser_args=browser_args),
351        PixelTestPage('pixel_precision_rounded_corner.html',
352                      base_name + '_PrecisionRoundedCorner',
353                      test_rect=[0, 0, 400, 400],
354                      browser_args=browser_args,
355                      matching_algorithm=algo.SobelMatchingAlgorithm(
356                          max_different_pixels=10,
357                          pixel_delta_threshold=30,
358                          edge_threshold=100)),
359    ]
360
361  # Pages that should be run with off-thread paint worklet flags.
362  @staticmethod
363  def PaintWorkletPages(base_name):
364    browser_args = [
365        '--enable-blink-features=OffMainThreadCSSPaint',
366        '--enable-gpu-rasterization', '--enable-oop-rasterization'
367    ]
368
369    return [
370        PixelTestPage(
371            'pixel_paintWorklet_transform.html',
372            base_name + '_PaintWorkletTransform',
373            test_rect=[0, 0, 200, 200],
374            browser_args=browser_args),
375    ]
376
377  # Pages that should be run with experimental canvas features.
378  @staticmethod
379  def ExperimentalCanvasFeaturesPages(base_name):
380    browser_args = [
381        cba.ENABLE_EXPERIMENTAL_WEB_PLATFORM_FEATURES,
382    ]
383    accelerated_args = [
384        cba.DISABLE_SOFTWARE_COMPOSITING_FALLBACK,
385    ]
386    unaccelerated_args = [
387        cba.DISABLE_ACCELERATED_2D_CANVAS,
388        cba.DISABLE_GPU_COMPOSITING,
389    ]
390
391    return [
392        PixelTestPage('pixel_offscreenCanvas_transfer_after_style_resize.html',
393                      base_name + '_OffscreenCanvasTransferAfterStyleResize',
394                      test_rect=[0, 0, 350, 350],
395                      browser_args=browser_args),
396        PixelTestPage('pixel_offscreenCanvas_transfer_before_style_resize.html',
397                      base_name + '_OffscreenCanvasTransferBeforeStyleResize',
398                      test_rect=[0, 0, 350, 350],
399                      browser_args=browser_args),
400        PixelTestPage('pixel_offscreenCanvas_webgl_paint_after_resize.html',
401                      base_name + '_OffscreenCanvasWebGLPaintAfterResize',
402                      test_rect=[0, 0, 200, 200],
403                      browser_args=browser_args),
404        PixelTestPage('pixel_offscreenCanvas_transferToImageBitmap_main.html',
405                      base_name + '_OffscreenCanvasTransferToImageBitmap',
406                      test_rect=[0, 0, 300, 300],
407                      browser_args=browser_args),
408        PixelTestPage('pixel_offscreenCanvas_transferToImageBitmap_worker.html',
409                      base_name + '_OffscreenCanvasTransferToImageBitmapWorker',
410                      test_rect=[0, 0, 300, 300],
411                      browser_args=browser_args),
412        PixelTestPage('pixel_offscreenCanvas_webgl_commit_main.html',
413                      base_name + '_OffscreenCanvasWebGLDefault',
414                      test_rect=[0, 0, 360, 200],
415                      browser_args=browser_args),
416        PixelTestPage('pixel_offscreenCanvas_webgl_commit_worker.html',
417                      base_name + '_OffscreenCanvasWebGLDefaultWorker',
418                      test_rect=[0, 0, 360, 200],
419                      browser_args=browser_args),
420        PixelTestPage('pixel_offscreenCanvas_webgl_commit_main.html',
421                      base_name + '_OffscreenCanvasWebGLSoftwareCompositing',
422                      test_rect=[0, 0, 360, 200],
423                      browser_args=browser_args +
424                      [cba.DISABLE_GPU_COMPOSITING]),
425        PixelTestPage(
426            'pixel_offscreenCanvas_webgl_commit_worker.html',
427            base_name + '_OffscreenCanvasWebGLSoftwareCompositingWorker',
428            test_rect=[0, 0, 360, 200],
429            browser_args=browser_args + [cba.DISABLE_GPU_COMPOSITING]),
430        PixelTestPage('pixel_offscreenCanvas_2d_commit_main.html',
431                      base_name + '_OffscreenCanvasAccelerated2D',
432                      test_rect=[0, 0, 360, 200],
433                      browser_args=browser_args + accelerated_args),
434        PixelTestPage('pixel_offscreenCanvas_2d_commit_worker.html',
435                      base_name + '_OffscreenCanvasAccelerated2DWorker',
436                      test_rect=[0, 0, 360, 200],
437                      browser_args=browser_args + accelerated_args),
438        PixelTestPage('pixel_offscreenCanvas_2d_commit_main.html',
439                      base_name + '_OffscreenCanvasUnaccelerated2D',
440                      test_rect=[0, 0, 360, 200],
441                      browser_args=browser_args + unaccelerated_args),
442        PixelTestPage('pixel_offscreenCanvas_2d_commit_worker.html',
443                      base_name + '_OffscreenCanvasUnaccelerated2DWorker',
444                      test_rect=[0, 0, 360, 200],
445                      browser_args=browser_args + unaccelerated_args),
446        PixelTestPage(
447            'pixel_offscreenCanvas_2d_commit_main.html',
448            base_name + '_OffscreenCanvasUnaccelerated2DGPUCompositing',
449            test_rect=[0, 0, 360, 200],
450            browser_args=browser_args + [cba.DISABLE_ACCELERATED_2D_CANVAS]),
451        PixelTestPage(
452            'pixel_offscreenCanvas_2d_commit_worker.html',
453            base_name + '_OffscreenCanvasUnaccelerated2DGPUCompositingWorker',
454            test_rect=[0, 0, 360, 200],
455            browser_args=browser_args + [cba.DISABLE_ACCELERATED_2D_CANVAS]),
456        PixelTestPage('pixel_offscreenCanvas_2d_resize_on_worker.html',
457                      base_name + '_OffscreenCanvas2DResizeOnWorker',
458                      test_rect=[0, 0, 200, 200],
459                      browser_args=browser_args),
460        PixelTestPage('pixel_offscreenCanvas_webgl_resize_on_worker.html',
461                      base_name + '_OffscreenCanvasWebglResizeOnWorker',
462                      test_rect=[0, 0, 200, 200],
463                      browser_args=browser_args),
464        PixelTestPage('pixel_canvas_display_srgb.html',
465                      base_name + '_CanvasDisplaySRGBAccelerated2D',
466                      test_rect=[0, 0, 140, 140],
467                      browser_args=browser_args + accelerated_args),
468        PixelTestPage('pixel_canvas_display_srgb.html',
469                      base_name + '_CanvasDisplaySRGBUnaccelerated2D',
470                      test_rect=[0, 0, 140, 140],
471                      browser_args=browser_args + unaccelerated_args),
472        PixelTestPage(
473            'pixel_canvas_display_srgb.html',
474            base_name + '_CanvasDisplaySRGBUnaccelerated2DGPUCompositing',
475            test_rect=[0, 0, 140, 140],
476            browser_args=browser_args + [cba.DISABLE_ACCELERATED_2D_CANVAS]),
477    ]
478
479  @staticmethod
480  def LowLatencyPages(base_name):
481    unaccelerated_args = [
482        cba.DISABLE_ACCELERATED_2D_CANVAS,
483        cba.DISABLE_GPU_COMPOSITING,
484    ]
485    return [
486        PixelTestPage('pixel_canvas_low_latency_2d.html',
487                      base_name + '_CanvasLowLatency2D',
488                      test_rect=[0, 0, 100, 100]),
489        PixelTestPage('pixel_canvas_low_latency_2d.html',
490                      base_name + '_CanvasUnacceleratedLowLatency2D',
491                      test_rect=[0, 0, 100, 100],
492                      browser_args=unaccelerated_args),
493        PixelTestPage('pixel_canvas_low_latency_webgl.html',
494                      base_name + '_CanvasLowLatencyWebGL',
495                      test_rect=[0, 0, 200, 200]),
496        PixelTestPage('pixel_canvas_low_latency_webgl_alpha_false.html',
497                      base_name + '_CanvasLowLatencyWebGLAlphaFalse',
498                      test_rect=[0, 0, 200, 200]),
499        PixelTestPage('pixel_canvas_low_latency_2d_draw_image.html',
500                      base_name + '_CanvasLowLatency2DDrawImage',
501                      test_rect=[0, 0, 200, 100]),
502        PixelTestPage('pixel_canvas_low_latency_webgl_draw_image.html',
503                      base_name + '_CanvasLowLatencyWebGLDrawImage',
504                      test_rect=[0, 0, 200, 100]),
505        PixelTestPage('pixel_canvas_low_latency_2d_image_data.html',
506                      base_name + '_CanvasLowLatency2DImageData',
507                      test_rect=[0, 0, 200, 100]),
508        PixelTestPage('pixel_canvas_low_latency_webgl_rounded_corners.html',
509                      base_name + '_CanvasLowLatencyWebGLRoundedCorners',
510                      test_rect=[0, 0, 100, 100],
511                      other_args={'no_overlay': True}),
512        PixelTestPage('pixel_canvas_low_latency_webgl_occluded.html',
513                      base_name + '_CanvasLowLatencyWebGLOccluded',
514                      test_rect=[0, 0, 100, 100],
515                      other_args={'no_overlay': True}),
516    ]
517
518  # Only add these tests on platforms where SwiftShader is enabled.
519  # Currently this is Windows and Linux.
520  @staticmethod
521  def SwiftShaderPages(base_name):
522    browser_args = [cba.DISABLE_GPU]
523    suffix = "_SwiftShader"
524    return [
525        PixelTestPage('pixel_canvas2d.html',
526                      base_name + '_Canvas2DRedBox' + suffix,
527                      test_rect=[0, 0, 300, 300],
528                      browser_args=browser_args),
529        PixelTestPage('pixel_css3d.html',
530                      base_name + '_CSS3DBlueBox' + suffix,
531                      test_rect=[0, 0, 300, 300],
532                      browser_args=browser_args),
533        PixelTestPage('pixel_webgl_aa_alpha.html',
534                      base_name + '_WebGLGreenTriangle_AA_Alpha' + suffix,
535                      test_rect=[0, 0, 300, 300],
536                      browser_args=browser_args),
537        PixelTestPage('pixel_repeated_webgl_to_2d.html',
538                      base_name + '_RepeatedWebGLTo2D' + suffix,
539                      test_rect=[0, 0, 256, 256],
540                      browser_args=browser_args),
541    ]
542
543  # Test rendering where GPU process is blocked.
544  @staticmethod
545  def NoGpuProcessPages(base_name):
546    browser_args = [cba.DISABLE_GPU, cba.DISABLE_SOFTWARE_RASTERIZER]
547    suffix = "_NoGpuProcess"
548    return [
549        PixelTestPage(
550            'pixel_canvas2d.html',
551            base_name + '_Canvas2DRedBox' + suffix,
552            test_rect=[0, 0, 300, 300],
553            browser_args=browser_args,
554            gpu_process_disabled=True),
555        PixelTestPage(
556            'pixel_css3d.html',
557            base_name + '_CSS3DBlueBox' + suffix,
558            test_rect=[0, 0, 300, 300],
559            browser_args=browser_args,
560            gpu_process_disabled=True),
561    ]
562
563  # Pages that should be run with various macOS specific command line
564  # arguments.
565  @staticmethod
566  def MacSpecificPages(base_name):
567    iosurface_2d_canvas_args = ['--enable-accelerated-2d-canvas']
568
569    non_chromium_image_args = ['--disable-webgl-image-chromium']
570
571    # This disables the Core Animation compositor, falling back to the
572    # old GLRenderer path, but continuing to allocate IOSurfaces for
573    # WebGL's back buffer.
574    no_overlays_args = ['--disable-mac-overlays']
575
576    # The filter effect tests produce images with lots of gradients and blurs
577    # which don't play nicely with Sobel filters, so a fuzzy algorithm instead
578    # of Sobel. The images are also relatively large (360k pixels), and large
579    # portions of the image are prone to noise, hence the large max different
580    # pixels value.
581    filter_effect_fuzzy_algo = algo.FuzzyMatchingAlgorithm(
582        max_different_pixels=57500, pixel_delta_threshold=10)
583
584    return [
585        # On macOS, test the IOSurface 2D Canvas compositing path.
586        PixelTestPage('pixel_canvas2d_accelerated.html',
587                      base_name + '_IOSurface2DCanvas',
588                      test_rect=[0, 0, 400, 400],
589                      browser_args=iosurface_2d_canvas_args),
590        PixelTestPage('pixel_canvas2d_webgl.html',
591                      base_name + '_IOSurface2DCanvasWebGL',
592                      test_rect=[0, 0, 300, 300],
593                      browser_args=iosurface_2d_canvas_args),
594
595        # On macOS, test WebGL non-Chromium Image compositing path.
596        PixelTestPage('pixel_webgl_aa_alpha.html',
597                      base_name +
598                      '_WebGLGreenTriangle_NonChromiumImage_AA_Alpha',
599                      test_rect=[0, 0, 300, 300],
600                      browser_args=non_chromium_image_args),
601        PixelTestPage('pixel_webgl_noaa_alpha.html',
602                      base_name +
603                      '_WebGLGreenTriangle_NonChromiumImage_NoAA_Alpha',
604                      test_rect=[0, 0, 300, 300],
605                      browser_args=non_chromium_image_args),
606        PixelTestPage('pixel_webgl_aa_noalpha.html',
607                      base_name +
608                      '_WebGLGreenTriangle_NonChromiumImage_AA_NoAlpha',
609                      test_rect=[0, 0, 300, 300],
610                      browser_args=non_chromium_image_args),
611        PixelTestPage('pixel_webgl_noaa_noalpha.html',
612                      base_name +
613                      '_WebGLGreenTriangle_NonChromiumImage_NoAA_NoAlpha',
614                      test_rect=[0, 0, 300, 300],
615                      browser_args=non_chromium_image_args),
616
617        # On macOS, test CSS filter effects with and without the CA compositor.
618        PixelTestPage('filter_effects.html',
619                      base_name + '_CSSFilterEffects',
620                      test_rect=[0, 0, 300, 300],
621                      matching_algorithm=filter_effect_fuzzy_algo),
622        PixelTestPage('filter_effects.html',
623                      base_name + '_CSSFilterEffects_NoOverlays',
624                      test_rect=[0, 0, 300, 300],
625                      browser_args=no_overlays_args,
626                      matching_algorithm=filter_effect_fuzzy_algo),
627
628        # Test WebGL's premultipliedAlpha:false without the CA compositor.
629        PixelTestPage('pixel_webgl_premultiplied_alpha_false.html',
630                      base_name + '_WebGL_PremultipliedAlpha_False_NoOverlays',
631                      test_rect=[0, 0, 150, 150],
632                      browser_args=no_overlays_args),
633    ]
634
635  # Pages that should be run only on dual-GPU MacBook Pros (at the
636  # present time, anyway).
637  @staticmethod
638  def DualGPUMacSpecificPages(base_name):
639    return [
640        PixelTestPage('pixel_webgl_high_to_low_power.html',
641                      base_name + '_WebGLHighToLowPower',
642                      test_rect=[0, 0, 300, 300],
643                      optional_action='RunTestWithHighPerformanceTab'),
644        PixelTestPage('pixel_webgl_low_to_high_power.html',
645                      base_name + '_WebGLLowToHighPower',
646                      test_rect=[0, 0, 300, 300],
647                      optional_action='RunLowToHighPowerTest'),
648        PixelTestPage('pixel_webgl_low_to_high_power_alpha_false.html',
649                      base_name + '_WebGLLowToHighPowerAlphaFalse',
650                      test_rect=[0, 0, 300, 300],
651                      optional_action='RunLowToHighPowerTest'),
652        PixelTestPage(
653            'pixel_offscreen_canvas_ibrc_webgl_main.html',
654            base_name + '_OffscreenCanvasIBRCWebGLHighPerfMain',
655            test_rect=[0, 0, 300, 300],
656            optional_action='RunOffscreenCanvasIBRCWebGLHighPerfTest'),
657        PixelTestPage(
658            'pixel_offscreen_canvas_ibrc_webgl_worker.html',
659            base_name + '_OffscreenCanvasIBRCWebGLHighPerfWorker',
660            test_rect=[0, 0, 300, 300],
661            optional_action='RunOffscreenCanvasIBRCWebGLHighPerfTest'),
662    ]
663
664  @staticmethod
665  def DirectCompositionPages(base_name):
666    browser_args = [
667        cba.ENABLE_DIRECT_COMPOSITION_VIDEO_OVERLAYS,
668        # All bots are connected with a power source, however, we want to to
669        # test with the code path that's enabled with battery power.
670        cba.DISABLE_DIRECT_COMPOSITION_VP_SCALING,
671    ]
672    browser_args_NV12 = browser_args + [
673        '--direct-composition-video-swap-chain-format=nv12'
674    ]
675    browser_args_YUY2 = browser_args + [
676        '--direct-composition-video-swap-chain-format=yuy2'
677    ]
678    browser_args_BGRA = browser_args + [
679        '--direct-composition-video-swap-chain-format=bgra'
680    ]
681    browser_args_DXVA = browser_args + [
682        cba.DISABLE_FEATURES_D3D11_VIDEO_DECODER
683    ]
684    browser_args_vp_scaling = [
685        cba.ENABLE_DIRECT_COMPOSITION_VIDEO_OVERLAYS,
686        cba.ENABLE_DIRECT_COMPOSITION_VP_SCALING,
687    ]
688
689    # Most tests fall roughly into 3 tiers of noisiness.
690    # Parameter values were determined using the automated optimization script,
691    # and similar values combined into a single set using the most permissive
692    # value for each parameter in that tier.
693    strict_dc_sobel_algorithm = algo.SobelMatchingAlgorithm(
694        max_different_pixels=1000,
695        pixel_delta_threshold=5,
696        edge_threshold=250,
697        ignored_border_thickness=1)
698    permissive_dc_sobel_algorithm = algo.SobelMatchingAlgorithm(
699        max_different_pixels=16800,
700        pixel_delta_threshold=20,
701        edge_threshold=30,
702        ignored_border_thickness=1)
703    very_permissive_dc_sobel_algorithm = algo.SobelMatchingAlgorithm(
704        max_different_pixels=30400,
705        pixel_delta_threshold=45,
706        edge_threshold=10,
707        ignored_border_thickness=1,
708    )
709
710    return [
711        PixelTestPage('pixel_video_mp4.html',
712                      base_name + '_DirectComposition_Video_MP4',
713                      test_rect=[0, 0, 240, 135],
714                      browser_args=browser_args,
715                      matching_algorithm=permissive_dc_sobel_algorithm),
716        PixelTestPage('pixel_video_mp4.html',
717                      base_name + '_DirectComposition_Video_MP4_DXVA',
718                      browser_args=browser_args_DXVA,
719                      test_rect=[0, 0, 240, 135],
720                      matching_algorithm=permissive_dc_sobel_algorithm),
721        PixelTestPage('pixel_video_mp4_fullsize.html',
722                      base_name + '_DirectComposition_Video_MP4_Fullsize',
723                      browser_args=browser_args,
724                      test_rect=[0, 0, 960, 540],
725                      matching_algorithm=strict_dc_sobel_algorithm),
726        PixelTestPage('pixel_video_mp4.html',
727                      base_name + '_DirectComposition_Video_MP4_NV12',
728                      test_rect=[0, 0, 240, 135],
729                      browser_args=browser_args_NV12,
730                      other_args={'pixel_format': 'NV12'},
731                      matching_algorithm=permissive_dc_sobel_algorithm),
732        PixelTestPage('pixel_video_mp4.html',
733                      base_name + '_DirectComposition_Video_MP4_YUY2',
734                      test_rect=[0, 0, 240, 135],
735                      browser_args=browser_args_YUY2,
736                      other_args={'pixel_format': 'YUY2'},
737                      matching_algorithm=permissive_dc_sobel_algorithm),
738        PixelTestPage('pixel_video_mp4.html',
739                      base_name + '_DirectComposition_Video_MP4_BGRA',
740                      test_rect=[0, 0, 240, 135],
741                      browser_args=browser_args_BGRA,
742                      other_args={'pixel_format': 'BGRA'},
743                      matching_algorithm=permissive_dc_sobel_algorithm),
744        PixelTestPage('pixel_video_mp4.html',
745                      base_name + '_DirectComposition_Video_MP4_VP_SCALING',
746                      test_rect=[0, 0, 240, 135],
747                      browser_args=browser_args_vp_scaling,
748                      other_args={'zero_copy': False},
749                      matching_algorithm=permissive_dc_sobel_algorithm),
750        PixelTestPage('pixel_video_mp4_four_colors_aspect_4x3.html',
751                      base_name +
752                      '_DirectComposition_Video_MP4_FourColors_Aspect_4x3',
753                      test_rect=[0, 0, 240, 135],
754                      browser_args=browser_args,
755                      matching_algorithm=permissive_dc_sobel_algorithm),
756        PixelTestPage('pixel_video_mp4_four_colors_rot_90.html',
757                      base_name +
758                      '_DirectComposition_Video_MP4_FourColors_Rot_90',
759                      test_rect=[0, 0, 270, 240],
760                      browser_args=browser_args,
761                      other_args={'presentation_mode': 'COMPOSED'},
762                      matching_algorithm=strict_dc_sobel_algorithm),
763        PixelTestPage('pixel_video_mp4_four_colors_rot_180.html',
764                      base_name +
765                      '_DirectComposition_Video_MP4_FourColors_Rot_180',
766                      test_rect=[0, 0, 240, 135],
767                      browser_args=browser_args,
768                      other_args={'presentation_mode': 'COMPOSED'},
769                      matching_algorithm=strict_dc_sobel_algorithm),
770        PixelTestPage('pixel_video_mp4_four_colors_rot_270.html',
771                      base_name +
772                      '_DirectComposition_Video_MP4_FourColors_Rot_270',
773                      test_rect=[0, 0, 270, 240],
774                      browser_args=browser_args,
775                      other_args={'presentation_mode': 'COMPOSED'},
776                      matching_algorithm=strict_dc_sobel_algorithm),
777        PixelTestPage('pixel_video_vp9.html',
778                      base_name + '_DirectComposition_Video_VP9',
779                      test_rect=[0, 0, 240, 135],
780                      browser_args=browser_args,
781                      matching_algorithm=very_permissive_dc_sobel_algorithm),
782        PixelTestPage('pixel_video_vp9.html',
783                      base_name + '_DirectComposition_Video_VP9_DXVA',
784                      browser_args=browser_args_DXVA,
785                      test_rect=[0, 0, 240, 135],
786                      matching_algorithm=very_permissive_dc_sobel_algorithm),
787        PixelTestPage(
788            'pixel_video_vp9_fullsize.html',
789            base_name + '_DirectComposition_Video_VP9_Fullsize',
790            test_rect=[0, 0, 960, 540],
791            browser_args=browser_args,
792            # Much larger image than other VP9 tests.
793            matching_algorithm=algo.SobelMatchingAlgorithm(
794                max_different_pixels=504000,
795                pixel_delta_threshold=10,
796                edge_threshold=10,
797                ignored_border_thickness=1,
798            )),
799        PixelTestPage('pixel_video_vp9.html',
800                      base_name + '_DirectComposition_Video_VP9_NV12',
801                      test_rect=[0, 0, 240, 135],
802                      browser_args=browser_args_NV12,
803                      other_args={'pixel_format': 'NV12'},
804                      matching_algorithm=very_permissive_dc_sobel_algorithm),
805        PixelTestPage('pixel_video_vp9.html',
806                      base_name + '_DirectComposition_Video_VP9_YUY2',
807                      test_rect=[0, 0, 240, 135],
808                      browser_args=browser_args_YUY2,
809                      other_args={'pixel_format': 'YUY2'},
810                      matching_algorithm=very_permissive_dc_sobel_algorithm),
811        PixelTestPage('pixel_video_vp9.html',
812                      base_name + '_DirectComposition_Video_VP9_BGRA',
813                      test_rect=[0, 0, 240, 135],
814                      browser_args=browser_args_BGRA,
815                      other_args={'pixel_format': 'BGRA'},
816                      matching_algorithm=very_permissive_dc_sobel_algorithm),
817        PixelTestPage('pixel_video_vp9_i420a.html',
818                      base_name + '_DirectComposition_Video_VP9_I420A',
819                      test_rect=[0, 0, 240, 135],
820                      browser_args=browser_args,
821                      other_args={'no_overlay': True},
822                      matching_algorithm=strict_dc_sobel_algorithm),
823        PixelTestPage('pixel_video_vp9.html',
824                      base_name + '_DirectComposition_Video_VP9_VP_SCALING',
825                      test_rect=[0, 0, 240, 135],
826                      browser_args=browser_args_vp_scaling,
827                      other_args={'zero_copy': False},
828                      matching_algorithm=very_permissive_dc_sobel_algorithm),
829        PixelTestPage('pixel_video_underlay.html',
830                      base_name + '_DirectComposition_Underlay',
831                      test_rect=[0, 0, 240, 136],
832                      browser_args=browser_args,
833                      matching_algorithm=permissive_dc_sobel_algorithm),
834        PixelTestPage('pixel_video_underlay.html',
835                      base_name + '_DirectComposition_Underlay_DXVA',
836                      test_rect=[0, 0, 240, 136],
837                      browser_args=browser_args_DXVA,
838                      matching_algorithm=permissive_dc_sobel_algorithm),
839        PixelTestPage('pixel_video_underlay_fullsize.html',
840                      base_name + '_DirectComposition_Underlay_Fullsize',
841                      test_rect=[0, 0, 960, 540],
842                      browser_args=browser_args,
843                      matching_algorithm=strict_dc_sobel_algorithm),
844        PixelTestPage('pixel_video_mp4_rounded_corner.html',
845                      base_name + '_DirectComposition_Video_MP4_Rounded_Corner',
846                      test_rect=[0, 0, 240, 135],
847                      browser_args=browser_args,
848                      other_args={'no_overlay': True}),
849        PixelTestPage('pixel_video_backdrop_filter.html',
850                      base_name + '_DirectComposition_Video_BackdropFilter',
851                      test_rect=[0, 0, 240, 135],
852                      browser_args=browser_args,
853                      other_args={'no_overlay': True}),
854        PixelTestPage(
855            'pixel_video_mp4.html',
856            base_name + '_DirectComposition_Video_Disable_Overlays',
857            test_rect=[0, 0, 240, 135],
858            browser_args=[cba.DISABLE_DIRECT_COMPOSITION_VIDEO_OVERLAYS],
859            other_args={'no_overlay': True},
860            matching_algorithm=very_permissive_dc_sobel_algorithm),
861    ]
862
863  @staticmethod
864  def HdrTestPages(base_name):
865    return [
866        PixelTestPage(
867            'pixel_canvas2d.html',
868            base_name + '_Canvas2DRedBoxScrgbLinear',
869            test_rect=[0, 0, 300, 300],
870            browser_args=['--force-color-profile=scrgb-linear']),
871        PixelTestPage(
872            'pixel_canvas2d.html',
873            base_name + '_Canvas2DRedBoxHdr10',
874            test_rect=[0, 0, 300, 300],
875            browser_args=['--force-color-profile=hdr10']),
876    ]
877
878  @staticmethod
879  def ForceFullDamagePages(base_name):
880    return [
881        PixelTestPage(
882            'wait_for_compositing.html',
883            base_name + '_ForceFullDamage',
884            test_rect=[0, 0, 0, 0],
885            other_args={'full_damage': True},
886            browser_args=[cba.ENABLE_DIRECT_COMPOSITION_FORCE_FULL_DAMAGE]),
887        PixelTestPage(
888            'wait_for_compositing.html',
889            base_name + '_ForcePartialDamage',
890            test_rect=[0, 0, 0, 0],
891            other_args={'full_damage': False},
892            browser_args=[cba.DISABLE_DIRECT_COMPOSITION_FORCE_FULL_DAMAGE]),
893    ]
894