Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
CombinationBuilderTest.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
8#include "tests/Test.h"
9
10#if defined(SK_GRAPHITE)
11
23
24#include <array>
25
26using namespace::skgpu::graphite;
27
28namespace {
29
30// The default PaintOptions should create a single combination with a solid color shader and
31// kSrcOver blending
32void empty_test(const KeyContext& keyContext,
33 PipelineDataGatherer* gatherer,
35 PaintOptions paintOptions;
36
37 REPORTER_ASSERT(reporter, paintOptions.priv().numCombinations() == 1);
38
39 std::vector<UniquePaintParamsID> precompileIDs;
40 paintOptions.priv().buildCombinations(keyContext,
41 gatherer,
42 DrawTypeFlags::kNone,
43 /* withPrimitiveBlender= */ false,
44 Coverage::kNone,
45 [&precompileIDs](UniquePaintParamsID id,
46 DrawTypeFlags,
47 bool /* withPrimitiveBlender */,
48 Coverage) {
49 precompileIDs.push_back(id);
50 });
51
52 SkASSERT(precompileIDs.size() == 1);
53}
54
55// A PaintOptions will supply a default solid color shader if needed.
56void no_shader_option_test(const KeyContext& keyContext,
57 PipelineDataGatherer* gatherer,
59 SkBlendMode blendModes[] = { SkBlendMode::kSrcOver };
60
61 PaintOptions paintOptions;
62 paintOptions.setBlendModes(blendModes);
63
64 REPORTER_ASSERT(reporter, paintOptions.priv().numCombinations() == 1);
65
66 std::vector<UniquePaintParamsID> precompileIDs;
67 paintOptions.priv().buildCombinations(keyContext,
68 gatherer,
69 DrawTypeFlags::kNone,
70 /* withPrimitiveBlender= */ false,
71 Coverage::kNone,
72 [&precompileIDs](UniquePaintParamsID id,
73 DrawTypeFlags,
74 bool /* withPrimitiveBlender */,
75 Coverage) {
76 precompileIDs.push_back(id);
77 });
78
79 SkASSERT(precompileIDs.size() == 1);
80}
81
82// A default kSrcOver blend mode will be supplied if no other blend options are added
83void no_blend_mode_option_test(const KeyContext& keyContext,
84 PipelineDataGatherer* gatherer,
86 PaintOptions paintOptions;
87 paintOptions.setShaders({ PrecompileShaders::Color() });
88
89 REPORTER_ASSERT(reporter, paintOptions.priv().numCombinations() == 1);
90
91 std::vector<UniquePaintParamsID> precompileIDs;
92 paintOptions.priv().buildCombinations(keyContext,
93 gatherer,
94 DrawTypeFlags::kNone,
95 /* withPrimitiveBlender= */ false,
96 Coverage::kNone,
97 [&precompileIDs](UniquePaintParamsID id,
98 DrawTypeFlags,
99 bool /* withPrimitiveBlender */,
100 Coverage) {
101 precompileIDs.push_back(id);
102 });
103
104 SkASSERT(precompileIDs.size() == 1);
105}
106
107void big_test(const KeyContext& keyContext,
108 PipelineDataGatherer* gatherer,
110 // paintOptions (256)
111 // |- sweepGrad_0 (4) | blendShader_0 (60)
112 // | 0: kSrc (1)
113 // | 1: (dsts) linearGrad_0 (2) | solid_0 (1)
114 // | 2: (srcs) linearGrad_1 (2) | blendShader_1 (18)
115 // | 0: kDst (1)
116 // | 1: (dsts) radGrad_0 (2) | solid_1 (1)
117 // | 2: (srcs) imageShader_0 (6)
118 // |
119 // |- 4-built-in-blend-modes
120
121 PaintOptions paintOptions;
122
123 // first, shaders. First top-level option (sweepGrad_0)
124 sk_sp<PrecompileShader> sweepGrad_0 = PrecompileShaders::SweepGradient();
125
126 std::array<SkBlendMode, 1> blendModes{ SkBlendMode::kSrc };
127
128 std::vector<SkBlendMode> moreBlendModes{ SkBlendMode::kDst };
129
130 // Second top-level option (blendShader_0)
131 auto blendShader_0 = PrecompileShaders::Blend(
132 SkSpan<SkBlendMode>(blendModes), // std::array
133 { // initializer_list
134 PrecompileShadersPriv::LinearGradient(/* withLM= */ true),
135 PrecompileShaders::Color()
136 },
137 {
138 PrecompileShadersPriv::LinearGradient(/* withLM= */ true),
139 PrecompileShaders::Blend(
140 SkSpan<SkBlendMode>(moreBlendModes),// std::vector
141 {
142 PrecompileShadersPriv::RadialGradient(/* withLM= */ true),
143 PrecompileShaders::Color()
144 },
145 {
146 PrecompileShaders::Image()
147 })
148 });
149
150 paintOptions.setShaders({ sweepGrad_0, blendShader_0 });
151
152 SkBlendMode evenMoreBlendModes[] = {
157 };
158
159 // now, blend modes
160 paintOptions.setBlendModes(evenMoreBlendModes); // c array
161
162 REPORTER_ASSERT(reporter, paintOptions.priv().numCombinations() == 256,
163 "Actual # of combinations %d", paintOptions.priv().numCombinations());
164
165 std::vector<UniquePaintParamsID> precompileIDs;
166 paintOptions.priv().buildCombinations(keyContext,
167 gatherer,
168 DrawTypeFlags::kNone,
169 /* withPrimitiveBlender= */ false,
170 Coverage::kNone,
171 [&precompileIDs](UniquePaintParamsID id,
172 DrawTypeFlags,
173 bool /* withPrimitiveBlender */,
174 Coverage) {
175 precompileIDs.push_back(id);
176 });
177
178 SkASSERT(precompileIDs.size() == 256);
179}
180
181template <typename T>
182std::vector<sk_sp<T>> create_runtime_combos(
184 SkRuntimeEffect::Result effectFactory(SkString),
185 sk_sp<T> precompileFactory(sk_sp<SkRuntimeEffect>,
187 const char* redCode,
188 const char* greenCode,
189 const char* combineCode) {
190 auto [redEffect, error1] = effectFactory(SkString(redCode));
191 REPORTER_ASSERT(reporter, redEffect, "%s", error1.c_str());
192 auto [greenEffect, error2] = effectFactory(SkString(greenCode));
193 REPORTER_ASSERT(reporter, greenEffect, "%s", error2.c_str());
194 auto [combineEffect, error3] = effectFactory(SkString(combineCode));
195 REPORTER_ASSERT(reporter, combineEffect, "%s", error3.c_str());
196
197 sk_sp<T> red = precompileFactory(redEffect, {});
199
200 sk_sp<T> green = precompileFactory(greenEffect, {});
202
203 sk_sp<T> combine = precompileFactory(combineEffect, { { red, green }, { green, red } });
204 REPORTER_ASSERT(reporter, combine);
205
206 return { combine };
207}
208
209void runtime_effect_test(const KeyContext& keyContext,
210 PipelineDataGatherer* gatherer,
212 // paintOptions (8)
213 // |- combineShader (2)
214 // | 0: redShader | greenShader
215 // | 1: greenShader | redShader
216 // |
217 // |- combineColorFilter (2)
218 // | 0: redColorFilter | greenColorFilter
219 // | 1: greenColorFilter | redColorFilter
220 // |
221 // |- combineBlender (2)
222 // | 0: redBlender | greenBlender
223 // | 1: greenBlender | redBlender
224
225 PaintOptions paintOptions;
226
227 // shaders
228 {
229 static const char* kRedS = R"(
230 half4 main(vec2 fragcoord) { return half4(.5, 0, 0, .5); }
231 )";
232 static const char* kGreenS = R"(
233 half4 main(vec2 fragcoord) { return half4(0, .5, 0, .5); }
234 )";
235
236 static const char* kCombineS = R"(
237 uniform shader first;
238 uniform shader second;
239 half4 main(vec2 fragcoords) {
240 return first.eval(fragcoords) + second.eval(fragcoords);
241 }
242 )";
243
244 std::vector<sk_sp<PrecompileShader>> combinations =
245 create_runtime_combos<PrecompileShader>(reporter,
247 MakePrecompileShader,
248 kRedS,
249 kGreenS,
250 kCombineS);
251 paintOptions.setShaders(combinations);
252 }
253
254 // color filters
255 {
256 static const char* kRedCF = R"(
257 half4 main(half4 color) { return half4(.5, 0, 0, .5); }
258 )";
259 static const char* kGreenCF = R"(
260 half4 main(half4 color) { return half4(0, .5, 0, .5); }
261 )";
262
263 static const char* kCombineCF = R"(
264 uniform colorFilter first;
265 uniform colorFilter second;
266 half4 main(half4 color) { return first.eval(color) + second.eval(color); }
267 )";
268
269 std::vector<sk_sp<PrecompileColorFilter>> combinations =
270 create_runtime_combos<PrecompileColorFilter>(reporter,
272 MakePrecompileColorFilter,
273 kRedCF,
274 kGreenCF,
275 kCombineCF);
276 paintOptions.setColorFilters(combinations);
277 }
278
279 // blenders
280 {
281 static const char* kRedB = R"(
282 half4 main(half4 src, half4 dst) { return half4(.5, 0, 0, .5); }
283 )";
284 static const char* kGreenB = R"(
285 half4 main(half4 src, half4 dst) { return half4(0, .5, 0, .5); }
286 )";
287
288 static const char* kCombineB = R"(
289 uniform blender first;
290 uniform blender second;
291 half4 main(half4 src, half4 dst) {
292 return first.eval(src, dst) + second.eval(src, dst);
293 }
294 )";
295
296 std::vector<sk_sp<PrecompileBlender>> combinations =
297 create_runtime_combos<PrecompileBlender>(reporter,
299 MakePrecompileBlender,
300 kRedB,
301 kGreenB,
302 kCombineB);
303 paintOptions.setBlenders(combinations);
304 }
305
306 REPORTER_ASSERT(reporter, paintOptions.priv().numCombinations() == 8);
307
308 std::vector<UniquePaintParamsID> precompileIDs;
309 paintOptions.priv().buildCombinations(keyContext,
310 gatherer,
311 DrawTypeFlags::kNone,
312 /* withPrimitiveBlender= */ false,
313 Coverage::kNone,
314 [&precompileIDs](UniquePaintParamsID id,
315 DrawTypeFlags,
316 bool /* withPrimitiveBlender */,
317 Coverage) {
318 precompileIDs.push_back(id);
319 });
320
321 SkASSERT(precompileIDs.size() == 8);
322}
323
324} // anonymous namespace
325
326DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(CombinationBuilderTest, reporter, context,
328 ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
329
330 auto rtEffectDict = std::make_unique<RuntimeEffectDictionary>();
331
333 KeyContext keyContext(context->priv().caps(),
334 dict,
335 rtEffectDict.get(),
336 ci,
337 /* dstTexture= */ nullptr,
338 /* dstOffset= */ {0, 0});
339
340 PipelineDataGatherer gatherer(Layout::kMetal);
341
342 empty_test(keyContext, &gatherer, reporter);
343 no_shader_option_test(keyContext, &gatherer, reporter);
344 no_blend_mode_option_test(keyContext, &gatherer, reporter);
345 big_test(keyContext, &gatherer, reporter);
346 runtime_effect_test(keyContext, &gatherer, reporter);
347}
348
349#endif // SK_GRAPHITE
reporter
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
#define SkASSERT(cond)
Definition SkAssert.h:116
SkBlendMode
Definition SkBlendMode.h:38
@ kSrcOver
r = s + (1-sa)*d
@ kDstOver
r = d + (1-da)*s
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
#define DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(name, reporter, graphite_ctx, ctsEnforcement)
Definition Test.h:373
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
static Result MakeForColorFilter(SkString sksl, const Options &)
static Result MakeForBlender(SkString sksl, const Options &)
static Result MakeForShader(SkString sksl, const Options &)