blob: b6fb3434f002bd72086f9047c7428a0fc20edc7e [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 "src/sksl/dsl/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 {
const SkSL::Type& DSLType::skslType() const {
if (fSkSLType) {
return *fSkSLType;
}
const SkSL::Context& context = DSLWriter::Context();
switch (fTypeConstant) {
case kBool:
return *context.fTypes.fBool;
case kBool2:
return *context.fTypes.fBool2;
case kBool3:
return *context.fTypes.fBool3;
case kBool4:
return *context.fTypes.fBool4;
case kHalf:
return *context.fTypes.fHalf;
case kHalf2:
return *context.fTypes.fHalf2;
case kHalf3:
return *context.fTypes.fHalf3;
case kHalf4:
return *context.fTypes.fHalf4;
case kFloat:
return *context.fTypes.fFloat;
case kFloat2:
return *context.fTypes.fFloat2;
case kFloat3:
return *context.fTypes.fFloat3;
case kFloat4:
return *context.fTypes.fFloat4;
case kInt:
return *context.fTypes.fInt;
case kInt2:
return *context.fTypes.fInt2;
case kInt3:
return *context.fTypes.fInt3;
case kInt4:
return *context.fTypes.fInt4;
case kShort:
return *context.fTypes.fShort;
case kShort2:
return *context.fTypes.fShort2;
case kShort3:
return *context.fTypes.fShort3;
case kShort4:
return *context.fTypes.fShort4;
case kVoid:
return *context.fTypes.fVoid;
default:
SkUNREACHABLE;
}
}
static DSLExpression construct1(const SkSL::Type& type, DSLExpression a) {
std::vector<DSLExpression> args;
args.push_back(std::move(a));
return DSLWriter::Construct(type, std::move(args));
}
static DSLExpression construct2(const SkSL::Type& type, DSLExpression a,
DSLExpression b) {
std::vector<DSLExpression> args;
args.push_back(std::move(a));
args.push_back(std::move(b));
return DSLWriter::Construct(type, std::move(args));
}
static DSLExpression construct3(const SkSL::Type& type, DSLExpression a,
DSLExpression b,
DSLExpression c) {
std::vector<DSLExpression> args;
args.push_back(std::move(a));
args.push_back(std::move(b));
args.push_back(std::move(c));
return DSLWriter::Construct(type, std::move(args));
}
static DSLExpression construct4(const SkSL::Type& type, DSLExpression a, DSLExpression b,
DSLExpression c, DSLExpression d) {
std::vector<DSLExpression> args;
args.push_back(std::move(a));
args.push_back(std::move(b));
args.push_back(std::move(c));
args.push_back(std::move(d));
return DSLWriter::Construct(type, std::move(args));
}
#define TYPE(T) \
DSLExpression T(DSLExpression a) { \
return construct1(*DSLWriter::Context().fTypes.f ## T, std::move(a)); \
} \
DSLExpression T ## 2(DSLExpression a) { \
return construct1(*DSLWriter::Context().fTypes.f ## T ## 2, std::move(a)); \
} \
DSLExpression T ## 2(DSLExpression a, DSLExpression b) { \
return construct2(*DSLWriter::Context().fTypes.f ## T ## 2, std::move(a), \
std::move(b)); \
} \
DSLExpression T ## 3(DSLExpression a) { \
return construct1(*DSLWriter::Context().fTypes.f ## T ## 3, std::move(a)); \
} \
DSLExpression T ## 3(DSLExpression a, DSLExpression b) { \
return construct2(*DSLWriter::Context().fTypes.f ## T ## 3, std::move(a), \
std::move(b)); \
} \
DSLExpression T ## 3(DSLExpression a, DSLExpression b, DSLExpression c) { \
return construct3(*DSLWriter::Context().fTypes.f ## T ## 3, std::move(a), \
std::move(b), std::move(c)); \
} \
DSLExpression T ## 4(DSLExpression a) { \
return construct1(*DSLWriter::Context().fTypes.f ## T ## 4, std::move(a)); \
} \
DSLExpression T ## 4(DSLExpression a, DSLExpression b) { \
return construct2(*DSLWriter::Context().fTypes.f ## T ## 4, std::move(a), \
std::move(b)); \
} \
DSLExpression T ## 4(DSLExpression a, DSLExpression b, DSLExpression c) { \
return construct3(*DSLWriter::Context().fTypes.f ## T ## 4, std::move(a), std::move(b), \
std::move(c)); \
} \
DSLExpression T ## 4(DSLExpression a, DSLExpression b, DSLExpression c, DSLExpression d) { \
return construct4(*DSLWriter::Context().fTypes.f ## T ## 4, std::move(a), std::move(b), \
std::move(c), std::move(d)); \
}
TYPE(Bool)
TYPE(Float)
TYPE(Half)
TYPE(Int)
TYPE(Short)
#undef TYPE
DSLType Array(const DSLType& base, int count) {
SkASSERT(count >= 1);
return DSLWriter::SymbolTable()->addArrayDimension(&base.skslType(), count);
}
DSLType Struct(const char* 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,
name,
skslFields));
DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::StructDefinition>(/*offset=*/-1,
*result));
return result;
}
} // namespace dsl
} // namespace SkSL