Honor lowp/mediump/highp precision qualifiers in DSLParser.

(Added bsalomon@ for public API review)

Change-Id: Id0e7f656d68f2c7bec2c38ca7ccc8c6bb49e7e91
Bug: skia:12248
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/436570
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
John Stiles 2021-08-05 10:15:16 -04:00 committed by SkCQ
parent a3f996c70d
commit 4adb66f313
5 changed files with 40 additions and 21 deletions

View File

@ -52,6 +52,7 @@ private:
friend DSLType Struct(skstd::string_view name, SkTArray<DSLField> fields);
friend class DSLCore;
friend class DSLFunction;
friend class DSLType;
friend class DSLVarBase;
friend class DSLWriter;
};

View File

@ -86,6 +86,8 @@ public:
DSLType(skstd::string_view name);
DSLType(skstd::string_view name, DSLModifiers modifiers);
/**
* Returns true if this type is a bool.
*/

View File

@ -283,7 +283,7 @@ bool DSLParser::declaration() {
Declare(result);
return true;
}
skstd::optional<DSLType> type = this->type();
skstd::optional<DSLType> type = this->type(modifiers);
if (!type) {
return false;
}
@ -459,7 +459,7 @@ skstd::optional<DSLStatement> DSLParser::varDeclarationsOrExpressionStatement()
// statement is a variable-declaration statement, not an expression-statement.
bool DSLParser::varDeclarationsPrefix(VarDeclarationsPrefix* prefixData) {
prefixData->modifiers = this->modifiers();
skstd::optional<DSLType> type = this->type();
skstd::optional<DSLType> type = this->type(prefixData->modifiers);
if (!type) {
return false;
}
@ -502,7 +502,7 @@ skstd::optional<DSLType> DSLParser::structDeclaration() {
while (!this->checkNext(Token::Kind::TK_RBRACE)) {
DSLModifiers modifiers = this->modifiers();
skstd::optional<DSLType> type = this->type();
skstd::optional<DSLType> type = this->type(modifiers);
if (!type) {
return skstd::nullopt;
}
@ -561,7 +561,7 @@ SkTArray<dsl::DSLGlobalVar> DSLParser::structVarDeclaration(DSLModifiers modifie
/* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */
skstd::optional<DSLWrapper<DSLParameter>> DSLParser::parameter() {
DSLModifiers modifiers = this->modifiersWithDefaults(0);
skstd::optional<DSLType> type = this->type();
skstd::optional<DSLType> type = this->type(modifiers);
if (!type) {
return skstd::nullopt;
}
@ -760,7 +760,7 @@ skstd::optional<DSLStatement> DSLParser::statement() {
}
/* IDENTIFIER(type) (LBRACKET intLiteral? RBRACKET)* QUESTION? */
skstd::optional<DSLType> DSLParser::type() {
skstd::optional<DSLType> DSLParser::type(DSLModifiers modifiers) {
Token type;
if (!this->expect(Token::Kind::TK_IDENTIFIER, "a type", &type)) {
return skstd::nullopt;
@ -769,7 +769,7 @@ skstd::optional<DSLType> DSLParser::type() {
this->error(type, ("no type named '" + this->text(type) + "'").c_str());
return skstd::nullopt;
}
DSLType result(this->text(type));
DSLType result(this->text(type), modifiers);
while (this->checkNext(Token::Kind::TK_LBRACKET)) {
if (result.isArray()) {
this->error(this->peek(), "multi-dimensional arrays are not supported");
@ -809,7 +809,7 @@ bool DSLParser::interfaceBlock(dsl::DSLModifiers modifiers) {
SkTArray<dsl::Field> fields;
while (!this->checkNext(Token::Kind::TK_RBRACE)) {
DSLModifiers modifiers = this->modifiers();
skstd::optional<dsl::DSLType> type = this->type();
skstd::optional<dsl::DSLType> type = this->type(modifiers);
if (!type) {
return false;
}

View File

@ -189,7 +189,7 @@ private:
skstd::optional<dsl::DSLStatement> statement();
skstd::optional<dsl::DSLType> type();
skstd::optional<dsl::DSLType> type(dsl::DSLModifiers modifiers);
bool interfaceBlock(dsl::DSLModifiers mods);

View File

@ -15,22 +15,38 @@ 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());
static const Type* find_type(skstd::string_view name) {
const Symbol* symbol = (*DSLWriter::SymbolTable())[name];
if (!symbol) {
DSLWriter::ReportError(String::printf("no symbol named '%.*s'",
(int)name.length(), name.data()).c_str());
return nullptr;
}
if (!symbol->is<Type>()) {
DSLWriter::ReportError(String::printf("symbol '%.*s' is not a type",
(int)name.length(), name.data()).c_str());
return nullptr;
}
return &symbol->as<Type>();
}
static const Type* find_type(skstd::string_view name, const Modifiers& modifiers) {
const Type* type = find_type(name);
if (!type) {
return nullptr;
}
return type->applyPrecisionQualifiers(DSLWriter::Context(),
modifiers,
DSLWriter::SymbolTable().get(),
/*offset=*/-1);
}
DSLType::DSLType(skstd::string_view name)
: fSkSLType(find_type(name)) {}
DSLType::DSLType(skstd::string_view name, DSLModifiers modifiers)
: fSkSLType(find_type(name, modifiers.fModifiers)) {}
bool DSLType::isBoolean() const {
return this->skslType().isBoolean();
}