diff options
Diffstat (limited to 'gfx/skia/skia/src/sksl/dsl/DSLType.cpp')
-rw-r--r-- | gfx/skia/skia/src/sksl/dsl/DSLType.cpp | 316 |
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 |