xref: /aosp_15_r20/external/skia/tools/testrunners/common/surface_manager/SurfaceManager.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2023 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "include/core/SkCanvas.h"
9 #include "src/core/SkColorSpacePriv.h"
10 #include "tools/ToolUtils.h"
11 #include "tools/testrunners/common/surface_manager/SurfaceManager.h"
12 
13 // Based on
14 // https://skia.googlesource.com/skia/+/88d5e1daa3ba3aae65139d4a3ded1e1b7078d59b/dm/DM.cpp#1315.
identify_gamut(SkColorSpace * cs)15 static std::string identify_gamut(SkColorSpace* cs) {
16     if (!cs) {
17         return "untagged";
18     }
19 
20     skcms_Matrix3x3 gamut;
21     if (cs->toXYZD50(&gamut)) {
22         auto eq = [](skcms_Matrix3x3 x, skcms_Matrix3x3 y) {
23             for (int i = 0; i < 3; i++) {
24                 for (int j = 0; j < 3; j++) {
25                     if (x.vals[i][j] != y.vals[i][j]) {
26                         return false;
27                     }
28                 }
29             }
30             return true;
31         };
32 
33         if (eq(gamut, SkNamedGamut::kSRGB)) {
34             return "sRGB";
35         }
36         if (eq(gamut, SkNamedGamut::kAdobeRGB)) {
37             return "Adobe";
38         }
39         if (eq(gamut, SkNamedGamut::kDisplayP3)) {
40             return "P3";
41         }
42         if (eq(gamut, SkNamedGamut::kRec2020)) {
43             return "2020";
44         }
45         if (eq(gamut, SkNamedGamut::kXYZ)) {
46             return "XYZ";
47         }
48         if (eq(gamut, gNarrow_toXYZD50)) {
49             return "narrow";
50         }
51         return "other";
52     }
53     return "non-XYZ";
54 }
55 
56 // Based on
57 // https://skia.googlesource.com/skia/+/88d5e1daa3ba3aae65139d4a3ded1e1b7078d59b/dm/DM.cpp#1341.
identify_transfer_fn(SkColorSpace * cs)58 static std::string identify_transfer_fn(SkColorSpace* cs) {
59     if (!cs) {
60         return "untagged";
61     }
62 
63     auto eq = [](skcms_TransferFunction x, skcms_TransferFunction y) {
64         return x.g == y.g && x.a == y.a && x.b == y.b && x.c == y.c && x.d == y.d && x.e == y.e &&
65                x.f == y.f;
66     };
67 
68     skcms_TransferFunction tf;
69     cs->transferFn(&tf);
70     switch (skcms_TransferFunction_getType(&tf)) {
71         case skcms_TFType_sRGBish:
72             if (tf.a == 1 && tf.b == 0 && tf.c == 0 && tf.d == 0 && tf.e == 0 && tf.f == 0) {
73                 return SkStringPrintf("gamma %.3g", tf.g).c_str();
74             }
75             if (eq(tf, SkNamedTransferFn::kSRGB)) {
76                 return "sRGB";
77             }
78             if (eq(tf, SkNamedTransferFn::kRec2020)) {
79                 return "2020";
80             }
81             return SkStringPrintf("%.3g %.3g %.3g %.3g %.3g %.3g %.3g",
82                                   tf.g,
83                                   tf.a,
84                                   tf.b,
85                                   tf.c,
86                                   tf.d,
87                                   tf.e,
88                                   tf.f)
89                     .c_str();
90 
91         case skcms_TFType_PQish:
92             if (eq(tf, SkNamedTransferFn::kPQ)) {
93                 return "PQ";
94             }
95             return SkStringPrintf("PQish %.3g %.3g %.3g %.3g %.3g %.3g",
96                                   tf.a,
97                                   tf.b,
98                                   tf.c,
99                                   tf.d,
100                                   tf.e,
101                                   tf.f)
102                     .c_str();
103 
104         case skcms_TFType_HLGish:
105             if (eq(tf, SkNamedTransferFn::kHLG)) {
106                 return "HLG";
107             }
108             return SkStringPrintf("HLGish %.3g %.3g %.3g %.3g %.3g (%.3g)",
109                                   tf.a,
110                                   tf.b,
111                                   tf.c,
112                                   tf.d,
113                                   tf.e,
114                                   tf.f + 1)
115                     .c_str();
116 
117         case skcms_TFType_HLGinvish:
118             break;
119         case skcms_TFType_Invalid:
120             break;
121     }
122     return "non-numeric";
123 }
124 
getGoldKeyValuePairs(std::string cpuName,std::string gpuName) const125 std::map<std::string, std::string> SurfaceManager::getGoldKeyValuePairs(std::string cpuName,
126                                                                         std::string gpuName) const {
127     std::map<std::string, std::string> kvPairs = {
128             {"surface_config", fConfig},
129             {"gamut", identify_gamut(fColorInfo.colorSpace())},
130             {"transfer_fn", identify_transfer_fn(fColorInfo.colorSpace())},
131             {"color_type", std::string(ToolUtils::colortype_name(fColorInfo.colorType()))},
132             {"alpha_type", std::string(ToolUtils::alphatype_name(fColorInfo.alphaType()))},
133             {"color_depth", std::string(ToolUtils::colortype_depth(fColorInfo.colorType()))},
134     };
135     kvPairs.merge(getCpuOrGpuKeyValuePairs(cpuName, gpuName));
136     return kvPairs;
137 }
138 
getPerfKeyValuePairs(std::string cpuName,std::string gpuName) const139 std::map<std::string, std::string> SurfaceManager::getPerfKeyValuePairs(std::string cpuName,
140                                                                         std::string gpuName) const {
141     return getCpuOrGpuKeyValuePairs(cpuName, gpuName);
142 }
143 
getCpuOrGpuKeyValuePairs(std::string cpuName,std::string gpuName) const144 std::map<std::string, std::string> SurfaceManager::getCpuOrGpuKeyValuePairs(
145         std::string cpuName, std::string gpuName) const {
146     // Leave these keys unset if the CPU or GPU name is not provided and the config is CPU or GPU
147     // bound, respectively. It is up to each test runner to print a warning informing the user of
148     // this behavior.
149     if ((fCpuOrGpu == CpuOrGpu::kCPU && cpuName == "") ||
150         (fCpuOrGpu == CpuOrGpu::kGPU && gpuName == "")) {
151         return std::map<std::string, std::string>();
152     }
153 
154     return std::map<std::string, std::string>{
155             {"cpu_or_gpu", fCpuOrGpu == CpuOrGpu::kCPU ? "CPU" : "GPU"},
156             {"cpu_or_gpu_value", fCpuOrGpu == CpuOrGpu::kCPU ? cpuName : gpuName},
157     };
158 }
159 
isCpuOrGpuBound() const160 SurfaceManager::CpuOrGpu SurfaceManager::isCpuOrGpuBound() const { return fCpuOrGpu; }
161