GrSkSLFP.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. /*
  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. #include "src/gpu/effects/GrSkSLFP.h"
  8. #include "include/gpu/GrTexture.h"
  9. #include "include/private/GrContext_Base.h"
  10. #include "src/gpu/GrBaseContextPriv.h"
  11. #include "src/sksl/SkSLUtil.h"
  12. #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
  13. #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
  14. #include "src/gpu/glsl/GrGLSLProgramBuilder.h"
  15. GrSkSLFPFactory::GrSkSLFPFactory(const char* name, const GrShaderCaps* shaderCaps, const char* sksl,
  16. SkSL::Program::Kind kind)
  17. : fKind(kind)
  18. , fName(name) {
  19. SkSL::Program::Settings settings;
  20. settings.fCaps = shaderCaps;
  21. fBaseProgram = fCompiler.convertProgram(fKind, SkSL::String(sksl), settings);
  22. if (fCompiler.errorCount()) {
  23. SkDebugf("%s\n", fCompiler.errorText().c_str());
  24. }
  25. SkASSERT(fBaseProgram);
  26. SkASSERT(!fCompiler.errorCount());
  27. for (const auto& e : *fBaseProgram) {
  28. if (e.fKind == SkSL::ProgramElement::kVar_Kind) {
  29. SkSL::VarDeclarations& v = (SkSL::VarDeclarations&) e;
  30. for (const auto& varStatement : v.fVars) {
  31. const SkSL::Variable& var = *((SkSL::VarDeclaration&) *varStatement).fVar;
  32. if (var.fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
  33. fInputVars.push_back(&var);
  34. }
  35. if (var.fModifiers.fLayout.fKey) {
  36. fKeyVars.push_back(&var);
  37. }
  38. }
  39. }
  40. }
  41. }
  42. const SkSL::Program* GrSkSLFPFactory::getSpecialization(const SkSL::String& key, const void* inputs,
  43. size_t inputSize) {
  44. const auto& found = fSpecializations.find(key);
  45. if (found != fSpecializations.end()) {
  46. return found->second.get();
  47. }
  48. std::unordered_map<SkSL::String, SkSL::Program::Settings::Value> inputMap;
  49. size_t offset = 0;
  50. for (const auto& v : fInputVars) {
  51. SkSL::String name(v->fName);
  52. if (&v->fType == fCompiler.context().fInt_Type.get() ||
  53. &v->fType == fCompiler.context().fShort_Type.get()) {
  54. offset = SkAlign4(offset);
  55. int32_t v = *(int32_t*) (((uint8_t*) inputs) + offset);
  56. inputMap.insert(std::make_pair(name, SkSL::Program::Settings::Value(v)));
  57. offset += sizeof(int32_t);
  58. } else if (&v->fType == fCompiler.context().fFloat_Type.get() ||
  59. &v->fType == fCompiler.context().fHalf_Type.get()) {
  60. offset = SkAlign4(offset);
  61. float v = *(float*) (((uint8_t*) inputs) + offset);
  62. inputMap.insert(std::make_pair(name, SkSL::Program::Settings::Value(v)));
  63. offset += sizeof(float);
  64. } 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);
  68. } else if (&v->fType == fCompiler.context().fFloat4_Type.get() ||
  69. &v->fType == fCompiler.context().fHalf4_Type.get()) {
  70. 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);
  76. }
  77. }
  78. std::unique_ptr<SkSL::Program> specialized = fCompiler.specialize(*fBaseProgram, inputMap);
  79. bool optimized = fCompiler.optimize(*specialized);
  80. if (!optimized) {
  81. SkDebugf("%s\n", fCompiler.errorText().c_str());
  82. SkASSERT(false);
  83. }
  84. const SkSL::Program* result = specialized.get();
  85. fSpecializations.insert(std::make_pair(key, std::move(specialized)));
  86. return result;
  87. }
  88. static SkSL::Layout::CType get_ctype(const SkSL::Context& context, const SkSL::Variable& v) {
  89. SkSL::Layout::CType result = v.fModifiers.fLayout.fCType;
  90. if (result == SkSL::Layout::CType::kDefault) {
  91. if (&v.fType == context.fFloat_Type.get()) {
  92. result = SkSL::Layout::CType::kFloat;
  93. } else if (&v.fType == context.fFloat4_Type.get()) {
  94. result = SkSL::Layout::CType::kSkRect;
  95. } else if (&v.fType == context.fHalf4_Type.get()) {
  96. result = SkSL::Layout::CType::kSkPMColor;
  97. } else if (&v.fType == context.fInt_Type.get()) {
  98. result = SkSL::Layout::CType::kInt32;
  99. } else if (&v.fType == context.fBool_Type.get()) {
  100. result = SkSL::Layout::CType::kBool;
  101. } else {
  102. return SkSL::Layout::CType::kDefault;
  103. }
  104. }
  105. return result;
  106. }
  107. class GrGLSLSkSLFP : public GrGLSLFragmentProcessor {
  108. public:
  109. GrGLSLSkSLFP(const SkSL::Context* context, const std::vector<const SkSL::Variable*>* inputVars,
  110. SkSL::String glsl, std::vector<SkSL::Compiler::FormatArg> formatArgs)
  111. : fContext(*context)
  112. , fInputVars(*inputVars)
  113. , fGLSL(glsl)
  114. , fFormatArgs(formatArgs) {}
  115. GrSLType uniformType(const SkSL::Type& type) {
  116. if (type == *fContext.fFloat_Type) {
  117. return kFloat_GrSLType;
  118. } else if (type == *fContext.fHalf_Type) {
  119. return kHalf_GrSLType;
  120. } else if (type == *fContext.fFloat2_Type) {
  121. return kFloat2_GrSLType;
  122. } else if (type == *fContext.fHalf2_Type) {
  123. return kHalf2_GrSLType;
  124. } else if (type == *fContext.fFloat4_Type) {
  125. return kFloat4_GrSLType;
  126. } else if (type == *fContext.fHalf4_Type) {
  127. return kHalf4_GrSLType;
  128. } else if (type == *fContext.fFloat4x4_Type) {
  129. return kFloat4x4_GrSLType;
  130. } else if (type == *fContext.fHalf4x4_Type) {
  131. return kHalf4x4_GrSLType;
  132. } else if (type == *fContext.fBool_Type) {
  133. return kBool_GrSLType;
  134. } else if (type == *fContext.fInt_Type) {
  135. return kInt_GrSLType;
  136. }
  137. printf("%s\n", SkSL::String(type.fName).c_str());
  138. SK_ABORT("unsupported uniform type");
  139. return kFloat_GrSLType;
  140. }
  141. void emitCode(EmitArgs& args) override {
  142. for (const auto& v : fInputVars) {
  143. if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag && v->fType !=
  144. *fContext.fFragmentProcessor_Type) {
  145. fUniformHandles.push_back(args.fUniformHandler->addUniform(
  146. kFragment_GrShaderFlag,
  147. this->uniformType(v->fType),
  148. SkSL::String(v->fName).c_str()));
  149. }
  150. }
  151. std::vector<SkString> childNames;
  152. for (int i = 0; i < this->numChildProcessors(); ++i) {
  153. childNames.push_back(SkStringPrintf("_child%d", i));
  154. this->emitChild(i, &childNames[i], args);
  155. }
  156. GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
  157. int substringStartIndex = 0;
  158. int formatArgIndex = 0;
  159. for (size_t i = 0; i < fGLSL.length(); ++i) {
  160. char c = fGLSL[i];
  161. if (c == '%') {
  162. fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
  163. i - substringStartIndex);
  164. ++i;
  165. c = fGLSL[i];
  166. switch (c) {
  167. case 's': {
  168. SkSL::Compiler::FormatArg& arg = fFormatArgs[formatArgIndex++];
  169. switch (arg.fKind) {
  170. case SkSL::Compiler::FormatArg::Kind::kInput:
  171. fragBuilder->codeAppend(args.fInputColor);
  172. break;
  173. case SkSL::Compiler::FormatArg::Kind::kOutput:
  174. fragBuilder->codeAppend(args.fOutputColor);
  175. break;
  176. case SkSL::Compiler::FormatArg::Kind::kUniform:
  177. fragBuilder->codeAppend(args.fUniformHandler->getUniformCStr(
  178. fUniformHandles[arg.fIndex]));
  179. break;
  180. case SkSL::Compiler::FormatArg::Kind::kChildProcessor:
  181. fragBuilder->codeAppend(childNames[arg.fIndex].c_str());
  182. break;
  183. }
  184. break;
  185. }
  186. default:
  187. fragBuilder->codeAppendf("%c", c);
  188. }
  189. substringStartIndex = i + 1;
  190. }
  191. }
  192. fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
  193. fGLSL.length() - substringStartIndex);
  194. }
  195. void onSetData(const GrGLSLProgramDataManager& pdman,
  196. const GrFragmentProcessor& _proc) override {
  197. size_t uniformIndex = 0;
  198. size_t offset = 0;
  199. const GrSkSLFP& outer = _proc.cast<GrSkSLFP>();
  200. char* inputs = (char*) outer.fInputs.get();
  201. for (const auto& v : outer.fFactory->fInputVars) {
  202. switch (get_ctype(fContext, *v)) {
  203. case SkSL::Layout::CType::kSkPMColor: {
  204. float f1 = ((uint8_t*) inputs)[offset++] / 255.0;
  205. float f2 = ((uint8_t*) inputs)[offset++] / 255.0;
  206. float f3 = ((uint8_t*) inputs)[offset++] / 255.0;
  207. float f4 = ((uint8_t*) inputs)[offset++] / 255.0;
  208. if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
  209. pdman.set4f(fUniformHandles[uniformIndex++], f1, f2, f3, f4);
  210. }
  211. break;
  212. }
  213. case SkSL::Layout::CType::kSkPMColor4f:
  214. case SkSL::Layout::CType::kSkRect: {
  215. offset = SkAlign4(offset);
  216. float f1 = *(float*) (inputs + offset);
  217. offset += sizeof(float);
  218. float f2 = *(float*) (inputs + offset);
  219. offset += sizeof(float);
  220. float f3 = *(float*) (inputs + offset);
  221. offset += sizeof(float);
  222. float f4 = *(float*) (inputs + offset);
  223. offset += sizeof(float);
  224. if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
  225. pdman.set4f(fUniformHandles[uniformIndex++], f1, f2, f3, f4);
  226. }
  227. break;
  228. }
  229. case SkSL::Layout::CType::kInt32: {
  230. int32_t i = *(int32_t*) (inputs + offset);
  231. offset += sizeof(int32_t);
  232. if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
  233. pdman.set1i(fUniformHandles[uniformIndex++], i);
  234. }
  235. break;
  236. }
  237. case SkSL::Layout::CType::kFloat: {
  238. float f = *(float*) (inputs + offset);
  239. offset += sizeof(float);
  240. if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
  241. pdman.set1f(fUniformHandles[uniformIndex++], f);
  242. }
  243. break;
  244. }
  245. case SkSL::Layout::CType::kBool:
  246. SkASSERT(!(v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag));
  247. ++offset;
  248. break;
  249. default:
  250. SkASSERT(&v->fType == fContext.fFragmentProcessor_Type.get());
  251. }
  252. }
  253. }
  254. const SkSL::Context& fContext;
  255. const std::vector<const SkSL::Variable*>& fInputVars;
  256. // nearly-finished GLSL; still contains printf-style "%s" format tokens
  257. const SkSL::String fGLSL;
  258. std::vector<SkSL::Compiler::FormatArg> fFormatArgs;
  259. std::vector<UniformHandle> fUniformHandles;
  260. };
  261. std::unique_ptr<GrSkSLFP> GrSkSLFP::Make(GrContext_Base* context, int index, const char* name,
  262. const char* sksl, const void* inputs,
  263. size_t inputSize, SkSL::Program::Kind kind) {
  264. return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().fpFactoryCache(),
  265. context->priv().caps()->shaderCaps(),
  266. kind, index, name, sksl, SkString(),
  267. inputs, inputSize));
  268. }
  269. std::unique_ptr<GrSkSLFP> GrSkSLFP::Make(GrContext_Base* context, int index, const char* name,
  270. SkString sksl, const void* inputs, size_t inputSize,
  271. SkSL::Program::Kind kind) {
  272. return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().fpFactoryCache(),
  273. context->priv().caps()->shaderCaps(),
  274. kind, index, name, nullptr, std::move(sksl),
  275. inputs, inputSize));
  276. }
  277. GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps,
  278. SkSL::Program::Kind kind, int index, const char* name, const char* sksl,
  279. SkString skslString, const void* inputs, size_t inputSize)
  280. : INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
  281. , fFactoryCache(factoryCache)
  282. , fShaderCaps(sk_ref_sp(shaderCaps))
  283. , fKind(kind)
  284. , fIndex(index)
  285. , fName(name)
  286. , fSkSLString(skslString)
  287. , fSkSL(sksl ? sksl : fSkSLString.c_str())
  288. , fInputs(new int8_t[inputSize])
  289. , fInputSize(inputSize) {
  290. if (fInputSize) {
  291. memcpy(fInputs.get(), inputs, inputSize);
  292. }
  293. }
  294. GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
  295. : INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
  296. , fFactoryCache(other.fFactoryCache)
  297. , fShaderCaps(other.fShaderCaps)
  298. , fFactory(other.fFactory)
  299. , fKind(other.fKind)
  300. , fIndex(other.fIndex)
  301. , fName(other.fName)
  302. , fSkSLString(other.fSkSLString)
  303. , fSkSL(other.fSkSL)
  304. , fInputs(new int8_t[other.fInputSize])
  305. , fInputSize(other.fInputSize) {
  306. if (fInputSize) {
  307. memcpy(fInputs.get(), other.fInputs.get(), fInputSize);
  308. }
  309. }
  310. const char* GrSkSLFP::name() const {
  311. return fName;
  312. }
  313. void GrSkSLFP::createFactory() const {
  314. if (!fFactory) {
  315. fFactory = fFactoryCache->get(fIndex);
  316. if (!fFactory) {
  317. fFactory = sk_sp<GrSkSLFPFactory>(new GrSkSLFPFactory(fName, fShaderCaps.get(), fSkSL,
  318. fKind));
  319. fFactoryCache->set(fIndex, fFactory);
  320. }
  321. }
  322. }
  323. void GrSkSLFP::addChild(std::unique_ptr<GrFragmentProcessor> child) {
  324. this->registerChildProcessor(std::move(child));
  325. }
  326. GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
  327. this->createFactory();
  328. const SkSL::Program* specialized = fFactory->getSpecialization(fKey, fInputs.get(), fInputSize);
  329. SkSL::String glsl;
  330. std::vector<SkSL::Compiler::FormatArg> formatArgs;
  331. if (!fFactory->fCompiler.toPipelineStage(*specialized, &glsl, &formatArgs)) {
  332. printf("%s\n", fFactory->fCompiler.errorText().c_str());
  333. SkASSERT(false);
  334. }
  335. return new GrGLSLSkSLFP(specialized->fContext.get(), &fFactory->fInputVars, glsl, formatArgs);
  336. }
  337. void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
  338. GrProcessorKeyBuilder* b) const {
  339. this->createFactory();
  340. b->add32(fIndex);
  341. size_t offset = 0;
  342. char* inputs = (char*) fInputs.get();
  343. const SkSL::Context& context = fFactory->fCompiler.context();
  344. for (const auto& v : fFactory->fInputVars) {
  345. if (&v->fType == context.fFragmentProcessor_Type.get()) {
  346. continue;
  347. }
  348. switch (get_ctype(context, *v)) {
  349. case SkSL::Layout::CType::kBool:
  350. if (v->fModifiers.fLayout.fKey) {
  351. fKey += inputs[offset];
  352. b->add32(inputs[offset]);
  353. }
  354. ++offset;
  355. break;
  356. case SkSL::Layout::CType::kInt32: {
  357. offset = SkAlign4(offset);
  358. if (v->fModifiers.fLayout.fKey) {
  359. fKey += inputs[offset + 0];
  360. fKey += inputs[offset + 1];
  361. fKey += inputs[offset + 2];
  362. fKey += inputs[offset + 3];
  363. b->add32(*(int32_t*) (inputs + offset));
  364. }
  365. offset += sizeof(int32_t);
  366. break;
  367. }
  368. case SkSL::Layout::CType::kFloat: {
  369. offset = SkAlign4(offset);
  370. if (v->fModifiers.fLayout.fKey) {
  371. fKey += inputs[offset + 0];
  372. fKey += inputs[offset + 1];
  373. fKey += inputs[offset + 2];
  374. fKey += inputs[offset + 3];
  375. b->add32(*(float*) (inputs + offset));
  376. }
  377. offset += sizeof(float);
  378. break;
  379. }
  380. case SkSL::Layout::CType::kSkPMColor:
  381. case SkSL::Layout::CType::kSkPMColor4f:
  382. case SkSL::Layout::CType::kSkRect:
  383. if (v->fModifiers.fLayout.fKey) {
  384. for (size_t i = 0; i < sizeof(float) * 4; ++i) {
  385. fKey += inputs[offset + i];
  386. }
  387. b->add32(*(int32_t*) (inputs + offset));
  388. offset += sizeof(float);
  389. b->add32(*(int32_t*) (inputs + offset));
  390. offset += sizeof(float);
  391. b->add32(*(int32_t*) (inputs + offset));
  392. offset += sizeof(float);
  393. b->add32(*(int32_t*) (inputs + offset));
  394. offset += sizeof(float);
  395. } else {
  396. offset += sizeof(float) * 4;
  397. }
  398. break;
  399. default:
  400. // unsupported input var type
  401. printf("%s\n", SkSL::String(v->fType.fName).c_str());
  402. SkASSERT(false);
  403. }
  404. }
  405. }
  406. bool GrSkSLFP::onIsEqual(const GrFragmentProcessor& other) const {
  407. const GrSkSLFP& sk = other.cast<GrSkSLFP>();
  408. SkASSERT(fIndex != sk.fIndex || fInputSize == sk.fInputSize);
  409. return fIndex == sk.fIndex &&
  410. !memcmp(fInputs.get(), sk.fInputs.get(), fInputSize);
  411. }
  412. std::unique_ptr<GrFragmentProcessor> GrSkSLFP::clone() const {
  413. std::unique_ptr<GrSkSLFP> result(new GrSkSLFP(*this));
  414. for (int i = 0; i < this->numChildProcessors(); ++i) {
  415. result->registerChildProcessor(this->childProcessor(i).clone());
  416. }
  417. return std::unique_ptr<GrFragmentProcessor>(result.release());
  418. }
  419. // We have to do a bit of manual refcounting in the cache methods below. Ideally, we could just
  420. // define fFactories to contain sk_sp<GrSkSLFPFactory> rather than GrSkSLFPFactory*, but that would
  421. // require GrContext to include GrSkSLFP, which creates much bigger headaches than a few manual
  422. // refcounts.
  423. sk_sp<GrSkSLFPFactory> GrSkSLFPFactoryCache::get(int index) {
  424. if (index >= (int) fFactories.size()) {
  425. return nullptr;
  426. }
  427. GrSkSLFPFactory* result = fFactories[index];
  428. SkSafeRef(result);
  429. return sk_sp<GrSkSLFPFactory>(result);
  430. }
  431. void GrSkSLFPFactoryCache::set(int index, sk_sp<GrSkSLFPFactory> factory) {
  432. while (index >= (int) fFactories.size()) {
  433. fFactories.emplace_back();
  434. }
  435. factory->ref();
  436. SkASSERT(!fFactories[index]);
  437. fFactories[index] = factory.get();
  438. }
  439. GrSkSLFPFactoryCache::~GrSkSLFPFactoryCache() {
  440. for (GrSkSLFPFactory* factory : fFactories) {
  441. if (factory) {
  442. factory->unref();
  443. }
  444. }
  445. }
  446. GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSkSLFP);
  447. #if GR_TEST_UTILS
  448. #include "include/effects/SkArithmeticImageFilter.h"
  449. #include "include/gpu/GrContext.h"
  450. #include "src/gpu/effects/generated/GrConstColorProcessor.h"
  451. extern const char* SKSL_ARITHMETIC_SRC;
  452. extern const char* SKSL_DITHER_SRC;
  453. extern const char* SKSL_OVERDRAW_SRC;
  454. using Value = SkSL::Program::Settings::Value;
  455. std::unique_ptr<GrFragmentProcessor> GrSkSLFP::TestCreate(GrProcessorTestData* d) {
  456. int type = d->fRandom->nextULessThan(3);
  457. switch (type) {
  458. case 0: {
  459. static int ditherIndex = NewIndex();
  460. int rangeType = d->fRandom->nextULessThan(3);
  461. std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), ditherIndex, "Dither",
  462. SKSL_DITHER_SRC, &rangeType,
  463. sizeof(rangeType));
  464. return std::unique_ptr<GrFragmentProcessor>(result.release());
  465. }
  466. case 1: {
  467. static int arithmeticIndex = NewIndex();
  468. ArithmeticFPInputs inputs;
  469. inputs.k[0] = d->fRandom->nextF();
  470. inputs.k[1] = d->fRandom->nextF();
  471. inputs.k[2] = d->fRandom->nextF();
  472. inputs.k[3] = d->fRandom->nextF();
  473. inputs.enforcePMColor = d->fRandom->nextBool();
  474. std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), arithmeticIndex,
  475. "Arithmetic", SKSL_ARITHMETIC_SRC,
  476. &inputs, sizeof(inputs));
  477. result->addChild(GrConstColorProcessor::Make(
  478. SK_PMColor4fWHITE,
  479. GrConstColorProcessor::InputMode::kIgnore));
  480. return std::unique_ptr<GrFragmentProcessor>(result.release());
  481. }
  482. case 2: {
  483. static int overdrawIndex = NewIndex();
  484. SkPMColor inputs[6];
  485. for (int i = 0; i < 6; ++i) {
  486. inputs[i] = d->fRandom->nextU();
  487. }
  488. std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), overdrawIndex,
  489. "Overdraw", SKSL_OVERDRAW_SRC,
  490. &inputs, sizeof(inputs));
  491. return std::unique_ptr<GrFragmentProcessor>(result.release());
  492. }
  493. }
  494. SK_ABORT("unreachable");
  495. return nullptr;
  496. }
  497. #endif