Added unsigned types and type query functions to DSL

Change-Id: I721825d1a38e9f6846b94f84d14cb8c85b7a7519
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/403601
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/include/sksl/DSLExpression.h b/include/sksl/DSLExpression.h
index b330a83..0189acb 100644
--- a/include/sksl/DSLExpression.h
+++ b/include/sksl/DSLExpression.h
@@ -53,6 +53,11 @@
     DSLExpression(int value);
 
     /**
+     * Creates an expression representing a literal uint.
+     */
+    DSLExpression(unsigned int value);
+
+    /**
      * Creates an expression representing a literal bool.
      */
     DSLExpression(bool value);
diff --git a/include/sksl/DSLType.h b/include/sksl/DSLType.h
index aeefe82..0ca32af 100644
--- a/include/sksl/DSLType.h
+++ b/include/sksl/DSLType.h
@@ -63,6 +63,14 @@
     kShort2_Type,
     kShort3_Type,
     kShort4_Type,
+    kUInt_Type,
+    kUInt2_Type,
+    kUInt3_Type,
+    kUInt4_Type,
+    kUShort_Type,
+    kUShort2_Type,
+    kUShort3_Type,
+    kUShort4_Type,
     kVoid_Type,
 };
 
@@ -74,6 +82,61 @@
     DSLType(const SkSL::Type* type)
         : fSkSLType(type) {}
 
+    /**
+     * Returns true if this type is a bool.
+     */
+    bool isBoolean() const;
+
+    /**
+     * Returns true if this is a numeric scalar type.
+     */
+    bool isNumber() const;
+
+    /**
+     * Returns true if this is a floating-point scalar type (float or half).
+     */
+    bool isFloat() const;
+
+    /**
+     * Returns true if this is a signed scalar type (int or short).
+     */
+    bool isSigned() const;
+
+    /**
+     * Returns true if this is an unsigned scalar type (uint or ushort).
+     */
+    bool isUnsigned() const;
+
+    /**
+     * Returns true if this is a signed or unsigned integer.
+     */
+    bool isInteger() const;
+
+    /**
+     * Returns true if this is a scalar type.
+     */
+    bool isScalar() const;
+
+    /**
+     * Returns true if this is a vector type.
+     */
+    bool isVector() const;
+
+    /**
+     * Returns true if this is a matrix type.
+     */
+    bool isMatrix() const;
+
+    /**
+     * Returns true if this is a array type.
+     */
+    bool isArray() const;
+
+    /**
+     * Returns true if this is a struct type.
+     */
+    bool isStruct() const;
+
     template<typename... Args>
     static DSLExpression Construct(DSLType type, Args&&... args) {
         SkTArray<DSLExpression> argArray;
@@ -141,7 +204,9 @@
 VECTOR_TYPE(Float)
 VECTOR_TYPE(Half)
 VECTOR_TYPE(Int)
+VECTOR_TYPE(UInt)
 VECTOR_TYPE(Short)
+VECTOR_TYPE(UShort)
 
 MATRIX_TYPE(Float)
 MATRIX_TYPE(Half)
diff --git a/src/sksl/dsl/DSLExpression.cpp b/src/sksl/dsl/DSLExpression.cpp
index e5c602b..799d3ab 100644
--- a/src/sksl/dsl/DSLExpression.cpp
+++ b/src/sksl/dsl/DSLExpression.cpp
@@ -54,9 +54,14 @@
 }
 
 DSLExpression::DSLExpression(int value)
-        : fExpression(SkSL::IntLiteral::Make(DSLWriter::Context(),
-                                             /*offset=*/-1,
-                                             value)) {}
+    : fExpression(SkSL::IntLiteral::Make(DSLWriter::Context(),
+                                         /*offset=*/-1,
+                                         value)) {}
+
+DSLExpression::DSLExpression(unsigned int value)
+    : fExpression(SkSL::IntLiteral::Make(DSLWriter::Context(),
+                                         /*offset=*/-1,
+                                         value)) {}
 
 DSLExpression::DSLExpression(bool value)
     : fExpression(SkSL::BoolLiteral::Make(DSLWriter::Context(),
diff --git a/src/sksl/dsl/DSLType.cpp b/src/sksl/dsl/DSLType.cpp
index 4f74101..e8dc0d6 100644
--- a/src/sksl/dsl/DSLType.cpp
+++ b/src/sksl/dsl/DSLType.cpp
@@ -15,6 +15,50 @@
 
 namespace dsl {
 
+bool DSLType::isBoolean() const {
+    return this->skslType().isBoolean();
+}
+
+bool DSLType::isNumber() const {
+    return this->skslType().isNumber();
+}
+
+bool DSLType::isFloat() const {
+    return this->skslType().isFloat();
+}
+
+bool DSLType::isSigned() const {
+    return this->skslType().isSigned();
+}
+
+bool DSLType::isUnsigned() const {
+    return this->skslType().isUnsigned();
+}
+
+bool DSLType::isInteger() const {
+    return this->skslType().isInteger();
+}
+
+bool DSLType::isScalar() const {
+    return this->skslType().isScalar();
+}
+
+bool DSLType::isVector() const {
+    return this->skslType().isVector();
+}
+
+bool DSLType::isMatrix() const {
+    return this->skslType().isMatrix();
+}
+
+bool DSLType::isArray() const {
+    return this->skslType().isArray();
+}
+
+bool DSLType::isStruct() const {
+    return this->skslType().isStruct();
+}
+
 const SkSL::Type& DSLType::skslType() const {
     if (fSkSLType) {
         return *fSkSLType;
@@ -101,6 +145,22 @@
             return *context.fTypes.fShort3;
         case kShort4_Type:
             return *context.fTypes.fShort4;
+        case kUInt_Type:
+            return *context.fTypes.fUInt;
+        case kUInt2_Type:
+            return *context.fTypes.fUInt2;
+        case kUInt3_Type:
+            return *context.fTypes.fUInt3;
+        case kUInt4_Type:
+            return *context.fTypes.fUInt4;
+        case kUShort_Type:
+            return *context.fTypes.fUShort;
+        case kUShort2_Type:
+            return *context.fTypes.fUShort2;
+        case kUShort3_Type:
+            return *context.fTypes.fUShort3;
+        case kUShort4_Type:
+            return *context.fTypes.fUShort4;
         case kVoid_Type:
             return *context.fTypes.fVoid;
         default:
diff --git a/tests/SkSLDSLTest.cpp b/tests/SkSLDSLTest.cpp
index 7faf2cc..e4b352d 100644
--- a/tests/SkSLDSLTest.cpp
+++ b/tests/SkSLDSLTest.cpp
@@ -282,6 +282,43 @@
     }
 }
 
+DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLUInt, r, ctxInfo) {
+    AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
+
+    EXPECT_EQUAL(UInt(std::numeric_limits<uint32_t>::max()),
+                "4294967295");
+    EXPECT_EQUAL(UInt2(std::numeric_limits<uint32_t>::min()),
+                "uint2(0)");
+    EXPECT_EQUAL(UInt2(0, 1),
+                "uint2(0, 1)");
+    EXPECT_EQUAL(UInt3(0),
+                "uint3(0)");
+    EXPECT_EQUAL(UInt3(UInt2(0, 1), -2),
+                "uint3(0, 1, -2)");
+    EXPECT_EQUAL(UInt3(0, 1, 2),
+                "uint3(0, 1, 2)");
+    EXPECT_EQUAL(UInt4(0),
+                "uint4(0)");
+    EXPECT_EQUAL(UInt4(UInt2(0, 1), UInt2(2, 3)),
+                "uint4(0, 1, 2, 3)");
+    EXPECT_EQUAL(UInt4(0, 1, UInt2(2, 3)),
+                "uint4(0, 1, 2, 3)");
+    EXPECT_EQUAL(UInt4(0, 1, 2, 3),
+                "uint4(0, 1, 2, 3)");
+
+    {
+        ExpectError error(r, "error: invalid arguments to 'uint2' constructor (expected 2 scalars,"
+                             " but found 4)\n");
+        UInt2(UInt4(1)).release();
+    }
+
+    {
+        ExpectError error(r, "error: invalid arguments to 'uint4' constructor (expected 4 scalars,"
+                             " but found 3)\n");
+        UInt4(UInt3(1)).release();
+    }
+}
+
 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLShort, r, ctxInfo) {
     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
 
@@ -319,6 +356,43 @@
     }
 }
 
+DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLUShort, r, ctxInfo) {
+    AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
+
+    EXPECT_EQUAL(UShort(std::numeric_limits<uint16_t>::max()),
+                "65535");
+    EXPECT_EQUAL(UShort2(std::numeric_limits<uint16_t>::min()),
+                "ushort2(0)");
+    EXPECT_EQUAL(UShort2(0, 1),
+                "ushort2(0, 1)");
+    EXPECT_EQUAL(UShort3(0),
+                "ushort3(0)");
+    EXPECT_EQUAL(UShort3(UShort2(0, 1), -2),
+                "ushort3(0, 1, -2)");
+    EXPECT_EQUAL(UShort3(0, 1, 2),
+                "ushort3(0, 1, 2)");
+    EXPECT_EQUAL(UShort4(0),
+                "ushort4(0)");
+    EXPECT_EQUAL(UShort4(UShort2(0, 1), UShort2(2, 3)),
+                "ushort4(0, 1, 2, 3)");
+    EXPECT_EQUAL(UShort4(0, 1, UShort2(2, 3)),
+                "ushort4(0, 1, 2, 3)");
+    EXPECT_EQUAL(UShort4(0, 1, 2, 3),
+                "ushort4(0, 1, 2, 3)");
+
+    {
+        ExpectError error(r, "error: invalid arguments to 'ushort2' constructor (expected 2 "
+                             "scalars, but found 4)\n");
+        UShort2(UShort4(1)).release();
+    }
+
+    {
+        ExpectError error(r, "error: invalid arguments to 'ushort4' constructor (expected 4 "
+                             "scalars, but found 3)\n");
+        UShort4(UShort3(1)).release();
+    }
+}
+
 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBool, r, ctxInfo) {
     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
 
@@ -354,6 +428,93 @@
     }
 }
 
+DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLType, r, ctxInfo) {
+    AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
+    REPORTER_ASSERT(r,  DSLType(kBool_Type).isBoolean());
+    REPORTER_ASSERT(r, !DSLType(kBool_Type).isNumber());
+    REPORTER_ASSERT(r, !DSLType(kBool_Type).isFloat());
+    REPORTER_ASSERT(r, !DSLType(kBool_Type).isSigned());
+    REPORTER_ASSERT(r, !DSLType(kBool_Type).isUnsigned());
+    REPORTER_ASSERT(r, !DSLType(kBool_Type).isInteger());
+    REPORTER_ASSERT(r,  DSLType(kBool_Type).isScalar());
+    REPORTER_ASSERT(r, !DSLType(kBool_Type).isVector());
+    REPORTER_ASSERT(r, !DSLType(kBool_Type).isMatrix());
+    REPORTER_ASSERT(r, !DSLType(kBool_Type).isArray());
+    REPORTER_ASSERT(r, !DSLType(kBool_Type).isStruct());
+
+    REPORTER_ASSERT(r, !DSLType(kInt_Type).isBoolean());
+    REPORTER_ASSERT(r,  DSLType(kInt_Type).isNumber());
+    REPORTER_ASSERT(r, !DSLType(kInt_Type).isFloat());
+    REPORTER_ASSERT(r,  DSLType(kInt_Type).isSigned());
+    REPORTER_ASSERT(r, !DSLType(kInt_Type).isUnsigned());
+    REPORTER_ASSERT(r,  DSLType(kInt_Type).isInteger());
+    REPORTER_ASSERT(r,  DSLType(kInt_Type).isScalar());
+    REPORTER_ASSERT(r, !DSLType(kInt_Type).isVector());
+    REPORTER_ASSERT(r, !DSLType(kInt_Type).isMatrix());
+    REPORTER_ASSERT(r, !DSLType(kInt_Type).isArray());
+    REPORTER_ASSERT(r, !DSLType(kInt_Type).isStruct());
+
+    REPORTER_ASSERT(r, !DSLType(kUInt_Type).isBoolean());
+    REPORTER_ASSERT(r,  DSLType(kUInt_Type).isNumber());
+    REPORTER_ASSERT(r, !DSLType(kUInt_Type).isFloat());
+    REPORTER_ASSERT(r, !DSLType(kUInt_Type).isSigned());
+    REPORTER_ASSERT(r,  DSLType(kUInt_Type).isUnsigned());
+    REPORTER_ASSERT(r,  DSLType(kUInt_Type).isInteger());
+    REPORTER_ASSERT(r,  DSLType(kUInt_Type).isScalar());
+    REPORTER_ASSERT(r, !DSLType(kUInt_Type).isVector());
+    REPORTER_ASSERT(r, !DSLType(kUInt_Type).isMatrix());
+    REPORTER_ASSERT(r, !DSLType(kUInt_Type).isArray());
+    REPORTER_ASSERT(r, !DSLType(kUInt_Type).isStruct());
+
+    REPORTER_ASSERT(r, !DSLType(kFloat_Type).isBoolean());
+    REPORTER_ASSERT(r,  DSLType(kFloat_Type).isNumber());
+    REPORTER_ASSERT(r,  DSLType(kFloat_Type).isFloat());
+    REPORTER_ASSERT(r, !DSLType(kFloat_Type).isSigned());
+    REPORTER_ASSERT(r, !DSLType(kFloat_Type).isUnsigned());
+    REPORTER_ASSERT(r, !DSLType(kFloat_Type).isInteger());
+    REPORTER_ASSERT(r,  DSLType(kFloat_Type).isScalar());
+    REPORTER_ASSERT(r, !DSLType(kFloat_Type).isVector());
+    REPORTER_ASSERT(r, !DSLType(kFloat_Type).isMatrix());
+    REPORTER_ASSERT(r, !DSLType(kFloat_Type).isArray());
+    REPORTER_ASSERT(r, !DSLType(kFloat_Type).isStruct());
+
+    REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isBoolean());
+    REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isNumber());
+    REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isFloat());
+    REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isSigned());
+    REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isUnsigned());
+    REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isInteger());
+    REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isScalar());
+    REPORTER_ASSERT(r,  DSLType(kFloat2_Type).isVector());
+    REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isMatrix());
+    REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isArray());
+    REPORTER_ASSERT(r, !DSLType(kFloat2_Type).isStruct());
+
+    REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isBoolean());
+    REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isNumber());
+    REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isFloat());
+    REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isSigned());
+    REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isUnsigned());
+    REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isInteger());
+    REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isScalar());
+    REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isVector());
+    REPORTER_ASSERT(r,  DSLType(kHalf2x2_Type).isMatrix());
+    REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isArray());
+    REPORTER_ASSERT(r, !DSLType(kHalf2x2_Type).isStruct());
+
+    REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isBoolean());
+    REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isNumber());
+    REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isFloat());
+    REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isSigned());
+    REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isUnsigned());
+    REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isInteger());
+    REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isScalar());
+    REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isVector());
+    REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isMatrix());
+    REPORTER_ASSERT(r,  DSLType(Array(kFloat_Type, 2)).isArray());
+    REPORTER_ASSERT(r, !DSLType(Array(kFloat_Type, 2)).isStruct());
+}
+
 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLMatrices, r, ctxInfo) {
     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
     Var f22(kFloat2x2_Type, "f22");