Allow sampling from SkBlenders.
Runtime shaders, color filters, and blenders are all able to sample from
a blender. These use the blend-function signature; both a src-color and
dst-color must be passed to sample. i.e.: sample(blender, s, d)
Change-Id: I3738e6b0b4af6d1d79e62ca1815c80d6a1ae9d6f
Bug: skia:12257
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/432056
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/codegen/SkSLVMCodeGenerator.cpp b/src/sksl/codegen/SkSLVMCodeGenerator.cpp
index f36dfea..0e8f16c 100644
--- a/src/sksl/codegen/SkSLVMCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLVMCodeGenerator.cpp
@@ -873,7 +873,7 @@
if (intrinsicKind == k_sample_IntrinsicKind) {
// Sample is very special. The first argument is a child (shader/colorFilter/blender),
// which is opaque and can't be evaluated.
- SkASSERT(nargs == 2);
+ SkASSERT(nargs >= 2);
const Expression* child = c.arguments()[0].get();
SkASSERT(child->type().isEffectChild());
SkASSERT(child->is<VariableReference>());
@@ -887,16 +887,43 @@
Value argVal = this->writeExpression(*arg);
skvm::Color color;
- if (child->type().typeKind() == Type::TypeKind::kShader) {
- SkASSERT(arg->type() == *fProgram.fContext->fTypes.fFloat2);
- skvm::Coord coord = {f32(argVal[0]), f32(argVal[1])};
- color = fSampleShader(fp_it->second, coord);
- } else {
- SkASSERT(child->type().typeKind() == Type::TypeKind::kColorFilter);
- SkASSERT(arg->type() == *fProgram.fContext->fTypes.fHalf4 ||
- arg->type() == *fProgram.fContext->fTypes.fFloat4);
- skvm::Color inColor = {f32(argVal[0]), f32(argVal[1]), f32(argVal[2]), f32(argVal[3])};
- color = fSampleColorFilter(fp_it->second, inColor);
+ switch (child->type().typeKind()) {
+ case Type::TypeKind::kShader: {
+ SkASSERT(nargs == 2);
+ SkASSERT(arg->type() == *fProgram.fContext->fTypes.fFloat2);
+ skvm::Coord coord = {f32(argVal[0]), f32(argVal[1])};
+ color = fSampleShader(fp_it->second, coord);
+ break;
+ }
+ case Type::TypeKind::kColorFilter: {
+ SkASSERT(nargs == 2);
+ SkASSERT(arg->type() == *fProgram.fContext->fTypes.fHalf4 ||
+ arg->type() == *fProgram.fContext->fTypes.fFloat4);
+ skvm::Color inColor = {f32(argVal[0]), f32(argVal[1]),
+ f32(argVal[2]), f32(argVal[3])};
+ color = fSampleColorFilter(fp_it->second, inColor);
+ break;
+ }
+ case Type::TypeKind::kBlender: {
+ SkASSERT(nargs == 3);
+ SkASSERT(arg->type() == *fProgram.fContext->fTypes.fHalf4 ||
+ arg->type() == *fProgram.fContext->fTypes.fFloat4);
+ skvm::Color srcColor = {f32(argVal[0]), f32(argVal[1]),
+ f32(argVal[2]), f32(argVal[3])};
+
+ arg = c.arguments()[2].get();
+ argVal = this->writeExpression(*arg);
+ SkASSERT(arg->type() == *fProgram.fContext->fTypes.fHalf4 ||
+ arg->type() == *fProgram.fContext->fTypes.fFloat4);
+ skvm::Color dstColor = {f32(argVal[0]), f32(argVal[1]),
+ f32(argVal[2]), f32(argVal[3])};
+
+ color = fSampleBlender(fp_it->second, srcColor, dstColor);
+ break;
+ }
+ default: {
+ SkDEBUGFAILF("cannot sample from type '%s'", child->type().description().c_str());
+ }
}
Value result(4);