Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 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 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 8 | #include "src/gpu/effects/GrSkSLFP.h" |
Robert Phillips | 1efecea | 2019-02-15 16:58:40 -0500 | [diff] [blame] | 9 | |
Brian Osman | ee426f2 | 2020-01-02 11:55:24 -0500 | [diff] [blame] | 10 | #include "include/effects/SkRuntimeEffect.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 11 | #include "include/private/GrContext_Base.h" |
Brian Osman | c18a645 | 2021-03-22 11:44:03 -0400 | [diff] [blame] | 12 | #include "src/core/SkVM.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 13 | #include "src/gpu/GrBaseContextPriv.h" |
Brian Salomon | f7f5433 | 2020-07-28 09:23:35 -0400 | [diff] [blame] | 14 | #include "src/gpu/GrColorInfo.h" |
Greg Daniel | 456f9b5 | 2020-03-05 19:14:18 +0000 | [diff] [blame] | 15 | #include "src/gpu/GrTexture.h" |
Brian Osman | 236ddb3 | 2021-02-05 12:15:29 -0500 | [diff] [blame] | 16 | #include "src/sksl/SkSLPipelineStageCodeGenerator.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 17 | #include "src/sksl/SkSLUtil.h" |
Brian Osman | 690b6f3 | 2021-02-05 16:30:34 -0500 | [diff] [blame] | 18 | #include "src/sksl/ir/SkSLVarDeclarations.h" |
Robert Phillips | 1efecea | 2019-02-15 16:58:40 -0500 | [diff] [blame] | 19 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 20 | #include "src/gpu/glsl/GrGLSLFragmentProcessor.h" |
| 21 | #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" |
| 22 | #include "src/gpu/glsl/GrGLSLProgramBuilder.h" |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 23 | |
Ethan Nicholas | eace935 | 2018-10-15 20:09:54 +0000 | [diff] [blame] | 24 | class GrGLSLSkSLFP : public GrGLSLFragmentProcessor { |
| 25 | public: |
Ethan Nicholas | eace935 | 2018-10-15 20:09:54 +0000 | [diff] [blame] | 26 | void emitCode(EmitArgs& args) override { |
Brian Osman | 690b6f3 | 2021-02-05 16:30:34 -0500 | [diff] [blame] | 27 | const GrSkSLFP& fp = args.fFp.cast<GrSkSLFP>(); |
| 28 | const SkSL::Program& program = *fp.fEffect->fBaseProgram; |
| 29 | |
Brian Osman | ac9d3f6 | 2020-06-25 11:07:30 -0400 | [diff] [blame] | 30 | // We need to ensure that we emit each child's helper function at least once. |
Brian Osman | 87e3bef | 2020-01-27 16:21:34 -0500 | [diff] [blame] | 31 | // Any child FP that isn't sampled won't trigger a call otherwise, leading to asserts later. |
Ethan Nicholas | eace935 | 2018-10-15 20:09:54 +0000 | [diff] [blame] | 32 | for (int i = 0; i < this->numChildProcessors(); ++i) { |
Brian Osman | a7685b2 | 2020-07-10 14:08:56 -0400 | [diff] [blame] | 33 | if (this->childProcessor(i)) { |
| 34 | this->emitChildFunction(i, args); |
| 35 | } |
Ethan Nicholas | eace935 | 2018-10-15 20:09:54 +0000 | [diff] [blame] | 36 | } |
Brian Osman | 690b6f3 | 2021-02-05 16:30:34 -0500 | [diff] [blame] | 37 | |
| 38 | class FPCallbacks : public SkSL::PipelineStage::Callbacks { |
| 39 | public: |
| 40 | FPCallbacks(GrGLSLSkSLFP* self, EmitArgs& args, const SkSL::Context& context) |
| 41 | : fSelf(self), fArgs(args), fContext(context) {} |
| 42 | |
| 43 | using String = SkSL::String; |
| 44 | |
| 45 | String declareUniform(const SkSL::VarDeclaration* decl) override { |
| 46 | const SkSL::Variable& var = decl->var(); |
| 47 | if (var.type().isOpaque()) { |
| 48 | // Nothing to do. The only opaque type we should see is fragmentProcessor, and |
| 49 | // those (children) are handled specially, above. |
Brian Osman | 3967588 | 2021-03-31 14:37:10 -0400 | [diff] [blame] | 50 | SkASSERT(var.type().isFragmentProcessor()); |
Brian Osman | 690b6f3 | 2021-02-05 16:30:34 -0500 | [diff] [blame] | 51 | return String(var.name()); |
| 52 | } |
| 53 | |
| 54 | const SkSL::Type* type = &var.type(); |
| 55 | bool isArray = false; |
| 56 | if (type->isArray()) { |
| 57 | type = &type->componentType(); |
| 58 | isArray = true; |
| 59 | } |
| 60 | |
| 61 | GrSLType gpuType; |
| 62 | SkAssertResult(SkSL::type_to_grsltype(fContext, *type, &gpuType)); |
| 63 | const char* uniformName = nullptr; |
| 64 | auto handle = |
| 65 | fArgs.fUniformHandler->addUniformArray(&fArgs.fFp.cast<GrSkSLFP>(), |
| 66 | kFragment_GrShaderFlag, |
| 67 | gpuType, |
| 68 | SkString(var.name()).c_str(), |
| 69 | isArray ? var.type().columns() : 0, |
| 70 | &uniformName); |
| 71 | fSelf->fUniformHandles.push_back(handle); |
| 72 | return String(uniformName); |
| 73 | } |
| 74 | |
Brian Osman | 55761ae | 2021-02-09 16:52:53 -0500 | [diff] [blame] | 75 | String getMangledName(const char* name) override { |
| 76 | return String(fArgs.fFragBuilder->getMangledFunctionName(name).c_str()); |
| 77 | } |
| 78 | |
| 79 | void defineFunction(const char* decl, const char* body, bool isMain) override { |
| 80 | if (isMain) { |
| 81 | fArgs.fFragBuilder->codeAppend(body); |
Brian Osman | 690b6f3 | 2021-02-05 16:30:34 -0500 | [diff] [blame] | 82 | } else { |
Brian Osman | 55761ae | 2021-02-09 16:52:53 -0500 | [diff] [blame] | 83 | fArgs.fFragBuilder->emitFunction(decl, body); |
Brian Osman | 690b6f3 | 2021-02-05 16:30:34 -0500 | [diff] [blame] | 84 | } |
| 85 | } |
| 86 | |
Brian Osman | 8e756f3 | 2021-02-10 10:19:27 -0500 | [diff] [blame] | 87 | void defineStruct(const char* definition) override { |
| 88 | fArgs.fFragBuilder->definitionAppend(definition); |
| 89 | } |
| 90 | |
Brian Osman | 5e603c3 | 2021-02-17 15:39:06 -0500 | [diff] [blame] | 91 | void declareGlobal(const char* declaration) override { |
| 92 | fArgs.fFragBuilder->definitionAppend(declaration); |
| 93 | } |
| 94 | |
Brian Osman | 690b6f3 | 2021-02-05 16:30:34 -0500 | [diff] [blame] | 95 | String sampleChild(int index, String coords) override { |
| 96 | return String(fSelf->invokeChild(index, fArgs, coords).c_str()); |
| 97 | } |
| 98 | |
| 99 | String sampleChildWithMatrix(int index, String matrix) override { |
| 100 | // If the child is sampled with a uniform matrix, we need to pass the empty string. |
| 101 | // 'invokeChildWithMatrix' will assert that the passed-in matrix matches the one |
| 102 | // extracted from the SkSL when the sample usages were determined. We've mangled |
| 103 | // the uniform names, though, so it won't match. |
| 104 | const GrFragmentProcessor* child = fArgs.fFp.childProcessor(index); |
| 105 | const bool hasUniformMatrix = child && child->sampleUsage().hasUniformMatrix(); |
| 106 | return String( |
| 107 | fSelf->invokeChildWithMatrix(index, fArgs, hasUniformMatrix ? "" : matrix) |
| 108 | .c_str()); |
| 109 | } |
| 110 | |
| 111 | GrGLSLSkSLFP* fSelf; |
| 112 | EmitArgs& fArgs; |
| 113 | const SkSL::Context& fContext; |
| 114 | }; |
| 115 | |
| 116 | FPCallbacks callbacks(this, args, *program.fContext); |
| 117 | |
| 118 | // Callback to define a function (and return its mangled name) |
| 119 | SkString coordsVarName = args.fFragBuilder->newTmpVarName("coords"); |
Brian Osman | b4ce944 | 2020-11-11 09:18:02 -0500 | [diff] [blame] | 120 | const char* coords = nullptr; |
| 121 | if (fp.referencesSampleCoords()) { |
| 122 | coords = coordsVarName.c_str(); |
Brian Osman | 690b6f3 | 2021-02-05 16:30:34 -0500 | [diff] [blame] | 123 | args.fFragBuilder->codeAppendf("float2 %s = %s;\n", coords, args.fSampleCoord); |
Brian Osman | b4ce944 | 2020-11-11 09:18:02 -0500 | [diff] [blame] | 124 | } |
Brian Osman | 690b6f3 | 2021-02-05 16:30:34 -0500 | [diff] [blame] | 125 | |
| 126 | SkSL::PipelineStage::ConvertProgram(program, coords, &callbacks); |
Ethan Nicholas | ce00811 | 2018-08-30 09:19:50 -0400 | [diff] [blame] | 127 | } |
| 128 | |
Ethan Nicholas | eace935 | 2018-10-15 20:09:54 +0000 | [diff] [blame] | 129 | void onSetData(const GrGLSLProgramDataManager& pdman, |
| 130 | const GrFragmentProcessor& _proc) override { |
Brian Osman | d18967c | 2021-04-01 09:56:07 -0400 | [diff] [blame^] | 131 | using Type = SkRuntimeEffect::Uniform::Type; |
Brian Osman | d927bd2 | 2019-12-18 11:23:12 -0500 | [diff] [blame] | 132 | size_t uniIndex = 0; |
Ethan Nicholas | eace935 | 2018-10-15 20:09:54 +0000 | [diff] [blame] | 133 | const GrSkSLFP& outer = _proc.cast<GrSkSLFP>(); |
Brian Osman | a4b9169 | 2020-08-10 14:26:16 -0400 | [diff] [blame] | 134 | const uint8_t* uniformData = outer.fUniforms->bytes(); |
| 135 | for (const auto& v : outer.fEffect->uniforms()) { |
Brian Osman | d18967c | 2021-04-01 09:56:07 -0400 | [diff] [blame^] | 136 | const UniformHandle handle = fUniformHandles[uniIndex++]; |
| 137 | auto floatData = [=] { return SkTAddOffset<const float>(uniformData, v.offset); }; |
| 138 | auto intData = [=] { return SkTAddOffset<const int>(uniformData, v.offset); }; |
Brian Osman | d76d186 | 2021-02-03 14:48:41 -0500 | [diff] [blame] | 139 | switch (v.type) { |
Brian Osman | d18967c | 2021-04-01 09:56:07 -0400 | [diff] [blame^] | 140 | case Type::kFloat: pdman.set1fv(handle, v.count, floatData()); break; |
| 141 | case Type::kFloat2: pdman.set2fv(handle, v.count, floatData()); break; |
| 142 | case Type::kFloat3: pdman.set3fv(handle, v.count, floatData()); break; |
| 143 | case Type::kFloat4: pdman.set4fv(handle, v.count, floatData()); break; |
| 144 | |
| 145 | case Type::kFloat2x2: pdman.setMatrix2fv(handle, v.count, floatData()); break; |
| 146 | case Type::kFloat3x3: pdman.setMatrix3fv(handle, v.count, floatData()); break; |
| 147 | case Type::kFloat4x4: pdman.setMatrix4fv(handle, v.count, floatData()); break; |
| 148 | |
| 149 | case Type::kInt: pdman.set1iv(handle, v.count, intData()); break; |
| 150 | case Type::kInt2: pdman.set2iv(handle, v.count, intData()); break; |
| 151 | case Type::kInt3: pdman.set3iv(handle, v.count, intData()); break; |
| 152 | case Type::kInt4: pdman.set4iv(handle, v.count, intData()); break; |
| 153 | |
Ethan Nicholas | c1c686b | 2019-04-02 17:30:23 -0400 | [diff] [blame] | 154 | default: |
Brian Osman | d927bd2 | 2019-12-18 11:23:12 -0500 | [diff] [blame] | 155 | SkDEBUGFAIL("Unsupported uniform type"); |
| 156 | break; |
Ethan Nicholas | 222e275 | 2018-10-11 11:21:34 -0400 | [diff] [blame] | 157 | } |
Ethan Nicholas | 222e275 | 2018-10-11 11:21:34 -0400 | [diff] [blame] | 158 | } |
| 159 | } |
Ethan Nicholas | eace935 | 2018-10-15 20:09:54 +0000 | [diff] [blame] | 160 | |
Ethan Nicholas | eace935 | 2018-10-15 20:09:54 +0000 | [diff] [blame] | 161 | std::vector<UniformHandle> fUniformHandles; |
| 162 | }; |
| 163 | |
Brian Osman | 7b1678a | 2019-12-16 09:17:25 -0500 | [diff] [blame] | 164 | std::unique_ptr<GrSkSLFP> GrSkSLFP::Make(GrContext_Base* context, sk_sp<SkRuntimeEffect> effect, |
Brian Osman | a4b9169 | 2020-08-10 14:26:16 -0400 | [diff] [blame] | 165 | const char* name, sk_sp<SkData> uniforms) { |
| 166 | if (uniforms->size() != effect->uniformSize()) { |
Brian Osman | 9bfd595 | 2020-02-05 10:51:44 -0500 | [diff] [blame] | 167 | return nullptr; |
| 168 | } |
Brian Osman | d7e7659 | 2020-11-02 12:26:22 -0500 | [diff] [blame] | 169 | return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().getShaderErrorHandler(), |
| 170 | std::move(effect), name, std::move(uniforms))); |
Ethan Nicholas | a70693b | 2019-03-04 13:07:36 -0500 | [diff] [blame] | 171 | } |
| 172 | |
Brian Osman | c18a645 | 2021-03-22 11:44:03 -0400 | [diff] [blame] | 173 | GrSkSLFP::GrSkSLFP(ShaderErrorHandler* shaderErrorHandler, |
| 174 | sk_sp<SkRuntimeEffect> effect, |
| 175 | const char* name, |
| 176 | sk_sp<SkData> uniforms) |
| 177 | : INHERITED(kGrSkSLFP_ClassID, |
| 178 | effect->fAllowColorFilter ? kConstantOutputForConstantInput_OptimizationFlag |
| 179 | : kNone_OptimizationFlags) |
Brian Osman | bd4f872 | 2020-03-06 15:23:54 -0500 | [diff] [blame] | 180 | , fShaderErrorHandler(shaderErrorHandler) |
Brian Osman | 7b1678a | 2019-12-16 09:17:25 -0500 | [diff] [blame] | 181 | , fEffect(std::move(effect)) |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 182 | , fName(name) |
Brian Osman | a4b9169 | 2020-08-10 14:26:16 -0400 | [diff] [blame] | 183 | , fUniforms(std::move(uniforms)) { |
Michael Ludwig | e88320b | 2020-06-24 09:04:56 -0400 | [diff] [blame] | 184 | if (fEffect->usesSampleCoords()) { |
| 185 | this->setUsesSampleCoordsDirectly(); |
| 186 | } |
Ethan Nicholas | eace935 | 2018-10-15 20:09:54 +0000 | [diff] [blame] | 187 | } |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 188 | |
| 189 | GrSkSLFP::GrSkSLFP(const GrSkSLFP& other) |
Brian Osman | c18a645 | 2021-03-22 11:44:03 -0400 | [diff] [blame] | 190 | : INHERITED(kGrSkSLFP_ClassID, other.optimizationFlags()) |
Brian Osman | bd4f872 | 2020-03-06 15:23:54 -0500 | [diff] [blame] | 191 | , fShaderErrorHandler(other.fShaderErrorHandler) |
Brian Osman | 7b1678a | 2019-12-16 09:17:25 -0500 | [diff] [blame] | 192 | , fEffect(other.fEffect) |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 193 | , fName(other.fName) |
Brian Osman | a4b9169 | 2020-08-10 14:26:16 -0400 | [diff] [blame] | 194 | , fUniforms(other.fUniforms) { |
Michael Ludwig | e88320b | 2020-06-24 09:04:56 -0400 | [diff] [blame] | 195 | if (fEffect->usesSampleCoords()) { |
| 196 | this->setUsesSampleCoordsDirectly(); |
| 197 | } |
Brian Osman | a7685b2 | 2020-07-10 14:08:56 -0400 | [diff] [blame] | 198 | |
| 199 | this->cloneAndRegisterAllChildProcessors(other); |
Ethan Nicholas | eace935 | 2018-10-15 20:09:54 +0000 | [diff] [blame] | 200 | } |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 201 | |
| 202 | const char* GrSkSLFP::name() const { |
| 203 | return fName; |
| 204 | } |
| 205 | |
Ethan Nicholas | ce00811 | 2018-08-30 09:19:50 -0400 | [diff] [blame] | 206 | void GrSkSLFP::addChild(std::unique_ptr<GrFragmentProcessor> child) { |
Brian Osman | be1b837 | 2020-06-18 13:40:26 -0400 | [diff] [blame] | 207 | int childIndex = this->numChildProcessors(); |
Brian Osman | 1298bc4 | 2020-06-30 13:39:35 -0400 | [diff] [blame] | 208 | SkASSERT((size_t)childIndex < fEffect->fSampleUsages.size()); |
Brian Osman | c18a645 | 2021-03-22 11:44:03 -0400 | [diff] [blame] | 209 | this->mergeOptimizationFlags(ProcessorOptimizationFlags(child.get())); |
Brian Osman | 1298bc4 | 2020-06-30 13:39:35 -0400 | [diff] [blame] | 210 | this->registerChild(std::move(child), fEffect->fSampleUsages[childIndex]); |
Ethan Nicholas | ce00811 | 2018-08-30 09:19:50 -0400 | [diff] [blame] | 211 | } |
| 212 | |
Brian Salomon | 18ab203 | 2021-02-23 10:07:05 -0500 | [diff] [blame] | 213 | std::unique_ptr<GrGLSLFragmentProcessor> GrSkSLFP::onMakeProgramImpl() const { |
| 214 | return std::make_unique<GrGLSLSkSLFP>(); |
Greg Daniel | f410794 | 2019-12-12 01:02:48 +0000 | [diff] [blame] | 215 | } |
| 216 | |
Brian Osman | d927bd2 | 2019-12-18 11:23:12 -0500 | [diff] [blame] | 217 | void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const { |
Brian Osman | a4b9169 | 2020-08-10 14:26:16 -0400 | [diff] [blame] | 218 | // In the unlikely event of a hash collision, we also include the uniform size in the key. |
Brian Osman | 3225306 | 2020-02-05 11:37:08 -0500 | [diff] [blame] | 219 | // That ensures that we will (at worst) use the wrong program, but one that expects the same |
Brian Osman | a4b9169 | 2020-08-10 14:26:16 -0400 | [diff] [blame] | 220 | // amount of uniform data. |
Brian Osman | 3225306 | 2020-02-05 11:37:08 -0500 | [diff] [blame] | 221 | b->add32(fEffect->hash()); |
Brian Osman | a4b9169 | 2020-08-10 14:26:16 -0400 | [diff] [blame] | 222 | b->add32(SkToU32(fUniforms->size())); |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 223 | } |
| 224 | |
| 225 | bool GrSkSLFP::onIsEqual(const GrFragmentProcessor& other) const { |
| 226 | const GrSkSLFP& sk = other.cast<GrSkSLFP>(); |
Brian Osman | a4b9169 | 2020-08-10 14:26:16 -0400 | [diff] [blame] | 227 | return fEffect->hash() == sk.fEffect->hash() && fUniforms->equals(sk.fUniforms.get()); |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 228 | } |
| 229 | |
| 230 | std::unique_ptr<GrFragmentProcessor> GrSkSLFP::clone() const { |
Brian Osman | a7685b2 | 2020-07-10 14:08:56 -0400 | [diff] [blame] | 231 | return std::unique_ptr<GrFragmentProcessor>(new GrSkSLFP(*this)); |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 232 | } |
| 233 | |
Brian Osman | c18a645 | 2021-03-22 11:44:03 -0400 | [diff] [blame] | 234 | SkPMColor4f GrSkSLFP::constantOutputForConstantInput(const SkPMColor4f& inputColor) const { |
| 235 | const skvm::Program* program = fEffect->getFilterColorProgram(); |
| 236 | SkASSERT(program); |
| 237 | |
| 238 | SkSTArray<2, SkPMColor4f, true> childColors; |
| 239 | for (int i = 0; i < this->numChildProcessors(); ++i) { |
| 240 | childColors.push_back(ConstantOutputForConstantInput(this->childProcessor(i), inputColor)); |
| 241 | } |
| 242 | |
| 243 | SkPMColor4f result; |
| 244 | program->eval(1, childColors.begin(), fUniforms->data(), result.vec()); |
| 245 | return result; |
| 246 | } |
| 247 | |
Robert Phillips | 7f11fb5 | 2019-12-03 13:35:19 -0500 | [diff] [blame] | 248 | /**************************************************************************************************/ |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 249 | |
| 250 | GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSkSLFP); |
| 251 | |
| 252 | #if GR_TEST_UTILS |
| 253 | |
Mike Klein | a73819b | 2020-04-17 08:26:30 -0500 | [diff] [blame] | 254 | #include "include/effects/SkOverdrawColorFilter.h" |
Mike Reed | b11e627 | 2020-06-24 16:56:33 -0400 | [diff] [blame] | 255 | #include "src/core/SkColorFilterBase.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 256 | #include "src/gpu/effects/generated/GrConstColorProcessor.h" |
Ethan Nicholas | 78aceb2 | 2018-08-31 16:13:58 -0400 | [diff] [blame] | 257 | |
Ethan Nicholas | 78aceb2 | 2018-08-31 16:13:58 -0400 | [diff] [blame] | 258 | extern const char* SKSL_OVERDRAW_SRC; |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 259 | |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 260 | std::unique_ptr<GrFragmentProcessor> GrSkSLFP::TestCreate(GrProcessorTestData* d) { |
John Stiles | a9c9b53 | 2020-07-09 17:13:13 -0400 | [diff] [blame] | 261 | SkColor colors[SkOverdrawColorFilter::kNumColors]; |
| 262 | for (SkColor& c : colors) { |
| 263 | c = d->fRandom->nextU(); |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 264 | } |
John Stiles | a9c9b53 | 2020-07-09 17:13:13 -0400 | [diff] [blame] | 265 | auto filter = SkOverdrawColorFilter::MakeWithSkColors(colors); |
| 266 | auto [success, fp] = as_CFB(filter)->asFragmentProcessor(/*inputFP=*/nullptr, d->context(), |
| 267 | GrColorInfo{}); |
| 268 | SkASSERT(success); |
| 269 | return std::move(fp); |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 270 | } |
| 271 | |
| 272 | #endif |
Brian Salomon | 5ca24f9 | 2021-03-23 17:04:41 -0400 | [diff] [blame] | 273 | |
| 274 | /**************************************************************************************************/ |
| 275 | |
| 276 | GrRuntimeFPBuilder::GrRuntimeFPBuilder(sk_sp<SkRuntimeEffect> effect) |
| 277 | : INHERITED(std::move(effect)) {} |
| 278 | |
| 279 | GrRuntimeFPBuilder::~GrRuntimeFPBuilder() = default; |
| 280 | |
| 281 | std::unique_ptr<GrFragmentProcessor> GrRuntimeFPBuilder::makeFP( |
| 282 | GrRecordingContext* recordingContext) { |
| 283 | return this->effect()->makeFP(recordingContext, |
| 284 | this->uniforms(), |
| 285 | this->children(), |
| 286 | this->numChildren()); |
| 287 | } |