added support for SkSL unpremul function
Change-Id: I970f1ad0dd0859448c874498fe02342f8abc3aa3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/242897
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index 641e4c0..916fa9c 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -32,6 +32,7 @@
fIntrinsicMap[String("lessThanEqual")] = METAL(LessThanEqual);
fIntrinsicMap[String("greaterThan")] = METAL(GreaterThan);
fIntrinsicMap[String("greaterThanEqual")] = METAL(GreaterThanEqual);
+ fIntrinsicMap[String("unpremul")] = SPECIAL(Unpremul);
}
void MetalCodeGenerator::write(const char* s) {
@@ -69,50 +70,51 @@
this->writeLine("#extension " + ext.fName + " : enable");
}
-void MetalCodeGenerator::writeType(const Type& type) {
+String MetalCodeGenerator::getTypeName(const Type& type) {
switch (type.kind()) {
case Type::kStruct_Kind:
- for (const Type* search : fWrittenStructs) {
- if (*search == type) {
- // already written
- this->write(type.name());
- return;
- }
- }
- fWrittenStructs.push_back(&type);
- this->writeLine("struct " + type.name() + " {");
- fIndentation++;
- this->writeFields(type.fields(), type.fOffset);
- fIndentation--;
- this->write("}");
- break;
+ return type.name();
case Type::kVector_Kind:
- this->writeType(type.componentType());
- this->write(to_string(type.columns()));
- break;
+ return this->getTypeName(type.componentType()) + to_string(type.columns());
case Type::kMatrix_Kind:
- this->writeType(type.componentType());
- this->write(to_string(type.columns()));
- this->write("x");
- this->write(to_string(type.rows()));
- break;
+ return this->getTypeName(type.componentType()) + to_string(type.columns()) + "x" +
+ to_string(type.rows());
case Type::kSampler_Kind:
- this->write("texture2d<float> "); // FIXME - support other texture types;
- break;
+ return "texture2d<float>"; // FIXME - support other texture types;
default:
if (type == *fContext.fHalf_Type) {
// FIXME - Currently only supporting floats in MSL to avoid type coercion issues.
- this->write(fContext.fFloat_Type->name());
+ return fContext.fFloat_Type->name();
} else if (type == *fContext.fByte_Type) {
- this->write("char");
+ return "char";
} else if (type == *fContext.fUByte_Type) {
- this->write("uchar");
+ return "uchar";
} else {
- this->write(type.name());
+ return type.name();
}
}
}
+void MetalCodeGenerator::writeType(const Type& type) {
+ if (type.kind() == Type::kStruct_Kind) {
+ for (const Type* search : fWrittenStructs) {
+ if (*search == type) {
+ // already written
+ this->write(this->getTypeName(type));
+ return;
+ }
+ }
+ fWrittenStructs.push_back(&type);
+ this->writeLine("struct " + type.name() + " {");
+ fIndentation++;
+ this->writeFields(type.fields(), type.fOffset);
+ fIndentation--;
+ this->write("}");
+ } else {
+ this->write(this->getTypeName(type));
+ }
+}
+
void MetalCodeGenerator::writeExpression(const Expression& expr, Precedence parentPrecedence) {
switch (expr.fKind) {
case Expression::kBinary_Kind:
@@ -369,6 +371,23 @@
this->writeExpression(*c.fArguments[1], kSequence_Precedence);
this->write(")))");
break;
+ case kUnpremul_SpecialIntrinsic: {
+ String tmpVar1 = "unpremul" + to_string(fVarCount++);
+ this->fFunctionHeader += String(" ") +
+ this->getTypeName(c.fArguments[0]->fType) + " " + tmpVar1 +
+ ";";
+ String tmpVar2 = "unpremulNonZeroAlpha" + to_string(fVarCount++);
+ this->fFunctionHeader += String(" ") +
+ this->getTypeName(c.fArguments[0]->fType.componentType()) +
+ " " + tmpVar2 + ";";
+ this->write("(" + tmpVar1 + " = ");
+ this->writeExpression(*c.fArguments[0], kSequence_Precedence);
+ this->write(", " + tmpVar2 + " = max(" + tmpVar1 + ".a, " +
+ to_string(SKSL_UNPREMUL_MIN) + "), " +
+ this->getTypeName(*fContext.fHalf4_Type) + "(" + tmpVar1 +
+ ".rgb / " + tmpVar2 + ", " + tmpVar2 + "))");
+ return;
+ }
default:
ABORT("unsupported special intrinsic kind");
}