Create SkSLOperators, centralize functionality
Change-Id: I3593e7ab0caac2fd572346038cbc8ff63e6fe970
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/366406
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index 37d8d20..cd67ac9 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -25,7 +25,7 @@
const char* MetalCodeGenerator::OperatorName(Token::Kind op) {
switch (op) {
case Token::Kind::TK_LOGICALXOR: return "!=";
- default: return Compiler::OperatorName(op);
+ default: return Operators::OperatorName(op);
}
}
@@ -271,7 +271,7 @@
if (param->modifiers().fFlags & Modifiers::kIn_Flag) {
this->write(" = ");
fIgnoreVariableReferenceModifiers = true;
- this->writeExpression(*arguments[index], kAssignment_Precedence);
+ this->writeExpression(*arguments[index], Precedence::kAssignment);
fIgnoreVariableReferenceModifiers = false;
}
@@ -305,7 +305,7 @@
}
// outParam.zyx = _var2;
fIgnoreVariableReferenceModifiers = true;
- this->writeExpression(*arguments[index], kAssignment_Precedence);
+ this->writeExpression(*arguments[index], Precedence::kAssignment);
fIgnoreVariableReferenceModifiers = false;
this->write(" = _var");
this->write(to_string(index));
@@ -381,9 +381,9 @@
separator = ", ";
if (outVars[i]) {
- this->writeExpression(*outVars[i], kSequence_Precedence);
+ this->writeExpression(*outVars[i], Precedence::kSequence);
} else {
- this->writeExpression(*arguments[i], kSequence_Precedence);
+ this->writeExpression(*arguments[i], Precedence::kSequence);
}
}
this->write(")");
@@ -513,7 +513,7 @@
for (const std::unique_ptr<Expression>& arg : arguments) {
this->write(separator);
separator = ", ";
- this->writeExpression(*arg, kSequence_Precedence);
+ this->writeExpression(*arg, Precedence::kSequence);
}
this->write(")");
}
@@ -522,9 +522,9 @@
const ExpressionArray& arguments = c.arguments();
switch (kind) {
case kTexture_IntrinsicKind: {
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write(".sample(");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write(SAMPLER_SUFFIX);
this->write(", ");
const Type& arg1Type = arguments[1]->type();
@@ -532,11 +532,11 @@
// have to store the vector in a temp variable to avoid double evaluating it
String tmpVar = this->getTempVariable(arg1Type);
this->write("(" + tmpVar + " = ");
- this->writeExpression(*arguments[1], kSequence_Precedence);
+ this->writeExpression(*arguments[1], Precedence::kSequence);
this->write(", " + tmpVar + ".xy / " + tmpVar + ".z))");
} else {
SkASSERT(arg1Type == *fContext.fTypes.fFloat2);
- this->writeExpression(*arguments[1], kSequence_Precedence);
+ this->writeExpression(*arguments[1], Precedence::kSequence);
this->write(")");
}
break;
@@ -546,9 +546,9 @@
String tmpX = this->getTempVariable(arguments[0]->type());
String tmpY = this->getTempVariable(arguments[1]->type());
this->write("(" + tmpX + " = ");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write(", " + tmpY + " = ");
- this->writeExpression(*arguments[1], kSequence_Precedence);
+ this->writeExpression(*arguments[1], Precedence::kSequence);
this->write(", " + tmpX + " - " + tmpY + " * floor(" + tmpX + " / " + tmpY + "))");
break;
}
@@ -556,9 +556,9 @@
case kDistance_IntrinsicKind: {
if (arguments[0]->type().columns() == 1) {
this->write("abs(");
- this->writeExpression(*arguments[0], kAdditive_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kAdditive);
this->write(" - ");
- this->writeExpression(*arguments[1], kAdditive_Precedence);
+ this->writeExpression(*arguments[1], Precedence::kAdditive);
this->write(")");
} else {
this->writeSimpleIntrinsic(c);
@@ -568,9 +568,9 @@
case kDot_IntrinsicKind: {
if (arguments[0]->type().columns() == 1) {
this->write("(");
- this->writeExpression(*arguments[0], kMultiplicative_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kMultiplicative);
this->write(" * ");
- this->writeExpression(*arguments[1], kMultiplicative_Precedence);
+ this->writeExpression(*arguments[1], Precedence::kMultiplicative);
this->write(")");
} else {
this->writeSimpleIntrinsic(c);
@@ -581,11 +581,11 @@
if (arguments[0]->type().columns() == 1) {
// ((((Nref) * (I) < 0) ? 1 : -1) * (N))
this->write("((((");
- this->writeExpression(*arguments[2], kSequence_Precedence);
+ this->writeExpression(*arguments[2], Precedence::kSequence);
this->write(") * (");
- this->writeExpression(*arguments[1], kSequence_Precedence);
+ this->writeExpression(*arguments[1], Precedence::kSequence);
this->write(") < 0) ? 1 : -1) * (");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write("))");
} else {
this->writeSimpleIntrinsic(c);
@@ -594,32 +594,32 @@
}
case kLength_IntrinsicKind: {
this->write(arguments[0]->type().columns() == 1 ? "abs(" : "length(");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write(")");
break;
}
case kNormalize_IntrinsicKind: {
this->write(arguments[0]->type().columns() == 1 ? "sign(" : "normalize(");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write(")");
break;
}
case kBitcast_IntrinsicKind: {
this->write(this->getBitcastIntrinsic(c.type()));
this->write("(");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write(")");
break;
}
case kDegrees_IntrinsicKind: {
this->write("((");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write(") * 57.2957795)");
break;
}
case kRadians_IntrinsicKind: {
this->write("((");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write(") * 0.0174532925)");
break;
}
@@ -660,11 +660,11 @@
// (_skTempI = ...
this->write("(" + tmpI + " = ");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
// , _skTempN = ...
this->write(", " + tmpN + " = ");
- this->writeExpression(*arguments[1], kSequence_Precedence);
+ this->writeExpression(*arguments[1], Precedence::kSequence);
// , _skTempI - 2 * _skTempN * _skTempI * _skTempN)
this->write(", " + tmpI + " - 2 * " + tmpN + " * " + tmpI + " * " + tmpN + ")");
@@ -678,11 +678,11 @@
// Metal does implement refract for vectors; rather than reimplementing refract from
// scratch, we can replace the call with `refract(float2(I,0), float2(N,0), eta).x`.
this->write("(refract(float2(");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write(", 0), float2(");
- this->writeExpression(*arguments[1], kSequence_Precedence);
+ this->writeExpression(*arguments[1], Precedence::kSequence);
this->write(", 0), ");
- this->writeExpression(*arguments[2], kSequence_Precedence);
+ this->writeExpression(*arguments[2], Precedence::kSequence);
this->write(").x)");
} else {
this->writeSimpleIntrinsic(c);
@@ -696,7 +696,7 @@
}
case kBitCount_IntrinsicKind: {
this->write("popcount(");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write(")");
break;
}
@@ -712,7 +712,7 @@
this->write("(");
this->write(skTemp);
this->write(" = (");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write("), select(ctz(");
this->write(skTemp);
this->write("), ");
@@ -737,7 +737,7 @@
this->write("(");
this->write(skTemp1);
this->write(" = (");
- this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->writeExpression(*arguments[0], Precedence::kSequence);
this->write("), ");
// Signed input types might be negative; we need another helper variable to negate the
@@ -784,7 +784,7 @@
case kCompareLessThanEqual_IntrinsicKind:
case kCompareNotEqual_IntrinsicKind: {
this->write("(");
- this->writeExpression(*c.arguments()[0], kRelational_Precedence);
+ this->writeExpression(*c.arguments()[0], Precedence::kRelational);
switch (kind) {
case kCompareEqual_IntrinsicKind:
this->write(" == ");
@@ -807,7 +807,7 @@
default:
SK_ABORT("unsupported comparison intrinsic kind");
}
- this->writeExpression(*c.arguments()[1], kRelational_Precedence);
+ this->writeExpression(*c.arguments()[1], Precedence::kRelational);
this->write(")");
break;
}
@@ -1055,7 +1055,7 @@
for (const std::unique_ptr<Expression>& expr : c.arguments()) {
this->write(separator);
separator = ", ";
- this->writeExpression(*expr, kSequence_Precedence);
+ this->writeExpression(*expr, Precedence::kSequence);
}
this->write(")");
return;
@@ -1080,7 +1080,7 @@
}
scalarCount += argType.columns();
}
- this->writeExpression(*arg, kSequence_Precedence);
+ this->writeExpression(*arg, Precedence::kSequence);
if (scalarCount && scalarCount == constructorType.rows()) {
this->write(")");
scalarCount = 0;
@@ -1145,16 +1145,16 @@
}
void MetalCodeGenerator::writeIndexExpression(const IndexExpression& expr) {
- this->writeExpression(*expr.base(), kPostfix_Precedence);
+ this->writeExpression(*expr.base(), Precedence::kPostfix);
this->write("[");
- this->writeExpression(*expr.index(), kTopLevel_Precedence);
+ this->writeExpression(*expr.index(), Precedence::kTopLevel);
this->write("]");
}
void MetalCodeGenerator::writeFieldAccess(const FieldAccess& f) {
const Type::Field* field = &f.base()->type().fields()[f.fieldIndex()];
if (FieldAccess::OwnerKind::kDefault == f.ownerKind()) {
- this->writeExpression(*f.base(), kPostfix_Precedence);
+ this->writeExpression(*f.base(), Precedence::kPostfix);
this->write(".");
}
switch (field->fModifiers.fLayout.fBuiltin) {
@@ -1176,7 +1176,7 @@
}
void MetalCodeGenerator::writeSwizzle(const Swizzle& swizzle) {
- this->writeExpression(*swizzle.base(), kPostfix_Precedence);
+ this->writeExpression(*swizzle.base(), Precedence::kPostfix);
this->write(".");
for (int c : swizzle.components()) {
SkASSERT(c >= 0 && c <= 3);
@@ -1184,43 +1184,6 @@
}
}
-MetalCodeGenerator::Precedence MetalCodeGenerator::GetBinaryPrecedence(Token::Kind op) {
- switch (op) {
- case Token::Kind::TK_STAR: // fall through
- case Token::Kind::TK_SLASH: // fall through
- case Token::Kind::TK_PERCENT: return MetalCodeGenerator::kMultiplicative_Precedence;
- case Token::Kind::TK_PLUS: // fall through
- case Token::Kind::TK_MINUS: return MetalCodeGenerator::kAdditive_Precedence;
- case Token::Kind::TK_SHL: // fall through
- case Token::Kind::TK_SHR: return MetalCodeGenerator::kShift_Precedence;
- case Token::Kind::TK_LT: // fall through
- case Token::Kind::TK_GT: // fall through
- case Token::Kind::TK_LTEQ: // fall through
- case Token::Kind::TK_GTEQ: return MetalCodeGenerator::kRelational_Precedence;
- case Token::Kind::TK_EQEQ: // fall through
- case Token::Kind::TK_NEQ: return MetalCodeGenerator::kEquality_Precedence;
- case Token::Kind::TK_BITWISEAND: return MetalCodeGenerator::kBitwiseAnd_Precedence;
- case Token::Kind::TK_BITWISEXOR: return MetalCodeGenerator::kBitwiseXor_Precedence;
- case Token::Kind::TK_BITWISEOR: return MetalCodeGenerator::kBitwiseOr_Precedence;
- case Token::Kind::TK_LOGICALAND: return MetalCodeGenerator::kLogicalAnd_Precedence;
- case Token::Kind::TK_LOGICALXOR: return MetalCodeGenerator::kLogicalXor_Precedence;
- case Token::Kind::TK_LOGICALOR: return MetalCodeGenerator::kLogicalOr_Precedence;
- case Token::Kind::TK_EQ: // fall through
- case Token::Kind::TK_PLUSEQ: // fall through
- case Token::Kind::TK_MINUSEQ: // fall through
- case Token::Kind::TK_STAREQ: // fall through
- case Token::Kind::TK_SLASHEQ: // fall through
- case Token::Kind::TK_PERCENTEQ: // fall through
- case Token::Kind::TK_SHLEQ: // fall through
- case Token::Kind::TK_SHREQ: // fall through
- case Token::Kind::TK_BITWISEANDEQ: // fall through
- case Token::Kind::TK_BITWISEXOREQ: // fall through
- case Token::Kind::TK_BITWISEOREQ: return MetalCodeGenerator::kAssignment_Precedence;
- case Token::Kind::TK_COMMA: return MetalCodeGenerator::kSequence_Precedence;
- default: SK_ABORT("unsupported binary operator");
- }
-}
-
void MetalCodeGenerator::writeMatrixTimesEqualHelper(const Type& left, const Type& right,
const Type& result) {
String key = "TimesEqual" + this->typeName(left) + this->typeName(right);
@@ -1243,7 +1206,7 @@
const Type& leftType = left.type();
const Type& rightType = right.type();
Token::Kind op = b.getOperator();
- Precedence precedence = GetBinaryPrecedence(b.getOperator());
+ Precedence precedence = Operators::GetBinaryPrecedence(b.getOperator());
bool needParens = precedence >= parentPrecedence;
switch (op) {
case Token::Kind::TK_EQEQ:
@@ -1268,7 +1231,7 @@
this->writeMatrixTimesEqualHelper(leftType, rightType, b.type());
}
this->writeExpression(left, precedence);
- if (op != Token::Kind::TK_EQ && Compiler::IsAssignment(op) &&
+ if (op != Token::Kind::TK_EQ && Operators::IsAssignment(op) &&
left.kind() == Expression::Kind::kSwizzle && !left.hasSideEffects()) {
// This doesn't compile in Metal:
// float4 x = float4(1);
@@ -1277,7 +1240,7 @@
// but switching it to x.xy = x.xy * float2x2(...) fixes it. We perform this tranformation
// as long as the LHS has no side effects, and hope for the best otherwise.
this->write(" = ");
- this->writeExpression(left, kAssignment_Precedence);
+ this->writeExpression(left, Precedence::kAssignment);
this->write(" ");
String opName = OperatorName(op);
SkASSERT(opName.endsWith("="));
@@ -1294,39 +1257,39 @@
void MetalCodeGenerator::writeTernaryExpression(const TernaryExpression& t,
Precedence parentPrecedence) {
- if (kTernary_Precedence >= parentPrecedence) {
+ if (Precedence::kTernary >= parentPrecedence) {
this->write("(");
}
- this->writeExpression(*t.test(), kTernary_Precedence);
+ this->writeExpression(*t.test(), Precedence::kTernary);
this->write(" ? ");
- this->writeExpression(*t.ifTrue(), kTernary_Precedence);
+ this->writeExpression(*t.ifTrue(), Precedence::kTernary);
this->write(" : ");
- this->writeExpression(*t.ifFalse(), kTernary_Precedence);
- if (kTernary_Precedence >= parentPrecedence) {
+ this->writeExpression(*t.ifFalse(), Precedence::kTernary);
+ if (Precedence::kTernary >= parentPrecedence) {
this->write(")");
}
}
void MetalCodeGenerator::writePrefixExpression(const PrefixExpression& p,
Precedence parentPrecedence) {
- if (kPrefix_Precedence >= parentPrecedence) {
+ if (Precedence::kPrefix >= parentPrecedence) {
this->write("(");
}
this->write(OperatorName(p.getOperator()));
- this->writeExpression(*p.operand(), kPrefix_Precedence);
- if (kPrefix_Precedence >= parentPrecedence) {
+ this->writeExpression(*p.operand(), Precedence::kPrefix);
+ if (Precedence::kPrefix >= parentPrecedence) {
this->write(")");
}
}
void MetalCodeGenerator::writePostfixExpression(const PostfixExpression& p,
Precedence parentPrecedence) {
- if (kPostfix_Precedence >= parentPrecedence) {
+ if (Precedence::kPostfix >= parentPrecedence) {
this->write("(");
}
- this->writeExpression(*p.operand(), kPostfix_Precedence);
+ this->writeExpression(*p.operand(), Precedence::kPostfix);
this->write(OperatorName(p.getOperator()));
- if (kPostfix_Precedence >= parentPrecedence) {
+ if (Precedence::kPostfix >= parentPrecedence) {
this->write(")");
}
}
@@ -1686,7 +1649,7 @@
}
void MetalCodeGenerator::writeVarInitializer(const Variable& var, const Expression& value) {
- this->writeExpression(value, kTopLevel_Precedence);
+ this->writeExpression(value, Precedence::kTopLevel);
}
void MetalCodeGenerator::writeName(const String& name) {
@@ -1717,7 +1680,7 @@
this->writeBlock(s.as<Block>());
break;
case Statement::Kind::kExpression:
- this->writeExpression(*s.as<ExpressionStatement>().expression(), kTopLevel_Precedence);
+ this->writeExpression(*s.as<ExpressionStatement>().expression(), Precedence::kTopLevel);
this->write(";");
break;
case Statement::Kind::kReturn:
@@ -1779,7 +1742,7 @@
void MetalCodeGenerator::writeIfStatement(const IfStatement& stmt) {
this->write("if (");
- this->writeExpression(*stmt.test(), kTopLevel_Precedence);
+ this->writeExpression(*stmt.test(), Precedence::kTopLevel);
this->write(") ");
this->writeStatement(*stmt.ifTrue());
if (stmt.ifFalse()) {
@@ -1792,7 +1755,7 @@
// Emit loops of the form 'for(;test;)' as 'while(test)', which is probably how they started
if (!f.initializer() && f.test() && !f.next()) {
this->write("while (");
- this->writeExpression(*f.test(), kTopLevel_Precedence);
+ this->writeExpression(*f.test(), Precedence::kTopLevel);
this->write(") ");
this->writeStatement(*f.statement());
return;
@@ -1805,11 +1768,11 @@
this->write("; ");
}
if (f.test()) {
- this->writeExpression(*f.test(), kTopLevel_Precedence);
+ this->writeExpression(*f.test(), Precedence::kTopLevel);
}
this->write("; ");
if (f.next()) {
- this->writeExpression(*f.next(), kTopLevel_Precedence);
+ this->writeExpression(*f.next(), Precedence::kTopLevel);
}
this->write(") ");
this->writeStatement(*f.statement());
@@ -1819,19 +1782,19 @@
this->write("do ");
this->writeStatement(*d.statement());
this->write(" while (");
- this->writeExpression(*d.test(), kTopLevel_Precedence);
+ this->writeExpression(*d.test(), Precedence::kTopLevel);
this->write(");");
}
void MetalCodeGenerator::writeSwitchStatement(const SwitchStatement& s) {
this->write("switch (");
- this->writeExpression(*s.value(), kTopLevel_Precedence);
+ this->writeExpression(*s.value(), Precedence::kTopLevel);
this->writeLine(") {");
fIndentation++;
for (const std::unique_ptr<SwitchCase>& c : s.cases()) {
if (c->value()) {
this->write("case ");
- this->writeExpression(*c->value(), kTopLevel_Precedence);
+ this->writeExpression(*c->value(), Precedence::kTopLevel);
this->writeLine(":");
} else {
this->writeLine("default:");
@@ -1866,7 +1829,7 @@
if (r.expression()) {
if (r.expression()->type() == *fContext.fTypes.fHalf4) {
this->write("_out.sk_FragColor = ");
- this->writeExpression(*r.expression(), kTopLevel_Precedence);
+ this->writeExpression(*r.expression(), Precedence::kTopLevel);
this->writeLine(";");
} else {
fErrors.error(r.fOffset, "Metal does not support returning '" +
@@ -1880,7 +1843,7 @@
this->write("return");
if (r.expression()) {
this->write(" ");
- this->writeExpression(*r.expression(), kTopLevel_Precedence);
+ this->writeExpression(*r.expression(), Precedence::kTopLevel);
}
this->write(";");
}