blob: 7a24797d2547b61c35507b124442669b1d7f9558 [file] [log] [blame]
/*
* 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 "src/sksl/dsl/priv/DSLWriter.h"
#include "src/sksl/ir/SkSLConstructor.h"
#include "src/sksl/ir/SkSLStructDefinition.h"
namespace SkSL {
namespace dsl {
DSLType::DSLType(skstd::string_view name) {
const SkSL::Symbol* symbol = (*DSLWriter::SymbolTable())[name];
if (symbol) {
if (symbol->is<SkSL::Type>()) {
fSkSLType = &symbol->as<SkSL::Type>();
} else {
DSLWriter::ReportError(String::printf("symbol '%.*s' is not a type",
(int) name.length(),
name.data()).c_str());
}
} else {
DSLWriter::ReportError(String::printf("no symbol named '%.*s'", (int) name.length(),
name.data()).c_str());
}
}
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;
}
const SkSL::Context& context = DSLWriter::Context();
switch (fTypeConstant) {
case kBool_Type:
return *context.fTypes.fBool;
case kBool2_Type:
return *context.fTypes.fBool2;
case kBool3_Type:
return *context.fTypes.fBool3;
case kBool4_Type:
return *context.fTypes.fBool4;
case kHalf_Type:
return *context.fTypes.fHalf;
case kHalf2_Type:
return *context.fTypes.fHalf2;
case kHalf3_Type:
return *context.fTypes.fHalf3;
case kHalf4_Type:
return *context.fTypes.fHalf4;
case kHalf2x2_Type:
return *context.fTypes.fHalf2x2;
case kHalf3x2_Type:
return *context.fTypes.fHalf3x2;
case kHalf4x2_Type:
return *context.fTypes.fHalf4x2;
case kHalf2x3_Type:
return *context.fTypes.fHalf2x3;
case kHalf3x3_Type:
return *context.fTypes.fHalf3x3;
case kHalf4x3_Type:
return *context.fTypes.fHalf4x3;
case kHalf2x4_Type:
return *context.fTypes.fHalf2x4;
case kHalf3x4_Type:
return *context.fTypes.fHalf3x4;
case kHalf4x4_Type:
return *context.fTypes.fHalf4x4;
case kFloat_Type:
return *context.fTypes.fFloat;
case kFloat2_Type:
return *context.fTypes.fFloat2;
case kFloat3_Type:
return *context.fTypes.fFloat3;
case kFloat4_Type:
return *context.fTypes.fFloat4;
case kFloat2x2_Type:
return *context.fTypes.fFloat2x2;
case kFloat3x2_Type:
return *context.fTypes.fFloat3x2;
case kFloat4x2_Type:
return *context.fTypes.fFloat4x2;
case kFloat2x3_Type:
return *context.fTypes.fFloat2x3;
case kFloat3x3_Type:
return *context.fTypes.fFloat3x3;
case kFloat4x3_Type:
return *context.fTypes.fFloat4x3;
case kFloat2x4_Type:
return *context.fTypes.fFloat2x4;
case kFloat3x4_Type:
return *context.fTypes.fFloat3x4;
case kFloat4x4_Type:
return *context.fTypes.fFloat4x4;
case kInt_Type:
return *context.fTypes.fInt;
case kInt2_Type:
return *context.fTypes.fInt2;
case kInt3_Type:
return *context.fTypes.fInt3;
case kInt4_Type:
return *context.fTypes.fInt4;
case kShader_Type:
return *context.fTypes.fShader;
case kShort_Type:
return *context.fTypes.fShort;
case kShort2_Type:
return *context.fTypes.fShort2;
case kShort3_Type:
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:
SkUNREACHABLE;
}
}
DSLExpression DSLType::Construct(DSLType type, SkTArray<DSLExpression> argArray) {
return DSLWriter::Construct(type.skslType(), std::move(argArray));
}
DSLType Array(const DSLType& base, int count) {
if (count <= 0) {
DSLWriter::ReportError("error: array size must be positive\n");
}
if (base.isArray()) {
DSLWriter::ReportError("error: multidimensional arrays are not permitted\n");
return base;
}
return DSLWriter::SymbolTable()->addArrayDimension(&base.skslType(), count);
}
DSLType Struct(skstd::string_view name, SkTArray<DSLField> fields) {
std::vector<SkSL::Type::Field> skslFields;
skslFields.reserve(fields.count());
for (const DSLField& field : fields) {
skslFields.emplace_back(field.fModifiers.fModifiers, field.fName, &field.fType.skslType());
}
const SkSL::Type* result = DSLWriter::SymbolTable()->add(Type::MakeStructType(/*offset=*/-1,
String(name),
skslFields));
DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::StructDefinition>(/*offset=*/-1,
*result));
return result;
}
} // namespace dsl
} // namespace SkSL