From 2955c26908936fb8c2708176f1555a9e7a6dab0f Mon Sep 17 00:00:00 2001 From: John Stiles Date: Fri, 23 Jul 2021 15:51:05 -0400 Subject: [PATCH] Add new SampleBlender callback to SkVMCodeGenerator. This CL doesn't actually allow the callbacks to be invoked from SkSL yet, but the callbacks now exist and are now threaded through the various callsites which will need them. Change-Id: I00f43ff94de9da8d93daf2e59885eea6f87c2e3e Bug: skia:12257 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/431696 Commit-Queue: John Stiles Auto-Submit: John Stiles Reviewed-by: Brian Osman --- fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp | 4 ++++ src/core/SkRuntimeEffect.cpp | 22 ++++++++++++++---- src/gpu/effects/GrSkSLFP.cpp | 5 ++++ src/sksl/SkSLMain.cpp | 5 ++++ .../codegen/SkSLPipelineStageCodeGenerator.h | 1 + src/sksl/codegen/SkSLVMCodeGenerator.cpp | 23 ++++++++++++------- src/sksl/codegen/SkSLVMCodeGenerator.h | 4 +++- 7 files changed, 51 insertions(+), 13 deletions(-) diff --git a/fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp b/fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp index 40398a272a..7e3d987b53 100644 --- a/fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp +++ b/fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp @@ -49,6 +49,10 @@ bool FuzzSKSL2Pipeline(sk_sp bytes) { result += ")"; return result; } + + String sampleBlender(int index, String src, String dst) override { + return "sample(" + SkSL::to_string(index) + ", " + src + ", " + dst + ")"; + } }; Callbacks callbacks; diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp index 77448afc37..22d300b5dd 100644 --- a/src/core/SkRuntimeEffect.cpp +++ b/src/core/SkRuntimeEffect.cpp @@ -624,7 +624,8 @@ std::unique_ptr SkFilterColorProgram::Make(const SkRuntime inputColor, inputColor, /*sampleShader=*/nullptr, - sampleColorFilter); + sampleColorFilter, + /*sampleBlender=*/nullptr); // Then store the result to the *third* arg ptr p.store({skvm::PixelFormat::FLOAT, 32, 32, 32, 32, 0, 32, 64, 96}, p.arg(16), result); @@ -823,6 +824,10 @@ public: } return color; }; + auto sampleBlender = [&](int ix, skvm::Color src, skvm::Color dst) { + // TODO(skia:12257): implement sample(blender, src, dst) + return src; + }; std::vector uniform = make_skvm_uniforms(p, uniforms, fEffect->uniformSize(), *inputs); @@ -832,7 +837,7 @@ public: skvm::Coord zeroCoord = { p->splat(0.0f), p->splat(0.0f) }; return SkSL::ProgramToSkVM(*fEffect->fBaseProgram, fEffect->fMain, p, SkMakeSpan(uniform), /*device=*/zeroCoord, /*local=*/zeroCoord, c, c, sampleShader, - sampleColorFilter); + sampleColorFilter, sampleBlender); } SkPMColor4f onFilterColor4f(const SkPMColor4f& color, SkColorSpace* dstCS) const override { @@ -1011,12 +1016,17 @@ public: } return color; }; + auto sampleBlender = [&](int ix, skvm::Color src, skvm::Color dst) { + // TODO(skia:12257): implement sample(blender, src, dst) + return src; + }; std::vector uniform = make_skvm_uniforms(p, uniforms, fEffect->uniformSize(), *inputs); return SkSL::ProgramToSkVM(*fEffect->fBaseProgram, fEffect->fMain, p, SkMakeSpan(uniform), - device, local, paint, paint, sampleShader, sampleColorFilter); + device, local, paint, paint, sampleShader, sampleColorFilter, + sampleBlender); } void flatten(SkWriteBuffer& buffer) const override { @@ -1131,6 +1141,10 @@ public: } return color; }; + auto sampleBlender = [&](int ix, skvm::Color src, skvm::Color dst) { + // TODO(skia:12257): implement sample(blender, src, dst) + return src; + }; std::vector uniform = make_skvm_uniforms(p, uniforms, fEffect->uniformSize(), *inputs); @@ -1139,7 +1153,7 @@ public: skvm::Coord zeroCoord = {p->splat(0.0f), p->splat(0.0f)}; return SkSL::ProgramToSkVM(*fEffect->fBaseProgram, fEffect->fMain, p, SkMakeSpan(uniform), /*device=*/zeroCoord, /*local=*/zeroCoord, src, dst, - sampleShader, sampleColorFilter); + sampleShader, sampleColorFilter, sampleBlender); } #if SK_SUPPORT_GPU diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp index 244cdba1b9..30e14b9b29 100644 --- a/src/gpu/effects/GrSkSLFP.cpp +++ b/src/gpu/effects/GrSkSLFP.cpp @@ -153,6 +153,11 @@ public: .c_str()); } + String sampleBlender(int index, String src, String dst) override { + // TODO(skia:12257): invokeChild does not yet allow sampling from a blender + return "half4(1)"; + } + GrGLSLSkSLFP* fSelf; EmitArgs& fArgs; const char* fInputColor; diff --git a/src/sksl/SkSLMain.cpp b/src/sksl/SkSLMain.cpp index 199bf815b2..edb0f76475 100644 --- a/src/sksl/SkSLMain.cpp +++ b/src/sksl/SkSLMain.cpp @@ -434,6 +434,11 @@ ResultCode processCommand(std::vector& args) { return result; } + String sampleBlender(int index, String src, String dst) override { + return "sample(child_" + SkSL::to_string(index) + ", " + src + ", " + + dst + ")"; + } + String fOutput; }; // The .stage output looks almost like valid SkSL, but not quite. diff --git a/src/sksl/codegen/SkSLPipelineStageCodeGenerator.h b/src/sksl/codegen/SkSLPipelineStageCodeGenerator.h index bd87a3421d..83946509cd 100644 --- a/src/sksl/codegen/SkSLPipelineStageCodeGenerator.h +++ b/src/sksl/codegen/SkSLPipelineStageCodeGenerator.h @@ -30,6 +30,7 @@ namespace PipelineStage { virtual String declareUniform(const VarDeclaration*) = 0; virtual String sampleShader(int index, String coords) = 0; virtual String sampleColorFilter(int index, String color) = 0; + virtual String sampleBlender(int index, String src, String dst) = 0; }; /* diff --git a/src/sksl/codegen/SkSLVMCodeGenerator.cpp b/src/sksl/codegen/SkSLVMCodeGenerator.cpp index 5cb849bcd3..ae5d2aea77 100644 --- a/src/sksl/codegen/SkSLVMCodeGenerator.cpp +++ b/src/sksl/codegen/SkSLVMCodeGenerator.cpp @@ -117,7 +117,8 @@ public: skvm::Coord device, skvm::Coord local, SampleShaderFn sampleShader, - SampleColorFilterFn sampleColorFilter); + SampleColorFilterFn sampleColorFilter, + SampleBlenderFn sampleBlender); void writeFunction(const FunctionDefinition& function, SkSpan arguments, @@ -220,6 +221,7 @@ private: const skvm::Coord fLocalCoord; const SampleShaderFn fSampleShader; const SampleColorFilterFn fSampleColorFilter; + const SampleBlenderFn fSampleBlender; // [Variable, first slot in fSlots] std::unordered_map fVariableMap; @@ -277,12 +279,14 @@ SkVMGenerator::SkVMGenerator(const Program& program, skvm::Coord device, skvm::Coord local, SampleShaderFn sampleShader, - SampleColorFilterFn sampleColorFilter) + SampleColorFilterFn sampleColorFilter, + SampleBlenderFn sampleBlender) : fProgram(program) , fBuilder(builder) , fLocalCoord(local) , fSampleShader(std::move(sampleShader)) - , fSampleColorFilter(std::move(sampleColorFilter)) { + , fSampleColorFilter(std::move(sampleColorFilter)) + , fSampleBlender(std::move(sampleBlender)) { fConditionMask = fLoopMask = fBuilder->splat(0xffff'ffff); // Now, add storage for each global variable (including uniforms) to fSlots, and entries in @@ -297,7 +301,7 @@ SkVMGenerator::SkVMGenerator(const Program& program, SkASSERT(fVariableMap.find(&var) == fVariableMap.end()); // For most variables, fVariableMap stores an index into fSlots, but for children, - // fVariableMap stores the index to pass to fSample(Shader|ColorFilter) + // fVariableMap stores the index to pass to fSample(Shader|ColorFilter|Blender) if (var.type().isEffectChild()) { fVariableMap[&var] = fpCount++; continue; @@ -1548,7 +1552,8 @@ skvm::Color ProgramToSkVM(const Program& program, skvm::Color inputColor, skvm::Color destColor, SampleShaderFn sampleShader, - SampleColorFilterFn sampleColorFilter) { + SampleColorFilterFn sampleColorFilter, + SampleBlenderFn sampleBlender) { skvm::Val zero = builder->splat(0.0f).id; skvm::Val result[4] = {zero,zero,zero,zero}; @@ -1586,7 +1591,7 @@ skvm::Color ProgramToSkVM(const Program& program, SkASSERT(argSlots <= SK_ARRAY_COUNT(args)); SkVMGenerator generator(program, builder, uniforms, device, local, std::move(sampleShader), - std::move(sampleColorFilter)); + std::move(sampleColorFilter), std::move(sampleBlender)); generator.writeFunction(function, {args, argSlots}, SkMakeSpan(result)); return skvm::Color{{builder, result[0]}, @@ -1627,7 +1632,8 @@ bool ProgramToSkVM(const Program& program, skvm::F32 zero = b->splat(0.0f); skvm::Coord zeroCoord = {zero, zero}; SkVMGenerator generator(program, b, uniforms, /*device=*/zeroCoord, /*local=*/zeroCoord, - /*sampleShader=*/nullptr, /*sampleColorFilter=*/nullptr); + /*sampleShader=*/nullptr, /*sampleColorFilter=*/nullptr, + /*sampleBlender=*/nullptr); generator.writeFunction(function, SkMakeSpan(argVals), SkMakeSpan(returnVals)); // generateCode has updated the contents of 'argVals' for any 'out' or 'inout' parameters. @@ -1761,7 +1767,8 @@ bool testingOnly_ProgramToSkVMShader(const Program& program, skvm::Builder* buil skvm::Color result = SkSL::ProgramToSkVM(program, *main, builder, SkMakeSpan(uniformVals), device, local, inColor, destColor, sampleShader, - /*sampleColorFilter=*/nullptr); + /*sampleColorFilter=*/nullptr, + /*sampleBlender=*/nullptr); storeF(builder->varying(), result.r); storeF(builder->varying(), result.g); diff --git a/src/sksl/codegen/SkSLVMCodeGenerator.h b/src/sksl/codegen/SkSLVMCodeGenerator.h index 01ad9f78ca..743a5808e5 100644 --- a/src/sksl/codegen/SkSLVMCodeGenerator.h +++ b/src/sksl/codegen/SkSLVMCodeGenerator.h @@ -22,6 +22,7 @@ struct Program; using SampleShaderFn = std::function; using SampleColorFilterFn = std::function; +using SampleBlenderFn = std::function; // Convert 'function' to skvm instructions in 'builder', for use by blends, shaders, & color filters skvm::Color ProgramToSkVM(const Program& program, @@ -33,7 +34,8 @@ skvm::Color ProgramToSkVM(const Program& program, skvm::Color inputColor, skvm::Color destColor, SampleShaderFn sampleShader, - SampleColorFilterFn sampleColorFilter); + SampleColorFilterFn sampleColorFilter, + SampleBlenderFn sampleBlender); struct SkVMSignature { size_t fParameterSlots = 0;