blob: 0ecb4bd3c078ad621ef5b23bed001163eaeb19ca [file] [log] [blame]
wangyix809e5af2015-09-09 12:58:32 -07001/*
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 "effects/GrXfermodeFragmentProcessor.h"
9
10#include "GrFragmentProcessor.h"
egdaniel7ea439b2015-12-03 09:20:44 -080011#include "GrInvariantOutput.h"
wangyix809e5af2015-09-09 12:58:32 -070012#include "effects/GrConstColorProcessor.h"
egdaniel64c47282015-11-13 06:54:19 -080013#include "glsl/GrGLSLFragmentProcessor.h"
14#include "glsl/GrGLSLBlend.h"
egdaniel2d721d32015-11-11 13:06:05 -080015#include "glsl/GrGLSLFragmentShaderBuilder.h"
bsalomonf276ac52015-10-09 13:36:42 -070016#include "SkGrPriv.h"
wangyix809e5af2015-09-09 12:58:32 -070017
bsalomonae4738f2015-09-15 15:33:27 -070018class ComposeTwoFragmentProcessor : public GrFragmentProcessor {
wangyix809e5af2015-09-09 12:58:32 -070019public:
bungeman06ca8ec2016-06-09 08:01:03 -070020 ComposeTwoFragmentProcessor(sk_sp<GrFragmentProcessor> src, sk_sp<GrFragmentProcessor> dst,
Mike Reed7d954ad2016-10-28 15:42:34 -040021 SkBlendMode mode)
Brian Salomon587e08f2017-01-27 10:59:27 -050022 : INHERITED(OptFlags(src.get(), dst.get(), mode)), fMode(mode) {
bsalomonae4738f2015-09-15 15:33:27 -070023 this->initClassID<ComposeTwoFragmentProcessor>();
bungeman06ca8ec2016-06-09 08:01:03 -070024 SkDEBUGCODE(int shaderAChildIndex = )this->registerChildProcessor(std::move(src));
25 SkDEBUGCODE(int shaderBChildIndex = )this->registerChildProcessor(std::move(dst));
wangyix809e5af2015-09-09 12:58:32 -070026 SkASSERT(0 == shaderAChildIndex);
27 SkASSERT(1 == shaderBChildIndex);
28 }
29
bsalomonae4738f2015-09-15 15:33:27 -070030 const char* name() const override { return "ComposeTwo"; }
wangyix809e5af2015-09-09 12:58:32 -070031
Brian Salomon94efbf52016-11-29 13:43:05 -050032 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
Mike Reed7d954ad2016-10-28 15:42:34 -040033 b->add32((int)fMode);
wangyix809e5af2015-09-09 12:58:32 -070034 }
35
Mike Reed7d954ad2016-10-28 15:42:34 -040036 SkBlendMode getMode() const { return fMode; }
wangyix809e5af2015-09-09 12:58:32 -070037
Brian Salomon587e08f2017-01-27 10:59:27 -050038private:
39 static OptimizationFlags OptFlags(const GrFragmentProcessor* src,
40 const GrFragmentProcessor* dst, SkBlendMode mode) {
41 // We only attempt the constant output optimization.
42 // The CPU and GPU implementations differ significantly for the advanced modes.
43 if (mode <= SkBlendMode::kLastSeparableMode && src->hasConstantOutputForConstantInput() &&
44 dst->hasConstantOutputForConstantInput()) {
45 return kConstantOutputForConstantInput_OptimizationFlag;
46 }
47 return kNone_OptimizationFlags;
48 }
49
wangyix809e5af2015-09-09 12:58:32 -070050 bool onIsEqual(const GrFragmentProcessor& other) const override {
bsalomonae4738f2015-09-15 15:33:27 -070051 const ComposeTwoFragmentProcessor& cs = other.cast<ComposeTwoFragmentProcessor>();
wangyix809e5af2015-09-09 12:58:32 -070052 return fMode == cs.fMode;
53 }
54
55 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
Brian Salomon5f13fba2017-01-23 14:35:25 -050056 inout->setToUnknown();
wangyix809e5af2015-09-09 12:58:32 -070057 }
58
Brian Salomon587e08f2017-01-27 10:59:27 -050059 GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
60 float alpha = input.fRGBA[3];
61 input = input.opaque();
62 GrColor4f srcColor = ConstantOutputForConstantInput(this->childProcessor(0), input);
63 GrColor4f dstColor = ConstantOutputForConstantInput(this->childProcessor(1), input);
64 SkPM4f src = GrColor4fToSkPM4f(srcColor);
65 SkPM4f dst = GrColor4fToSkPM4f(dstColor);
66 auto proc = SkXfermode::GetProc4f(fMode);
67 return SkPM4fToGrColor4f(proc(src, dst)).mulByScalar(alpha);
68 }
69
egdaniel57d3b032015-11-13 11:57:27 -080070 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
wangyix809e5af2015-09-09 12:58:32 -070071
Mike Reed7d954ad2016-10-28 15:42:34 -040072 SkBlendMode fMode;
wangyix809e5af2015-09-09 12:58:32 -070073
74 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
75
76 typedef GrFragmentProcessor INHERITED;
77};
78
79/////////////////////////////////////////////////////////////////////
80
egdaniel64c47282015-11-13 06:54:19 -080081class GLComposeTwoFragmentProcessor : public GrGLSLFragmentProcessor {
wangyix809e5af2015-09-09 12:58:32 -070082public:
wangyix809e5af2015-09-09 12:58:32 -070083 void emitCode(EmitArgs&) override;
84
85private:
egdaniel64c47282015-11-13 06:54:19 -080086 typedef GrGLSLFragmentProcessor INHERITED;
wangyix809e5af2015-09-09 12:58:32 -070087};
88
89/////////////////////////////////////////////////////////////////////
90
bsalomonae4738f2015-09-15 15:33:27 -070091GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ComposeTwoFragmentProcessor);
wangyix809e5af2015-09-09 12:58:32 -070092
Hal Canary6f6961e2017-01-31 13:50:44 -050093#if GR_TEST_UTILS
bungeman06ca8ec2016-06-09 08:01:03 -070094sk_sp<GrFragmentProcessor> ComposeTwoFragmentProcessor::TestCreate(GrProcessorTestData* d) {
wangyix809e5af2015-09-09 12:58:32 -070095 // Create two random frag procs.
bungeman06ca8ec2016-06-09 08:01:03 -070096 sk_sp<GrFragmentProcessor> fpA(GrProcessorUnitTest::MakeChildFP(d));
97 sk_sp<GrFragmentProcessor> fpB(GrProcessorUnitTest::MakeChildFP(d));
wangyix809e5af2015-09-09 12:58:32 -070098
Mike Reed7d954ad2016-10-28 15:42:34 -040099 SkBlendMode mode = static_cast<SkBlendMode>(
100 d->fRandom->nextRangeU(0, (int)SkBlendMode::kLastMode));
bungeman06ca8ec2016-06-09 08:01:03 -0700101 return sk_sp<GrFragmentProcessor>(
102 new ComposeTwoFragmentProcessor(std::move(fpA), std::move(fpB), mode));
wangyix809e5af2015-09-09 12:58:32 -0700103}
Hal Canary6f6961e2017-01-31 13:50:44 -0500104#endif
wangyix809e5af2015-09-09 12:58:32 -0700105
egdaniel57d3b032015-11-13 11:57:27 -0800106GrGLSLFragmentProcessor* ComposeTwoFragmentProcessor::onCreateGLSLInstance() const{
robertphillips9cdb9922016-02-03 12:25:40 -0800107 return new GLComposeTwoFragmentProcessor;
wangyix809e5af2015-09-09 12:58:32 -0700108}
109
110/////////////////////////////////////////////////////////////////////
111
bsalomonae4738f2015-09-15 15:33:27 -0700112void GLComposeTwoFragmentProcessor::emitCode(EmitArgs& args) {
wangyix809e5af2015-09-09 12:58:32 -0700113
cdalton85285412016-02-18 12:37:07 -0800114 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
bsalomonae4738f2015-09-15 15:33:27 -0700115 const ComposeTwoFragmentProcessor& cs = args.fFp.cast<ComposeTwoFragmentProcessor>();
wangyix809e5af2015-09-09 12:58:32 -0700116
bsalomonf1b7a1d2015-09-28 06:26:28 -0700117 const char* inputColor = nullptr;
bsalomonb5b60322015-09-14 12:26:33 -0700118 if (args.fInputColor) {
bsalomonf1b7a1d2015-09-28 06:26:28 -0700119 inputColor = "inputColor";
egdaniel4ca2e602015-11-18 08:01:26 -0800120 fragBuilder->codeAppendf("vec4 inputColor = vec4(%s.rgb, 1.0);", args.fInputColor);
bsalomonb5b60322015-09-14 12:26:33 -0700121 }
wangyix809e5af2015-09-09 12:58:32 -0700122
123 // declare outputColor and emit the code for each of the two children
ethannicholas22f939e2016-10-13 13:25:34 -0700124 SkString srcColor("xfer_src");
bsalomonf1b7a1d2015-09-28 06:26:28 -0700125 this->emitChild(0, inputColor, &srcColor, args);
wangyix809e5af2015-09-09 12:58:32 -0700126
ethannicholas22f939e2016-10-13 13:25:34 -0700127 SkString dstColor("xfer_dst");
bsalomonf1b7a1d2015-09-28 06:26:28 -0700128 this->emitChild(1, inputColor, &dstColor, args);
wangyix809e5af2015-09-09 12:58:32 -0700129
130 // emit blend code
Mike Reed7d954ad2016-10-28 15:42:34 -0400131 SkBlendMode mode = cs.getMode();
egdaniel4ca2e602015-11-18 08:01:26 -0800132 fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode));
133 GrGLSLBlend::AppendMode(fragBuilder,
134 srcColor.c_str(),
135 dstColor.c_str(),
136 args.fOutputColor,
137 mode);
wangyix809e5af2015-09-09 12:58:32 -0700138
139 // re-multiply the output color by the input color's alpha
bsalomonf1b7a1d2015-09-28 06:26:28 -0700140 if (args.fInputColor) {
egdaniel4ca2e602015-11-18 08:01:26 -0800141 fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
bsalomonb5b60322015-09-14 12:26:33 -0700142 }
wangyix809e5af2015-09-09 12:58:32 -0700143}
144
bungeman06ca8ec2016-06-09 08:01:03 -0700145sk_sp<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromTwoProcessors(
Mike Reed7d954ad2016-10-28 15:42:34 -0400146 sk_sp<GrFragmentProcessor> src, sk_sp<GrFragmentProcessor> dst, SkBlendMode mode) {
wangyix809e5af2015-09-09 12:58:32 -0700147 switch (mode) {
Mike Reed7d954ad2016-10-28 15:42:34 -0400148 case SkBlendMode::kClear:
Brian Osman618d3042016-10-25 10:51:28 -0400149 return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(),
bungeman06ca8ec2016-06-09 08:01:03 -0700150 GrConstColorProcessor::kIgnore_InputMode);
Mike Reed7d954ad2016-10-28 15:42:34 -0400151 case SkBlendMode::kSrc:
bungeman06ca8ec2016-06-09 08:01:03 -0700152 return src;
Mike Reed7d954ad2016-10-28 15:42:34 -0400153 case SkBlendMode::kDst:
bungeman06ca8ec2016-06-09 08:01:03 -0700154 return dst;
wangyix809e5af2015-09-09 12:58:32 -0700155 default:
bungeman06ca8ec2016-06-09 08:01:03 -0700156 return sk_sp<GrFragmentProcessor>(
157 new ComposeTwoFragmentProcessor(std::move(src), std::move(dst), mode));
bsalomonae4738f2015-09-15 15:33:27 -0700158 }
159}
160
161//////////////////////////////////////////////////////////////////////////////
162
163class ComposeOneFragmentProcessor : public GrFragmentProcessor {
164public:
165 enum Child {
166 kDst_Child,
167 kSrc_Child,
168 };
169
Mike Reed7d954ad2016-10-28 15:42:34 -0400170 ComposeOneFragmentProcessor(sk_sp<GrFragmentProcessor> dst, SkBlendMode mode, Child child)
Brian Salomon587e08f2017-01-27 10:59:27 -0500171 : INHERITED(OptFlags(dst.get(), mode)), fMode(mode), fChild(child) {
bsalomonae4738f2015-09-15 15:33:27 -0700172 this->initClassID<ComposeOneFragmentProcessor>();
bungeman06ca8ec2016-06-09 08:01:03 -0700173 SkDEBUGCODE(int dstIndex = )this->registerChildProcessor(std::move(dst));
bsalomonae4738f2015-09-15 15:33:27 -0700174 SkASSERT(0 == dstIndex);
175 }
176
177 const char* name() const override { return "ComposeOne"; }
178
robertphillips783a4da2015-11-19 14:00:02 -0800179 SkString dumpInfo() const override {
180 SkString str;
181
182 for (int i = 0; i < this->numChildProcessors(); ++i) {
183 str.append(this->childProcessor(i).dumpInfo());
184 }
185 return str;
186 }
187
Brian Salomon94efbf52016-11-29 13:43:05 -0500188 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
Mike Reed7d954ad2016-10-28 15:42:34 -0400189 GR_STATIC_ASSERT(((int)SkBlendMode::kLastMode & SK_MaxU16) == (int)SkBlendMode::kLastMode);
190 b->add32((int)fMode | (fChild << 16));
bsalomonae4738f2015-09-15 15:33:27 -0700191 }
192
Mike Reed7d954ad2016-10-28 15:42:34 -0400193 SkBlendMode mode() const { return fMode; }
bsalomonae4738f2015-09-15 15:33:27 -0700194
195 Child child() const { return fChild; }
196
Brian Salomon587e08f2017-01-27 10:59:27 -0500197private:
198 OptimizationFlags OptFlags(const GrFragmentProcessor* child, SkBlendMode mode) {
199 // We only attempt the constant output optimization.
200 // The CPU and GPU implementations differ significantly for the advanced modes.
201 if (mode <= SkBlendMode::kLastSeparableMode && child->hasConstantOutputForConstantInput()) {
202 return kConstantOutputForConstantInput_OptimizationFlag;
203 }
204 return kNone_OptimizationFlags;
205 }
206
bsalomonae4738f2015-09-15 15:33:27 -0700207 bool onIsEqual(const GrFragmentProcessor& that) const override {
208 return fMode == that.cast<ComposeOneFragmentProcessor>().fMode;
209 }
210
211 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
212 SkXfermode::Coeff skSrcCoeff, skDstCoeff;
213 if (SkXfermode::ModeAsCoeff(fMode, &skSrcCoeff, &skDstCoeff)) {
214 GrBlendCoeff srcCoeff = SkXfermodeCoeffToGrBlendCoeff(skSrcCoeff);
215 GrBlendCoeff dstCoeff = SkXfermodeCoeffToGrBlendCoeff(skDstCoeff);
Brian Salomonaab259e2017-01-17 10:44:34 -0500216 GrInvariantOutput childOutput(0xFFFFFFFF, kRGBA_GrColorComponentFlags);
bsalomonae4738f2015-09-15 15:33:27 -0700217 this->childProcessor(0).computeInvariantOutput(&childOutput);
218 GrColor blendColor;
219 GrColorComponentFlags blendFlags;
220 if (kDst_Child == fChild) {
221 GrGetCoeffBlendKnownComponents(srcCoeff, dstCoeff,
222 inout->color(), inout->validFlags(),
223 childOutput.color(), childOutput.validFlags(),
224 &blendColor, &blendFlags);
225 } else {
226 GrGetCoeffBlendKnownComponents(srcCoeff, dstCoeff,
227 childOutput.color(), childOutput.validFlags(),
228 inout->color(), inout->validFlags(),
229 &blendColor, &blendFlags);
230 }
Brian Salomon5f13fba2017-01-23 14:35:25 -0500231 inout->setToOther(blendFlags, blendColor);
bsalomonae4738f2015-09-15 15:33:27 -0700232 } else {
Brian Salomon5f13fba2017-01-23 14:35:25 -0500233 inout->setToUnknown();
bsalomonae4738f2015-09-15 15:33:27 -0700234 }
235 }
236
Brian Salomon587e08f2017-01-27 10:59:27 -0500237 GrColor4f constantOutputForConstantInput(GrColor4f inputColor) const override {
238 GrColor4f childColor =
239 ConstantOutputForConstantInput(this->childProcessor(0), GrColor4f::OpaqueWhite());
240 SkPM4f src, dst;
241 if (kSrc_Child == fChild) {
242 src = GrColor4fToSkPM4f(childColor);
243 dst = GrColor4fToSkPM4f(inputColor);
244 } else {
245 src = GrColor4fToSkPM4f(inputColor);
246 dst = GrColor4fToSkPM4f(childColor);
247 }
248 auto proc = SkXfermode::GetProc4f(fMode);
249 return SkPM4fToGrColor4f(proc(src, dst));
250 }
251
bsalomonae4738f2015-09-15 15:33:27 -0700252private:
egdaniel57d3b032015-11-13 11:57:27 -0800253 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
bsalomonae4738f2015-09-15 15:33:27 -0700254
Mike Reed7d954ad2016-10-28 15:42:34 -0400255 SkBlendMode fMode;
256 Child fChild;
bsalomonae4738f2015-09-15 15:33:27 -0700257
258 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
259
260 typedef GrFragmentProcessor INHERITED;
261};
262
263//////////////////////////////////////////////////////////////////////////////
264
egdaniel64c47282015-11-13 06:54:19 -0800265class GLComposeOneFragmentProcessor : public GrGLSLFragmentProcessor {
bsalomonae4738f2015-09-15 15:33:27 -0700266public:
bsalomonae4738f2015-09-15 15:33:27 -0700267 void emitCode(EmitArgs& args) override {
cdalton85285412016-02-18 12:37:07 -0800268 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
Mike Reed7d954ad2016-10-28 15:42:34 -0400269 SkBlendMode mode = args.fFp.cast<ComposeOneFragmentProcessor>().mode();
bsalomonae4738f2015-09-15 15:33:27 -0700270 ComposeOneFragmentProcessor::Child child =
271 args.fFp.cast<ComposeOneFragmentProcessor>().child();
bsalomon38ddbad2015-09-24 06:00:00 -0700272 SkString childColor("child");
273 this->emitChild(0, nullptr, &childColor, args);
bsalomonae4738f2015-09-15 15:33:27 -0700274
275 const char* inputColor = args.fInputColor;
276 // We don't try to optimize for this case at all
277 if (!inputColor) {
egdaniel4ca2e602015-11-18 08:01:26 -0800278 fragBuilder->codeAppendf("const vec4 ones = vec4(1);");
bsalomonae4738f2015-09-15 15:33:27 -0700279 inputColor = "ones";
280 }
281
282 // emit blend code
egdaniel4ca2e602015-11-18 08:01:26 -0800283 fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode));
bsalomon38ddbad2015-09-24 06:00:00 -0700284 const char* childStr = childColor.c_str();
bsalomonae4738f2015-09-15 15:33:27 -0700285 if (ComposeOneFragmentProcessor::kDst_Child == child) {
egdaniel4ca2e602015-11-18 08:01:26 -0800286 GrGLSLBlend::AppendMode(fragBuilder, inputColor, childStr, args.fOutputColor, mode);
bsalomonae4738f2015-09-15 15:33:27 -0700287 } else {
egdaniel4ca2e602015-11-18 08:01:26 -0800288 GrGLSLBlend::AppendMode(fragBuilder, childStr, inputColor, args.fOutputColor, mode);
bsalomonae4738f2015-09-15 15:33:27 -0700289 }
bsalomonae4738f2015-09-15 15:33:27 -0700290 }
291
292private:
egdaniel64c47282015-11-13 06:54:19 -0800293 typedef GrGLSLFragmentProcessor INHERITED;
bsalomonae4738f2015-09-15 15:33:27 -0700294};
295
296/////////////////////////////////////////////////////////////////////
297
298GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ComposeOneFragmentProcessor);
299
Hal Canary6f6961e2017-01-31 13:50:44 -0500300#if GR_TEST_UTILS
bungeman06ca8ec2016-06-09 08:01:03 -0700301sk_sp<GrFragmentProcessor> ComposeOneFragmentProcessor::TestCreate(GrProcessorTestData* d) {
bsalomonae4738f2015-09-15 15:33:27 -0700302 // Create one random frag procs.
303 // For now, we'll prevent either children from being a shader with children to prevent the
304 // possibility of an arbitrarily large tree of procs.
bungeman06ca8ec2016-06-09 08:01:03 -0700305 sk_sp<GrFragmentProcessor> dst(GrProcessorUnitTest::MakeChildFP(d));
Mike Reed7d954ad2016-10-28 15:42:34 -0400306 SkBlendMode mode = static_cast<SkBlendMode>(
307 d->fRandom->nextRangeU(0, (int)SkBlendMode::kLastMode));
bsalomonae4738f2015-09-15 15:33:27 -0700308 ComposeOneFragmentProcessor::Child child = d->fRandom->nextBool() ?
309 ComposeOneFragmentProcessor::kDst_Child :
310 ComposeOneFragmentProcessor::kSrc_Child;
bungeman06ca8ec2016-06-09 08:01:03 -0700311 return sk_sp<GrFragmentProcessor>(new ComposeOneFragmentProcessor(std::move(dst), mode, child));
bsalomonae4738f2015-09-15 15:33:27 -0700312}
Hal Canary6f6961e2017-01-31 13:50:44 -0500313#endif
bsalomonae4738f2015-09-15 15:33:27 -0700314
egdaniel57d3b032015-11-13 11:57:27 -0800315GrGLSLFragmentProcessor* ComposeOneFragmentProcessor::onCreateGLSLInstance() const {
robertphillips9cdb9922016-02-03 12:25:40 -0800316 return new GLComposeOneFragmentProcessor;
bsalomonae4738f2015-09-15 15:33:27 -0700317}
318
319//////////////////////////////////////////////////////////////////////////////
320
bungeman06ca8ec2016-06-09 08:01:03 -0700321sk_sp<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromDstProcessor(
Mike Reed7d954ad2016-10-28 15:42:34 -0400322 sk_sp<GrFragmentProcessor> dst, SkBlendMode mode) {
bsalomonae4738f2015-09-15 15:33:27 -0700323 switch (mode) {
Mike Reed7d954ad2016-10-28 15:42:34 -0400324 case SkBlendMode::kClear:
Brian Osman618d3042016-10-25 10:51:28 -0400325 return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(),
bsalomonae4738f2015-09-15 15:33:27 -0700326 GrConstColorProcessor::kIgnore_InputMode);
Mike Reed7d954ad2016-10-28 15:42:34 -0400327 case SkBlendMode::kSrc:
bsalomonae4738f2015-09-15 15:33:27 -0700328 return nullptr;
329 default:
bungeman06ca8ec2016-06-09 08:01:03 -0700330 return sk_sp<GrFragmentProcessor>(
331 new ComposeOneFragmentProcessor(std::move(dst), mode,
332 ComposeOneFragmentProcessor::kDst_Child));
bsalomonae4738f2015-09-15 15:33:27 -0700333 }
334}
335
bungeman06ca8ec2016-06-09 08:01:03 -0700336sk_sp<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromSrcProcessor(
Mike Reed7d954ad2016-10-28 15:42:34 -0400337 sk_sp<GrFragmentProcessor> src, SkBlendMode mode) {
bsalomonae4738f2015-09-15 15:33:27 -0700338 switch (mode) {
Mike Reed7d954ad2016-10-28 15:42:34 -0400339 case SkBlendMode::kClear:
Brian Osman618d3042016-10-25 10:51:28 -0400340 return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(),
bsalomonae4738f2015-09-15 15:33:27 -0700341 GrConstColorProcessor::kIgnore_InputMode);
Mike Reed7d954ad2016-10-28 15:42:34 -0400342 case SkBlendMode::kDst:
bsalomonae4738f2015-09-15 15:33:27 -0700343 return nullptr;
344 default:
bungeman06ca8ec2016-06-09 08:01:03 -0700345 return sk_sp<GrFragmentProcessor>(
346 new ComposeOneFragmentProcessor(src, mode,
347 ComposeOneFragmentProcessor::kSrc_Child));
wangyix809e5af2015-09-09 12:58:32 -0700348 }
349}