blob: 3174d403646c5060b2939b2410b7dc07e8aca851 [file] [log] [blame]
Ethan Nicholas00543112018-07-31 09:44:36 -04001/*
2 * Copyright 2018 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 "GrSkSLFP.h"
Ethan Nicholas00543112018-07-31 09:44:36 -04009#include "glsl/GrGLSLFragmentShaderBuilder.h"
10#include "glsl/GrGLSLProgramBuilder.h"
11#include "GrContext.h"
12#include "GrContextPriv.h"
13#include "GrTexture.h"
14#include "SkSLUtil.h"
15
16GrSkSLFPFactory::GrSkSLFPFactory(const char* name, const GrShaderCaps* shaderCaps, const char* sksl)
17 : fName(name) {
18 SkSL::Program::Settings settings;
19 settings.fCaps = shaderCaps;
20 fBaseProgram = fCompiler.convertProgram(SkSL::Program::kPipelineStage_Kind,
21 SkSL::String(sksl),
22 settings);
23 if (fCompiler.errorCount()) {
24 SkDebugf("%s\n", fCompiler.errorText().c_str());
25 }
26 SkASSERT(fBaseProgram);
27 SkASSERT(!fCompiler.errorCount());
28 for (const auto& e : *fBaseProgram) {
29 if (e.fKind == SkSL::ProgramElement::kVar_Kind) {
30 SkSL::VarDeclarations& v = (SkSL::VarDeclarations&) e;
31 for (const auto& varStatement : v.fVars) {
32 const SkSL::Variable& var = *((SkSL::VarDeclaration&) *varStatement).fVar;
33 if (var.fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
34 fInputVars.push_back(&var);
35 }
Ethan Nicholas222e2752018-10-11 11:21:34 -040036 if (var.fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
37 fUniformVars.push_back(&var);
38 }
Ethan Nicholas00543112018-07-31 09:44:36 -040039 if (var.fModifiers.fLayout.fKey) {
40 fKeyVars.push_back(&var);
41 }
42 }
43 }
44 }
45}
46
47const SkSL::Program* GrSkSLFPFactory::getSpecialization(const SkSL::String& key, const void* inputs,
48 size_t inputSize) {
49 const auto& found = fSpecializations.find(key);
50 if (found != fSpecializations.end()) {
51 return found->second.get();
52 }
53
54 std::unordered_map<SkSL::String, SkSL::Program::Settings::Value> inputMap;
55 size_t offset = 0;
56 for (const auto& v : fInputVars) {
57 SkSL::String name(v->fName);
Ethan Nicholas222e2752018-10-11 11:21:34 -040058 if (v->fType.kind() == SkSL::Type::kEnum_Kind ||
59 &v->fType == fCompiler.context().fInt_Type.get()) {
Ethan Nicholas00543112018-07-31 09:44:36 -040060 offset = SkAlign4(offset);
61 int32_t v = *(int32_t*) (((uint8_t*) inputs) + offset);
62 inputMap.insert(std::make_pair(name, SkSL::Program::Settings::Value(v)));
63 offset += sizeof(int32_t);
Ethan Nicholasce008112018-08-30 09:19:50 -040064 } else if (&v->fType == fCompiler.context().fBool_Type.get()) {
65 bool v = *(((bool*) inputs) + offset);
66 inputMap.insert(std::make_pair(name, SkSL::Program::Settings::Value(v)));
67 offset += sizeof(bool);
Ethan Nicholas78aceb22018-08-31 16:13:58 -040068 } else if (&v->fType == fCompiler.context().fFloat4_Type.get() ||
69 &v->fType == fCompiler.context().fHalf4_Type.get()) {
Ethan Nicholasce008112018-08-30 09:19:50 -040070 offset = SkAlign4(offset) + sizeof(float) * 4;
71 } else if (&v->fType == fCompiler.context().fFragmentProcessor_Type.get()) {
72 // do nothing
73 } else {
74 printf("can't handle input var: %s\n", SkSL::String(v->fType.fName).c_str());
75 SkASSERT(false);
Ethan Nicholas00543112018-07-31 09:44:36 -040076 }
77 }
Ethan Nicholas00543112018-07-31 09:44:36 -040078
79 std::unique_ptr<SkSL::Program> specialized = fCompiler.specialize(*fBaseProgram, inputMap);
80 SkAssertResult(fCompiler.optimize(*specialized));
81 const SkSL::Program* result = specialized.get();
82 fSpecializations.insert(std::make_pair(key, std::move(specialized)));
83 return result;
84}
85
Ethan Nicholas222e2752018-10-11 11:21:34 -040086GrGLSLSkSLFP::GrGLSLSkSLFP(SkSL::Context* context,
87 const std::vector<const SkSL::Variable*>* uniformVars,
88 SkSL::String glsl,
89 std::vector<SkSL::Compiler::FormatArg> formatArgs,
90 void* extraData)
91 : fContext(*context)
92 , fUniformVars(*uniformVars)
93 , fGLSL(glsl)
94 , fFormatArgs(formatArgs)
95 , fExtraData(extraData) {}
Ethan Nicholas00543112018-07-31 09:44:36 -040096
Ethan Nicholas222e2752018-10-11 11:21:34 -040097GrSLType GrGLSLSkSLFP::uniformType(const SkSL::Type& type) {
98 if (type == *fContext.fFloat_Type) {
Ethan Nicholasce008112018-08-30 09:19:50 -040099 return kFloat_GrSLType;
Ethan Nicholas222e2752018-10-11 11:21:34 -0400100 } else if (type == *fContext.fHalf_Type) {
101 return kHalf_GrSLType;
102 } else if (type == *fContext.fFloat2_Type) {
103 return kFloat2_GrSLType;
104 } else if (type == *fContext.fHalf2_Type) {
105 return kHalf2_GrSLType;
106 } else if (type == *fContext.fFloat4_Type) {
107 return kFloat4_GrSLType;
108 } else if (type == *fContext.fHalf4_Type) {
109 return kHalf4_GrSLType;
110 } else if (type == *fContext.fFloat4x4_Type) {
111 return kFloat4x4_GrSLType;
112 } else if (type == *fContext.fHalf4x4_Type) {
113 return kHalf4x4_GrSLType;
114 } else if (type == *fContext.fBool_Type) {
115 return kBool_GrSLType;
116 } else if (type == *fContext.fInt_Type) {
117 return kInt_GrSLType;
Ethan Nicholasce008112018-08-30 09:19:50 -0400118 }
Ethan Nicholas222e2752018-10-11 11:21:34 -0400119 SK_ABORT("unsupported uniform type");
120 return kFloat_GrSLType;
121}
Ethan Nicholasce008112018-08-30 09:19:50 -0400122
Ethan Nicholas222e2752018-10-11 11:21:34 -0400123void* GrGLSLSkSLFP::extraData() const {
124 return fExtraData;
125}
126
127void GrGLSLSkSLFP::emitCode(EmitArgs& args) {
128 for (const auto& v : fUniformVars) {
129 if (v->fType != *fContext.fFragmentProcessor_Type) {
130 fUniformHandles.push_back(args.fUniformHandler->addUniform(
131 kFragment_GrShaderFlag,
132 this->uniformType(v->fType),
133 kDefault_GrSLPrecision,
134 SkSL::String(v->fName).c_str()));
Ethan Nicholasce008112018-08-30 09:19:50 -0400135 }
Ethan Nicholas222e2752018-10-11 11:21:34 -0400136 }
137 std::vector<SkString> childNames;
138 for (int i = 0; i < this->numChildProcessors(); ++i) {
139 childNames.push_back(SkStringPrintf("_child%d", i));
140 this->emitChild(i, &childNames[i], args);
141 }
142 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
143 int substringStartIndex = 0;
144 int formatArgIndex = 0;
145 for (size_t i = 0; i < fGLSL.length(); ++i) {
146 char c = fGLSL[i];
147 if (c == '%') {
148 fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
149 i - substringStartIndex);
150 ++i;
151 c = fGLSL[i];
152 switch (c) {
153 case 's': {
154 SkSL::Compiler::FormatArg& arg = fFormatArgs[formatArgIndex++];
155 switch (arg.fKind) {
156 case SkSL::Compiler::FormatArg::Kind::kInput:
157 fragBuilder->codeAppend(args.fInputColor);
158 break;
159 case SkSL::Compiler::FormatArg::Kind::kOutput:
160 fragBuilder->codeAppend(args.fOutputColor);
161 break;
162 case SkSL::Compiler::FormatArg::Kind::kUniform:
163 fragBuilder->codeAppend(args.fUniformHandler->getUniformCStr(
164 fUniformHandles[arg.fIndex]));
165 break;
166 case SkSL::Compiler::FormatArg::Kind::kChildProcessor:
167 fragBuilder->codeAppend(childNames[arg.fIndex].c_str());
168 break;
Ethan Nicholasce008112018-08-30 09:19:50 -0400169 }
Ethan Nicholas222e2752018-10-11 11:21:34 -0400170 break;
Ethan Nicholas00543112018-07-31 09:44:36 -0400171 }
Ethan Nicholas222e2752018-10-11 11:21:34 -0400172 default:
173 fragBuilder->codeAppendf("%c", c);
Ethan Nicholas00543112018-07-31 09:44:36 -0400174 }
Ethan Nicholas222e2752018-10-11 11:21:34 -0400175 substringStartIndex = i + 1;
Ethan Nicholasce008112018-08-30 09:19:50 -0400176 }
177 }
Ethan Nicholas222e2752018-10-11 11:21:34 -0400178 fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
179 fGLSL.length() - substringStartIndex);
180}
Ethan Nicholasce008112018-08-30 09:19:50 -0400181
Ethan Nicholas222e2752018-10-11 11:21:34 -0400182void GrGLSLSkSLFP::onSetData(const GrGLSLProgramDataManager& pdman,
183 const GrFragmentProcessor& _proc) {
184 size_t uniformIndex = 0;
185 size_t offset = 0;
186 const GrSkSLFP& outer = _proc.cast<GrSkSLFP>();
187 uint8_t* inputs = (uint8_t*) outer.fInputs;
188 const SkSL::Context& context = outer.fFactory->fCompiler.context();
189 for (const auto& v : outer.fFactory->fInputVars) {
190 if (&v->fType == context.fFloat4_Type.get() ||
191 &v->fType == context.fHalf4_Type.get()) {
192 float f1, f2, f3, f4;
193 switch (v->fModifiers.fLayout.fCType) {
194 case SkSL::Layout::CType::kSkPMColor:
195 f1 = inputs[offset++] / 255.0;
196 f2 = inputs[offset++] / 255.0;
197 f3 = inputs[offset++] / 255.0;
198 f4 = inputs[offset++] / 255.0;
199 break;
200 case SkSL::Layout::CType::kSkRect: // fall through
201 case SkSL::Layout::CType::kDefault:
202 offset = SkAlign4(offset);
203 f1 = *(float*) (inputs + offset);
204 offset += sizeof(float);
205 f2 = *(float*) (inputs + offset);
206 offset += sizeof(float);
207 f3 = *(float*) (inputs + offset);
208 offset += sizeof(float);
209 f4 = *(float*) (inputs + offset);
210 offset += sizeof(float);
211 break;
212 default:
213 SK_ABORT("unsupported uniform ctype");
214 }
215 if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
216 pdman.set4f(fUniformHandles[uniformIndex++], f1, f2, f3, f4);
217 }
218 } else if (v->fType.kind() == SkSL::Type::kEnum_Kind ||
219 &v->fType == context.fInt_Type.get()) {
220 int32_t i = *(int*) (inputs + offset);
221 offset += sizeof(int32_t);
222 if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
223 pdman.set1i(fUniformHandles[uniformIndex++], i);
224 }
225 } else if (&v->fType == context.fBool_Type.get()) {
226 SkASSERT(!(v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag));
227 ++offset;
228 } else {
229 SkASSERT(&v->fType == context.fFragmentProcessor_Type.get());
230 }
231 }
232 if (fUniformHandles.size() && outer.fSetDataHook) {
233 outer.fSetDataHook(pdman, *this, outer.fInputs, fExtraData);
234 }
Ethan Nicholas00543112018-07-31 09:44:36 -0400235}
236
Ethan Nicholas00543112018-07-31 09:44:36 -0400237GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps,
238 int index, const char* name, const char* sksl, const void* inputs,
Ethan Nicholas222e2752018-10-11 11:21:34 -0400239 size_t inputSize, const void* extraData, size_t extraDataSize,
240 UntypedDataHookFn setDataHook)
Ethan Nicholas00543112018-07-31 09:44:36 -0400241 : INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
242 , fFactoryCache(factoryCache)
243 , fShaderCaps(sk_ref_sp(shaderCaps))
244 , fIndex(index)
245 , fName(name)
246 , fSkSL(sksl)
Ethan Nicholas222e2752018-10-11 11:21:34 -0400247 , fInputs(inputs)
248 , fInputSize(inputSize)
249 , fExtraData(extraData)
250 , fExtraDataSize(extraDataSize)
251 , fSetDataHook(setDataHook) {}
Ethan Nicholas00543112018-07-31 09:44:36 -0400252
253GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
254 : INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
255 , fFactoryCache(other.fFactoryCache)
256 , fShaderCaps(other.fShaderCaps)
257 , fFactory(other.fFactory)
258 , fIndex(other.fIndex)
259 , fName(other.fName)
260 , fSkSL(other.fSkSL)
Ethan Nicholas222e2752018-10-11 11:21:34 -0400261 , fInputs(other.fInputs)
262 , fInputSize(other.fInputSize)
263 , fExtraData(other.fExtraData)
264 , fExtraDataSize(other.fExtraDataSize)
265 , fSetDataHook(other.fSetDataHook) {}
Ethan Nicholas00543112018-07-31 09:44:36 -0400266
267const char* GrSkSLFP::name() const {
268 return fName;
269}
270
271void GrSkSLFP::createFactory() const {
272 if (!fFactory) {
273 fFactory = fFactoryCache->get(fIndex);
274 if (!fFactory) {
275 fFactory = sk_sp<GrSkSLFPFactory>(new GrSkSLFPFactory(fName, fShaderCaps.get(), fSkSL));
276 fFactoryCache->set(fIndex, fFactory);
277 }
278 }
279}
280
Ethan Nicholasce008112018-08-30 09:19:50 -0400281void GrSkSLFP::addChild(std::unique_ptr<GrFragmentProcessor> child) {
282 this->registerChildProcessor(std::move(child));
283}
284
Ethan Nicholas00543112018-07-31 09:44:36 -0400285GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
286 this->createFactory();
Ethan Nicholas222e2752018-10-11 11:21:34 -0400287 const SkSL::Program* specialized = fFactory->getSpecialization(fKey, fInputs, fInputSize);
Ethan Nicholas00543112018-07-31 09:44:36 -0400288 SkSL::String glsl;
289 std::vector<SkSL::Compiler::FormatArg> formatArgs;
Ethan Nicholasce008112018-08-30 09:19:50 -0400290 if (!fFactory->fCompiler.toPipelineStage(*specialized, &glsl, &formatArgs)) {
Ethan Nicholas00543112018-07-31 09:44:36 -0400291 printf("%s\n", fFactory->fCompiler.errorText().c_str());
Ethan Nicholasce008112018-08-30 09:19:50 -0400292 SkASSERT(false);
Ethan Nicholas00543112018-07-31 09:44:36 -0400293 }
Ethan Nicholas222e2752018-10-11 11:21:34 -0400294 void* result = ::operator new(sizeof(GrGLSLSkSLFP) + fExtraDataSize);
295 void* extraDataBytes = ((uint8_t*) result) + sizeof(GrGLSLSkSLFP);
296 if (fExtraDataSize) {
297 memcpy(extraDataBytes, fExtraData, fExtraDataSize);
298 }
299 return new (result) GrGLSLSkSLFP(specialized->fContext.get(), &fFactory->fUniformVars, glsl,
300 formatArgs, extraDataBytes);
Ethan Nicholas00543112018-07-31 09:44:36 -0400301}
302
303void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
304 GrProcessorKeyBuilder* b) const {
305 this->createFactory();
306 size_t offset = 0;
Ethan Nicholas222e2752018-10-11 11:21:34 -0400307 uint8_t* inputs = (uint8_t*) fInputs;
Ethan Nicholasce008112018-08-30 09:19:50 -0400308 const SkSL::Context& context = fFactory->fCompiler.context();
Ethan Nicholas00543112018-07-31 09:44:36 -0400309 for (const auto& v : fFactory->fInputVars) {
Ethan Nicholas222e2752018-10-11 11:21:34 -0400310 if (v->fType.kind() == SkSL::Type::kEnum_Kind || &v->fType == context.fInt_Type.get()) {
Ethan Nicholas00543112018-07-31 09:44:36 -0400311 offset = SkAlign4(offset);
312 if (v->fModifiers.fLayout.fKey) {
313 fKey += inputs[offset + 0];
314 fKey += inputs[offset + 1];
315 fKey += inputs[offset + 2];
316 fKey += inputs[offset + 3];
317 b->add32(*(int32_t*) (inputs + offset));
318 }
319 offset += sizeof(int32_t);
Ethan Nicholas78aceb22018-08-31 16:13:58 -0400320 } else if (&v->fType == context.fFloat4_Type.get() ||
321 &v->fType == context.fHalf4_Type.get()) {
Ethan Nicholasce008112018-08-30 09:19:50 -0400322 if (v->fModifiers.fLayout.fKey) {
323 for (size_t i = 0; i < sizeof(float) * 4; ++i) {
324 fKey += inputs[offset + i];
325 }
326 b->add32(*(int32_t*) (inputs + offset));
327 offset += sizeof(float);
328 b->add32(*(int32_t*) (inputs + offset));
329 offset += sizeof(float);
330 b->add32(*(int32_t*) (inputs + offset));
331 offset += sizeof(float);
332 b->add32(*(int32_t*) (inputs + offset));
333 offset += sizeof(float);
334 } else {
335 offset += sizeof(float) * 4;
336 }
337 } else if (&v->fType == context.fBool_Type.get()) {
338 if (v->fModifiers.fLayout.fKey) {
339 fKey += inputs[offset];
340 b->add32(inputs[offset]);
341 }
342 ++offset;
343 } else if (&v->fType == context.fFragmentProcessor_Type.get()) {
344 continue;
345 } else {
Ethan Nicholas00543112018-07-31 09:44:36 -0400346 // unsupported input var type
Ethan Nicholasce008112018-08-30 09:19:50 -0400347 printf("%s\n", SkSL::String(v->fType.fName).c_str());
Ethan Nicholas00543112018-07-31 09:44:36 -0400348 SkASSERT(false);
349 }
350 }
Ethan Nicholas00543112018-07-31 09:44:36 -0400351}
352
353bool GrSkSLFP::onIsEqual(const GrFragmentProcessor& other) const {
354 const GrSkSLFP& sk = other.cast<GrSkSLFP>();
355 SkASSERT(fIndex != sk.fIndex || fInputSize == sk.fInputSize);
356 return fIndex == sk.fIndex &&
Ethan Nicholas222e2752018-10-11 11:21:34 -0400357 !memcmp(fInputs, sk.fInputs, fInputSize);
Ethan Nicholas00543112018-07-31 09:44:36 -0400358}
359
360std::unique_ptr<GrFragmentProcessor> GrSkSLFP::clone() const {
Ethan Nicholas222e2752018-10-11 11:21:34 -0400361 void* placement = GrSkSLFP::operator new(sizeof(GrSkSLFP) + fInputSize + fExtraDataSize);
362 std::unique_ptr<GrSkSLFP> result(new (placement) GrSkSLFP(*this));
363 void* inputsTarget = ((int8_t*) placement) + sizeof(GrSkSLFP);
364 memcpy(inputsTarget, fInputs, fInputSize);
365 result->fInputs = inputsTarget;
366 if (fExtraData) {
367 void* extraDataTarget = ((int8_t*) placement) + sizeof(GrSkSLFP) + fInputSize;
368 memcpy(extraDataTarget, fExtraData, fExtraDataSize);
369 result->fExtraData = extraDataTarget;
370 }
Ethan Nicholasce008112018-08-30 09:19:50 -0400371 for (int i = 0; i < this->numChildProcessors(); ++i) {
372 result->registerChildProcessor(this->childProcessor(i).clone());
373 }
374 return std::unique_ptr<GrFragmentProcessor>(result.release());
Ethan Nicholas00543112018-07-31 09:44:36 -0400375}
376
377// We have to do a bit of manual refcounting in the cache methods below. Ideally, we could just
378// define fFactories to contain sk_sp<GrSkSLFPFactory> rather than GrSkSLFPFactory*, but that would
379// require GrContext to include GrSkSLFP, which creates much bigger headaches than a few manual
380// refcounts.
381
382sk_sp<GrSkSLFPFactory> GrSkSLFPFactoryCache::get(int index) {
383 if (index >= (int) fFactories.size()) {
384 return nullptr;
385 }
386 GrSkSLFPFactory* result = fFactories[index];
Ethan Nicholasce008112018-08-30 09:19:50 -0400387 SkSafeRef(result);
Ethan Nicholas00543112018-07-31 09:44:36 -0400388 return sk_sp<GrSkSLFPFactory>(result);
389}
390
391void GrSkSLFPFactoryCache::set(int index, sk_sp<GrSkSLFPFactory> factory) {
392 while (index >= (int) fFactories.size()) {
393 fFactories.emplace_back();
394 }
395 factory->ref();
396 SkASSERT(!fFactories[index]);
397 fFactories[index] = factory.get();
398}
399
400GrSkSLFPFactoryCache::~GrSkSLFPFactoryCache() {
401 for (GrSkSLFPFactory* factory : fFactories) {
402 if (factory) {
403 factory->unref();
404 }
405 }
406}
407
408GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSkSLFP);
409
410#if GR_TEST_UTILS
411
Ethan Nicholas78aceb22018-08-31 16:13:58 -0400412#include "GrConstColorProcessor.h"
413#include "SkArithmeticImageFilter.h"
Ethan Nicholas222e2752018-10-11 11:21:34 -0400414#include "effects/GrConvexPolyEffect.h"
Ethan Nicholas78aceb22018-08-31 16:13:58 -0400415
416extern const char* SKSL_ARITHMETIC_SRC;
417extern const char* SKSL_DITHER_SRC;
418extern const char* SKSL_OVERDRAW_SRC;
Ethan Nicholas00543112018-07-31 09:44:36 -0400419
420using Value = SkSL::Program::Settings::Value;
421
422std::unique_ptr<GrFragmentProcessor> GrSkSLFP::TestCreate(GrProcessorTestData* d) {
Ethan Nicholas222e2752018-10-11 11:21:34 -0400423 int type = d->fRandom->nextULessThan(4);
Ethan Nicholas00543112018-07-31 09:44:36 -0400424 switch (type) {
425 case 0: {
426 static int ditherIndex = NewIndex();
427 int rangeType = d->fRandom->nextULessThan(3);
Ethan Nicholasce008112018-08-30 09:19:50 -0400428 std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), ditherIndex, "Dither",
Ethan Nicholas222e2752018-10-11 11:21:34 -0400429 SKSL_DITHER_SRC, rangeType);
Ethan Nicholasce008112018-08-30 09:19:50 -0400430 return std::unique_ptr<GrFragmentProcessor>(result.release());
431 }
432 case 1: {
433 static int arithmeticIndex = NewIndex();
434 ArithmeticFPInputs inputs;
435 inputs.k[0] = d->fRandom->nextF();
436 inputs.k[1] = d->fRandom->nextF();
437 inputs.k[2] = d->fRandom->nextF();
438 inputs.k[3] = d->fRandom->nextF();
439 inputs.enforcePMColor = d->fRandom->nextBool();
440 std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), arithmeticIndex,
441 "Arithmetic", SKSL_ARITHMETIC_SRC,
Ethan Nicholas222e2752018-10-11 11:21:34 -0400442 inputs);
Ethan Nicholasce008112018-08-30 09:19:50 -0400443 result->addChild(GrConstColorProcessor::Make(
Brian Osmanf28e55d2018-10-03 16:35:54 -0400444 SK_PMColor4fWHITE,
Ethan Nicholasce008112018-08-30 09:19:50 -0400445 GrConstColorProcessor::InputMode::kIgnore));
446 return std::unique_ptr<GrFragmentProcessor>(result.release());
Ethan Nicholas00543112018-07-31 09:44:36 -0400447 }
Ethan Nicholas78aceb22018-08-31 16:13:58 -0400448 case 2: {
449 static int overdrawIndex = NewIndex();
450 SkPMColor inputs[6];
451 for (int i = 0; i < 6; ++i) {
452 inputs[i] = d->fRandom->nextU();
453 }
454 std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), overdrawIndex,
455 "Overdraw", SKSL_OVERDRAW_SRC,
Ethan Nicholas222e2752018-10-11 11:21:34 -0400456 inputs);
Ethan Nicholas78aceb22018-08-31 16:13:58 -0400457 return std::unique_ptr<GrFragmentProcessor>(result.release());
458 }
Ethan Nicholas222e2752018-10-11 11:21:34 -0400459 case 3: {
460 SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(),
461 d->fRandom->nextSScalar1(),
462 d->fRandom->nextSScalar1(),
463 d->fRandom->nextSScalar1());
464 std::unique_ptr<GrFragmentProcessor> fp;
465 do {
466 GrClipEdgeType edgeType = static_cast<GrClipEdgeType>(
467 d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
468
469 fp = GrConvexPolyEffect::Make(edgeType, rect, d->context());
470 } while (nullptr == fp);
471 return fp;
472 }
Ethan Nicholas00543112018-07-31 09:44:36 -0400473 }
474 SK_ABORT("unreachable");
475 return nullptr;
476}
477
478#endif