blob: 78918ce2018d2a646e467cc74bb6301d38ea5a3c [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
Brian Salomon246a3c22017-02-10 16:16:21 -050018// 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.
20static 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
bsalomonae4738f2015-09-15 15:33:27 -070030class ComposeTwoFragmentProcessor : public GrFragmentProcessor {
wangyix809e5af2015-09-09 12:58:32 -070031public:
bungeman06ca8ec2016-06-09 08:01:03 -070032 ComposeTwoFragmentProcessor(sk_sp<GrFragmentProcessor> src, sk_sp<GrFragmentProcessor> dst,
Mike Reed7d954ad2016-10-28 15:42:34 -040033 SkBlendMode mode)
Brian Salomon587e08f2017-01-27 10:59:27 -050034 : INHERITED(OptFlags(src.get(), dst.get(), mode)), fMode(mode) {
bsalomonae4738f2015-09-15 15:33:27 -070035 this->initClassID<ComposeTwoFragmentProcessor>();
bungeman06ca8ec2016-06-09 08:01:03 -070036 SkDEBUGCODE(int shaderAChildIndex = )this->registerChildProcessor(std::move(src));
37 SkDEBUGCODE(int shaderBChildIndex = )this->registerChildProcessor(std::move(dst));
wangyix809e5af2015-09-09 12:58:32 -070038 SkASSERT(0 == shaderAChildIndex);
39 SkASSERT(1 == shaderBChildIndex);
40 }
41
bsalomonae4738f2015-09-15 15:33:27 -070042 const char* name() const override { return "ComposeTwo"; }
wangyix809e5af2015-09-09 12:58:32 -070043
Brian Salomon94efbf52016-11-29 13:43:05 -050044 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
Mike Reed7d954ad2016-10-28 15:42:34 -040045 b->add32((int)fMode);
wangyix809e5af2015-09-09 12:58:32 -070046 }
47
Mike Reed7d954ad2016-10-28 15:42:34 -040048 SkBlendMode getMode() const { return fMode; }
wangyix809e5af2015-09-09 12:58:32 -070049
Brian Salomon587e08f2017-01-27 10:59:27 -050050private:
51 static OptimizationFlags OptFlags(const GrFragmentProcessor* src,
52 const GrFragmentProcessor* dst, SkBlendMode mode) {
Brian Salomon246a3c22017-02-10 16:16:21 -050053 if (does_cpu_blend_impl_match_gpu(mode) && src->hasConstantOutputForConstantInput() &&
54 dst->hasConstantOutputForConstantInput()) {
Brian Salomon587e08f2017-01-27 10:59:27 -050055 return kConstantOutputForConstantInput_OptimizationFlag;
56 }
57 return kNone_OptimizationFlags;
58 }
59
wangyix809e5af2015-09-09 12:58:32 -070060 bool onIsEqual(const GrFragmentProcessor& other) const override {
bsalomonae4738f2015-09-15 15:33:27 -070061 const ComposeTwoFragmentProcessor& cs = other.cast<ComposeTwoFragmentProcessor>();
wangyix809e5af2015-09-09 12:58:32 -070062 return fMode == cs.fMode;
63 }
64
65 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
Brian Salomon5f13fba2017-01-23 14:35:25 -050066 inout->setToUnknown();
wangyix809e5af2015-09-09 12:58:32 -070067 }
68
Brian Salomon587e08f2017-01-27 10:59:27 -050069 GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
70 float alpha = input.fRGBA[3];
71 input = input.opaque();
72 GrColor4f srcColor = ConstantOutputForConstantInput(this->childProcessor(0), input);
73 GrColor4f dstColor = ConstantOutputForConstantInput(this->childProcessor(1), input);
74 SkPM4f src = GrColor4fToSkPM4f(srcColor);
75 SkPM4f dst = GrColor4fToSkPM4f(dstColor);
76 auto proc = SkXfermode::GetProc4f(fMode);
77 return SkPM4fToGrColor4f(proc(src, dst)).mulByScalar(alpha);
78 }
79
egdaniel57d3b032015-11-13 11:57:27 -080080 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
wangyix809e5af2015-09-09 12:58:32 -070081
Mike Reed7d954ad2016-10-28 15:42:34 -040082 SkBlendMode fMode;
wangyix809e5af2015-09-09 12:58:32 -070083
84 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
85
86 typedef GrFragmentProcessor INHERITED;
87};
88
89/////////////////////////////////////////////////////////////////////
90
egdaniel64c47282015-11-13 06:54:19 -080091class GLComposeTwoFragmentProcessor : public GrGLSLFragmentProcessor {
wangyix809e5af2015-09-09 12:58:32 -070092public:
wangyix809e5af2015-09-09 12:58:32 -070093 void emitCode(EmitArgs&) override;
94
95private:
egdaniel64c47282015-11-13 06:54:19 -080096 typedef GrGLSLFragmentProcessor INHERITED;
wangyix809e5af2015-09-09 12:58:32 -070097};
98
99/////////////////////////////////////////////////////////////////////
100
bsalomonae4738f2015-09-15 15:33:27 -0700101GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ComposeTwoFragmentProcessor);
wangyix809e5af2015-09-09 12:58:32 -0700102
Hal Canary6f6961e2017-01-31 13:50:44 -0500103#if GR_TEST_UTILS
bungeman06ca8ec2016-06-09 08:01:03 -0700104sk_sp<GrFragmentProcessor> ComposeTwoFragmentProcessor::TestCreate(GrProcessorTestData* d) {
wangyix809e5af2015-09-09 12:58:32 -0700105 // Create two random frag procs.
bungeman06ca8ec2016-06-09 08:01:03 -0700106 sk_sp<GrFragmentProcessor> fpA(GrProcessorUnitTest::MakeChildFP(d));
107 sk_sp<GrFragmentProcessor> fpB(GrProcessorUnitTest::MakeChildFP(d));
wangyix809e5af2015-09-09 12:58:32 -0700108
Mike Reed7d954ad2016-10-28 15:42:34 -0400109 SkBlendMode mode = static_cast<SkBlendMode>(
110 d->fRandom->nextRangeU(0, (int)SkBlendMode::kLastMode));
bungeman06ca8ec2016-06-09 08:01:03 -0700111 return sk_sp<GrFragmentProcessor>(
112 new ComposeTwoFragmentProcessor(std::move(fpA), std::move(fpB), mode));
wangyix809e5af2015-09-09 12:58:32 -0700113}
Hal Canary6f6961e2017-01-31 13:50:44 -0500114#endif
wangyix809e5af2015-09-09 12:58:32 -0700115
egdaniel57d3b032015-11-13 11:57:27 -0800116GrGLSLFragmentProcessor* ComposeTwoFragmentProcessor::onCreateGLSLInstance() const{
robertphillips9cdb9922016-02-03 12:25:40 -0800117 return new GLComposeTwoFragmentProcessor;
wangyix809e5af2015-09-09 12:58:32 -0700118}
119
120/////////////////////////////////////////////////////////////////////
121
bsalomonae4738f2015-09-15 15:33:27 -0700122void GLComposeTwoFragmentProcessor::emitCode(EmitArgs& args) {
wangyix809e5af2015-09-09 12:58:32 -0700123
cdalton85285412016-02-18 12:37:07 -0800124 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
bsalomonae4738f2015-09-15 15:33:27 -0700125 const ComposeTwoFragmentProcessor& cs = args.fFp.cast<ComposeTwoFragmentProcessor>();
wangyix809e5af2015-09-09 12:58:32 -0700126
bsalomonf1b7a1d2015-09-28 06:26:28 -0700127 const char* inputColor = nullptr;
bsalomonb5b60322015-09-14 12:26:33 -0700128 if (args.fInputColor) {
bsalomonf1b7a1d2015-09-28 06:26:28 -0700129 inputColor = "inputColor";
egdaniel4ca2e602015-11-18 08:01:26 -0800130 fragBuilder->codeAppendf("vec4 inputColor = vec4(%s.rgb, 1.0);", args.fInputColor);
bsalomonb5b60322015-09-14 12:26:33 -0700131 }
wangyix809e5af2015-09-09 12:58:32 -0700132
133 // declare outputColor and emit the code for each of the two children
ethannicholas22f939e2016-10-13 13:25:34 -0700134 SkString srcColor("xfer_src");
bsalomonf1b7a1d2015-09-28 06:26:28 -0700135 this->emitChild(0, inputColor, &srcColor, args);
wangyix809e5af2015-09-09 12:58:32 -0700136
ethannicholas22f939e2016-10-13 13:25:34 -0700137 SkString dstColor("xfer_dst");
bsalomonf1b7a1d2015-09-28 06:26:28 -0700138 this->emitChild(1, inputColor, &dstColor, args);
wangyix809e5af2015-09-09 12:58:32 -0700139
140 // emit blend code
Mike Reed7d954ad2016-10-28 15:42:34 -0400141 SkBlendMode mode = cs.getMode();
egdaniel4ca2e602015-11-18 08:01:26 -0800142 fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode));
143 GrGLSLBlend::AppendMode(fragBuilder,
144 srcColor.c_str(),
145 dstColor.c_str(),
146 args.fOutputColor,
147 mode);
wangyix809e5af2015-09-09 12:58:32 -0700148
149 // re-multiply the output color by the input color's alpha
bsalomonf1b7a1d2015-09-28 06:26:28 -0700150 if (args.fInputColor) {
egdaniel4ca2e602015-11-18 08:01:26 -0800151 fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
bsalomonb5b60322015-09-14 12:26:33 -0700152 }
wangyix809e5af2015-09-09 12:58:32 -0700153}
154
bungeman06ca8ec2016-06-09 08:01:03 -0700155sk_sp<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromTwoProcessors(
Mike Reed7d954ad2016-10-28 15:42:34 -0400156 sk_sp<GrFragmentProcessor> src, sk_sp<GrFragmentProcessor> dst, SkBlendMode mode) {
wangyix809e5af2015-09-09 12:58:32 -0700157 switch (mode) {
Mike Reed7d954ad2016-10-28 15:42:34 -0400158 case SkBlendMode::kClear:
Brian Osman618d3042016-10-25 10:51:28 -0400159 return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(),
bungeman06ca8ec2016-06-09 08:01:03 -0700160 GrConstColorProcessor::kIgnore_InputMode);
Mike Reed7d954ad2016-10-28 15:42:34 -0400161 case SkBlendMode::kSrc:
bungeman06ca8ec2016-06-09 08:01:03 -0700162 return src;
Mike Reed7d954ad2016-10-28 15:42:34 -0400163 case SkBlendMode::kDst:
bungeman06ca8ec2016-06-09 08:01:03 -0700164 return dst;
wangyix809e5af2015-09-09 12:58:32 -0700165 default:
bungeman06ca8ec2016-06-09 08:01:03 -0700166 return sk_sp<GrFragmentProcessor>(
167 new ComposeTwoFragmentProcessor(std::move(src), std::move(dst), mode));
bsalomonae4738f2015-09-15 15:33:27 -0700168 }
169}
170
171//////////////////////////////////////////////////////////////////////////////
172
173class ComposeOneFragmentProcessor : public GrFragmentProcessor {
174public:
175 enum Child {
176 kDst_Child,
177 kSrc_Child,
178 };
179
Mike Reed7d954ad2016-10-28 15:42:34 -0400180 ComposeOneFragmentProcessor(sk_sp<GrFragmentProcessor> dst, SkBlendMode mode, Child child)
Brian Salomon587e08f2017-01-27 10:59:27 -0500181 : INHERITED(OptFlags(dst.get(), mode)), fMode(mode), fChild(child) {
bsalomonae4738f2015-09-15 15:33:27 -0700182 this->initClassID<ComposeOneFragmentProcessor>();
bungeman06ca8ec2016-06-09 08:01:03 -0700183 SkDEBUGCODE(int dstIndex = )this->registerChildProcessor(std::move(dst));
bsalomonae4738f2015-09-15 15:33:27 -0700184 SkASSERT(0 == dstIndex);
185 }
186
187 const char* name() const override { return "ComposeOne"; }
188
robertphillips783a4da2015-11-19 14:00:02 -0800189 SkString dumpInfo() const override {
190 SkString str;
191
192 for (int i = 0; i < this->numChildProcessors(); ++i) {
193 str.append(this->childProcessor(i).dumpInfo());
194 }
195 return str;
196 }
197
Brian Salomon94efbf52016-11-29 13:43:05 -0500198 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
Mike Reed7d954ad2016-10-28 15:42:34 -0400199 GR_STATIC_ASSERT(((int)SkBlendMode::kLastMode & SK_MaxU16) == (int)SkBlendMode::kLastMode);
200 b->add32((int)fMode | (fChild << 16));
bsalomonae4738f2015-09-15 15:33:27 -0700201 }
202
Mike Reed7d954ad2016-10-28 15:42:34 -0400203 SkBlendMode mode() const { return fMode; }
bsalomonae4738f2015-09-15 15:33:27 -0700204
205 Child child() const { return fChild; }
206
Brian Salomon587e08f2017-01-27 10:59:27 -0500207private:
208 OptimizationFlags OptFlags(const GrFragmentProcessor* child, SkBlendMode mode) {
Brian Salomon246a3c22017-02-10 16:16:21 -0500209 if (does_cpu_blend_impl_match_gpu(mode) && child->hasConstantOutputForConstantInput()) {
Brian Salomon587e08f2017-01-27 10:59:27 -0500210 return kConstantOutputForConstantInput_OptimizationFlag;
211 }
212 return kNone_OptimizationFlags;
213 }
214
bsalomonae4738f2015-09-15 15:33:27 -0700215 bool onIsEqual(const GrFragmentProcessor& that) const override {
216 return fMode == that.cast<ComposeOneFragmentProcessor>().fMode;
217 }
218
219 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
220 SkXfermode::Coeff skSrcCoeff, skDstCoeff;
221 if (SkXfermode::ModeAsCoeff(fMode, &skSrcCoeff, &skDstCoeff)) {
222 GrBlendCoeff srcCoeff = SkXfermodeCoeffToGrBlendCoeff(skSrcCoeff);
223 GrBlendCoeff dstCoeff = SkXfermodeCoeffToGrBlendCoeff(skDstCoeff);
Brian Salomonaab259e2017-01-17 10:44:34 -0500224 GrInvariantOutput childOutput(0xFFFFFFFF, kRGBA_GrColorComponentFlags);
bsalomonae4738f2015-09-15 15:33:27 -0700225 this->childProcessor(0).computeInvariantOutput(&childOutput);
226 GrColor blendColor;
227 GrColorComponentFlags blendFlags;
228 if (kDst_Child == fChild) {
229 GrGetCoeffBlendKnownComponents(srcCoeff, dstCoeff,
230 inout->color(), inout->validFlags(),
231 childOutput.color(), childOutput.validFlags(),
232 &blendColor, &blendFlags);
233 } else {
234 GrGetCoeffBlendKnownComponents(srcCoeff, dstCoeff,
235 childOutput.color(), childOutput.validFlags(),
236 inout->color(), inout->validFlags(),
237 &blendColor, &blendFlags);
238 }
Brian Salomon5f13fba2017-01-23 14:35:25 -0500239 inout->setToOther(blendFlags, blendColor);
bsalomonae4738f2015-09-15 15:33:27 -0700240 } else {
Brian Salomon5f13fba2017-01-23 14:35:25 -0500241 inout->setToUnknown();
bsalomonae4738f2015-09-15 15:33:27 -0700242 }
243 }
244
Brian Salomon587e08f2017-01-27 10:59:27 -0500245 GrColor4f constantOutputForConstantInput(GrColor4f inputColor) const override {
246 GrColor4f childColor =
247 ConstantOutputForConstantInput(this->childProcessor(0), GrColor4f::OpaqueWhite());
248 SkPM4f src, dst;
249 if (kSrc_Child == fChild) {
250 src = GrColor4fToSkPM4f(childColor);
251 dst = GrColor4fToSkPM4f(inputColor);
252 } else {
253 src = GrColor4fToSkPM4f(inputColor);
254 dst = GrColor4fToSkPM4f(childColor);
255 }
256 auto proc = SkXfermode::GetProc4f(fMode);
257 return SkPM4fToGrColor4f(proc(src, dst));
258 }
259
bsalomonae4738f2015-09-15 15:33:27 -0700260private:
egdaniel57d3b032015-11-13 11:57:27 -0800261 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
bsalomonae4738f2015-09-15 15:33:27 -0700262
Mike Reed7d954ad2016-10-28 15:42:34 -0400263 SkBlendMode fMode;
264 Child fChild;
bsalomonae4738f2015-09-15 15:33:27 -0700265
266 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
267
268 typedef GrFragmentProcessor INHERITED;
269};
270
271//////////////////////////////////////////////////////////////////////////////
272
egdaniel64c47282015-11-13 06:54:19 -0800273class GLComposeOneFragmentProcessor : public GrGLSLFragmentProcessor {
bsalomonae4738f2015-09-15 15:33:27 -0700274public:
bsalomonae4738f2015-09-15 15:33:27 -0700275 void emitCode(EmitArgs& args) override {
cdalton85285412016-02-18 12:37:07 -0800276 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
Mike Reed7d954ad2016-10-28 15:42:34 -0400277 SkBlendMode mode = args.fFp.cast<ComposeOneFragmentProcessor>().mode();
bsalomonae4738f2015-09-15 15:33:27 -0700278 ComposeOneFragmentProcessor::Child child =
279 args.fFp.cast<ComposeOneFragmentProcessor>().child();
bsalomon38ddbad2015-09-24 06:00:00 -0700280 SkString childColor("child");
281 this->emitChild(0, nullptr, &childColor, args);
bsalomonae4738f2015-09-15 15:33:27 -0700282
283 const char* inputColor = args.fInputColor;
284 // We don't try to optimize for this case at all
285 if (!inputColor) {
egdaniel4ca2e602015-11-18 08:01:26 -0800286 fragBuilder->codeAppendf("const vec4 ones = vec4(1);");
bsalomonae4738f2015-09-15 15:33:27 -0700287 inputColor = "ones";
288 }
289
290 // emit blend code
egdaniel4ca2e602015-11-18 08:01:26 -0800291 fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode));
bsalomon38ddbad2015-09-24 06:00:00 -0700292 const char* childStr = childColor.c_str();
bsalomonae4738f2015-09-15 15:33:27 -0700293 if (ComposeOneFragmentProcessor::kDst_Child == child) {
egdaniel4ca2e602015-11-18 08:01:26 -0800294 GrGLSLBlend::AppendMode(fragBuilder, inputColor, childStr, args.fOutputColor, mode);
bsalomonae4738f2015-09-15 15:33:27 -0700295 } else {
egdaniel4ca2e602015-11-18 08:01:26 -0800296 GrGLSLBlend::AppendMode(fragBuilder, childStr, inputColor, args.fOutputColor, mode);
bsalomonae4738f2015-09-15 15:33:27 -0700297 }
bsalomonae4738f2015-09-15 15:33:27 -0700298 }
299
300private:
egdaniel64c47282015-11-13 06:54:19 -0800301 typedef GrGLSLFragmentProcessor INHERITED;
bsalomonae4738f2015-09-15 15:33:27 -0700302};
303
304/////////////////////////////////////////////////////////////////////
305
306GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ComposeOneFragmentProcessor);
307
Hal Canary6f6961e2017-01-31 13:50:44 -0500308#if GR_TEST_UTILS
bungeman06ca8ec2016-06-09 08:01:03 -0700309sk_sp<GrFragmentProcessor> ComposeOneFragmentProcessor::TestCreate(GrProcessorTestData* d) {
bsalomonae4738f2015-09-15 15:33:27 -0700310 // Create one random frag procs.
311 // For now, we'll prevent either children from being a shader with children to prevent the
312 // possibility of an arbitrarily large tree of procs.
bungeman06ca8ec2016-06-09 08:01:03 -0700313 sk_sp<GrFragmentProcessor> dst(GrProcessorUnitTest::MakeChildFP(d));
Mike Reed7d954ad2016-10-28 15:42:34 -0400314 SkBlendMode mode = static_cast<SkBlendMode>(
315 d->fRandom->nextRangeU(0, (int)SkBlendMode::kLastMode));
bsalomonae4738f2015-09-15 15:33:27 -0700316 ComposeOneFragmentProcessor::Child child = d->fRandom->nextBool() ?
317 ComposeOneFragmentProcessor::kDst_Child :
318 ComposeOneFragmentProcessor::kSrc_Child;
bungeman06ca8ec2016-06-09 08:01:03 -0700319 return sk_sp<GrFragmentProcessor>(new ComposeOneFragmentProcessor(std::move(dst), mode, child));
bsalomonae4738f2015-09-15 15:33:27 -0700320}
Hal Canary6f6961e2017-01-31 13:50:44 -0500321#endif
bsalomonae4738f2015-09-15 15:33:27 -0700322
egdaniel57d3b032015-11-13 11:57:27 -0800323GrGLSLFragmentProcessor* ComposeOneFragmentProcessor::onCreateGLSLInstance() const {
robertphillips9cdb9922016-02-03 12:25:40 -0800324 return new GLComposeOneFragmentProcessor;
bsalomonae4738f2015-09-15 15:33:27 -0700325}
326
327//////////////////////////////////////////////////////////////////////////////
328
bungeman06ca8ec2016-06-09 08:01:03 -0700329sk_sp<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromDstProcessor(
Mike Reed7d954ad2016-10-28 15:42:34 -0400330 sk_sp<GrFragmentProcessor> dst, SkBlendMode mode) {
bsalomonae4738f2015-09-15 15:33:27 -0700331 switch (mode) {
Mike Reed7d954ad2016-10-28 15:42:34 -0400332 case SkBlendMode::kClear:
Brian Osman618d3042016-10-25 10:51:28 -0400333 return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(),
bsalomonae4738f2015-09-15 15:33:27 -0700334 GrConstColorProcessor::kIgnore_InputMode);
Mike Reed7d954ad2016-10-28 15:42:34 -0400335 case SkBlendMode::kSrc:
bsalomonae4738f2015-09-15 15:33:27 -0700336 return nullptr;
337 default:
bungeman06ca8ec2016-06-09 08:01:03 -0700338 return sk_sp<GrFragmentProcessor>(
339 new ComposeOneFragmentProcessor(std::move(dst), mode,
340 ComposeOneFragmentProcessor::kDst_Child));
bsalomonae4738f2015-09-15 15:33:27 -0700341 }
342}
343
bungeman06ca8ec2016-06-09 08:01:03 -0700344sk_sp<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromSrcProcessor(
Mike Reed7d954ad2016-10-28 15:42:34 -0400345 sk_sp<GrFragmentProcessor> src, SkBlendMode mode) {
bsalomonae4738f2015-09-15 15:33:27 -0700346 switch (mode) {
Mike Reed7d954ad2016-10-28 15:42:34 -0400347 case SkBlendMode::kClear:
Brian Osman618d3042016-10-25 10:51:28 -0400348 return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(),
bsalomonae4738f2015-09-15 15:33:27 -0700349 GrConstColorProcessor::kIgnore_InputMode);
Mike Reed7d954ad2016-10-28 15:42:34 -0400350 case SkBlendMode::kDst:
bsalomonae4738f2015-09-15 15:33:27 -0700351 return nullptr;
352 default:
bungeman06ca8ec2016-06-09 08:01:03 -0700353 return sk_sp<GrFragmentProcessor>(
354 new ComposeOneFragmentProcessor(src, mode,
355 ComposeOneFragmentProcessor::kSrc_Child));
wangyix809e5af2015-09-09 12:58:32 -0700356 }
357}