1cb93a386Sopenharmony_ciSkQP Render Test Algorithm
2cb93a386Sopenharmony_ci==========================
3cb93a386Sopenharmony_ci
4cb93a386Sopenharmony_ciThe following is a description of the render test validation algorithm that
5cb93a386Sopenharmony_ciwill be used by the version of SkQP that will be released for Android Q-release.
6cb93a386Sopenharmony_ci
7cb93a386Sopenharmony_ciThere is a global macro constant: `SK_SKQP_GLOBAL_ERROR_TOLERANCE`, which
8cb93a386Sopenharmony_cireflects the `gn` variable `skia_skqp_global_error_tolerance`.  This is usually
9cb93a386Sopenharmony_ciset to 8.
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ciFirst, look for a file named `skqp/rendertests.txt` in the
12cb93a386Sopenharmony_ci`platform_tools/android/apps/skqp/src/main/assets` directory.  The format of
13cb93a386Sopenharmony_cithis file is:  each line contains one render test name, followed by a comma,
14cb93a386Sopenharmony_cifollowed by an integer.  The integer is the `passing_threshold` for that test.
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ciFor each test, we have a `max_image` and a `min_image`.  These are PNG-encoded
17cb93a386Sopenharmony_ciimages stored in SkQP's APK's asset directory (in the paths `gmkb/${TEST}/min.png`
18cb93a386Sopenharmony_ciand `gmkb/${TEST}/max.png`).
19cb93a386Sopenharmony_ci
20cb93a386Sopenharmony_ciThe test input is a rendered image.  This will be produced by running one of
21cb93a386Sopenharmony_cithe render tests against the either the `vk` (Vulkan) or `gles` (OpenGL ES)
22cb93a386Sopenharmony_ciSkia backend.
23cb93a386Sopenharmony_ci
24cb93a386Sopenharmony_ciHere is psuedocode for the error calculation:
25cb93a386Sopenharmony_ci
26cb93a386Sopenharmony_ci    function calculate_pixel_error(pixel_value, pixel_max, pixel_min):
27cb93a386Sopenharmony_ci        pixel_error = 0
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ci        for color_channel in { red, green, blue, alpha }:
30cb93a386Sopenharmony_ci            value = get_color(pixel_value, color_channel)
31cb93a386Sopenharmony_ci            v_max = get_color(pixel_max,   color_channel)
32cb93a386Sopenharmony_ci            v_min = get_color(pixel_min,   color_channel)
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_ci            if value > v_max:
35cb93a386Sopenharmony_ci                channel_error = value - v_max
36cb93a386Sopenharmony_ci            elif value < v_min:
37cb93a386Sopenharmony_ci                channel_error = v_min - value
38cb93a386Sopenharmony_ci            else:
39cb93a386Sopenharmony_ci                channel_error = 0
40cb93a386Sopenharmony_ci            pixel_error = max(pixel_error, channel_error)
41cb93a386Sopenharmony_ci
42cb93a386Sopenharmony_ci        return max(0, pixel_error - SK_SKQP_GLOBAL_ERROR_TOLERANCE);
43cb93a386Sopenharmony_ci
44cb93a386Sopenharmony_ci    function get_error(rendered_image, max_image, min_image):
45cb93a386Sopenharmony_ci        assert(dimensions(rendered_image) == dimensions(max_image))
46cb93a386Sopenharmony_ci        assert(dimensions(rendered_image) == dimensions(min_image))
47cb93a386Sopenharmony_ci
48cb93a386Sopenharmony_ci        max_error = 0
49cb93a386Sopenharmony_ci        bad_pixels = 0
50cb93a386Sopenharmony_ci        total_error = 0
51cb93a386Sopenharmony_ci
52cb93a386Sopenharmony_ci        error_image = allocate_bitmap(dimensions(rendered_image))
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_ci        for xy in list_all_pixel_coordinates(rendered_image):
55cb93a386Sopenharmony_ci            pixel_error = calculate_pixel_error(rendered_image(xy),
56cb93a386Sopenharmony_ci                                                max_image(xy),
57cb93a386Sopenharmony_ci                                                min_image(xy))
58cb93a386Sopenharmony_ci            if pixel_error > 0:
59cb93a386Sopenharmony_ci                for neighboring_xy in find_neighbors(xy):
60cb93a386Sopenharmony_ci                    if not inside(neighboring_xy, dimensions(rendered_image)):
61cb93a386Sopenharmony_ci                        continue
62cb93a386Sopenharmony_ci                    pixel_error = min(pixel_error,
63cb93a386Sopenharmony_ci                                      calculate_pixel_error(rendered_image(xy),
64cb93a386Sopenharmony_ci                                                            max_image(neighboring_xy),
65cb93a386Sopenharmony_ci                                                            min_image(neighboring_xy)))
66cb93a386Sopenharmony_ci
67cb93a386Sopenharmony_ci            if pixel_error > 0:
68cb93a386Sopenharmony_ci                max_error = max(max_error, pixel_error)
69cb93a386Sopenharmony_ci                bad_pixels += 1
70cb93a386Sopenharmony_ci                total_error += pixel_error
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_ci                error_image(xy) = linear_interpolation(black, red, pixel_error)
73cb93a386Sopenharmony_ci            else:
74cb93a386Sopenharmony_ci                error_image(xy) = white
75cb93a386Sopenharmony_ci
76cb93a386Sopenharmony_ci        return ((total_error, max_error, bad_pixels), error_image)
77cb93a386Sopenharmony_ci
78cb93a386Sopenharmony_ciFor each render test, there is a threshold value for `total_error`, :
79cb93a386Sopenharmony_ci`passing_threshold`.
80cb93a386Sopenharmony_ci
81cb93a386Sopenharmony_ciIf `passing_threshold >= 0 && total_error > passing_threshold`, then the test
82cb93a386Sopenharmony_ciis a failure and is included in the report.  if `passing_threshold == -1`, then
83cb93a386Sopenharmony_cithe test always passes, but we do execute the test to verify that the driver
84cb93a386Sopenharmony_cidoes not crash.
85cb93a386Sopenharmony_ci
86cb93a386Sopenharmony_ciWe generate a report with the following information for each test:
87cb93a386Sopenharmony_ci
88cb93a386Sopenharmony_ci    backend_name,render_test_name,max_error,bad_pixels,total_error
89cb93a386Sopenharmony_ci
90cb93a386Sopenharmony_ciin CSV format in the file `out.csv`.  A HTML report of just the failing tests
91cb93a386Sopenharmony_ciis written to the file `report.html`.  This version includes four images for
92cb93a386Sopenharmony_cieach test:  `rendered_image`, `max_image`, `min_image`, and `error_image`, as
93cb93a386Sopenharmony_ciwell as the three metrics: `max_error`, `bad_pixels`, and `total_error`.
94cb93a386Sopenharmony_ci
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_ci
97