summaryrefslogtreecommitdiffstats
path: root/gfx/skia/skia/src/sksl/dsl/DSLType.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/skia/skia/src/sksl/dsl/DSLType.cpp')
-rw-r--r--gfx/skia/skia/src/sksl/dsl/DSLType.cpp316
1 files changed, 316 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/sksl/dsl/DSLType.cpp b/gfx/skia/skia/src/sksl/dsl/DSLType.cpp
new file mode 100644
index 0000000000..82c000e5ab
--- /dev/null
+++ b/gfx/skia/skia/src/sksl/dsl/DSLType.cpp
@@ -0,0 +1,316 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/sksl/DSLType.h"
+
+#include "include/core/SkTypes.h"
+#include "include/private/SkSLDefines.h"
+#include "include/private/SkSLProgramElement.h"
+#include "include/private/SkSLString.h"
+#include "include/private/SkSLSymbol.h"
+#include "include/sksl/SkSLErrorReporter.h"
+#include "src/sksl/SkSLBuiltinTypes.h"
+#include "src/sksl/SkSLContext.h"
+#include "src/sksl/SkSLProgramSettings.h"
+#include "src/sksl/SkSLThreadContext.h"
+#include "src/sksl/ir/SkSLConstructor.h"
+#include "src/sksl/ir/SkSLStructDefinition.h"
+#include "src/sksl/ir/SkSLSymbolTable.h"
+#include "src/sksl/ir/SkSLType.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace SkSL {
+
+struct Modifiers;
+
+namespace dsl {
+
+static const SkSL::Type* verify_type(const Context& context,
+ const SkSL::Type* type,
+ bool allowGenericTypes,
+ Position pos) {
+ if (!context.fConfig->fIsBuiltinCode && type) {
+ if (!allowGenericTypes && (type->isGeneric() || type->isLiteral())) {
+ context.fErrors->error(pos, "type '" + std::string(type->name()) + "' is generic");
+ return context.fTypes.fPoison.get();
+ }
+ if (!type->isAllowedInES2(context)) {
+ context.fErrors->error(pos, "type '" + std::string(type->name()) +"' is not supported");
+ return context.fTypes.fPoison.get();
+ }
+ }
+ return type;
+}
+
+static const SkSL::Type* find_type(const Context& context,
+ Position pos,
+ std::string_view name) {
+ const Symbol* symbol = ThreadContext::SymbolTable()->find(name);
+ if (!symbol) {
+ context.fErrors->error(pos, String::printf("no symbol named '%.*s'",
+ (int)name.length(), name.data()));
+ return context.fTypes.fPoison.get();
+ }
+ if (!symbol->is<SkSL::Type>()) {
+ context.fErrors->error(pos, String::printf("symbol '%.*s' is not a type",
+ (int)name.length(), name.data()));
+ return context.fTypes.fPoison.get();
+ }
+ const SkSL::Type* type = &symbol->as<SkSL::Type>();
+ return verify_type(context, type, /*allowGenericTypes=*/false, pos);
+}
+
+static const SkSL::Type* find_type(const Context& context,
+ Position overallPos,
+ std::string_view name,
+ Position modifiersPos,
+ Modifiers* modifiers) {
+ const auto* type = find_type(context, overallPos, name);
+ return type->applyQualifiers(context, modifiers, ThreadContext::SymbolTable().get(),
+ modifiersPos);
+}
+
+static const SkSL::Type* get_type_from_type_constant(TypeConstant tc) {
+ const Context& context = ThreadContext::Context();
+ switch (tc) {
+ case kBool_Type:
+ return context.fTypes.fBool.get();
+ case kBool2_Type:
+ return context.fTypes.fBool2.get();
+ case kBool3_Type:
+ return context.fTypes.fBool3.get();
+ case kBool4_Type:
+ return context.fTypes.fBool4.get();
+ case kHalf_Type:
+ return context.fTypes.fHalf.get();
+ case kHalf2_Type:
+ return context.fTypes.fHalf2.get();
+ case kHalf3_Type:
+ return context.fTypes.fHalf3.get();
+ case kHalf4_Type:
+ return context.fTypes.fHalf4.get();
+ case kHalf2x2_Type:
+ return context.fTypes.fHalf2x2.get();
+ case kHalf3x2_Type:
+ return context.fTypes.fHalf3x2.get();
+ case kHalf4x2_Type:
+ return context.fTypes.fHalf4x2.get();
+ case kHalf2x3_Type:
+ return context.fTypes.fHalf2x3.get();
+ case kHalf3x3_Type:
+ return context.fTypes.fHalf3x3.get();
+ case kHalf4x3_Type:
+ return context.fTypes.fHalf4x3.get();
+ case kHalf2x4_Type:
+ return context.fTypes.fHalf2x4.get();
+ case kHalf3x4_Type:
+ return context.fTypes.fHalf3x4.get();
+ case kHalf4x4_Type:
+ return context.fTypes.fHalf4x4.get();
+ case kFloat_Type:
+ return context.fTypes.fFloat.get();
+ case kFloat2_Type:
+ return context.fTypes.fFloat2.get();
+ case kFloat3_Type:
+ return context.fTypes.fFloat3.get();
+ case kFloat4_Type:
+ return context.fTypes.fFloat4.get();
+ case kFloat2x2_Type:
+ return context.fTypes.fFloat2x2.get();
+ case kFloat3x2_Type:
+ return context.fTypes.fFloat3x2.get();
+ case kFloat4x2_Type:
+ return context.fTypes.fFloat4x2.get();
+ case kFloat2x3_Type:
+ return context.fTypes.fFloat2x3.get();
+ case kFloat3x3_Type:
+ return context.fTypes.fFloat3x3.get();
+ case kFloat4x3_Type:
+ return context.fTypes.fFloat4x3.get();
+ case kFloat2x4_Type:
+ return context.fTypes.fFloat2x4.get();
+ case kFloat3x4_Type:
+ return context.fTypes.fFloat3x4.get();
+ case kFloat4x4_Type:
+ return context.fTypes.fFloat4x4.get();
+ case kInt_Type:
+ return context.fTypes.fInt.get();
+ case kInt2_Type:
+ return context.fTypes.fInt2.get();
+ case kInt3_Type:
+ return context.fTypes.fInt3.get();
+ case kInt4_Type:
+ return context.fTypes.fInt4.get();
+ case kShader_Type:
+ return context.fTypes.fShader.get();
+ case kShort_Type:
+ return context.fTypes.fShort.get();
+ case kShort2_Type:
+ return context.fTypes.fShort2.get();
+ case kShort3_Type:
+ return context.fTypes.fShort3.get();
+ case kShort4_Type:
+ return context.fTypes.fShort4.get();
+ case kUInt_Type:
+ return context.fTypes.fUInt.get();
+ case kUInt2_Type:
+ return context.fTypes.fUInt2.get();
+ case kUInt3_Type:
+ return context.fTypes.fUInt3.get();
+ case kUInt4_Type:
+ return context.fTypes.fUInt4.get();
+ case kUShort_Type:
+ return context.fTypes.fUShort.get();
+ case kUShort2_Type:
+ return context.fTypes.fUShort2.get();
+ case kUShort3_Type:
+ return context.fTypes.fUShort3.get();
+ case kUShort4_Type:
+ return context.fTypes.fUShort4.get();
+ case kVoid_Type:
+ return context.fTypes.fVoid.get();
+ case kPoison_Type:
+ return context.fTypes.fPoison.get();
+ default:
+ SkUNREACHABLE;
+ }
+}
+
+DSLType::DSLType(TypeConstant tc, Position pos)
+ : fSkSLType(verify_type(ThreadContext::Context(),
+ get_type_from_type_constant(tc),
+ /*allowGenericTypes=*/false,
+ pos)) {}
+
+DSLType::DSLType(std::string_view name, Position pos)
+ : fSkSLType(find_type(ThreadContext::Context(), pos, name)) {}
+
+DSLType::DSLType(std::string_view name, DSLModifiers* modifiers, Position pos)
+ : fSkSLType(find_type(ThreadContext::Context(),
+ pos,
+ name,
+ modifiers->fPosition,
+ &modifiers->fModifiers)) {}
+
+DSLType::DSLType(const SkSL::Type* type, Position pos)
+ : fSkSLType(verify_type(ThreadContext::Context(), type, /*allowGenericTypes=*/true, pos)) {}
+
+DSLType DSLType::Invalid() {
+ return DSLType(ThreadContext::Context().fTypes.fInvalid.get(), Position());
+}
+
+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();
+}
+
+bool DSLType::isInterfaceBlock() const {
+ return this->skslType().isInterfaceBlock();
+}
+
+bool DSLType::isEffectChild() const {
+ return this->skslType().isEffectChild();
+}
+
+DSLExpression DSLType::Construct(DSLType type, SkSpan<DSLExpression> argArray) {
+ SkSL::ExpressionArray skslArgs;
+ skslArgs.reserve_back(argArray.size());
+
+ for (DSLExpression& arg : argArray) {
+ if (!arg.hasValue()) {
+ return DSLExpression();
+ }
+ skslArgs.push_back(arg.release());
+ }
+ return DSLExpression(SkSL::Constructor::Convert(ThreadContext::Context(), Position(),
+ type.skslType(), std::move(skslArgs)));
+}
+
+DSLType Array(const DSLType& base, int count, Position pos) {
+ count = base.skslType().convertArraySize(ThreadContext::Context(), pos,
+ DSLExpression(count, pos).release());
+ if (!count) {
+ return DSLType(kPoison_Type);
+ }
+ return DSLType(ThreadContext::SymbolTable()->addArrayDimension(&base.skslType(), count), pos);
+}
+
+DSLType UnsizedArray(const DSLType& base, Position pos) {
+ if (!base.skslType().checkIfUsableInArray(ThreadContext::Context(), pos)) {
+ return DSLType(kPoison_Type);
+ }
+ return ThreadContext::SymbolTable()->addArrayDimension(&base.skslType(),
+ SkSL::Type::kUnsizedArray);
+}
+
+DSLType StructType(std::string_view name,
+ SkSpan<DSLField> fields,
+ bool interfaceBlock,
+ Position pos) {
+ std::vector<SkSL::Type::Field> skslFields;
+ skslFields.reserve(fields.size());
+ for (const DSLField& field : fields) {
+ skslFields.emplace_back(field.fPosition, field.fModifiers.fModifiers, field.fName,
+ &field.fType.skslType());
+ }
+ auto newType = SkSL::Type::MakeStructType(ThreadContext::Context(), pos, name,
+ std::move(skslFields), interfaceBlock);
+ return DSLType(ThreadContext::SymbolTable()->add(std::move(newType)), pos);
+}
+
+DSLType Struct(std::string_view name, SkSpan<DSLField> fields, Position pos) {
+ DSLType result = StructType(name, fields, /*interfaceBlock=*/false, pos);
+ ThreadContext::ProgramElements().push_back(
+ std::make_unique<SkSL::StructDefinition>(pos, result.skslType()));
+ return result;
+}
+
+} // namespace dsl
+
+} // namespace SkSL