Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
RasterPipelineCodeGeneratorTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 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
15#include "src/sksl/SkSLUtil.h"
21#include "tests/Test.h"
22
23#include <memory>
24#include <optional>
25#include <string>
26
27//#define DUMP_PROGRAMS 1
28#if defined(DUMP_PROGRAMS)
30#endif
31
32static void test(skiatest::Reporter* r,
33 const char* src,
34 SkSpan<const float> uniforms,
35 SkColor4f startingColor,
36 std::optional<SkColor4f> expectedResult) {
38 SkSL::ProgramSettings settings;
39 settings.fMaxVersionAllowed = SkSL::Version::k300;
40 std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
41 SkSL::ProgramKind::kRuntimeColorFilter, std::string(src), settings);
42 if (!program) {
43 ERRORF(r, "Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
44 return;
45 }
46 const SkSL::FunctionDeclaration* main = program->getFunction("main");
47 if (!main) {
48 ERRORF(r, "Program must have a 'main' function");
49 return;
50 }
51 SkArenaAlloc alloc(/*firstHeapAllocation=*/1000);
52 SkRasterPipeline pipeline(&alloc);
53 pipeline.appendConstantColor(&alloc, startingColor);
54 SkSL::DebugTracePriv debugTrace;
55 std::unique_ptr<SkSL::RP::Program> rasterProg =
56 SkSL::MakeRasterPipelineProgram(*program, *main->definition(), &debugTrace);
57 if (!rasterProg && !expectedResult.has_value()) {
58 // We didn't get a program, as expected. Test passes.
59 return;
60 }
61 if (!rasterProg && expectedResult.has_value()) {
62 ERRORF(r, "MakeRasterPipelineProgram failed");
63 return;
64 }
65 if (rasterProg && !expectedResult.has_value()) {
66 ERRORF(r, "MakeRasterPipelineProgram should have failed, but didn't");
67 return;
68 }
69
70#if defined(DUMP_PROGRAMS)
71 // Dump the program instructions via SkDebugf.
72 SkDebugf("-----\n\n");
73 SkDebugfStream stream;
74 rasterProg->dump(&stream);
75 SkDebugf("\n-----\n\n");
76#endif
77
78 // Append the SkSL program to the raster pipeline.
79 rasterProg->appendStages(&pipeline, &alloc, /*callbacks=*/nullptr, uniforms);
80
81 // Move the float values from RGBA into an 8888 memory buffer.
82 uint32_t out[SkRasterPipeline_kMaxStride_highp] = {};
83 SkRasterPipeline_MemoryCtx outCtx{/*pixels=*/out, /*stride=*/SkRasterPipeline_kMaxStride_highp};
84 pipeline.append(SkRasterPipelineOp::store_8888, &outCtx);
85 pipeline.run(0, 0, 1, 1);
86
87 // Make sure the first pixel (exclusively) of `out` matches RGBA.
88 uint32_t expected = expectedResult->toBytes_RGBA();
89 REPORTER_ASSERT(r, out[0] == expected,
90 "Got:%02X%02X%02X%02X Expected:%02X%02X%02X%02X",
91 (out[0] >> 24) & 0xFF,
92 (out[0] >> 16) & 0xFF,
93 (out[0] >> 8) & 0xFF,
94 out[0] & 0xFF,
95 (expected >> 24) & 0xFF,
96 (expected >> 16) & 0xFF,
97 (expected >> 8) & 0xFF,
98 expected & 0xFF);
99
100 // Make sure the rest of the pixels are untouched.
101 for (size_t i = 1; i < std::size(out); ++i) {
102 REPORTER_ASSERT(r, out[i] == 0);
103 }
104}
105
106DEF_TEST(SkSLRasterPipelineCodeGeneratorNestedTernaryTest, r) {
107 // Add in your SkSL here.
108 test(r,
109 R"__SkSL__(
110 half4 main(half4) {
111 half three = 3, one = 1, two = 2;
112 half result = (three > (one > two ? 2.0 : 5.0)) ? 1.0 : 0.499;
113 return half4(result);
114 }
115 )__SkSL__",
116 /*uniforms=*/{},
117 /*startingColor=*/SkColor4f{0.0, 0.0, 0.0, 0.0},
118 /*expectedResult=*/SkColor4f{0.499f, 0.499f, 0.499f, 0.499f});
119}
120
121DEF_TEST(SkSLRasterPipelineCodeGeneratorArithmeticTest, r) {
122 test(r,
123 R"__SkSL__(
124 half4 main(half4) {
125 const half4 colorGreen = half4(0,1,0,1), colorRed = half4(1,0,0,1);
126
127 half a = 3.0, b = 4.0, c = a + b - 2.0;
128 if (a*a + b*b == c*c*c/5.0) {
129 int A = 3, B = 4, C = A + B - 2;
130 if (A*A + B*B == C*C*C/5) {
131 return colorGreen;
132 }
134
135 return colorRed;
136 }
137 )__SkSL__",
138 /*uniforms=*/{},
139 /*startingColor=*/SkColor4f{0.0, 0.0, 0.0, 0.0},
140 /*expectedResult=*/SkColor4f{0.0f, 1.0f, 0.0f, 1.0f});
141}
142
143DEF_TEST(SkSLRasterPipelineCodeGeneratorCoercedTypeTest, r) {
144 static constexpr float kUniforms[] = {0.0, 1.0, 0.0, 1.0,
145 1.0, 0.0, 0.0, 1.0};
146 test(r,
147 R"__SkSL__(
148 uniform half4 colorGreen;
149 uniform float4 colorRed;
150 half4 main(half4 color) {
151 return ((colorGreen + colorRed) == float4(1.0, 1.0, 0.0, 2.0)) ? colorGreen
152 : colorGreen.gr01;
153 }
154 )__SkSL__",
155 kUniforms,
156 /*startingColor=*/SkColor4f{0.0, 0.0, 0.0, 0.0},
157 /*expectedResult=*/SkColor4f{0.0, 1.0, 0.0, 1.0});
158}
159
160DEF_TEST(SkSLRasterPipelineCodeGeneratorIdentitySwizzle, r) {
161 static constexpr float kUniforms[] = {0.0, 1.0, 0.0, 1.0,
162 1.0, 0.0, 0.0, 1.0};
163 test(r,
164 R"__SkSL__(
165
166uniform half4 colorGreen, colorRed;
167
168const int SEVEN = 7, TEN = 10;
169const half4x4 MATRIXFIVE = half4x4(5);
170
171noinline bool verify_const_globals(int seven, int ten, half4x4 matrixFive) {
172 return seven == 7 && ten == 10 && matrixFive == half4x4(5);
173}
174
175half4 main(float4) {
176 return verify_const_globals(SEVEN, TEN, MATRIXFIVE) ? colorGreen : colorRed;
177}
178
179 )__SkSL__",
180 kUniforms,
181 /*startingColor=*/SkColor4f{0.5, 1.0, 0.0, 0.25},
182 /*expectedResult=*/SkColor4f{0.0, 1.0, 0.0, 1.0});
183
184}
185
186DEF_TEST(SkSLRasterPipelineCodeGeneratorBitwiseNotTest, r) {
187 static constexpr int32_t kUniforms[] = { 0, 12, 3456, 4567890,
188 ~0, ~12, ~3456, ~4567890};
189 test(r,
190 R"__SkSL__(
191 uniform int4 value, expected;
192 const half4 colorGreen = half4(0,1,0,1), colorRed = half4(1,0,0,1);
193
194 half4 main(vec4) {
195 return (~value.x == expected.x &&
196 ~value.xy == expected.xy &&
197 ~value.xyz == expected.xyz &&
198 ~value.xyzw == expected.xyzw) ? colorGreen : colorRed;
199 }
200 )__SkSL__",
201 SkSpan((const float*)kUniforms, std::size(kUniforms)),
202 /*startingColor=*/SkColor4f{0.0, 0.0, 0.0, 0.0},
203 /*expectedResult=*/SkColor4f{0.0, 1.0, 0.0, 1.0});
204}
205
206DEF_TEST(SkSLRasterPipelineCodeGeneratorComparisonIntrinsicTest, r) {
207 test(r,
208 R"__SkSL__(
209 half4 main(vec4) {
210 const half4 colorGreen = half4(0,1,0,1), colorRed = half4(1,0,0,1);
211 half4 a = half4(1, 2, 0, 1),
212 b = half4(2, 2, 1, 0);
213 int3 c = int3(1111, 3333, 5555),
214 d = int3(1111, 5555, 3333);
215 uint2 e = uint2(1111111111u, 222),
216 f = uint2(3333333333u, 222);
217 return (lessThan(a, b) == bool4(true, false, true, false) &&
218 lessThan(c, d) == bool3(false, true, false) &&
219 lessThan(e, f) == bool2(true, false) &&
220 greaterThan(a, b) == bool4(false, false, false, true) &&
221 greaterThan(c, d) == bool3(false, false, true) &&
222 greaterThan(e, f) == bool2(false, false) &&
223 lessThanEqual(a, b) == bool4(true, true, true, false) &&
224 lessThanEqual(c, d) == bool3(true, true, false) &&
225 lessThanEqual(e, f) == bool2(true, true) &&
226 greaterThanEqual(a, b) == bool4(false, true, false, true) &&
227 greaterThanEqual(c, d) == bool3(true, false, true) &&
228 greaterThanEqual(e, f) == bool2(false, true) &&
229 equal(a, b) == bool4(false, true, false, false) &&
230 equal(c, d) == bool3(true, false, false) &&
231 equal(e, f) == bool2(false, true) &&
232 notEqual(a, b) == bool4(true, false, true, true) &&
233 notEqual(c, d) == bool3(false, true, true) &&
234 notEqual(e, f) == bool2(true, false) &&
235 max(a, b) == half4(2, 2, 1, 1) &&
236 max(c, d) == int3(1111, 5555, 5555) &&
237 max(e, f) == uint2(3333333333u, 222) &&
238 max(a, 1) == half4(1, 2, 1, 1) &&
239 max(c, 3333) == int3(3333, 3333, 5555) &&
240 max(e, 7777) == uint2(1111111111u, 7777) &&
241 min(a, b) == half4(1, 2, 0, 0) &&
242 min(c, d) == int3(1111, 3333, 3333) &&
243 min(e, f) == uint2(1111111111u, 222) &&
244 min(a, 1) == half4(1, 1, 0, 1) &&
245 min(c, 3333) == int3(1111, 3333, 3333) &&
246 min(e, 7777) == uint2(7777, 222)) ? colorGreen : colorRed;
247 }
248 )__SkSL__",
249 /*uniforms=*/{},
250 /*startingColor=*/SkColor4f{0.0, 0.0, 0.0, 0.0},
251 /*expectedResult=*/SkColor4f{0.0, 1.0, 0.0, 1.0});
252}
#define test(name)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static constexpr int SkRasterPipeline_kMaxStride_highp
#define DEF_TEST(name, reporter)
Definition Test.h:312
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
#define ERRORF(r,...)
Definition Test.h:293
void run(size_t x, size_t y, size_t w, size_t h) const
void append(SkRasterPipelineOp, void *=nullptr)
void appendConstantColor(SkArenaAlloc *, const float rgba[4])
std::unique_ptr< RP::Program > MakeRasterPipelineProgram(const SkSL::Program &program, const FunctionDefinition &function, DebugTracePriv *debugTrace, bool writeTraceOps)
Definition main.py:1