1 /*
2 * Copyright 2024 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
12 #include "include/gpu/graphite/Context.h"
13 #include "src/gpu/graphite/ContextPriv.h"
14 #include "src/gpu/graphite/ContextUtils.h"
15 #include "src/gpu/graphite/GraphicsPipelineDesc.h"
16 #include "src/gpu/graphite/PrecompileContextPriv.h"
17 #include "src/gpu/graphite/RenderPassDesc.h"
18 #include "src/gpu/graphite/RendererProvider.h"
19 #include "tools/graphite/UniqueKeyUtils.h"
20
21 /*** From here to the matching banner can be cut and pasted into Chrome's graphite_precompile.cc **/
22 #include "include/gpu/graphite/PrecompileContext.h"
23 #include "include/gpu/graphite/precompile/PaintOptions.h"
24 #include "include/gpu/graphite/precompile/Precompile.h"
25 #include "include/gpu/graphite/precompile/PrecompileColorFilter.h"
26 #include "include/gpu/graphite/precompile/PrecompileShader.h"
27
28 namespace {
29
30 using ::skgpu::graphite::DepthStencilFlags;
31 using ::skgpu::graphite::DrawTypeFlags;
32 using ::skgpu::graphite::PaintOptions;
33 using ::skgpu::graphite::RenderPassProperties;
34
35 // "SolidColor SrcOver"
solid_srcover()36 PaintOptions solid_srcover() {
37 PaintOptions paintOptions;
38 paintOptions.setBlendModes({ SkBlendMode::kSrcOver });
39 return paintOptions;
40 }
41
42 // "SolidColor SrcOver"
43 // "SolidColor Src"
44 // "SolidColor Clear"
solid_clear_src_srcover()45 PaintOptions solid_clear_src_srcover() {
46 PaintOptions paintOptions;
47 paintOptions.setBlendModes({ SkBlendMode::kClear,
48 SkBlendMode::kSrc,
49 SkBlendMode::kSrcOver });
50 return paintOptions;
51 }
52
53 // "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] SrcOver"
54 // "LocalMatrix [ Compose [ Image(0) ColorSpaceTransformPremul ] ] SrcOver"
image_premul_srcover()55 PaintOptions image_premul_srcover() {
56 SkColorInfo ci { kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr };
57 PaintOptions paintOptions;
58 paintOptions.setShaders({ skgpu::graphite::PrecompileShaders::Image({ &ci, 1 }) });
59 paintOptions.setBlendModes({ SkBlendMode::kSrcOver });
60 return paintOptions;
61 }
62
63 // "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] Src"
64 // "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] SrcOver"
65 // "LocalMatrix [ Compose [ Image(0) ColorSpaceTransformPremul ] ] SrcOver"
image_premul_src_srcover()66 PaintOptions image_premul_src_srcover() {
67 SkColorInfo ci { kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr };
68 PaintOptions paintOptions;
69 paintOptions.setShaders({ skgpu::graphite::PrecompileShaders::Image({ &ci, 1 }) });
70 paintOptions.setBlendModes({ SkBlendMode::kSrc,
71 SkBlendMode::kSrcOver });
72 return paintOptions;
73 }
74
75 // "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformSRGB ] ] Src"
image_srgb_src()76 PaintOptions image_srgb_src() {
77 SkColorInfo ci { kRGBA_8888_SkColorType,
78 kPremul_SkAlphaType,
79 SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,
80 SkNamedGamut::kAdobeRGB) };
81 PaintOptions paintOptions;
82 paintOptions.setShaders({ skgpu::graphite::PrecompileShaders::Image({ &ci, 1 }) });
83 paintOptions.setBlendModes({ SkBlendMode::kSrc });
84 return paintOptions;
85 }
86
87 // "Compose [ SolidColor BlendCompose [ SolidColor Passthrough PorterDuffBlender ] ] SrcOver"
blend_porter_duff_cf_srcover()88 PaintOptions blend_porter_duff_cf_srcover() {
89 PaintOptions paintOptions;
90 // kSrcOver will trigger the PorterDuffBlender
91 paintOptions.setColorFilters(
92 { skgpu::graphite::PrecompileColorFilters::Blend({ SkBlendMode::kSrcOver }) });
93 paintOptions.setBlendModes({ SkBlendMode::kSrcOver });
94
95 return paintOptions;
96 }
97
98 // "RP(color: Dawn(f=R8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: a000)",
99 // Single sampled R w/ just depth
100 const RenderPassProperties kR_1_D { DepthStencilFlags::kDepth,
101 kAlpha_8_SkColorType,
102 /* fDstCS= */ nullptr,
103 /* fRequiresMSAA= */ false };
104
105 // "RP(color: Dawn(f=R8,s=4), resolve: Dawn(f=R8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: a000)",
106 // MSAA R w/ depth and stencil
107 const RenderPassProperties kR_4_DS { DepthStencilFlags::kDepthStencil,
108 kAlpha_8_SkColorType,
109 /* fDstCS= */ nullptr,
110 /* fRequiresMSAA= */ true };
111
112 // "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba)"
113 // Single sampled BGRA w/ just depth
114 const RenderPassProperties kBGRA_1_D { DepthStencilFlags::kDepth,
115 kBGRA_8888_SkColorType,
116 /* fDstCS= */ nullptr,
117 /* fRequiresMSAA= */ false };
118
119 // "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba)"
120 // MSAA BGRA w/ just depth
121 const RenderPassProperties kBGRA_4_D { DepthStencilFlags::kDepth,
122 kBGRA_8888_SkColorType,
123 /* fDstCS= */ nullptr,
124 /* fRequiresMSAA= */ true };
125
126 // "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba)"
127 // MSAA BGRA w/ depth and stencil
128 const RenderPassProperties kBGRA_4_DS { DepthStencilFlags::kDepthStencil,
129 kBGRA_8888_SkColorType,
130 /* fDstCS= */ nullptr,
131 /* fRequiresMSAA= */ true };
132
133 // The same as kBGRA_1_D but w/ an SRGB colorSpace
134 const RenderPassProperties kBGRA_1_D_SRGB { DepthStencilFlags::kDepth,
135 kBGRA_8888_SkColorType,
136 SkColorSpace::MakeSRGB(),
137 /* fRequiresMSAA= */ false };
138
139 const struct PrecompileSettings {
140 PaintOptions fPaintOptions;
141 DrawTypeFlags fDrawTypeFlags = DrawTypeFlags::kNone;
142 RenderPassProperties fRenderPassProps;
143 } kPrecompileCases[] = {
144 { blend_porter_duff_cf_srcover(), DrawTypeFlags::kNone, kBGRA_1_D }, // unused
145 { blend_porter_duff_cf_srcover(), DrawTypeFlags::kNonSimpleShape, kBGRA_1_D }, // 13
146 { solid_srcover(), DrawTypeFlags::kNonSimpleShape, kR_4_DS }, // 2,3
147 { solid_srcover(), DrawTypeFlags::kBitmapText_Mask, kBGRA_1_D }, // 7
148 { solid_srcover(), DrawTypeFlags::kBitmapText_Mask, kBGRA_4_DS }, // 24
149 { solid_srcover(), DrawTypeFlags::kNonSimpleShape, kBGRA_4_D }, // 21,22
150 { solid_srcover(), DrawTypeFlags::kNonSimpleShape, kBGRA_4_DS }, // 28,34,35,57,58,61,62,65
151 { solid_srcover(), DrawTypeFlags::kCircularArc, kBGRA_4_DS }, //26
152 { solid_clear_src_srcover(), DrawTypeFlags::kSimpleShape, kBGRA_1_D }, // 6,8,9,10,15
153 { solid_clear_src_srcover(), DrawTypeFlags::kSimpleShape, kBGRA_4_DS }, // 23,30,31,53
154 { image_premul_src_srcover(), DrawTypeFlags::kSimpleShape, kBGRA_1_D }, // 11,16,17,19,38
155 { image_premul_srcover(), DrawTypeFlags::kSimpleShape, kBGRA_4_DS }, // 32,33,60
156 { image_srgb_src(), DrawTypeFlags::kSimpleShape, kBGRA_1_D_SRGB }, // 18
157 };
158
159 /*********** Here ends the part that can be pasted into Chrome's graphite_precompile.cc ***********/
160
161 // This helper maps from the RenderPass string in the Pipeline label to the
162 // RenderPassProperties needed by the Precompile system
163 // TODO(robertphillips): converting this to a more piecemeal approach might better illuminate
164 // the mapping between the string and the RenderPassProperties
get_render_pass_properties(const char * str)165 RenderPassProperties get_render_pass_properties(const char* str) {
166 static const struct {
167 const char* fStr;
168 RenderPassProperties fRenderPassProperties;
169 } kRenderPassPropertiesMapping[] = {
170 { "RP(color: Dawn(f=R8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: a000)",
171 kR_1_D },
172 { "RP(color: Dawn(f=R8,s=4), resolve: Dawn(f=R8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: a000)",
173 kR_4_DS },
174 { "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba)",
175 kBGRA_1_D },
176 { "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba)",
177 kBGRA_4_D },
178 { "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba)",
179 kBGRA_4_DS },
180 };
181
182 for (const auto& rppm : kRenderPassPropertiesMapping) {
183 if (strstr(str, rppm.fStr)) {
184 return rppm.fRenderPassProperties;
185 }
186 }
187
188 SkAssertResult(0);
189 return {};
190 }
191
192 // This helper maps from the RenderStep's name in the Pipeline label to the DrawTypeFlag that
193 // resulted in its use.
get_draw_type_flags(const char * str)194 DrawTypeFlags get_draw_type_flags(const char* str) {
195 static const struct {
196 const char* fStr;
197 DrawTypeFlags fFlags;
198 } kDrawTypeFlagsMapping[] = {
199 { "BitmapTextRenderStep[Mask]", DrawTypeFlags::kBitmapText_Mask },
200 { "BitmapTextRenderStep[LCD]", DrawTypeFlags::kBitmapText_LCD },
201 { "BitmapTextRenderStep[Color]", DrawTypeFlags::kBitmapText_Color },
202
203 { "SDFTextRenderStep", DrawTypeFlags::kSDFText },
204 { "SDFTextLCDRenderStep", DrawTypeFlags::kSDFText_LCD },
205
206 { "VerticesRenderStep[Tris]", DrawTypeFlags::kDrawVertices },
207 { "VerticesRenderStep[TrisTexCoords]", DrawTypeFlags::kDrawVertices },
208 { "VerticesRenderStep[TrisColor]", DrawTypeFlags::kDrawVertices },
209 { "VerticesRenderStep[TrisColorTexCoords]", DrawTypeFlags::kDrawVertices },
210 { "VerticesRenderStep[Tristrips]", DrawTypeFlags::kDrawVertices },
211 { "VerticesRenderStep[TristripsTexCoords]", DrawTypeFlags::kDrawVertices },
212 { "VerticesRenderStep[TristripsColor]", DrawTypeFlags::kDrawVertices },
213 { "VerticesRenderStep[TristripsColorTexCoords]", DrawTypeFlags::kDrawVertices },
214
215 { "CircularArcRenderStep", DrawTypeFlags::kCircularArc },
216
217 { "AnalyticRRectRenderStep", DrawTypeFlags::kSimpleShape },
218 { "CoverBoundsRenderStep[NonAAFill]", DrawTypeFlags::kSimpleShape },
219 { "PerEdgeAAQuadRenderStep", DrawTypeFlags::kSimpleShape },
220
221 { "CoverageMaskRenderStep", DrawTypeFlags::kNonSimpleShape },
222 { "CoverBoundsRenderStep[RegularCover]", DrawTypeFlags::kNonSimpleShape },
223 { "CoverBoundsRenderStep[InverseCover]", DrawTypeFlags::kNonSimpleShape },
224 { "MiddleOutFanRenderStep[EvenOdd]", DrawTypeFlags::kNonSimpleShape },
225 { "MiddleOutFanRenderStep[Winding]", DrawTypeFlags::kNonSimpleShape },
226 { "TessellateCurvesRenderStep[EvenOdd]", DrawTypeFlags::kNonSimpleShape },
227 { "TessellateCurvesRenderStep[Winding]", DrawTypeFlags::kNonSimpleShape },
228 { "TessellateStrokesRenderStep", DrawTypeFlags::kNonSimpleShape },
229 { "TessellateWedgesRenderStep[Convex]", DrawTypeFlags::kNonSimpleShape },
230 { "TessellateWedgesRenderStep[EvenOdd]", DrawTypeFlags::kNonSimpleShape },
231 { "TessellateWedgesRenderStep[Winding]", DrawTypeFlags::kNonSimpleShape },
232 };
233
234 for (const auto& dtfm : kDrawTypeFlagsMapping) {
235 if (strstr(str, dtfm.fStr)) {
236 SkAssertResult(dtfm.fFlags != DrawTypeFlags::kNone);
237 return dtfm.fFlags;
238 }
239 }
240
241 SkAssertResult(0);
242 return DrawTypeFlags::kNone;
243 }
244
245
246 // Precompile with the provided paintOptions, drawType, and RenderPassSettings then verify that
247 // the expected string is in the generated set.
248 // Additionally, verify that overgeneration is within expected tolerances.
249 // If you add an additional RenderStep you may need to increase the tolerance values.
run_test(skgpu::graphite::PrecompileContext * precompileContext,skiatest::Reporter * reporter,SkSpan<const char * > cases,size_t caseID,const PrecompileSettings & settings,unsigned int expectedNumPipelines)250 void run_test(skgpu::graphite::PrecompileContext* precompileContext,
251 skiatest::Reporter* reporter,
252 SkSpan<const char*> cases,
253 size_t caseID,
254 const PrecompileSettings& settings,
255 unsigned int expectedNumPipelines) {
256 using namespace skgpu::graphite;
257
258 const char* expectedString = cases[caseID];
259
260 precompileContext->priv().globalCache()->resetGraphicsPipelines();
261
262 Precompile(precompileContext,
263 settings.fPaintOptions,
264 settings.fDrawTypeFlags,
265 { &settings.fRenderPassProps, 1 });
266
267 std::vector<std::string> generated;
268
269 {
270 const RendererProvider* rendererProvider = precompileContext->priv().rendererProvider();
271 const ShaderCodeDictionary* dict = precompileContext->priv().shaderCodeDictionary();
272
273 std::vector<skgpu::UniqueKey> generatedKeys;
274
275 UniqueKeyUtils::FetchUniqueKeys(precompileContext, &generatedKeys);
276
277 for (const skgpu::UniqueKey& key : generatedKeys) {
278 GraphicsPipelineDesc pipelineDesc;
279 RenderPassDesc renderPassDesc;
280 UniqueKeyUtils::ExtractKeyDescs(precompileContext, key, &pipelineDesc, &renderPassDesc);
281
282 const RenderStep* renderStep = rendererProvider->lookup(pipelineDesc.renderStepID());
283 generated.push_back(GetPipelineLabel(dict, renderPassDesc, renderStep,
284 pipelineDesc.paintParamsID()));
285 }
286 }
287
288 bool correctGenerationAmt = generated.size() == expectedNumPipelines;
289 REPORTER_ASSERT(reporter, correctGenerationAmt,
290 "case %zu generated unexpected amount - a: %zu != e: %d\n",
291 caseID, generated.size(), expectedNumPipelines);
292
293 const size_t len = strlen(expectedString);
294
295 bool foundIt = false;
296 for (size_t i = 0; i < generated.size(); ++i) {
297 // The generated strings have trailing whitespace
298 if (!strncmp(expectedString, generated[i].c_str(), len)) {
299 foundIt = true;
300 break;
301 }
302 }
303
304 REPORTER_ASSERT(reporter, foundIt);
305
306 #ifdef SK_DEBUG
307 if (foundIt && correctGenerationAmt) {
308 return;
309 }
310
311 SkDebugf("Expected string:\n%s\n%s in %zu strings:\n",
312 expectedString,
313 foundIt ? "found" : "NOT found",
314 generated.size());
315
316 for (size_t i = 0; i < generated.size(); ++i) {
317 SkDebugf("%zu: %s\n", i, generated[i].c_str());
318 }
319 #endif
320 }
321
322 // The pipeline strings were created using the Dawn Metal backend so that is the only viable
323 // comparison
is_dawn_metal_context_type(skgpu::ContextType type)324 bool is_dawn_metal_context_type(skgpu::ContextType type) {
325 return type == skgpu::ContextType::kDawn_Metal;
326 }
327
328 } // anonymous namespace
329
330
331 DEF_GRAPHITE_TEST_FOR_CONTEXTS(ChromePrecompileTest, is_dawn_metal_context_type,
332 reporter, context, /* testContext */, CtsEnforcement::kNever) {
333 using namespace skgpu::graphite;
334
335 std::unique_ptr<PrecompileContext> precompileContext = context->makePrecompileContext();
336 const skgpu::graphite::Caps* caps = precompileContext->priv().caps();
337
338 TextureInfo textureInfo = caps->getDefaultSampledTextureInfo(kBGRA_8888_SkColorType,
339 skgpu::Mipmapped::kNo,
340 skgpu::Protected::kNo,
341 skgpu::Renderable::kYes);
342
343 TextureInfo msaaTex = caps->getDefaultMSAATextureInfo(textureInfo, Discardable::kYes);
344
345 if (msaaTex.numSamples() <= 1) {
346 // The following pipelines rely on having MSAA
347 return;
348 }
349
350 #ifdef SK_ENABLE_VELLO_SHADERS
351 if (caps->computeSupport()) {
352 // The following pipelines rely on not utilizing Vello
353 return;
354 }
355 #endif
356
357 //
358 // These Pipelines are candidates for inclusion in Chrome's precompile. They were generated
359 // by collecting all the Pipelines from the following stories:
360 //
361 // animometer_webgl_attrib_arrays, balls_javascript_canvas, canvas_05000_pixels_per_second,
362 // chip_tune, css_value_type_shadow, fill_shapes, ie_chalkboard, main_30fps_impl_60fps,
363 // new_tilings, transform_transitions_js_block, web_animations_staggered_infinite_iterations,
364 // wikipedia_2018
365 //
366 const char* kCases[] = {
367 //---- Single-sample - R8Unorm/Depth16Unorm --> kR_1_D
368 /* 0 */ "RP(color: Dawn(f=R8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: a000) + "
369 "CoverBoundsRenderStep[NonAAFill] + "
370 "KnownRuntimeEffect_1DBlur12 [ LocalMatrix [ Compose [ Image(0) ColorSpaceTransform ] ] ] Src",
371
372 /* 1 */ "RP(color: Dawn(f=R8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: a000) + "
373 "CoverBoundsRenderStep[NonAAFill] + "
374 "KnownRuntimeEffect_1DBlur8 [ LocalMatrix [ Compose [ Image(0) ColorSpaceTransform ] ] ] Src",
375
376 //---- MSAA4 - R8Unorm/Depth24PlusStencil8 --> kR_4_DS
377 /* 2 */ "RP(color: Dawn(f=R8,s=4), resolve: Dawn(f=R8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: a000) + "
378 "TessellateWedgesRenderStep[EvenOdd] + "
379 "(empty)",
380
381 /* 3 */ "RP(color: Dawn(f=R8,s=4), resolve: Dawn(f=R8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: a000) + "
382 "CoverBoundsRenderStep[RegularCover] + "
383 "SolidColor SrcOver",
384
385 //---- Single-sample - BGRA8Unorm/Depth16Unorm -> kBGRA_1_D
386 /* 4 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
387 "AnalyticBlurRenderStep + "
388 "Compose [ SolidColor BlendCompose [ SolidColor Passthrough PorterDuffBlender ] ] SrcOver",
389
390 // For now, we're going to pass on the AnalyticClip Pipelines
391 /* 5 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
392 "AnalyticBlurRenderStep + "
393 "Compose [ SolidColor BlendCompose [ SolidColor Passthrough PorterDuffBlender ] ] SrcOver AnalyticClip",
394
395 /* 6 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
396 "AnalyticRRectRenderStep + "
397 "SolidColor SrcOver",
398
399 /* 7 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
400 "BitmapTextRenderStep[Mask] + "
401 "SolidColor SrcOver",
402
403 /* 8 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
404 "CoverBoundsRenderStep[NonAAFill] + "
405 "SolidColor SrcOver",
406
407 /* 9 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
408 "CoverBoundsRenderStep[NonAAFill] + "
409 "SolidColor Src",
410
411 /* 10 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
412 "CoverBoundsRenderStep[NonAAFill] + "
413 "SolidColor Clear",
414
415 /* 11 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
416 "CoverBoundsRenderStep[NonAAFill] + "
417 "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] Src",
418
419 // For now, we're going to pass on the AnalyticClip Pipelines
420 /* 12 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
421 "CoverBoundsRenderStep[NonAAFill] + "
422 "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] SrcOver AnalyticClip",
423
424 /* 13 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
425 "CoverageMaskRenderStep + "
426 "Compose [ SolidColor BlendCompose [ SolidColor Passthrough PorterDuffBlender ] ] SrcOver",
427
428 // This is the only AlphaOnlyPaintColor case so, we're going to pass for now
429 /* 14 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
430 "PerEdgeAAQuadRenderStep + "
431 "BlendCompose [ LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] AlphaOnlyPaintColor SrcIn ] SrcOver",
432
433 /* 15 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
434 "PerEdgeAAQuadRenderStep + "
435 "SolidColor SrcOver",
436
437 /* 16 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
438 "PerEdgeAAQuadRenderStep + "
439 "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] Src",
440
441 /* 17 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
442 "PerEdgeAAQuadRenderStep + "
443 "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] SrcOver",
444
445 /* 18 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
446 "PerEdgeAAQuadRenderStep + "
447 "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformSRGB ] ] Src",
448
449 /* 19 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
450 "PerEdgeAAQuadRenderStep + "
451 "LocalMatrix [ Compose [ Image(0) ColorSpaceTransformPremul ] ] SrcOver",
452
453 //---- MSAA4 - BGRA8Unorm/Depth16Unorm -> bgra_4_D
454 // For now, we're going to pass on the AnalyticClip Pipelines
455 /* 20 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba) + "
456 "CoverBoundsRenderStep[NonAAFill] + "
457 "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] SrcOver AnalyticClip",
458
459 /* 21 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba) + "
460 "TessellateStrokesRenderStep + "
461 "SolidColor SrcOver",
462
463 /* 22 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba) + "
464 "TessellateWedgesRenderStep[Convex] + "
465 "SolidColor SrcOver",
466
467 //---- MSAA4 - BGRA8Unorm/Depth24PlusStencil8 --> kBGRA_4_DS
468 /* 23 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
469 "AnalyticRRectRenderStep + "
470 "SolidColor SrcOver",
471
472 /* 24 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
473 "BitmapTextRenderStep[Mask] + "
474 "SolidColor SrcOver",
475
476 // This seems like a quirk of our test set. Is linear gradient text that common? Pass for now.
477 /* 25 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
478 "BitmapTextRenderStep[Mask] + "
479 "LocalMatrix [ Compose [ LinearGradient4 ColorSpaceTransformPremul ] ] SrcOver",
480
481 /* 26 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
482 "CircularArcRenderStep + "
483 "SolidColor SrcOver",
484
485 /* 27 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
486 "CoverBoundsRenderStep[InverseCover] + "
487 "(empty)",
488
489 /* 28 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
490 "CoverBoundsRenderStep[RegularCover] + "
491 "SolidColor SrcOver",
492
493 /* 29 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
494 "CoverBoundsRenderStep[RegularCover] + "
495 "(empty)",
496
497 /* 30 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
498 "CoverBoundsRenderStep[NonAAFill] + "
499 "SolidColor SrcOver",
500
501 /* 31 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
502 "CoverBoundsRenderStep[NonAAFill] + "
503 "SolidColor Clear",
504
505 /* 32 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
506 "CoverBoundsRenderStep[NonAAFill] + "
507 "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] SrcOver",
508
509 /* 33 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
510 "PerEdgeAAQuadRenderStep + "
511 "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] SrcOver",
512
513 /* 34 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
514 "TessellateWedgesRenderStep[Winding] + "
515 "(empty)",
516
517 /* 35 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
518 "TessellateWedgesRenderStep[EvenOdd] + "
519 "(empty)",
520
521 /* 36 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
522 "TessellateWedgesRenderStep[Convex] + "
523 "SolidColor SrcOver",
524
525 //----------------------------
526 // These are leftover Pipelines that were generated by the stories but are pretty infrequently used.
527 // Some of them get picked up in the preceding cases
528 //---- Single-sample - BGRA8Unorm/Depth16Unorm -> kBGRA_1_D
529 /* 37 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
530 "CoverBoundsRenderStep[NonAAFill] + "
531 "Compose [ LocalMatrix [ Compose [ LinearGradient4 ColorSpaceTransformPremul ] ] Dither ] SrcOver",
532
533 /* 38 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
534 "CoverBoundsRenderStep[NonAAFill] + "
535 "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] SrcOver",
536
537 /* 39 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
538 "CoverBoundsRenderStep[NonAAFill] + "
539 "LocalMatrix [ Compose [ Image(0) ColorSpaceTransformPremul ] ] SrcOver",
540
541 /* 40 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
542 "CoverBoundsRenderStep[NonAAFill] + "
543 "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformSRGB ] ] SrcOver",
544
545 /* 41 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
546 "CoverBoundsRenderStep[NonAAFill] + "
547 "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformSRGB ] ] Src",
548
549 /* 42 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
550 "CoverBoundsRenderStep[NonAAFill] + "
551 "LocalMatrix [ Compose [ HWYUVImage ColorSpaceTransformSRGB ] ] SrcOver",
552
553 /* 43 */ "RP(color: Dawn(f=BGRA8,s=1), resolve: {}, ds: Dawn(f=D16,s=1), samples: 1, swizzle: rgba) + "
554 "PerEdgeAAQuadRenderStep + "
555 "LocalMatrix [ Compose [ HWYUVImage ColorSpaceTransformSRGB ] ] SrcOver",
556
557 //---- MSAA4 - BGRA8Unorm/Depth16Unorm -> kBGRA_4_D
558 /* 44 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba) + "
559 "AnalyticRRectRenderStep + "
560 "SolidColor SrcOver",
561
562 /* 45 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba) + "
563 "BitmapTextRenderStep[Mask] + "
564 "SolidColor SrcOver",
565
566 /* 46 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba) + "
567 "CoverBoundsRenderStep[NonAAFill] + "
568 "SolidColor SrcOver",
569
570 /* 47 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba) + "
571 "CoverBoundsRenderStep[NonAAFill] + "
572 "SolidColor Src",
573
574 /* 48 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba) + "
575 "CoverBoundsRenderStep[NonAAFill] + "
576 "Compose [ LocalMatrix [ Compose [ LinearGradient4 ColorSpaceTransformPremul ] ] Dither ] SrcOver",
577
578 /* 49 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba) + "
579 "CoverBoundsRenderStep[NonAAFill] + "
580 "LocalMatrix [ Compose [ HWYUVImage ColorSpaceTransformSRGB ] ] SrcOver",
581
582 /* 50 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba) + "
583 "PerEdgeAAQuadRenderStep + "
584 "LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] SrcOver",
585
586 /* 51 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D16,s=4), samples: 4, swizzle: rgba) + "
587 "PerEdgeAAQuadRenderStep + "
588 "LocalMatrix [ Compose [ HWYUVImage ColorSpaceTransformSRGB ] ] SrcOver",
589
590 //---- MSAA4 - BGRA8Unorm/Depth24PlusStencil8 --> kBGRA_4_DS
591 /* 52 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
592 "AnalyticRRectRenderStep + "
593 "Compose [ LocalMatrix [ Compose [ LinearGradient4 ColorSpaceTransformPremul ] ] Dither ] SrcOver",
594
595 /* 53 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
596 "CoverBoundsRenderStep[NonAAFill] + "
597 "SolidColor Src",
598
599 /* 54 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
600 "CoverBoundsRenderStep[NonAAFill] + "
601 "Compose [ LocalMatrix [ Compose [ LinearGradient4 ColorSpaceTransformPremul ] ] Dither ] SrcOver",
602
603 // For now, we're going to pass on the AnalyticClip Pipelines
604 /* 55 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
605 "CoverBoundsRenderStep[NonAAFill] + "
606 "SolidColor SrcOver AnalyticClip",
607
608 /* 56 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
609 "CoverBoundsRenderStep[RegularCover] + "
610 "Compose [ LocalMatrix [ Compose [ LinearGradient8 ColorSpaceTransformPremul ] ] Dither ] SrcOver",
611
612 /* 57 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
613 "MiddleOutFanRenderStep[Winding] + "
614 "(empty)",
615
616 /* 58 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
617 "MiddleOutFanRenderStep[EvenOdd] + "
618 "(empty)",
619
620 /* 59 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
621 "PerEdgeAAQuadRenderStep + "
622 "BlendCompose [ LocalMatrix [ Compose [ HardwareImage(0) ColorSpaceTransformPremul ] ] AlphaOnlyPaintColor SrcIn ] SrcOver",
623
624 /* 60 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
625 "PerEdgeAAQuadRenderStep + "
626 "LocalMatrix [ Compose [ Image(0) ColorSpaceTransformPremul ] ] SrcOver",
627
628 /* 61 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
629 "TessellateCurvesRenderStep[Winding] + "
630 "(empty)",
631
632 /* 62 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
633 "TessellateCurvesRenderStep[EvenOdd] + "
634 "(empty)",
635
636 /* 63 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
637 "TessellateWedgesRenderStep[Convex] + "
638 "Compose [ LocalMatrix [ Compose [ LinearGradientBuffer ColorSpaceTransformPremul ] ] Dither ] SrcOver",
639
640 /* 64 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
641 "TessellateWedgesRenderStep[Convex] + "
642 "Compose [ LocalMatrix [ Compose [ LinearGradient8 ColorSpaceTransformPremul ] ] Dither ] SrcOver",
643
644 /* 65 */ "RP(color: Dawn(f=BGRA8,s=4), resolve: Dawn(f=BGRA8,s=1), ds: Dawn(f=D24_S8,s=4), samples: 4, swizzle: rgba) + "
645 "TessellateStrokesRenderStep + "
646 "SolidColor SrcOver",
647 };
648
649 for (size_t i = 0; i < std::size(kCases); ++i) {
650 PrecompileSettings settings;
651
652 // TODO(robertphillips): splitting kCases[i] into substrings (based on a " + " separator)
653 // before passing to the helpers would make this prettier
654 RenderPassProperties expectedRenderPassSettings = get_render_pass_properties(kCases[i]);
655 unsigned int expectedNumPipelines = 0;
656
657 switch (i) {
658 #if 0
659 // Punting on the blur cases for now since they horribly over-generate
660 case 0: [[fallthrough]];
661 case 1:
662 renderPassSettings = kR_1_D;
663 drawTypeFlags = DrawTypeFlags::kSimpleShape;
664 paintOptions = blur_image();
665 expectedNumPipelines = 11;
666 break;
667 #endif
668
669 // 2 and 3 form a single-draw pair and are, thus, addressed by the same settings
670 case 2: [[fallthrough]]; // TessellateWedgesRenderStep[EvenOdd]
671 case 3: // kSrcOver - CoverBoundsRenderStep[RegularCover]
672 // solid_srcover, kNonSimpleShape, kR_4_DS
673 settings = kPrecompileCases[2];
674 expectedNumPipelines = 11; // This is pretty bad for just 2 Pipelines
675 break;
676
677 // 4 and 13 share the same paintOptions
678 case 4: // AnalyticBlurRenderStep
679 #if 0
680 // We need to handle AnalyticBlurs differently (b/403264070)
681 // blend_porter_duff_color_filter_srcover(), kAnalyticBlur, kBGRA_1_D
682 settings = kPrecompileCases[0];
683 expectedNumPipelines = 1;
684 break;
685 #else
686 continue;
687 #endif
688
689 case 13: // CoverageMaskRenderStep
690 // this case could be greatly reduced if CoverageMaskRenderStep were split out
691 // blend_porter_duff_color_filter_srcover(), kNonSimpleShape, kBGRA_1_D
692 settings = kPrecompileCases[1];
693 expectedNumPipelines = 11; // This is pretty bad for just 1 Pipeline
694 break;
695
696 // This is the only AlphaOnlyPaintColor case so, we're going to pass for now
697 case 14:
698 continue;
699
700 // For now, we're passing on the AnalyticClip Pipelines
701 case 5: // same as 4 but with an AnalyticClip
702 case 12:
703 case 20:
704 case 55:
705 continue;
706
707 // The two text pipelines (7 and 24) just differ in render pass settings (one MSAA, the
708 // other not)
709 case 7:
710 // solid_srcover(), kBitmapText_Mask, kBGRA_1_D
711 settings = kPrecompileCases[3];
712 expectedNumPipelines = 1;
713 break;
714 case 24:
715 // solid_srcover(), kBitmapText_Mask, kBGRA_4_DS
716 settings = kPrecompileCases[4];
717 expectedNumPipelines = 1;
718 break;
719
720 // 21 & 22 form a pair (since they both need kNonSimpleShape)
721 case 21: // kSrcOver - TessellateStrokesRenderStep
722 case 22: // kSrcOver - TessellateWedgesRenderStep[Convex]
723 // solid_srcover(), kNonSimpleShape, kBGRA_4_D
724 settings = kPrecompileCases[5];
725 expectedNumPipelines = 11; // very bad for 2 pipelines
726 break;
727
728 // Skipping linear gradient text draw. It doesn't seem representative.
729 case 25:
730 continue;
731
732 // TODO(robertphillips): these two cases aren't being generated!
733 case 27: // CoverBoundsRenderStep[InverseCover]
734 case 29: // CoverBoundsRenderStep[RegularCover]
735 continue; // they should normally just fall through
736
737 // the next 9 form a block (since they all need kNonSimpleShape)
738 case 28: // kSrcOver - CoverBoundsRenderStep[RegularCover]
739 case 34: // TessellateWedgesRenderStep[Winding]
740 case 35: // TessellateWedgesRenderStep[EvenOdd]
741 case 36: // kSrcOver - TessellateWedgesRenderStep[Convex]
742 // related utility Pipelines
743 case 57: // MiddleOutFanRenderStep[Winding]
744 case 58: // MiddleOutFanRenderStep[EvenOdd]
745 case 61: // TessellateCurvesRenderStep[Winding]
746 case 62: // TessellateCurvesRenderStep[EvenOdd]
747 case 65: // kSrcOver - TessellateStrokesRenderStep
748 // solid_srcover(), kNonSimpleShape, kBGRA_4_DS
749 settings = kPrecompileCases[6];
750 expectedNumPipelines = 11; // not so bad for 9 pipelines
751 break;
752
753 // These are the same except for the blend mode
754 // kSrcOver seems fine (since it gets 3 pipelines). kSrc and kClear seem like they
755 // should be narrowed (since they're over-generating a lot)
756 case 6: // kSrcOver - AnalyticRRectRenderStep
757 case 8: // kSrcOver - CoverBoundsRenderStep[NonAAFill]
758 case 9: // kSrc - CoverBoundsRenderStep[NonAAFill]
759 case 10: // kClear - CoverBoundsRenderStep[NonAAFill]
760 case 15: // kSrcOver - PerEdgeAAQuadRenderStep
761 // solid_clear_src_srcover(), kSimpleShape, kBGRA_1_D
762 settings = kPrecompileCases[8];
763 // This is 3 each for kClear, kSrc and kSrcOver:
764 // AnalyticRRectRenderStep
765 // CoverBoundsRenderStep[NonAAFill]
766 // PerEdgeAAQuadRenderStep
767 expectedNumPipelines = 9; // This is pretty bad for 5 pipelines
768 break;
769
770 case 26: // kSrcOver - CircularArcRenderStep
771 // solid_srcover(), kCircularArc, kBGRA_4_DS
772 settings = kPrecompileCases[7];
773 expectedNumPipelines = 1;
774 break;
775
776 case 23: // kSrcOver - AnalyticRRectRenderStep
777 case 30: // kSrcOver - CoverBoundsRenderStep[NonAAFill]
778 case 31: // kClear - CoverBoundsRenderStep[NonAAFill]
779 case 53: // kSrc - CoverBoundsRenderStep[NonAAFill]
780 // solid_clear_src_srcover(), kSimpleShape, kBGRA_4_DS
781 settings = kPrecompileCases[9];
782 // This is 3 each for kClear, kSrc and kSrcOver:
783 // AnalyticRRectRenderStep
784 // CoverBoundsRenderStep[NonAAFill]
785 // PerEdgeAAQuadRenderStep
786 expectedNumPipelines = 9; // This is pretty bad for 4 pipelines
787 break;
788
789 // For all the image paintOptions we could add the option to exclude cubics to
790 // the public API
791 case 11: // CoverBoundsRenderStep[NonAAFill] + HardwareImage(0) + kSrc
792 case 16: // PerEdgeAAQuadRenderStep + HardwareImage(0) + kSrc
793 case 17: // PerEdgeAAQuadRenderStep + HardwareImage(0) + kSrcOver
794 case 19: // PerEdgeAAQuadRenderStep + Image(0) + kSrcOver
795 case 38: // CoverBoundsRenderStep[NonAAFill] + HardwareImage(0) + kSrcOver
796 // image_premul_src_srcover(), kSimpleShape, kBGRA_1_D
797 settings = kPrecompileCases[10];
798 expectedNumPipelines = 24; // a bad deal for 5 pipelines
799 break;
800
801 // same as except 16 except it has ColorSpaceTransformSRGB
802 case 18: // PerEdgeAAQuadRenderStep + HardwareImage(0) + kSrc
803 // image_srgb_src(), kSimpleShape, kBGRA_1_D_SRGB
804 settings = kPrecompileCases[12];
805 expectedRenderPassSettings.fDstCS = SkColorSpace::MakeSRGB();
806 expectedNumPipelines = 12; // a bad deal for 1 pipeline
807 break;
808
809 case 32: // CoverBoundsRenderStep[NonAAFill] + HardwareImage(0) + kSrcOver
810 case 33: // PerEdgeAAQuadRenderStep + HardwareImage(0) + kSrcOver
811 case 60: // PerEdgeAAQuadRenderStep + Image(0) + kSrcOver
812 // image_premul_srcover(), kSimpleShape, kBGRA_4_DS
813 settings = kPrecompileCases[11];
814 expectedNumPipelines = 12; // a bad deal for 3 pipelines
815 break;
816 default:
817 continue;
818 }
819
820 SkAssertResult(settings.fRenderPassProps == expectedRenderPassSettings);
821 DrawTypeFlags expectedDrawTypeFlags = get_draw_type_flags(kCases[i]);
822 SkAssertResult(settings.fDrawTypeFlags == expectedDrawTypeFlags);
823
824 if (settings.fRenderPassProps.fRequiresMSAA && caps->loadOpAffectsMSAAPipelines()) {
825 expectedNumPipelines *= 2; // due to wgpu::LoadOp::ExpandResolveTexture
826 }
827
828 run_test(precompileContext.get(), reporter,
829 { kCases, std::size(kCases) }, i,
830 settings, expectedNumPipelines);
831 }
832 }
833
834 #endif // SK_GRAPHITE
835