Added DSL LogicalXor function

Because C++ does not have the '^^' operator, we had previously just
skipped support for this GLSL operator. This implements it as a
function.

Change-Id: I310658d900de4609572aed4750d6fb27f88d0722
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/430036
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/include/sksl/DSLExpression.h b/include/sksl/DSLExpression.h
index f180d50..31f91d3 100644
--- a/include/sksl/DSLExpression.h
+++ b/include/sksl/DSLExpression.h
@@ -179,6 +179,7 @@
 DSLPossibleExpression operator|=(DSLExpression left, DSLExpression right);
 DSLPossibleExpression operator^(DSLExpression left, DSLExpression right);
 DSLPossibleExpression operator^=(DSLExpression left, DSLExpression right);
+DSLPossibleExpression LogicalXor(DSLExpression left, DSLExpression right);
 DSLPossibleExpression operator,(DSLExpression left, DSLExpression right);
 DSLPossibleExpression operator,(DSLPossibleExpression left, DSLExpression right);
 DSLPossibleExpression operator,(DSLExpression left, DSLPossibleExpression right);
diff --git a/src/sksl/dsl/DSLExpression.cpp b/src/sksl/dsl/DSLExpression.cpp
index aac4cdb..0ce77cf 100644
--- a/src/sksl/dsl/DSLExpression.cpp
+++ b/src/sksl/dsl/DSLExpression.cpp
@@ -207,6 +207,10 @@
 OP(|=, TK_BITWISEOREQ)
 OP(^, TK_BITWISEXOR)
 OP(^=, TK_BITWISEXOREQ)
+DSLPossibleExpression LogicalXor(DSLExpression left, DSLExpression right) {
+    return DSLWriter::ConvertBinary(left.release(), SkSL::Token::Kind::TK_LOGICALXOR,
+                                    right.release());
+}
 OP(==, TK_EQEQ)
 OP(!=, TK_NEQ)
 OP(>, TK_GT)
diff --git a/tests/SkSLDSLTest.cpp b/tests/SkSLDSLTest.cpp
index 7ee7eaf..dbd55ca 100644
--- a/tests/SkSLDSLTest.cpp
+++ b/tests/SkSLDSLTest.cpp
@@ -1037,6 +1037,18 @@
     }
 }
 
+DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLLogicalXor, r, ctxInfo) {
+    AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
+    Var a(kBool_Type, "a"), b(kBool_Type, "b");
+    Expression e1 = LogicalXor(a, b);
+    EXPECT_EQUAL(e1, "(a ^^ b)");
+
+    {
+        ExpectError error(r, "error: type mismatch: '^^' cannot operate on 'bool', 'int'\n");
+        DSLExpression(LogicalXor(a, 5)).release();
+    }
+}
+
 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLComma, r, ctxInfo) {
     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
     Var a(kInt_Type, "a"), b(kInt_Type, "b");