Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
FactoryFunctions.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
9
13#include "src/gpu/Blend.h"
23
24namespace skgpu::graphite {
25
26namespace {
27
28#ifdef SK_DEBUG
29
30bool precompilebase_is_valid_as_child(const PrecompileBase *child) {
31 if (!child) {
32 return true;
33 }
34
35 switch (child->type()) {
39 return true;
40 default:
41 return false;
42 }
43}
44
45#endif // SK_DEBUG
46
47// If all the options are null the span is considered empty
49 if (options.empty()) {
50 return true;
51 }
52
53 for (const auto& o : options) {
54 if (o) {
55 return false;
56 }
57 }
58
59 return true;
60}
61
62} // anonymous namespace
63
64//--------------------------------------------------------------------------------------------------
66public:
67 PrecompileBlendModeBlender(SkBlendMode blendMode) : fBlendMode(blendMode) {}
68
69 std::optional<SkBlendMode> asBlendMode() const final { return fBlendMode; }
70
71private:
72 void addToKey(const KeyContext& keyContext,
73 PaintParamsKeyBuilder* builder,
74 PipelineDataGatherer* gatherer,
75 int desiredCombination) const override {
76 SkASSERT(desiredCombination == 0); // The blend mode blender only ever has one combination
77
78 AddModeBlend(keyContext, builder, gatherer, fBlendMode);
79 }
80
81
82 SkBlendMode fBlendMode;
83};
84
86 return sk_make_sp<PrecompileBlendModeBlender>(blendMode);
87}
88
90 const SkRuntimeEffect* arithmeticEffect =
91 GetKnownRuntimeEffect(SkKnownRuntimeEffects::StableKey::kArithmetic);
92
93 return MakePrecompileBlender(sk_ref_sp(arithmeticEffect));
94}
95
96//--------------------------------------------------------------------------------------------------
98public:
100
101private:
102 void addToKey(const KeyContext& keyContext,
103 PaintParamsKeyBuilder* builder,
104 PipelineDataGatherer* gatherer,
105 int desiredCombination) const override {
106
107 SkASSERT(desiredCombination == 0); // The empty shader only ever has one combination
108
109 builder->addBlock(BuiltInCodeSnippetID::kPriorOutput);
110 }
111
112};
113
115 return sk_make_sp<PrecompileEmptyShader>();
116}
117
118//--------------------------------------------------------------------------------------------------
120public:
122
123private:
124 void addToKey(const KeyContext& keyContext,
125 PaintParamsKeyBuilder* builder,
126 PipelineDataGatherer* gatherer,
127 int desiredCombination) const override {
128
129 SkASSERT(desiredCombination == 0); // The Perlin noise shader only ever has one combination
130
131 // TODO: update PerlinNoiseShaderBlock so the NoiseData is optional
132 static const PerlinNoiseShaderBlock::PerlinNoiseData kIgnoredNoiseData(
133 PerlinNoiseShaderBlock::Type::kFractalNoise, { 0.0f, 0.0f }, 2, {1, 1});
134
135 PerlinNoiseShaderBlock::AddBlock(keyContext, builder, gatherer, kIgnoredNoiseData);
136 }
137
138};
139
141 return sk_make_sp<PrecompilePerlinNoiseShader>();
142}
143
145 return sk_make_sp<PrecompilePerlinNoiseShader>();
146}
147
148//--------------------------------------------------------------------------------------------------
150public:
152
153 bool isConstant(int desiredCombination) const override {
154 SkASSERT(desiredCombination == 0); // The color shader only ever has one combination
155 return true;
156 }
157
158private:
159 void addToKey(const KeyContext& keyContext,
160 PaintParamsKeyBuilder* builder,
161 PipelineDataGatherer* gatherer,
162 int desiredCombination) const override {
163
164 SkASSERT(desiredCombination == 0); // The color shader only ever has one combination
165
166 // The white PMColor is just a placeholder for the actual paint params color
167 SolidColorShaderBlock::AddBlock(keyContext, builder, gatherer, SK_PMColor4fWHITE);
168 }
169};
170
172 return sk_make_sp<PrecompileColorShader>();
173}
174
175// The colorSpace is safe to ignore - it is just applied to the color and doesn't modify the
176// generated program.
178 return sk_make_sp<PrecompileColorShader>();
179}
180
181//--------------------------------------------------------------------------------------------------
183public:
187 bool needsPorterDuffBased,
188 bool needsSeparableMode)
189 : fRuntimeBlendEffects(runtimeBlendEffects.begin(), runtimeBlendEffects.end())
190 , fDstOptions(dsts.begin(), dsts.end())
191 , fSrcOptions(srcs.begin(), srcs.end()) {
192
193 fNumBlenderCombos = 0;
194 for (const auto& rt : fRuntimeBlendEffects) {
195 fNumBlenderCombos += rt->numCombinations();
196 }
197 if (needsPorterDuffBased) {
198 ++fNumBlenderCombos;
199 }
200 if (needsSeparableMode) {
201 ++fNumBlenderCombos;
202 }
203
204 SkASSERT(fNumBlenderCombos >= 1);
205
206 fNumDstCombos = 0;
207 for (const auto& d : fDstOptions) {
208 fNumDstCombos += d->numCombinations();
209 }
210
211 fNumSrcCombos = 0;
212 for (const auto& s : fSrcOptions) {
213 fNumSrcCombos += s->numCombinations();
214 }
215
216 if (needsPorterDuffBased) {
217 fPorterDuffIndex = 0;
218 if (needsSeparableMode) {
219 fSeparableModeIndex = 1;
220 if (!fRuntimeBlendEffects.empty()) {
221 fBlenderIndex = 2;
222 }
223 } else if (!fRuntimeBlendEffects.empty()) {
224 fBlenderIndex = 1;
225 }
226 } else if (needsSeparableMode) {
227 fSeparableModeIndex = 0;
228 if (!fRuntimeBlendEffects.empty()) {
229 fBlenderIndex = 1;
230 }
231 } else {
232 SkASSERT(!fRuntimeBlendEffects.empty());
233 fBlenderIndex = 0;
234 }
235 }
236
237private:
238 int numChildCombinations() const override {
239 return fNumBlenderCombos * fNumDstCombos * fNumSrcCombos;
240 }
241
242 void addToKey(const KeyContext& keyContext,
243 PaintParamsKeyBuilder* builder,
244 PipelineDataGatherer* gatherer,
245 int desiredCombination) const override {
246 SkASSERT(desiredCombination < this->numCombinations());
247
248 const int desiredDstCombination = desiredCombination % fNumDstCombos;
249 int remainingCombinations = desiredCombination / fNumDstCombos;
250
251 const int desiredSrcCombination = remainingCombinations % fNumSrcCombos;
252 remainingCombinations /= fNumSrcCombos;
253
254 int desiredBlendCombination = remainingCombinations;
255 SkASSERT(desiredBlendCombination < fNumBlenderCombos);
256
257 if (desiredBlendCombination == fPorterDuffIndex ||
258 desiredBlendCombination == fSeparableModeIndex) {
259 BlendShaderBlock::BeginBlock(keyContext, builder, gatherer);
260
261 } else {
262 const SkRuntimeEffect* blendEffect =
263 GetKnownRuntimeEffect(SkKnownRuntimeEffects::StableKey::kBlend);
264
265 RuntimeEffectBlock::BeginBlock(keyContext, builder, gatherer,
266 { sk_ref_sp(blendEffect) });
267 SkASSERT(desiredBlendCombination >= fBlenderIndex);
268 desiredBlendCombination -= fBlenderIndex;
269 }
270
271 AddToKey<PrecompileShader>(keyContext, builder, gatherer, fSrcOptions,
272 desiredSrcCombination);
273 AddToKey<PrecompileShader>(keyContext, builder, gatherer, fDstOptions,
274 desiredDstCombination);
275
276 if (desiredBlendCombination == fPorterDuffIndex) {
277 CoeffBlenderBlock::AddBlock(keyContext, builder, gatherer,
278 { 0.0f, 0.0f, 0.0f, 0.0f }); // coeffs aren't used
279 } else if (desiredBlendCombination == fSeparableModeIndex) {
280 BlendModeBlenderBlock::AddBlock(keyContext, builder, gatherer,
281 SkBlendMode::kOverlay); // the blendmode is unused
282 } else {
283 AddToKey<PrecompileBlender>(keyContext, builder, gatherer, fRuntimeBlendEffects,
284 desiredBlendCombination);
285 }
286
287 builder->endBlock(); // BlendShaderBlock or RuntimeEffectBlock
288 }
289
290 std::vector<sk_sp<PrecompileBlender>> fRuntimeBlendEffects;
291 std::vector<sk_sp<PrecompileShader>> fDstOptions;
292 std::vector<sk_sp<PrecompileShader>> fSrcOptions;
293
294 int fNumBlenderCombos;
295 int fNumDstCombos;
296 int fNumSrcCombos;
297
298 int fPorterDuffIndex = -1;
299 int fSeparableModeIndex = -1;
300 int fBlenderIndex = -1;
301};
302
304 SkSpan<const sk_sp<PrecompileBlender>> blenders,
307 std::vector<sk_sp<PrecompileBlender>> tmp;
308 tmp.reserve(blenders.size());
309
310 bool needsPorterDuffBased = false;
311 bool needsBlendModeBased = false;
312
313 for (const auto& b : blenders) {
314 if (!b) {
315 needsPorterDuffBased = true; // fall back to kSrcOver
316 } else if (b->asBlendMode().has_value()) {
317 SkBlendMode bm = b->asBlendMode().value();
318
320 if (!coeffs.empty()) {
321 needsPorterDuffBased = true;
322 } else {
323 needsBlendModeBased = true;
324 }
325 } else {
326 tmp.push_back(b);
327 }
328 }
329
330 if (!needsPorterDuffBased && !needsBlendModeBased && tmp.empty()) {
331 needsPorterDuffBased = true; // fallback to kSrcOver
332 }
333
334 return sk_make_sp<PrecompileBlendShader>(SkSpan<const sk_sp<PrecompileBlender>>(tmp),
335 dsts, srcs,
336 needsPorterDuffBased, needsBlendModeBased);
337}
338
340 SkSpan<SkBlendMode> blendModes,
343
344 bool needsPorterDuffBased = false;
345 bool needsBlendModeBased = false;
346
347 for (SkBlendMode bm : blendModes) {
349 if (!porterDuffConstants.empty()) {
350 needsPorterDuffBased = true;
351 } else {
352 needsBlendModeBased = true;
353 }
354 }
355
356 if (!needsPorterDuffBased && !needsBlendModeBased) {
357 needsPorterDuffBased = true; // fallback to kSrcOver
358 }
359
360 return sk_make_sp<PrecompileBlendShader>(SkSpan<const sk_sp<PrecompileBlender>>(),
361 dsts, srcs,
362 needsPorterDuffBased, needsBlendModeBased);
363}
364
365//--------------------------------------------------------------------------------------------------
367public:
369 : fShaders(shaders.begin(), shaders.end()) {
370 fNumShaderCombos = 0;
371 for (const auto& s : fShaders) {
372 fNumShaderCombos += s->numCombinations();
373 }
374 }
375
376private:
377 int numChildCombinations() const override {
378 return fNumShaderCombos;
379 }
380
381 void addToKey(const KeyContext& keyContext,
382 PaintParamsKeyBuilder* builder,
383 PipelineDataGatherer* gatherer,
384 int desiredCombination) const override {
385 SkASSERT(desiredCombination < fNumShaderCombos);
386
387 constexpr SkRect kIgnored { 0, 0, 256, 256 }; // ignored bc we're precompiling
388
389 // TODO: update CoordClampShaderBlock so this is optional
391
392 CoordClampShaderBlock::BeginBlock(keyContext, builder, gatherer, data);
393 AddToKey<PrecompileShader>(keyContext, builder, gatherer, fShaders, desiredCombination);
394 builder->endBlock();
395 }
396
397 std::vector<sk_sp<PrecompileShader>> fShaders;
398 int fNumShaderCombos;
399};
400
402 return sk_make_sp<PrecompileCoordClampShader>(input);
403}
404
405//--------------------------------------------------------------------------------------------------
406// TODO: Investigate the YUV-image use case
408public:
410
411private:
412 // The ImageShader has 3 potential sampling/tiling variants: hardware-tiled, shader-tiled and
413 // cubic sampling (which always uses shader-tiling)
414 inline static constexpr int kNumSamplingTilingCombos = 3;
415 inline static constexpr int kCubicSampled = 2;
416 inline static constexpr int kHWTiled = 1;
417 inline static constexpr int kShaderTiled = 0;
418
419 // There are also 2 potential alpha combinations: alpha-only and not-alpha-only
420 inline static constexpr int kNumAlphaCombinations = 2;
421 inline static constexpr int kAlphaOnly = 1;
422 inline static constexpr int kNonAlphaOnly = 0;
423
424 int numIntrinsicCombinations() const override {
425 int numSamplingTilingCombos =
426 (fFlags & PrecompileImageShaderFlags::kExcludeCubic) ? 2 : kNumSamplingTilingCombos;
427
429 // RawImageShaders don't blend alpha-only images w/ the paint color
430 return numSamplingTilingCombos;
431 }
432 return numSamplingTilingCombos * kNumAlphaCombinations;
433 }
434
435 void addToKey(const KeyContext& keyContext,
436 PaintParamsKeyBuilder* builder,
437 PipelineDataGatherer* gatherer,
438 int desiredCombination) const override {
439 SkASSERT(desiredCombination < this->numIntrinsicCombinations());
440
441 int desiredAlphaCombo, desiredSamplingTilingCombo;
442
444 desiredAlphaCombo = kNonAlphaOnly;
445 desiredSamplingTilingCombo = desiredCombination;
446 } else {
447 desiredAlphaCombo = desiredCombination % kNumAlphaCombinations;
448 desiredSamplingTilingCombo = desiredCombination / kNumAlphaCombinations;
449 }
450 SkDEBUGCODE(int numSamplingTilingCombos =
451 (fFlags & PrecompileImageShaderFlags::kExcludeCubic) ? 2 : kNumSamplingTilingCombos;)
452 SkASSERT(desiredSamplingTilingCombo < numSamplingTilingCombos);
453
454 static constexpr SkSamplingOptions kDefaultCubicSampling(SkCubicResampler::Mitchell());
455 static constexpr SkSamplingOptions kDefaultSampling;
456 constexpr ReadSwizzle kIgnoredSwizzle = ReadSwizzle::kRGBA;
457
458 // ImageShaderBlock will use hardware tiling when the subset covers the entire image, so we
459 // create subset + image size combinations where subset == imgSize (for a shader that uses
460 // hardware tiling) and subset < imgSize (for a shader that does shader-based tiling).
461 static constexpr SkRect kSubset = SkRect::MakeWH(1.0f, 1.0f);
462 static constexpr SkISize kHWTileableSize = SkISize::Make(1, 1);
463 static constexpr SkISize kShaderTileableSize = SkISize::Make(2, 2);
464
466 desiredSamplingTilingCombo == kCubicSampled ? kDefaultCubicSampling
467 : kDefaultSampling,
469 desiredSamplingTilingCombo == kHWTiled ? kHWTileableSize : kShaderTileableSize,
470 kSubset, kIgnoredSwizzle);
471
472 if (desiredAlphaCombo == kAlphaOnly) {
474
475 Blend(keyContext, builder, gatherer,
476 /* addBlendToKey= */ [&] () -> void {
477 AddKnownModeBlend(keyContext, builder, gatherer, SkBlendMode::kDstIn);
478 },
479 /* addSrcToKey= */ [&] () -> void {
480 ImageShaderBlock::AddBlock(keyContext, builder, gatherer, imgData);
481 },
482 /* addDstToKey= */ [&]() -> void {
483 RGBPaintColorBlock::AddBlock(keyContext, builder, gatherer);
484 });
485 } else {
486 ImageShaderBlock::AddBlock(keyContext, builder, gatherer, imgData);
487 }
488 }
489
491};
492
495 { sk_make_sp<PrecompileImageShader>(PrecompileImageShaderFlags::kNone) });
496}
497
499 // Raw images do not perform color space conversion, but in Graphite, this is represented as
500 // an identity color space xform, not as a distinct shader
502 { sk_make_sp<PrecompileImageShader>(PrecompileImageShaderFlags::kExcludeAlpha) });
503}
504
509
510//--------------------------------------------------------------------------------------------------
512public:
514
515private:
516 // non-cubic and cubic sampling
517 inline static constexpr int kNumIntrinsicCombinations = 2;
518
519 int numIntrinsicCombinations() const override { return kNumIntrinsicCombinations; }
520
521 void addToKey(const KeyContext& keyContext,
522 PaintParamsKeyBuilder* builder,
523 PipelineDataGatherer* gatherer,
524 int desiredCombination) const override {
525 SkASSERT(desiredCombination < kNumIntrinsicCombinations);
526
527 static constexpr SkSamplingOptions kDefaultCubicSampling(SkCubicResampler::Mitchell());
528 static constexpr SkSamplingOptions kDefaultSampling;
529
530 YUVImageShaderBlock::ImageData imgData(desiredCombination == 1 ? kDefaultCubicSampling
531 : kDefaultSampling,
534
535 YUVImageShaderBlock::AddBlock(keyContext, builder, gatherer, imgData);
536 }
537};
538
540 return sk_make_sp<PrecompileYUVImageShader>();
541}
542
543//--------------------------------------------------------------------------------------------------
544// The PictureShader ultimately turns into an SkImageShader optionally wrapped in a
545// LocalMatrixShader. The PrecompileImageShader already captures that use case so just reuse it.
546// Note that this means each precompile PictureShader will add 24 combinations:
547// 2 (pictureshader LM) x 2 (imageShader LM) x 6 (imageShader variations)
549 // Note: We don't need to consider the PrecompileYUVImageShader since the image
550 // being drawn was created internally by Skia (as non-YUV).
552}
553
556 if (withLM) {
557 return PrecompileShaders::LocalMatrix({ std::move(s) });
558 }
559 return s;
560}
561
562//--------------------------------------------------------------------------------------------------
564public:
566
567private:
568 /*
569 * The gradients currently have two specializations based on the number of stops.
570 */
571 inline static constexpr int kNumStopVariants = 2;
572 inline static constexpr int kStopVariants[kNumStopVariants] = { 4, 8 };
573
574 int numIntrinsicCombinations() const override {
575 return kNumStopVariants;
576 }
577
578 void addToKey(const KeyContext& keyContext,
579 PaintParamsKeyBuilder* builder,
580 PipelineDataGatherer* gatherer,
581 int desiredCombination) const override {
582 const int intrinsicCombination = desiredCombination / this->numChildCombinations();
583 SkDEBUGCODE(int childCombination = desiredCombination % this->numChildCombinations();)
584 SkASSERT(intrinsicCombination < kNumStopVariants);
585 SkASSERT(childCombination == 0);
586
587 GradientShaderBlocks::GradientData gradData(fType, kStopVariants[intrinsicCombination]);
588
589 constexpr SkAlphaType kAlphaType = kPremul_SkAlphaType;
591 sk_srgb_singleton(), kAlphaType);
592
593 Compose(keyContext, builder, gatherer,
594 /* addInnerToKey= */ [&]() -> void {
595 GradientShaderBlocks::AddBlock(keyContext, builder, gatherer, gradData);
596 },
597 /* addOuterToKey= */ [&]() -> void {
598 ColorSpaceTransformBlock::AddBlock(keyContext, builder, gatherer, csData);
599 });
600 }
601
603};
604
607 sk_make_sp<PrecompileGradientShader>(SkShaderBase::GradientType::kLinear);
609}
610
613 sk_make_sp<PrecompileGradientShader>(SkShaderBase::GradientType::kLinear);
614 if (withLM) {
615 return PrecompileShaders::LocalMatrix({ std::move(s) });
616 }
617 return s;
618}
619
622 sk_make_sp<PrecompileGradientShader>(SkShaderBase::GradientType::kRadial);
624}
625
628 sk_make_sp<PrecompileGradientShader>(SkShaderBase::GradientType::kRadial);
629 if (withLM) {
630 return PrecompileShaders::LocalMatrix({ std::move(s) });
631 }
632 return s;
633}
634
637 sk_make_sp<PrecompileGradientShader>(SkShaderBase::GradientType::kSweep);
639}
640
643 sk_make_sp<PrecompileGradientShader>(SkShaderBase::GradientType::kSweep);
644 if (withLM) {
645 return PrecompileShaders::LocalMatrix({ std::move(s) });
646 }
647 return s;
648}
649
652 sk_make_sp<PrecompileGradientShader>(SkShaderBase::GradientType::kConical);
654}
655
658 sk_make_sp<PrecompileGradientShader>(SkShaderBase::GradientType::kConical);
659 if (withLM) {
660 return PrecompileShaders::LocalMatrix({ std::move(s) });
661 }
662 return s;
663}
664
665//--------------------------------------------------------------------------------------------------
666// In the main Skia API the SkLocalMatrixShader is optimized away when the LM is the identity
667// or omitted. The PrecompileLocalMatrixShader captures this by adding two intrinsic options.
668// One with the LMShader wrapping the child and one without the LMShader.
670public:
671 enum class Flags {
672 kNone,
674 };
675
678 : fWrapped(wrapped.begin(), wrapped.end())
679 , fFlags(flags) {
680 fNumWrappedCombos = 0;
681 for (const auto& s : fWrapped) {
682 fNumWrappedCombos += s->numCombinations();
683 }
684 }
685
686 bool isConstant(int desiredCombination) const override {
687 SkASSERT(desiredCombination < this->numCombinations());
688
689 /*
690 * Regardless of whether the LocalMatrixShader elides itself or not, we always want
691 * the Constantness of the wrapped shader.
692 */
693 int desiredWrappedCombination = desiredCombination / kNumIntrinsicCombinations;
694 SkASSERT(desiredWrappedCombination < fNumWrappedCombos);
695
696 auto wrapped = PrecompileBase::SelectOption(SkSpan(fWrapped), desiredWrappedCombination);
697 if (wrapped.first) {
698 return wrapped.first->isConstant(wrapped.second);
699 }
700
701 return false;
702 }
703
704private:
705 // The LocalMatrixShader has two potential variants: with and without the LocalMatrixShader
706 inline static constexpr int kNumIntrinsicCombinations = 2;
707 inline static constexpr int kWithLocalMatrix = 1;
708 inline static constexpr int kWithoutLocalMatrix = 0;
709
710 bool isALocalMatrixShader() const override { return true; }
711
712 int numIntrinsicCombinations() const override {
713 if (fFlags != Flags::kIncludeWithOutVariant) {
714 return 1; // just kWithLocalMatrix
715 }
716 return kNumIntrinsicCombinations;
717 }
718
719 int numChildCombinations() const override { return fNumWrappedCombos; }
720
721 void addToKey(const KeyContext& keyContext,
722 PaintParamsKeyBuilder* builder,
723 PipelineDataGatherer* gatherer,
724 int desiredCombination) const override {
725 SkASSERT(desiredCombination < this->numCombinations());
726
727 int desiredLMCombination, desiredWrappedCombination;
728
729 if (fFlags != Flags::kIncludeWithOutVariant) {
730 desiredLMCombination = kWithLocalMatrix;
731 desiredWrappedCombination = desiredCombination;
732 } else {
733 desiredLMCombination = desiredCombination % kNumIntrinsicCombinations;
734 desiredWrappedCombination = desiredCombination / kNumIntrinsicCombinations;
735 }
736 SkASSERT(desiredWrappedCombination < fNumWrappedCombos);
737
738 if (desiredLMCombination == kWithLocalMatrix) {
740
741 LocalMatrixShaderBlock::BeginBlock(keyContext, builder, gatherer, kIgnoredLMShaderData);
742 }
743
744 AddToKey<PrecompileShader>(keyContext, builder, gatherer, fWrapped,
745 desiredWrappedCombination);
746
747 if (desiredLMCombination == kWithLocalMatrix) {
748 builder->endBlock();
749 }
750 }
751
752 std::vector<sk_sp<PrecompileShader>> fWrapped;
753 int fNumWrappedCombos;
754 Flags fFlags;
755};
756
759 return sk_make_sp<PrecompileLocalMatrixShader>(std::move(wrapped));
760}
761
768
769//--------------------------------------------------------------------------------------------------
771public:
773 SkSpan<const sk_sp<PrecompileColorFilter>> colorFilters)
774 : fShaders(shaders.begin(), shaders.end())
775 , fColorFilters(colorFilters.begin(), colorFilters.end()) {
776 fNumShaderCombos = 0;
777 for (const auto& s : fShaders) {
778 fNumShaderCombos += s->numCombinations();
779 }
780 fNumColorFilterCombos = 0;
781 for (const auto& cf : fColorFilters) {
782 fNumColorFilterCombos += cf->numCombinations();
783 }
784 }
785
786private:
787 int numChildCombinations() const override { return fNumShaderCombos * fNumColorFilterCombos; }
788
789 void addToKey(const KeyContext& keyContext,
790 PaintParamsKeyBuilder* builder,
791 PipelineDataGatherer* gatherer,
792 int desiredCombination) const override {
793 SkASSERT(desiredCombination < this->numCombinations());
794
795 int desiredShaderCombination = desiredCombination % fNumShaderCombos;
796 int desiredColorFilterCombination = desiredCombination / fNumShaderCombos;
797 SkASSERT(desiredColorFilterCombination < fNumColorFilterCombos);
798
799 Compose(keyContext, builder, gatherer,
800 /* addInnerToKey= */ [&]() -> void {
801 AddToKey<PrecompileShader>(keyContext, builder, gatherer, fShaders,
802 desiredShaderCombination);
803 },
804 /* addOuterToKey= */ [&]() -> void {
805 AddToKey<PrecompileColorFilter>(keyContext, builder, gatherer, fColorFilters,
806 desiredColorFilterCombination);
807 });
808 }
809
810 std::vector<sk_sp<PrecompileShader>> fShaders;
811 std::vector<sk_sp<PrecompileColorFilter>> fColorFilters;
812 int fNumShaderCombos;
813 int fNumColorFilterCombos;
814};
815
817 SkSpan<const sk_sp<PrecompileShader>> shaders,
818 SkSpan<const sk_sp<PrecompileColorFilter>> colorFilters) {
819 return sk_make_sp<PrecompileColorFilterShader>(std::move(shaders), std::move(colorFilters));
820}
821
822//--------------------------------------------------------------------------------------------------
824public:
826 SkSpan<const sk_sp<SkColorSpace>> colorSpaces)
827 : fShaders(shaders.begin(), shaders.end())
828 , fColorSpaces(colorSpaces.begin(), colorSpaces.end()) {
829 fNumShaderCombos = 0;
830 for (const auto& s : fShaders) {
831 fNumShaderCombos += s->numCombinations();
832 }
833 }
834
835private:
836 int numChildCombinations() const override { return fNumShaderCombos * fColorSpaces.size(); }
837
838 void addToKey(const KeyContext& keyContext,
839 PaintParamsKeyBuilder* builder,
840 PipelineDataGatherer* gatherer,
841 int desiredCombination) const override {
842 SkASSERT(desiredCombination < this->numCombinations());
843
844 int desiredShaderCombination = desiredCombination % fNumShaderCombos;
845 int desiredColorSpaceCombination = desiredCombination / fNumShaderCombos;
846 SkASSERT(desiredColorSpaceCombination < (int) fColorSpaces.size());
847
848 const SkColorInfo& dstInfo = keyContext.dstColorInfo();
849 const SkAlphaType dstAT = dstInfo.alphaType();
850 sk_sp<SkColorSpace> dstCS = dstInfo.refColorSpace();
851 if (!dstCS) {
852 dstCS = SkColorSpace::MakeSRGB();
853 }
854
855 sk_sp<SkColorSpace> workingCS = fColorSpaces[desiredColorSpaceCombination];
856 SkColorInfo workingInfo(dstInfo.colorType(), dstAT, workingCS);
857 KeyContextWithColorInfo workingContext(keyContext, workingInfo);
858
859 Compose(keyContext, builder, gatherer,
860 /* addInnerToKey= */ [&]() -> void {
861 AddToKey<PrecompileShader>(keyContext, builder, gatherer, fShaders,
862 desiredShaderCombination);
863 },
864 /* addOuterToKey= */ [&]() -> void {
866 workingCS.get(), dstAT, dstCS.get(), dstAT);
867 ColorSpaceTransformBlock::AddBlock(keyContext, builder, gatherer, data);
868 });
869 }
870
871 std::vector<sk_sp<PrecompileShader>> fShaders;
872 std::vector<sk_sp<SkColorSpace>> fColorSpaces;
873 int fNumShaderCombos;
874};
875
877 SkSpan<const sk_sp<PrecompileShader>> shaders,
878 SkSpan<const sk_sp<SkColorSpace>> colorSpaces) {
879 return sk_make_sp<PrecompileWorkingColorSpaceShader>(std::move(shaders),
880 std::move(colorSpaces));
881}
882
883//--------------------------------------------------------------------------------------------------
884// In Graphite this acts as a non-elidable LocalMatrixShader
886public:
888 : fWrapped(wrapped.begin(), wrapped.end()) {
889 fNumWrappedCombos = 0;
890 for (const auto& s : fWrapped) {
891 fNumWrappedCombos += s->numCombinations();
892 }
893 }
894
895 bool isConstant(int desiredCombination) const override {
896 SkASSERT(desiredCombination < fNumWrappedCombos);
897
898 auto wrapped = PrecompileBase::SelectOption(SkSpan(fWrapped), desiredCombination);
899 if (wrapped.first) {
900 return wrapped.first->isConstant(wrapped.second);
901 }
902
903 return false;
904 }
905
906private:
907 int numChildCombinations() const override { return fNumWrappedCombos; }
908
909 void addToKey(const KeyContext& keyContext,
910 PaintParamsKeyBuilder* builder,
911 PipelineDataGatherer* gatherer,
912 int desiredCombination) const override {
913 SkASSERT(desiredCombination < fNumWrappedCombos);
914
916
917 LocalMatrixShaderBlock::BeginBlock(keyContext, builder, gatherer, kIgnoredLMShaderData);
918
919 AddToKey<PrecompileShader>(keyContext, builder, gatherer, fWrapped, desiredCombination);
920
921 builder->endBlock();
922 }
923
924 std::vector<sk_sp<PrecompileShader>> fWrapped;
925 int fNumWrappedCombos;
926};
927
929 return sk_make_sp<PrecompileCTMShader>(std::move(wrapped));
930}
931
932//--------------------------------------------------------------------------------------------------
934public:
936 : fWrapped(std::move(wrapped)) {
937 fNumWrappedCombos = fWrapped->numCombinations();
938 }
939
940private:
941 // 6 known 1D blur effects + 6 known 2D blur effects
942 inline static constexpr int kNumIntrinsicCombinations = 12;
943
944 int numIntrinsicCombinations() const override { return kNumIntrinsicCombinations; }
945
946 int numChildCombinations() const override { return fNumWrappedCombos; }
947
948 void addToKey(const KeyContext& keyContext,
949 PaintParamsKeyBuilder* builder,
950 PipelineDataGatherer* gatherer,
951 int desiredCombination) const override {
952 SkASSERT(desiredCombination < this->numCombinations());
953
954 using namespace SkKnownRuntimeEffects;
955
956 int desiredBlurCombination = desiredCombination % kNumIntrinsicCombinations;
957 int desiredWrappedCombination = desiredCombination / kNumIntrinsicCombinations;
958 SkASSERT(desiredWrappedCombination < fNumWrappedCombos);
959
960 static const StableKey kIDs[kNumIntrinsicCombinations] = {
961 StableKey::k1DBlur4, StableKey::k1DBlur8, StableKey::k1DBlur12,
962 StableKey::k1DBlur16, StableKey::k1DBlur20, StableKey::k1DBlur28,
963
964 StableKey::k2DBlur4, StableKey::k2DBlur8, StableKey::k2DBlur12,
965 StableKey::k2DBlur16, StableKey::k2DBlur20, StableKey::k2DBlur28,
966 };
967
968 const SkRuntimeEffect* fEffect = GetKnownRuntimeEffect(kIDs[desiredBlurCombination]);
969
971
972 RuntimeEffectBlock::BeginBlock(keyContext, builder, gatherer, { sk_ref_sp(fEffect) });
973 fWrapped->priv().addToKey(childContext, builder, gatherer, desiredWrappedCombination);
974 builder->endBlock();
975 }
976
978 int fNumWrappedCombos;
979};
980
982 return sk_make_sp<PrecompileBlurShader>(std::move(wrapped));
983}
984
985//--------------------------------------------------------------------------------------------------
987public:
989
990private:
991 void addToKey(const KeyContext& keyContext,
992 PaintParamsKeyBuilder* builder,
993 PipelineDataGatherer* gatherer,
994 int desiredCombination) const override {
995 SkASSERT(desiredCombination == 0);
996
997 // TODO: need to add a BlurMaskFilter Block. This is somewhat blocked on figuring out
998 // what we're going to do with the Blur system.
999 }
1000};
1001
1003 return sk_make_sp<PrecompileBlurMaskFilter>();
1004}
1005
1006//--------------------------------------------------------------------------------------------------
1007//--------------------------------------------------------------------------------------------------
1009public:
1011
1012private:
1013 void addToKey(const KeyContext& keyContext,
1014 PaintParamsKeyBuilder* builder,
1015 PipelineDataGatherer* gatherer,
1016 int desiredCombination) const override {
1017 SkASSERT(desiredCombination == 0);
1018
1019 // Here, kSrcOver and the white color are just a stand-ins for some later blend mode
1020 // and color.
1021 AddBlendModeColorFilter(keyContext, builder, gatherer,
1023 }
1024};
1025
1026sk_sp<PrecompileColorFilter> PrecompileColorFilters::Blend() {
1027 return sk_make_sp<PrecompileBlendModeColorFilter>();
1028}
1029
1030//--------------------------------------------------------------------------------------------------
1032 void addToKey(const KeyContext& keyContext,
1033 PaintParamsKeyBuilder* builder,
1034 PipelineDataGatherer* gatherer,
1035 int desiredCombination) const override {
1036 SkASSERT(desiredCombination == 0);
1037
1038 constexpr SkAlphaType kAlphaType = kPremul_SkAlphaType;
1040 sk_srgb_singleton(), kAlphaType);
1041
1042 ColorSpaceTransformBlock::AddBlock(keyContext, builder, gatherer, csData);
1043 }
1044};
1045
1046sk_sp<PrecompileColorFilter> PrecompileColorFilters::LinearToSRGBGamma() {
1047 return sk_make_sp<PrecompileColorSpaceXformColorFilter>();
1048}
1049
1050sk_sp<PrecompileColorFilter> PrecompileColorFilters::SRGBToLinearGamma() {
1051 return sk_make_sp<PrecompileColorSpaceXformColorFilter>();
1052}
1053
1055 return sk_make_sp<PrecompileColorSpaceXformColorFilter>();
1056}
1057
1058//--------------------------------------------------------------------------------------------------
1059sk_sp<PrecompileColorFilter> PrecompileColorFilters::Luma() {
1060 const SkRuntimeEffect* lumaEffect =
1061 GetKnownRuntimeEffect(SkKnownRuntimeEffects::StableKey::kLuma);
1062
1063 return MakePrecompileColorFilter(sk_ref_sp(lumaEffect));
1064}
1065
1066//--------------------------------------------------------------------------------------------------
1068public:
1070 SkSpan<const sk_sp<PrecompileColorFilter>> innerOptions)
1071 : fOuterOptions(outerOptions.begin(), outerOptions.end())
1072 , fInnerOptions(innerOptions.begin(), innerOptions.end()) {
1073
1074 fNumOuterCombos = 0;
1075 for (const auto& outerOption : fOuterOptions) {
1076 fNumOuterCombos += outerOption ? outerOption->numCombinations() : 1;
1077 }
1078
1079 fNumInnerCombos = 0;
1080 for (const auto& innerOption : fInnerOptions) {
1081 fNumInnerCombos += innerOption ? innerOption->numCombinations() : 1;
1082 }
1083 }
1084
1085private:
1086 int numChildCombinations() const override { return fNumOuterCombos * fNumInnerCombos; }
1087
1088 void addToKey(const KeyContext& keyContext,
1089 PaintParamsKeyBuilder* builder,
1090 PipelineDataGatherer* gatherer,
1091 int desiredCombination) const override {
1092 SkASSERT(desiredCombination < this->numCombinations());
1093
1094 const int desiredOuterCombination = desiredCombination % fNumOuterCombos;
1095 int remainingCombinations = desiredCombination / fNumOuterCombos;
1096
1097 const int desiredInnerCombination = remainingCombinations % fNumInnerCombos;
1098 remainingCombinations /= fNumInnerCombos;
1099
1100 SkASSERT(!remainingCombinations);
1101
1102 sk_sp<PrecompileColorFilter> inner, outer;
1103 int innerChildOptions, outerChildOptions;
1104
1105 std::tie(outer, outerChildOptions) = SelectOption<PrecompileColorFilter>(
1106 fOuterOptions, desiredOuterCombination);
1107 std::tie(inner, innerChildOptions) = SelectOption<PrecompileColorFilter>(
1108 fInnerOptions, desiredInnerCombination);
1109
1110 if (!inner && !outer) {
1111 // A "passthrough" color filter returns the input color as-is.
1112 builder->addBlock(BuiltInCodeSnippetID::kPriorOutput);
1113 } else if (!inner) {
1114 outer->priv().addToKey(keyContext, builder, gatherer, outerChildOptions);
1115 } else if (!outer) {
1116 inner->priv().addToKey(keyContext, builder, gatherer, innerChildOptions);
1117 } else {
1118 Compose(keyContext, builder, gatherer,
1119 /* addInnerToKey= */ [&]() -> void {
1120 inner->priv().addToKey(keyContext, builder, gatherer, innerChildOptions);
1121 },
1122 /* addOuterToKey= */ [&]() -> void {
1123 outer->priv().addToKey(keyContext, builder, gatherer, outerChildOptions);
1124 });
1125 }
1126 }
1127
1128 std::vector<sk_sp<PrecompileColorFilter>> fOuterOptions;
1129 std::vector<sk_sp<PrecompileColorFilter>> fInnerOptions;
1130
1131 int fNumOuterCombos;
1132 int fNumInnerCombos;
1133};
1134
1135sk_sp<PrecompileColorFilter> PrecompileColorFilters::Compose(
1136 SkSpan<const sk_sp<PrecompileColorFilter>> outerOptions,
1137 SkSpan<const sk_sp<PrecompileColorFilter>> innerOptions) {
1138 if (is_empty(outerOptions) && is_empty(innerOptions)) {
1139 return nullptr;
1140 }
1141
1142 return sk_make_sp<PrecompileComposeColorFilter>(outerOptions, innerOptions);
1143}
1144
1145//--------------------------------------------------------------------------------------------------
1147 void addToKey(const KeyContext& keyContext,
1148 PaintParamsKeyBuilder* builder,
1149 PipelineDataGatherer* gatherer,
1150 int desiredCombination) const override {
1151 SkASSERT(desiredCombination == 0);
1152
1154 }
1155};
1156
1158 return sk_make_sp<PrecompileGaussianColorFilter>();
1159}
1160
1161//--------------------------------------------------------------------------------------------------
1163 void addToKey(const KeyContext& keyContext,
1164 PaintParamsKeyBuilder* builder,
1165 PipelineDataGatherer* gatherer,
1166 int desiredCombination) const override {
1167 SkASSERT(desiredCombination == 0);
1168
1169 static constexpr float kIdentity[20] = { 1, 0, 0, 0, 0,
1170 0, 1, 0, 0, 0,
1171 0, 0, 1, 0, 0,
1172 0, 0, 0, 1, 0 };
1173
1174 MatrixColorFilterBlock::MatrixColorFilterData matrixCFData(kIdentity, /* inHSLA= */ false);
1175
1176 MatrixColorFilterBlock::AddBlock(keyContext, builder, gatherer, matrixCFData);
1177 }
1178};
1179
1180sk_sp<PrecompileColorFilter> PrecompileColorFilters::Matrix() {
1181 return sk_make_sp<PrecompileMatrixColorFilter>();
1182}
1183
1184sk_sp<PrecompileColorFilter> PrecompileColorFilters::HSLAMatrix() {
1185 return sk_make_sp<PrecompileMatrixColorFilter>();
1186}
1187
1188//--------------------------------------------------------------------------------------------------
1189sk_sp<PrecompileColorFilter> PrecompileColorFilters::Lerp(
1190 SkSpan<const sk_sp<PrecompileColorFilter>> dstOptions,
1191 SkSpan<const sk_sp<PrecompileColorFilter>> srcOptions) {
1192
1193 if (dstOptions.empty() && srcOptions.empty()) {
1194 return nullptr;
1195 }
1196
1197 const SkRuntimeEffect* lerpEffect =
1198 GetKnownRuntimeEffect(SkKnownRuntimeEffects::StableKey::kLerp);
1199
1200 // Since the RuntimeEffect Precompile objects behave differently we have to manually create
1201 // all the combinations here (b/332690425).
1203 combos.reserve(dstOptions.size() * srcOptions.size());
1204 for (const sk_sp<PrecompileColorFilter>& d : dstOptions) {
1205 for (const sk_sp<PrecompileColorFilter>& s : srcOptions) {
1206 combos.push_back({ d, s });
1207 }
1208 }
1210 comboSpans.reserve(combos.size());
1211 for (const std::array<const PrecompileChildPtr, 2>& combo : combos) {
1212 comboSpans.push_back({ combo });
1213 }
1214
1215 return MakePrecompileColorFilter(sk_ref_sp(lerpEffect), comboSpans);
1216}
1217
1218//--------------------------------------------------------------------------------------------------
1220 void addToKey(const KeyContext& keyContext,
1221 PaintParamsKeyBuilder* builder,
1222 PipelineDataGatherer* gatherer,
1223 int desiredCombination) const override {
1224 SkASSERT(desiredCombination == 0);
1225
1226 TableColorFilterBlock::TableColorFilterData data(/* proxy= */ nullptr);
1227
1228 TableColorFilterBlock::AddBlock(keyContext, builder, gatherer, data);
1229 }
1230};
1231
1232sk_sp<PrecompileColorFilter> PrecompileColorFilters::Table() {
1233 return sk_make_sp<PrecompileTableColorFilter>();
1234}
1235
1236//--------------------------------------------------------------------------------------------------
1237sk_sp<PrecompileColorFilter> PrecompileColorFilters::Lighting() {
1238 return PrecompileColorFilters::Matrix();
1239}
1240
1241//--------------------------------------------------------------------------------------------------
1243public:
1245 : fChildOptions(childOptions.begin(), childOptions.end()) {
1246
1247 fNumChildCombos = 0;
1248 for (const auto& childOption : fChildOptions) {
1249 fNumChildCombos += childOption->numCombinations();
1250 }
1251 }
1252
1253private:
1254 int numChildCombinations() const override { return fNumChildCombos; }
1255
1256 void addToKey(const KeyContext& keyContext,
1257 PaintParamsKeyBuilder* builder,
1258 PipelineDataGatherer* gatherer,
1259 int desiredCombination) const override {
1260 SkASSERT(desiredCombination < fNumChildCombos);
1261
1262 constexpr SkAlphaType kAlphaType = kPremul_SkAlphaType;
1264 sk_srgb_singleton(), kAlphaType);
1265
1266 // Use two nested compose blocks to chain (dst->working), child, and (working->dst) together
1267 // while appearing as one block to the parent node.
1268 Compose(keyContext, builder, gatherer,
1269 /* addInnerToKey= */ [&]() -> void {
1270 // Inner compose
1271 Compose(keyContext, builder, gatherer,
1272 /* addInnerToKey= */ [&]() -> void {
1273 // Innermost (inner of inner compose)
1274 ColorSpaceTransformBlock::AddBlock(keyContext, builder, gatherer,
1275 csData);
1276 },
1277 /* addOuterToKey= */ [&]() -> void {
1278 // Middle (outer of inner compose)
1279 AddToKey<PrecompileColorFilter>(keyContext, builder, gatherer,
1280 fChildOptions, desiredCombination);
1281 });
1282 },
1283 /* addOuterToKey= */ [&]() -> void {
1284 // Outermost (outer of outer compose)
1285 ColorSpaceTransformBlock::AddBlock(keyContext, builder, gatherer, csData);
1286 });
1287 }
1288
1289 std::vector<sk_sp<PrecompileColorFilter>> fChildOptions;
1290
1291 int fNumChildCombos;
1292};
1293
1295 SkSpan<const sk_sp<PrecompileColorFilter>> childOptions) {
1296 return sk_make_sp<PrecompileWithWorkingFormatColorFilter>(childOptions);
1297}
1298
1299//--------------------------------------------------------------------------------------------------
1300//--------------------------------------------------------------------------------------------------
1306
1308 : fChild(std::move(child)) {
1309 SkASSERT(precompilebase_is_valid_as_child(fChild.get()));
1310}
1311
1312std::optional<SkRuntimeEffect::ChildType> PrecompileChildPtr::type() const {
1313 if (fChild) {
1314 switch (fChild->type()) {
1316 return SkRuntimeEffect::ChildType::kShader;
1318 return SkRuntimeEffect::ChildType::kColorFilter;
1320 return SkRuntimeEffect::ChildType::kBlender;
1321 default:
1322 break;
1323 }
1324 }
1325 return std::nullopt;
1326}
1327
1329 return (fChild && fChild->type() == PrecompileBase::Type::kShader)
1330 ? static_cast<PrecompileShader*>(fChild.get())
1331 : nullptr;
1332}
1333
1335 return (fChild && fChild->type() == PrecompileBase::Type::kColorFilter)
1336 ? static_cast<PrecompileColorFilter*>(fChild.get())
1337 : nullptr;
1338}
1339
1341 return (fChild && fChild->type() == PrecompileBase::Type::kBlender)
1342 ? static_cast<PrecompileBlender*>(fChild.get())
1343 : nullptr;
1344}
1345
1346//--------------------------------------------------------------------------------------------------
1347namespace {
1348
1349int num_options_in_set(const std::vector<PrecompileChildPtr>& optionSet) {
1350 int numOptions = 1;
1351 for (const PrecompileChildPtr& childOption : optionSet) {
1352 // A missing child will fall back to a passthrough object
1353 if (childOption.base()) {
1354 numOptions *= childOption.base()->numCombinations();
1355 }
1356 }
1357
1358 return numOptions;
1359}
1360
1361// This is the precompile correlate to KeyHelper.cpp's add_children_to_key
1362void add_children_to_key(const KeyContext& keyContext,
1363 PaintParamsKeyBuilder* builder,
1364 PipelineDataGatherer* gatherer,
1365 int desiredCombination,
1366 const std::vector<PrecompileChildPtr>& optionSet,
1369
1370 SkASSERT(optionSet.size() == childInfo.size());
1371
1372 KeyContextWithScope childContext(keyContext, KeyContext::Scope::kRuntimeEffect);
1373
1374 int remainingCombinations = desiredCombination;
1375
1376 for (size_t index = 0; index < optionSet.size(); ++index) {
1377 const PrecompileChildPtr& childOption = optionSet[index];
1378
1379 const int numChildCombos = childOption.base() ? childOption.base()->numCombinations()
1380 : 1;
1381 const int curCombo = remainingCombinations % numChildCombos;
1382 remainingCombinations /= numChildCombos;
1383
1384 std::optional<ChildType> type = childOption.type();
1385 if (type == ChildType::kShader) {
1386 childOption.shader()->priv().addToKey(childContext, builder, gatherer, curCombo);
1387 } else if (type == ChildType::kColorFilter) {
1388 childOption.colorFilter()->priv().addToKey(childContext, builder, gatherer, curCombo);
1389 } else if (type == ChildType::kBlender) {
1390 childOption.blender()->priv().addToKey(childContext, builder, gatherer, curCombo);
1391 } else {
1392 SkASSERT(curCombo == 0);
1393
1394 // We don't have a child effect. Substitute in a no-op effect.
1395 switch (childInfo[index].type) {
1396 case ChildType::kShader:
1397 // A missing shader returns transparent black
1398 SolidColorShaderBlock::AddBlock(childContext, builder, gatherer,
1400 break;
1401
1402 case ChildType::kColorFilter:
1403 // A "passthrough" shader returns the input color as-is.
1405 break;
1406
1407 case ChildType::kBlender:
1408 // A "passthrough" blender performs `blend_src_over(src, dest)`.
1409 AddKnownModeBlend(childContext, builder, gatherer, SkBlendMode::kSrcOver);
1410 break;
1411 }
1412 }
1413 }
1414}
1415
1416} // anonymous namespace
1417
1418template<typename T>
1419class PrecompileRTEffect : public T {
1420public:
1423 : fEffect(std::move(effect)) {
1424 fChildOptions.reserve(childOptions.size());
1425 for (PrecompileChildOptions c : childOptions) {
1426 fChildOptions.push_back({ c.begin(), c.end() });
1427 }
1428 }
1429
1430private:
1431 int numChildCombinations() const override {
1432 int numOptions = 0;
1433 for (const std::vector<PrecompileChildPtr>& optionSet : fChildOptions) {
1434 numOptions += num_options_in_set(optionSet);
1435 }
1436
1437 return numOptions ? numOptions : 1;
1438 }
1439
1440 void addToKey(const KeyContext& keyContext,
1441 PaintParamsKeyBuilder* builder,
1442 PipelineDataGatherer* gatherer,
1443 int desiredCombination) const override {
1444
1445 SkASSERT(desiredCombination < this->numCombinations());
1446
1447 SkSpan<const SkRuntimeEffect::Child> childInfo = fEffect->children();
1448
1449 RuntimeEffectBlock::BeginBlock(keyContext, builder, gatherer, { fEffect });
1450
1451 for (const std::vector<PrecompileChildPtr>& optionSet : fChildOptions) {
1452 int numOptionsInSet = num_options_in_set(optionSet);
1453
1454 if (desiredCombination < numOptionsInSet) {
1455 add_children_to_key(keyContext, builder, gatherer, desiredCombination, optionSet,
1456 childInfo);
1457 break;
1458 }
1459
1460 desiredCombination -= numOptionsInSet;
1461 }
1462
1463 builder->endBlock();
1464 }
1465
1466 sk_sp<SkRuntimeEffect> fEffect;
1467 std::vector<std::vector<PrecompileChildPtr>> fChildOptions;
1468};
1469
1473 // TODO: check that 'effect' has the kAllowShader_Flag bit set and:
1474 // for each entry in childOptions:
1475 // all the SkPrecompileChildPtrs have the same type as the corresponding child in the effect
1476 return sk_make_sp<PrecompileRTEffect<PrecompileShader>>(std::move(effect), childOptions);
1477}
1478
1482 // TODO: check that 'effect' has the kAllowColorFilter_Flag bit set and:
1483 // for each entry in childOptions:
1484 // all the SkPrecompileChildPtrs have the same type as the corresponding child in the effect
1485 return sk_make_sp<PrecompileRTEffect<PrecompileColorFilter>>(std::move(effect), childOptions);
1486}
1487
1491 // TODO: check that 'effect' has the kAllowBlender_Flag bit set and:
1492 // for each entry in childOptions:
1493 // all the SkPrecompileChildPtrs have the same type as the corresponding child in the effect
1494 return sk_make_sp<PrecompileRTEffect<PrecompileBlender>>(std::move(effect), childOptions);
1495}
1496
1497} // namespace skgpu::graphite
1498
1499//--------------------------------------------------------------------------------------------------
const char * options
static const char * srcs[2]
static void is_empty(skiatest::Reporter *reporter, const SkPath &p)
SkAlphaType
Definition SkAlphaType.h:26
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
#define SkASSERT(cond)
Definition SkAssert.h:116
SkBlendMode
Definition SkBlendMode.h:38
@ kDstIn
r = d * sa
@ kSrcOver
r = s + (1-sa)*d
@ kOverlay
multiply or screen, depending on destination
constexpr SkPMColor4f SK_PMColor4fWHITE
constexpr SkPMColor4f SK_PMColor4fTRANSPARENT
SkColorSpace * sk_srgb_singleton()
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
static sk_sp< GrTextureProxy > wrapped(skiatest::Reporter *reporter, GrRecordingContext *rContext, GrProxyProvider *proxyProvider, SkBackingFit fit)
SkAlphaType alphaType() const
sk_sp< SkColorSpace > refColorSpace() const
SkColorType colorType() const
static sk_sp< SkColorSpace > MakeSRGB()
static const SkMatrix & I()
SkSpan< const Child > children() const
constexpr bool empty() const
Definition SkSpan_impl.h:96
constexpr size_t size() const
Definition SkSpan_impl.h:95
T * get() const
Definition SkRefCnt.h:303
const SkColorInfo & dstColorInfo() const
Definition KeyContext.h:65
virtual int numChildCombinations() const
Definition Precompile.h:58
static std::pair< sk_sp< T >, int > SelectOption(SkSpan< const sk_sp< T > > options, int desiredOption)
Definition Precompile.h:99
std::optional< SkBlendMode > asBlendMode() const final
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
PrecompileBlendShader(SkSpan< const sk_sp< PrecompileBlender > > runtimeBlendEffects, SkSpan< const sk_sp< PrecompileShader > > dsts, SkSpan< const sk_sp< PrecompileShader > > srcs, bool needsPorterDuffBased, bool needsSeparableMode)
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
static sk_sp< PrecompileBlender > Mode(SkBlendMode)
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
PrecompileBlurShader(sk_sp< PrecompileShader > wrapped)
bool isConstant(int desiredCombination) const override
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
PrecompileCTMShader(SkSpan< const sk_sp< PrecompileShader > > wrapped)
PrecompileBlender * blender() const
std::optional< SkRuntimeEffect::ChildType > type() const
PrecompileColorFilter * colorFilter() const
PrecompileColorFilterShader(SkSpan< const sk_sp< PrecompileShader > > shaders, SkSpan< const sk_sp< PrecompileColorFilter > > colorFilters)
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
bool isConstant(int desiredCombination) const override
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
PrecompileComposeColorFilter(SkSpan< const sk_sp< PrecompileColorFilter > > outerOptions, SkSpan< const sk_sp< PrecompileColorFilter > > innerOptions)
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
PrecompileCoordClampShader(SkSpan< const sk_sp< PrecompileShader > > shaders)
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
PrecompileGradientShader(SkShaderBase::GradientType type)
PrecompileImageShader(SkEnumBitMask< PrecompileImageShaderFlags > flags)
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
PrecompileLocalMatrixShader(SkSpan< const sk_sp< PrecompileShader > > wrapped, Flags flags=Flags::kNone)
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
bool isConstant(int desiredCombination) const override
static sk_sp< PrecompileMaskFilter > Blur()
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
PrecompileRTEffect(sk_sp< SkRuntimeEffect > effect, SkSpan< const PrecompileChildOptions > childOptions)
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
PrecompileWithWorkingFormatColorFilter(SkSpan< const sk_sp< PrecompileColorFilter > > childOptions)
PrecompileWorkingColorSpaceShader(SkSpan< const sk_sp< PrecompileShader > > shaders, SkSpan< const sk_sp< SkColorSpace > > colorSpaces)
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
void addToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, int desiredCombination) const override
void reserve(int n)
Definition SkTArray.h:165
int size() const
Definition SkTArray.h:416
static const char * begin(const StringSlice &s)
Definition editor.cpp:252
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
static bool b
struct MyStruct s
FlutterSemanticsFlag flags
glong glong end
const SkRuntimeEffect * GetKnownRuntimeEffect(StableKey stableKey)
SK_API sk_sp< PrecompileBlender > Arithmetic()
sk_sp< PrecompileColorFilter > WithWorkingFormat(SkSpan< const sk_sp< PrecompileColorFilter > > childOptions)
sk_sp< PrecompileColorFilter > Gaussian()
sk_sp< PrecompileColorFilter > ColorSpaceXform()
sk_sp< PrecompileShader > Image(SkEnumBitMask< PrecompileImageShaderFlags >)
sk_sp< PrecompileShader > CTM(SkSpan< const sk_sp< PrecompileShader > > wrapped)
sk_sp< PrecompileShader > LocalMatrixBothVariants(SkSpan< const sk_sp< PrecompileShader > > wrapped)
sk_sp< PrecompileShader > TwoPointConicalGradient(bool withLM)
sk_sp< PrecompileShader > Blur(sk_sp< PrecompileShader > child)
sk_sp< PrecompileShader > LinearGradient(bool withLM)
sk_sp< PrecompileShader > Picture(bool withLM)
sk_sp< PrecompileShader > SweepGradient(bool withLM)
sk_sp< PrecompileShader > RadialGradient(bool withLM)
SK_API sk_sp< PrecompileShader > ColorFilter(SkSpan< const sk_sp< PrecompileShader > > shaders, SkSpan< const sk_sp< PrecompileColorFilter > > colorFilters)
SK_API sk_sp< PrecompileShader > LocalMatrix(SkSpan< const sk_sp< PrecompileShader > > wrapped)
SK_API sk_sp< PrecompileShader > WorkingColorSpace(SkSpan< const sk_sp< PrecompileShader > > shaders, SkSpan< const sk_sp< SkColorSpace > > colorSpaces)
SK_API sk_sp< PrecompileShader > LinearGradient()
SK_API sk_sp< PrecompileShader > RadialGradient()
SK_API sk_sp< PrecompileShader > Picture()
SK_API sk_sp< PrecompileShader > CoordClamp(SkSpan< const sk_sp< PrecompileShader > >)
SK_API sk_sp< PrecompileShader > MakeTurbulence()
SK_API sk_sp< PrecompileShader > Image()
SK_API sk_sp< PrecompileShader > Empty()
SK_API sk_sp< PrecompileShader > Blend(SkSpan< SkBlendMode > blendModes, SkSpan< const sk_sp< PrecompileShader > > dsts, SkSpan< const sk_sp< PrecompileShader > > srcs)
SK_API sk_sp< PrecompileShader > MakeFractalNoise()
SK_API sk_sp< PrecompileShader > YUVImage()
SK_API sk_sp< PrecompileShader > SweepGradient()
SK_API sk_sp< PrecompileShader > RawImage()
SK_API sk_sp< PrecompileShader > Color()
SK_API sk_sp< PrecompileShader > TwoPointConicalGradient()
sk_sp< PrecompileBlender > MakePrecompileBlender(sk_sp< SkRuntimeEffect > effect, SkSpan< const PrecompileChildOptions > childOptions)
sk_sp< PrecompileShader > MakePrecompileShader(sk_sp< SkRuntimeEffect > effect, SkSpan< const PrecompileChildOptions > childOptions)
void AddKnownModeBlend(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, SkBlendMode bm)
void AddBlendModeColorFilter(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, SkBlendMode bm, const SkPMColor4f &srcColor)
void Compose(const KeyContext &keyContext, PaintParamsKeyBuilder *keyBuilder, PipelineDataGatherer *gatherer, AddToKeyFn addInnerToKey, AddToKeyFn addOuterToKey)
void Blend(const KeyContext &keyContext, PaintParamsKeyBuilder *keyBuilder, PipelineDataGatherer *gatherer, AddToKeyFn addBlendToKey, AddToKeyFn addSrcToKey, AddToKeyFn addDstToKey)
sk_sp< PrecompileColorFilter > MakePrecompileColorFilter(sk_sp< SkRuntimeEffect > effect, SkSpan< const PrecompileChildOptions > childOptions)
void AddModeBlend(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, SkBlendMode bm)
SkSpan< const float > GetPorterDuffBlendConstants(SkBlendMode mode)
Definition Blend.cpp:53
Definition ref_ptr.h:256
#define T
static constexpr SkCubicResampler Mitchell()
static constexpr SkISize MakeEmpty()
Definition SkSize.h:22
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static constexpr SkRect MakeEmpty()
Definition SkRect.h:595
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, SkBlendMode)
static void BeginBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *)
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, SkSpan< const float > coeffs)
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, const ColorSpaceTransformData &)
static void BeginBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, const CoordClampData &)
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, const GradientData &)
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, const ImageData &)
static void BeginBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, const LMShaderData &)
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, const MatrixColorFilterData &)
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, const PerlinNoiseData &)
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *)
static void BeginBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, const ShaderData &)
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, const SkPMColor4f &)
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, const TableColorFilterData &)
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, const ImageData &)