1 /*
2  * Copyright 2015 Google Inc.
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 "GrXfermodeFragmentProcessor.h"
9 
10 #include "GrConstColorProcessor.h"
11 #include "GrFragmentProcessor.h"
12 #include "glsl/GrGLSLFragmentProcessor.h"
13 #include "glsl/GrGLSLBlend.h"
14 #include "glsl/GrGLSLFragmentShaderBuilder.h"
15 #include "SkGr.h"
16 #include "SkXfermodePriv.h"
17 
18 // Some of the cpu implementations of blend modes differ too much from the GPU enough that
19 // we can't use the cpu implementation to implement constantOutputForConstantInput.
does_cpu_blend_impl_match_gpu(SkBlendMode mode)20 static inline bool does_cpu_blend_impl_match_gpu(SkBlendMode mode) {
21     // The non-seperable modes differ too much. So does SoftLight. ColorBurn differs too much on our
22     // test iOS device (but we just disable it across the aboard since it may happen on untested
23     // GPUs).
24     return mode <= SkBlendMode::kLastSeparableMode && mode != SkBlendMode::kSoftLight &&
25            mode != SkBlendMode::kColorBurn;
26 }
27 
28 //////////////////////////////////////////////////////////////////////////////
29 
30 class ComposeTwoFragmentProcessor : public GrFragmentProcessor {
31 public:
Make(std::unique_ptr<GrFragmentProcessor> src,std::unique_ptr<GrFragmentProcessor> dst,SkBlendMode mode)32     static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> src,
33                                                      std::unique_ptr<GrFragmentProcessor> dst,
34                                                      SkBlendMode mode) {
35         return std::unique_ptr<GrFragmentProcessor>(
36                 new ComposeTwoFragmentProcessor(std::move(src), std::move(dst), mode));
37     }
38 
name() const39     const char* name() const override { return "ComposeTwo"; }
40 
41 #ifdef SK_DEBUG
dumpInfo() const42     SkString dumpInfo() const override {
43         SkString str;
44 
45         str.appendf("Mode: %s", SkBlendMode_Name(fMode));
46 
47         for (int i = 0; i < this->numChildProcessors(); ++i) {
48             str.appendf(" [%s %s]",
49                         this->childProcessor(i).name(), this->childProcessor(i).dumpInfo().c_str());
50         }
51         return str;
52     }
53 #endif
54 
55     std::unique_ptr<GrFragmentProcessor> clone() const override;
56 
getMode() const57     SkBlendMode getMode() const { return fMode; }
58 
59 private:
ComposeTwoFragmentProcessor(std::unique_ptr<GrFragmentProcessor> src,std::unique_ptr<GrFragmentProcessor> dst,SkBlendMode mode)60     ComposeTwoFragmentProcessor(std::unique_ptr<GrFragmentProcessor> src,
61                                 std::unique_ptr<GrFragmentProcessor> dst,
62                                 SkBlendMode mode)
63             : INHERITED(kComposeTwoFragmentProcessor_ClassID, OptFlags(src.get(), dst.get(), mode))
64             , fMode(mode) {
65         SkDEBUGCODE(int shaderAChildIndex = )this->registerChildProcessor(std::move(src));
66         SkDEBUGCODE(int shaderBChildIndex = )this->registerChildProcessor(std::move(dst));
67         SkASSERT(0 == shaderAChildIndex);
68         SkASSERT(1 == shaderBChildIndex);
69     }
70 
OptFlags(const GrFragmentProcessor * src,const GrFragmentProcessor * dst,SkBlendMode mode)71     static OptimizationFlags OptFlags(const GrFragmentProcessor* src,
72                                       const GrFragmentProcessor* dst, SkBlendMode mode) {
73         OptimizationFlags flags;
74         switch (mode) {
75             case SkBlendMode::kClear:
76             case SkBlendMode::kSrc:
77             case SkBlendMode::kDst:
78                 SK_ABORT("Should never create clear, src, or dst compose two FP.");
79                 flags = kNone_OptimizationFlags;
80                 break;
81 
82             // Produces opaque if both src and dst are opaque.
83             case SkBlendMode::kSrcIn:
84             case SkBlendMode::kDstIn:
85             case SkBlendMode::kModulate:
86                 flags = src->preservesOpaqueInput() && dst->preservesOpaqueInput()
87                                 ? kPreservesOpaqueInput_OptimizationFlag
88                                 : kNone_OptimizationFlags;
89                 break;
90 
91             // Produces zero when both are opaque, indeterminate if one is opaque.
92             case SkBlendMode::kSrcOut:
93             case SkBlendMode::kDstOut:
94             case SkBlendMode::kXor:
95                 flags = kNone_OptimizationFlags;
96                 break;
97 
98             // Is opaque if the dst is opaque.
99             case SkBlendMode::kSrcATop:
100                 flags = dst->preservesOpaqueInput() ? kPreservesOpaqueInput_OptimizationFlag
101                                                     : kNone_OptimizationFlags;
102                 break;
103 
104             // DstATop is the converse of kSrcATop. Screen is also opaque if the src is a opaque.
105             case SkBlendMode::kDstATop:
106             case SkBlendMode::kScreen:
107                 flags = src->preservesOpaqueInput() ? kPreservesOpaqueInput_OptimizationFlag
108                                                     : kNone_OptimizationFlags;
109                 break;
110 
111             // These modes are all opaque if either src or dst is opaque. All the advanced modes
112             // compute alpha as src-over.
113             case SkBlendMode::kSrcOver:
114             case SkBlendMode::kDstOver:
115             case SkBlendMode::kPlus:
116             case SkBlendMode::kOverlay:
117             case SkBlendMode::kDarken:
118             case SkBlendMode::kLighten:
119             case SkBlendMode::kColorDodge:
120             case SkBlendMode::kColorBurn:
121             case SkBlendMode::kHardLight:
122             case SkBlendMode::kSoftLight:
123             case SkBlendMode::kDifference:
124             case SkBlendMode::kExclusion:
125             case SkBlendMode::kMultiply:
126             case SkBlendMode::kHue:
127             case SkBlendMode::kSaturation:
128             case SkBlendMode::kColor:
129             case SkBlendMode::kLuminosity:
130                 flags = src->preservesOpaqueInput() || dst->preservesOpaqueInput()
131                                 ? kPreservesOpaqueInput_OptimizationFlag
132                                 : kNone_OptimizationFlags;
133                 break;
134         }
135         if (does_cpu_blend_impl_match_gpu(mode) && src->hasConstantOutputForConstantInput() &&
136             dst->hasConstantOutputForConstantInput()) {
137             flags |= kConstantOutputForConstantInput_OptimizationFlag;
138         }
139         return flags;
140     }
141 
onGetGLSLProcessorKey(const GrShaderCaps & caps,GrProcessorKeyBuilder * b) const142     void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
143         b->add32((int)fMode);
144     }
145 
onIsEqual(const GrFragmentProcessor & other) const146     bool onIsEqual(const GrFragmentProcessor& other) const override {
147         const ComposeTwoFragmentProcessor& cs = other.cast<ComposeTwoFragmentProcessor>();
148         return fMode == cs.fMode;
149     }
150 
constantOutputForConstantInput(const SkPMColor4f & input) const151     SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
152         SkPMColor4f opaqueInput = { input.fR, input.fG, input.fB, 1 };
153         SkPMColor4f src = ConstantOutputForConstantInput(this->childProcessor(0), opaqueInput);
154         SkPMColor4f dst = ConstantOutputForConstantInput(this->childProcessor(1), opaqueInput);
155         SkPMColor4f res = SkBlendMode_Apply(fMode, src, dst);
156         return res * input.fA;
157     }
158 
159     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
160 
161     SkBlendMode fMode;
162 
163     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
164 
165     typedef GrFragmentProcessor INHERITED;
166 };
167 
168 /////////////////////////////////////////////////////////////////////
169 
170 class GLComposeTwoFragmentProcessor : public GrGLSLFragmentProcessor {
171 public:
172     void emitCode(EmitArgs&) override;
173 
174 private:
175     typedef GrGLSLFragmentProcessor INHERITED;
176 };
177 
178 /////////////////////////////////////////////////////////////////////
179 
180 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ComposeTwoFragmentProcessor);
181 
182 #if GR_TEST_UTILS
TestCreate(GrProcessorTestData * d)183 std::unique_ptr<GrFragmentProcessor> ComposeTwoFragmentProcessor::TestCreate(
184         GrProcessorTestData* d) {
185     // Create two random frag procs.
186     std::unique_ptr<GrFragmentProcessor> fpA(GrProcessorUnitTest::MakeChildFP(d));
187     std::unique_ptr<GrFragmentProcessor> fpB(GrProcessorUnitTest::MakeChildFP(d));
188 
189     SkBlendMode mode;
190     do {
191         mode = static_cast<SkBlendMode>(d->fRandom->nextRangeU(0, (int)SkBlendMode::kLastMode));
192     } while (SkBlendMode::kClear == mode || SkBlendMode::kSrc == mode || SkBlendMode::kDst == mode);
193     return std::unique_ptr<GrFragmentProcessor>(
194             new ComposeTwoFragmentProcessor(std::move(fpA), std::move(fpB), mode));
195 }
196 #endif
197 
clone() const198 std::unique_ptr<GrFragmentProcessor> ComposeTwoFragmentProcessor::clone() const {
199     auto src = this->childProcessor(0).clone();
200     auto dst = this->childProcessor(1).clone();
201     return std::unique_ptr<GrFragmentProcessor>(
202             new ComposeTwoFragmentProcessor(std::move(src), std::move(dst), fMode));
203 }
204 
onCreateGLSLInstance() const205 GrGLSLFragmentProcessor* ComposeTwoFragmentProcessor::onCreateGLSLInstance() const{
206     return new GLComposeTwoFragmentProcessor;
207 }
208 
209 /////////////////////////////////////////////////////////////////////
210 
emitCode(EmitArgs & args)211 void GLComposeTwoFragmentProcessor::emitCode(EmitArgs& args) {
212 
213     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
214     const ComposeTwoFragmentProcessor& cs = args.fFp.cast<ComposeTwoFragmentProcessor>();
215 
216     const char* inputColor = nullptr;
217     if (args.fInputColor) {
218         inputColor = "inputColor";
219         fragBuilder->codeAppendf("half4 inputColor = half4(%s.rgb, 1.0);", args.fInputColor);
220     }
221 
222     // declare outputColor and emit the code for each of the two children
223     SkString srcColor("xfer_src");
224     this->emitChild(0, inputColor, &srcColor, args);
225 
226     SkString dstColor("xfer_dst");
227     this->emitChild(1, inputColor, &dstColor, args);
228 
229     // emit blend code
230     SkBlendMode mode = cs.getMode();
231     fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkBlendMode_Name(mode));
232     GrGLSLBlend::AppendMode(fragBuilder,
233                             srcColor.c_str(),
234                             dstColor.c_str(),
235                             args.fOutputColor,
236                             mode);
237 
238     // re-multiply the output color by the input color's alpha
239     if (args.fInputColor) {
240         fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
241     }
242 }
243 
MakeFromTwoProcessors(std::unique_ptr<GrFragmentProcessor> src,std::unique_ptr<GrFragmentProcessor> dst,SkBlendMode mode)244 std::unique_ptr<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromTwoProcessors(
245         std::unique_ptr<GrFragmentProcessor> src,
246         std::unique_ptr<GrFragmentProcessor> dst,
247         SkBlendMode mode) {
248     switch (mode) {
249         case SkBlendMode::kClear:
250             return GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT,
251                                                GrConstColorProcessor::InputMode::kIgnore);
252         case SkBlendMode::kSrc:
253             return src;
254         case SkBlendMode::kDst:
255             return dst;
256         default:
257             return ComposeTwoFragmentProcessor::Make(std::move(src), std::move(dst), mode);
258     }
259 }
260 
261 //////////////////////////////////////////////////////////////////////////////
262 
263 class ComposeOneFragmentProcessor : public GrFragmentProcessor {
264 public:
265     enum Child {
266         kDst_Child,
267         kSrc_Child,
268     };
269 
Make(std::unique_ptr<GrFragmentProcessor> fp,SkBlendMode mode,Child child)270     static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp,
271                                                      SkBlendMode mode, Child child) {
272         if (!fp) {
273             return nullptr;
274         }
275         return std::unique_ptr<GrFragmentProcessor>(
276                 new ComposeOneFragmentProcessor(std::move(fp), mode, child));
277     }
278 
name() const279     const char* name() const override { return "ComposeOne"; }
280 
281 #ifdef SK_DEBUG
dumpInfo() const282     SkString dumpInfo() const override {
283         SkString str;
284 
285         str.appendf("Mode: %s, Child: %s",
286                     SkBlendMode_Name(fMode), kDst_Child == fChild ? "Dst" : "Src");
287 
288         for (int i = 0; i < this->numChildProcessors(); ++i) {
289             str.appendf(" [%s %s]",
290                         this->childProcessor(i).name(), this->childProcessor(i).dumpInfo().c_str());
291         }
292         return str;
293     }
294 #endif
295 
296     std::unique_ptr<GrFragmentProcessor> clone() const override;
297 
mode() const298     SkBlendMode mode() const { return fMode; }
299 
child() const300     Child child() const { return fChild; }
301 
302 private:
OptFlags(const GrFragmentProcessor * fp,SkBlendMode mode,Child child)303     OptimizationFlags OptFlags(const GrFragmentProcessor* fp, SkBlendMode mode, Child child) {
304         OptimizationFlags flags;
305         switch (mode) {
306             case SkBlendMode::kClear:
307                 SK_ABORT("Should never create clear compose one FP.");
308                 flags = kNone_OptimizationFlags;
309                 break;
310 
311             case SkBlendMode::kSrc:
312                 SkASSERT(child == kSrc_Child);
313                 flags = fp->preservesOpaqueInput() ? kPreservesOpaqueInput_OptimizationFlag
314                                                    : kNone_OptimizationFlags;
315                 break;
316 
317             case SkBlendMode::kDst:
318                 SkASSERT(child == kDst_Child);
319                 flags = fp->preservesOpaqueInput() ? kPreservesOpaqueInput_OptimizationFlag
320                                                    : kNone_OptimizationFlags;
321                 break;
322 
323             // Produces opaque if both src and dst are opaque. These also will modulate the child's
324             // output by either the input color or alpha. However, if the child is not compatible
325             // with the coverage as alpha then it may produce a color that is not valid premul.
326             case SkBlendMode::kSrcIn:
327             case SkBlendMode::kDstIn:
328             case SkBlendMode::kModulate:
329                 flags = ProcessorOptimizationFlags(fp) &
330                         ~kConstantOutputForConstantInput_OptimizationFlag;
331                 break;
332 
333             // Produces zero when both are opaque, indeterminate if one is opaque.
334             case SkBlendMode::kSrcOut:
335             case SkBlendMode::kDstOut:
336             case SkBlendMode::kXor:
337                 flags = kNone_OptimizationFlags;
338                 break;
339 
340             // Is opaque if the dst is opaque.
341             case SkBlendMode::kSrcATop:
342                 if (child == kDst_Child) {
343                     flags = fp->preservesOpaqueInput() ? kPreservesOpaqueInput_OptimizationFlag
344                                                        : kNone_OptimizationFlags;
345                 } else {
346                     flags = kPreservesOpaqueInput_OptimizationFlag;
347                 }
348                 break;
349 
350             // DstATop is the converse of kSrcATop. Screen is also opaque if the src is a opaque.
351             case SkBlendMode::kDstATop:
352             case SkBlendMode::kScreen:
353                 if (child == kSrc_Child) {
354                     flags = fp->preservesOpaqueInput() ? kPreservesOpaqueInput_OptimizationFlag
355                                                        : kNone_OptimizationFlags;
356                 } else {
357                     flags = kPreservesOpaqueInput_OptimizationFlag;
358                 }
359                 break;
360 
361             // These modes are all opaque if either src or dst is opaque. All the advanced modes
362             // compute alpha as src-over.
363             case SkBlendMode::kSrcOver:
364             case SkBlendMode::kDstOver:
365             case SkBlendMode::kPlus:
366             case SkBlendMode::kOverlay:
367             case SkBlendMode::kDarken:
368             case SkBlendMode::kLighten:
369             case SkBlendMode::kColorDodge:
370             case SkBlendMode::kColorBurn:
371             case SkBlendMode::kHardLight:
372             case SkBlendMode::kSoftLight:
373             case SkBlendMode::kDifference:
374             case SkBlendMode::kExclusion:
375             case SkBlendMode::kMultiply:
376             case SkBlendMode::kHue:
377             case SkBlendMode::kSaturation:
378             case SkBlendMode::kColor:
379             case SkBlendMode::kLuminosity:
380                 flags = kPreservesOpaqueInput_OptimizationFlag;
381                 break;
382         }
383         if (does_cpu_blend_impl_match_gpu(mode) && fp->hasConstantOutputForConstantInput()) {
384             flags |= kConstantOutputForConstantInput_OptimizationFlag;
385         }
386         return flags;
387     }
388 
onGetGLSLProcessorKey(const GrShaderCaps & caps,GrProcessorKeyBuilder * b) const389     void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
390         GR_STATIC_ASSERT(((int)SkBlendMode::kLastMode & UINT16_MAX) == (int)SkBlendMode::kLastMode);
391         b->add32((int)fMode | (fChild << 16));
392     }
393 
onIsEqual(const GrFragmentProcessor & that) const394     bool onIsEqual(const GrFragmentProcessor& that) const override {
395         return fMode == that.cast<ComposeOneFragmentProcessor>().fMode;
396     }
397 
constantOutputForConstantInput(const SkPMColor4f & inputColor) const398     SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inputColor) const override {
399         SkPMColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0),
400                                                                 SK_PMColor4fWHITE);
401         SkPMColor4f src, dst;
402         if (kSrc_Child == fChild) {
403             src = childColor;
404             dst = inputColor;
405         } else {
406             src = inputColor;
407             dst = childColor;
408         }
409         return SkBlendMode_Apply(fMode, src, dst);
410     }
411 
412 private:
ComposeOneFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp,SkBlendMode mode,Child child)413     ComposeOneFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp, SkBlendMode mode,
414                                 Child child)
415             : INHERITED(kComposeOneFragmentProcessor_ClassID, OptFlags(fp.get(), mode, child))
416             , fMode(mode)
417             , fChild(child) {
418         SkDEBUGCODE(int dstIndex =) this->registerChildProcessor(std::move(fp));
419         SkASSERT(0 == dstIndex);
420     }
421 
422     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
423 
424     SkBlendMode fMode;
425     Child       fChild;
426 
427     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
428 
429     typedef GrFragmentProcessor INHERITED;
430 };
431 
432 //////////////////////////////////////////////////////////////////////////////
433 
434 class GLComposeOneFragmentProcessor : public GrGLSLFragmentProcessor {
435 public:
emitCode(EmitArgs & args)436     void emitCode(EmitArgs& args) override {
437         GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
438         SkBlendMode mode = args.fFp.cast<ComposeOneFragmentProcessor>().mode();
439         ComposeOneFragmentProcessor::Child child =
440             args.fFp.cast<ComposeOneFragmentProcessor>().child();
441         SkString childColor("child");
442         this->emitChild(0, &childColor, args);
443 
444         // emit blend code
445         fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkBlendMode_Name(mode));
446         const char* childStr = childColor.c_str();
447         if (ComposeOneFragmentProcessor::kDst_Child == child) {
448             GrGLSLBlend::AppendMode(fragBuilder, args.fInputColor, childStr, args.fOutputColor, mode);
449         } else {
450             GrGLSLBlend::AppendMode(fragBuilder, childStr, args.fInputColor, args.fOutputColor, mode);
451         }
452     }
453 
454 private:
455     typedef GrGLSLFragmentProcessor INHERITED;
456 };
457 
458 /////////////////////////////////////////////////////////////////////
459 
460 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ComposeOneFragmentProcessor);
461 
462 #if GR_TEST_UTILS
TestCreate(GrProcessorTestData * d)463 std::unique_ptr<GrFragmentProcessor> ComposeOneFragmentProcessor::TestCreate(
464         GrProcessorTestData* d) {
465     // Create one random frag procs.
466     // For now, we'll prevent either children from being a shader with children to prevent the
467     // possibility of an arbitrarily large tree of procs.
468     std::unique_ptr<GrFragmentProcessor> dst(GrProcessorUnitTest::MakeChildFP(d));
469     SkBlendMode mode;
470     ComposeOneFragmentProcessor::Child child;
471     do {
472         mode = static_cast<SkBlendMode>(d->fRandom->nextRangeU(0, (int)SkBlendMode::kLastMode));
473         child = d->fRandom->nextBool() ? kDst_Child : kSrc_Child;
474     } while (SkBlendMode::kClear == mode || (SkBlendMode::kDst == mode && child == kSrc_Child) ||
475              (SkBlendMode::kSrc == mode && child == kDst_Child));
476     return std::unique_ptr<GrFragmentProcessor>(
477             new ComposeOneFragmentProcessor(std::move(dst), mode, child));
478 }
479 #endif
480 
onCreateGLSLInstance() const481 GrGLSLFragmentProcessor* ComposeOneFragmentProcessor::onCreateGLSLInstance() const {
482     return new GLComposeOneFragmentProcessor;
483 }
484 
clone() const485 std::unique_ptr<GrFragmentProcessor> ComposeOneFragmentProcessor::clone() const {
486     return std::unique_ptr<GrFragmentProcessor>(
487             new ComposeOneFragmentProcessor(this->childProcessor(0).clone(), fMode, fChild));
488 }
489 
490 //////////////////////////////////////////////////////////////////////////////
491 
492 // It may seems as though when the input FP is the dst and the mode is kDst (or same for src/kSrc)
493 // that these factories could simply return the input FP. However, that doesn't have quite
494 // the same effect as the returned compose FP will replace the FP's input with solid white and
495 // ignore the original input. This could be implemented as:
496 // RunInSeries(ConstColor(WHITE, kIgnoreInput), inputFP).
497 
MakeFromDstProcessor(std::unique_ptr<GrFragmentProcessor> dst,SkBlendMode mode)498 std::unique_ptr<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromDstProcessor(
499         std::unique_ptr<GrFragmentProcessor> dst, SkBlendMode mode) {
500     switch (mode) {
501         case SkBlendMode::kClear:
502             return GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT,
503                                                GrConstColorProcessor::InputMode::kIgnore);
504         case SkBlendMode::kSrc:
505             return nullptr;
506         default:
507             return ComposeOneFragmentProcessor::Make(std::move(dst), mode,
508                                                      ComposeOneFragmentProcessor::kDst_Child);
509     }
510 }
511 
MakeFromSrcProcessor(std::unique_ptr<GrFragmentProcessor> src,SkBlendMode mode)512 std::unique_ptr<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromSrcProcessor(
513         std::unique_ptr<GrFragmentProcessor> src, SkBlendMode mode) {
514     switch (mode) {
515         case SkBlendMode::kClear:
516             return GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT,
517                                                GrConstColorProcessor::InputMode::kIgnore);
518         case SkBlendMode::kDst:
519             return nullptr;
520         default:
521             return ComposeOneFragmentProcessor::Make(std::move(src), mode,
522                                                      ComposeOneFragmentProcessor::kSrc_Child);
523     }
524 }
525