Removed SkSL::StringFragment in favor of string_view
This CL preserves the "StringFragment" name as an alias for string_view to reduce the impact. The StringFragment alias will be removed in a followup CL. Change-Id: I89209bc626b0be0d0190823b6217f4c83cafe1bc Reviewed-on: https://skia-review.googlesource.com/c/skia/+/416736 Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
a1feabd383
commit
d2e0960696
1
BUILD.gn
1
BUILD.gn
@ -624,6 +624,7 @@ if (skia_compile_processors || skia_compile_sksl_tests) {
|
||||
"src/core/SkStream.cpp",
|
||||
"src/core/SkString.cpp",
|
||||
"src/core/SkStringUtils.cpp",
|
||||
"src/core/SkStringView.cpp",
|
||||
"src/core/SkThreadID.cpp",
|
||||
"src/core/SkUtils.cpp",
|
||||
"src/core/SkVM.cpp",
|
||||
|
@ -30,7 +30,7 @@ bool FuzzSKSL2Pipeline(sk_sp<SkData> bytes) {
|
||||
using String = SkSL::String;
|
||||
|
||||
String declareUniform(const SkSL::VarDeclaration* decl) override {
|
||||
return decl->var().name();
|
||||
return String(decl->var().name());
|
||||
}
|
||||
|
||||
void defineFunction(const char* /*decl*/, const char* /*body*/, bool /*isMain*/) override {}
|
||||
|
@ -20,6 +20,10 @@
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
|
||||
namespace skstd {
|
||||
class string_view;
|
||||
}
|
||||
|
||||
/* Some helper functions for C strings */
|
||||
static inline bool SkStrStartsWith(const char string[], const char prefixStr[]) {
|
||||
SkASSERT(string);
|
||||
@ -122,6 +126,7 @@ public:
|
||||
SkString(const SkString&);
|
||||
SkString(SkString&&);
|
||||
explicit SkString(const std::string&);
|
||||
explicit SkString(skstd::string_view);
|
||||
~SkString();
|
||||
|
||||
bool isEmpty() const { return 0 == fRec->fLength; }
|
||||
|
@ -109,6 +109,15 @@ public:
|
||||
other.fLength = tempLength;
|
||||
}
|
||||
|
||||
constexpr void remove_prefix(size_type n) {
|
||||
fData += n;
|
||||
fLength -= n;
|
||||
}
|
||||
|
||||
constexpr void remove_suffix(size_type n) {
|
||||
fLength -= n;
|
||||
}
|
||||
|
||||
private:
|
||||
const_pointer fData;
|
||||
size_type fLength;
|
||||
@ -128,4 +137,16 @@ bool operator>=(string_view left, string_view right);
|
||||
|
||||
} // namespace skstd
|
||||
|
||||
namespace std {
|
||||
template<> struct hash<skstd::string_view> {
|
||||
size_t operator()(const skstd::string_view& s) const {
|
||||
size_t result = 0;
|
||||
for (auto iter = s.begin(); iter != s.end(); ++iter) {
|
||||
result = result * 101 + (size_t) *iter;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
@ -208,7 +208,7 @@ struct Layout {
|
||||
if (fInvocations >= 0) {
|
||||
result += separator() + "invocations = " + to_string(fInvocations);
|
||||
}
|
||||
if (fWhen.fLength) {
|
||||
if (fWhen.length()) {
|
||||
result += separator() + "when = " + fWhen;
|
||||
}
|
||||
if (result.size() > 0) {
|
||||
|
@ -22,62 +22,13 @@ namespace SkSL {
|
||||
|
||||
class String;
|
||||
|
||||
// Represents a (not necessarily null-terminated) slice of a string.
|
||||
struct StringFragment {
|
||||
StringFragment()
|
||||
: fChars("")
|
||||
, fLength(0) {}
|
||||
|
||||
StringFragment(const char* chars)
|
||||
: fChars(chars)
|
||||
, fLength(strlen(chars)) {}
|
||||
|
||||
StringFragment(const char* chars, size_t length)
|
||||
: fChars(chars)
|
||||
, fLength(length) {}
|
||||
|
||||
StringFragment(skstd::string_view s)
|
||||
: fChars(s.data())
|
||||
, fLength(s.length()) {}
|
||||
|
||||
const char* begin() const { return fChars; }
|
||||
const char* end() const { return fChars + fLength; }
|
||||
|
||||
const char* data() const { return fChars; }
|
||||
size_t size() const { return fLength; }
|
||||
size_t length() const { return fLength; }
|
||||
char operator[](size_t idx) const { return fChars[idx]; }
|
||||
|
||||
bool startsWith(const char prefix[]) const;
|
||||
bool endsWith(const char suffix[]) const;
|
||||
|
||||
bool operator==(const char* s) const;
|
||||
bool operator!=(const char* s) const;
|
||||
bool operator==(StringFragment s) const;
|
||||
bool operator!=(StringFragment s) const;
|
||||
bool operator<(StringFragment s) const;
|
||||
String operator+(const char* s) const;
|
||||
String operator+(const StringFragment& s) const;
|
||||
String operator+(const String& s) const;
|
||||
|
||||
#ifndef SKSL_STANDALONE
|
||||
operator SkString() const { return SkString(fChars, fLength); }
|
||||
#endif
|
||||
|
||||
const char* fChars;
|
||||
size_t fLength;
|
||||
};
|
||||
|
||||
bool operator==(const char* s1, StringFragment s2);
|
||||
|
||||
bool operator!=(const char* s1, StringFragment s2);
|
||||
using StringFragment = skstd::string_view;
|
||||
|
||||
class SK_API String : public std::string {
|
||||
public:
|
||||
using std::string::string;
|
||||
|
||||
explicit String(std::string s) : INHERITED(std::move(s)) {}
|
||||
String(StringFragment s) : INHERITED(s.fChars, s.fLength) {}
|
||||
explicit String(skstd::string_view s) : INHERITED(s.data(), s.length()) {}
|
||||
// TODO(johnstiles): add operator skstd::string_view
|
||||
|
||||
@ -85,11 +36,11 @@ public:
|
||||
void appendf(const char* fmt, ...) SK_PRINTF_LIKE(2, 3);
|
||||
void vappendf(const char* fmt, va_list va);
|
||||
|
||||
bool startsWith(const char prefix[]) const {
|
||||
return StringFragment(data(), size()).startsWith(prefix);
|
||||
bool starts_with(const char prefix[]) const {
|
||||
return StringFragment(data(), size()).starts_with(prefix);
|
||||
}
|
||||
bool endsWith(const char suffix[]) const {
|
||||
return StringFragment(data(), size()).endsWith(suffix);
|
||||
bool ends_with(const char suffix[]) const {
|
||||
return StringFragment(data(), size()).ends_with(suffix);
|
||||
}
|
||||
|
||||
bool consumeSuffix(const char suffix[]);
|
||||
@ -101,20 +52,13 @@ public:
|
||||
String& operator+=(const char* s);
|
||||
String& operator+=(const String& s);
|
||||
String& operator+=(StringFragment s);
|
||||
bool operator==(const char* s) const;
|
||||
bool operator!=(const char* s) const;
|
||||
bool operator==(const String& s) const;
|
||||
bool operator!=(const String& s) const;
|
||||
friend String operator+(const char* s1, const String& s2);
|
||||
friend bool operator==(const char* s1, const String& s2);
|
||||
friend bool operator!=(const char* s1, const String& s2);
|
||||
|
||||
private:
|
||||
using INHERITED = std::string;
|
||||
};
|
||||
|
||||
String operator+(const char* s1, const String& s2);
|
||||
bool operator!=(const char* s1, const String& s2);
|
||||
String operator+(StringFragment left, StringFragment right);
|
||||
|
||||
String to_string(double value);
|
||||
String to_string(int32_t value);
|
||||
@ -128,16 +72,6 @@ bool stoi(const StringFragment& s, SKSL_INT* value);
|
||||
} // namespace SkSL
|
||||
|
||||
namespace std {
|
||||
template<> struct hash<SkSL::StringFragment> {
|
||||
size_t operator()(const SkSL::StringFragment& s) const {
|
||||
size_t result = 0;
|
||||
for (size_t i = 0; i < s.fLength; ++i) {
|
||||
result = result * 101 + (size_t) s.fChars[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct hash<SkSL::String> {
|
||||
size_t operator()(const SkSL::String& s) const {
|
||||
return hash<std::string>{}(s);
|
||||
|
@ -223,7 +223,7 @@ SkRuntimeEffect::Result SkRuntimeEffect::Make(SkString sksl,
|
||||
// Child effects that can be sampled ('shader' or 'colorFilter')
|
||||
if (varType.isEffectChild()) {
|
||||
Child c;
|
||||
c.name = var.name();
|
||||
c.name = SkString(var.name());
|
||||
c.type = child_type(varType);
|
||||
c.index = children.size();
|
||||
children.push_back(c);
|
||||
@ -233,7 +233,7 @@ SkRuntimeEffect::Result SkRuntimeEffect::Make(SkString sksl,
|
||||
// 'uniform' variables
|
||||
else if (var.modifiers().fFlags & SkSL::Modifiers::kUniform_Flag) {
|
||||
Uniform uni;
|
||||
uni.name = var.name();
|
||||
uni.name = SkString(var.name());
|
||||
uni.flags = 0;
|
||||
uni.count = 1;
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "include/core/SkString.h"
|
||||
#include "include/core/SkStringView.h"
|
||||
#include "include/private/SkTPin.h"
|
||||
#include "include/private/SkTo.h"
|
||||
#include "src/core/SkSafeMath.h"
|
||||
@ -294,6 +295,10 @@ SkString::SkString(const std::string& src) {
|
||||
fRec = Rec::Make(src.c_str(), src.size());
|
||||
}
|
||||
|
||||
SkString::SkString(skstd::string_view src) {
|
||||
fRec = Rec::Make(src.data(), src.length());
|
||||
}
|
||||
|
||||
SkString::~SkString() {
|
||||
this->validate();
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ String ASTNode::description() const {
|
||||
if (this->begin() != this->end()) {
|
||||
return String(getString()) + " = " + this->begin()->description();
|
||||
}
|
||||
return getString();
|
||||
return String(getString());
|
||||
case Kind::kExtension:
|
||||
return "#extension " + getString();
|
||||
case Kind::kField:
|
||||
@ -111,7 +111,7 @@ String ASTNode::description() const {
|
||||
return result;
|
||||
}
|
||||
case Kind::kIdentifier:
|
||||
return getString();
|
||||
return String(getString());
|
||||
case Kind::kIndex:
|
||||
return this->begin()->description() + "[" + (this->begin() + 1)->description() + "]";
|
||||
case Kind::kIf: {
|
||||
@ -204,10 +204,10 @@ String ASTNode::description() const {
|
||||
return "(" + this->begin()->description() + " ? " + (this->begin() + 1)->description() +
|
||||
" : " + (this->begin() + 2)->description() + ")";
|
||||
case Kind::kType:
|
||||
return getString();
|
||||
return String(getString());
|
||||
case Kind::kVarDeclaration: {
|
||||
const VarData& vd = getVarData();
|
||||
String result = vd.fName;
|
||||
String result(vd.fName);
|
||||
auto iter = this->begin();
|
||||
if (vd.fIsArray) {
|
||||
result += "[" + (iter++)->description() + "]";
|
||||
|
@ -475,6 +475,7 @@ struct ASTNode {
|
||||
return *reinterpret_cast<const SKSL_FLOAT*>(fData.fBytes);
|
||||
}
|
||||
|
||||
// TODO(ethannicholas): Rename this to getStringView() as part of changing the return type
|
||||
const StringFragment& getString() const {
|
||||
SkASSERT(fData.fKind == NodeData::Kind::kStringFragment);
|
||||
return *reinterpret_cast<const StringFragment*>(fData.fBytes);
|
||||
|
@ -409,20 +409,20 @@ ParsedModule Compiler::parseModule(ProgramKind kind, ModuleData data, const Pars
|
||||
case ProgramElement::Kind::kEnum: {
|
||||
const Enum& e = element->as<Enum>();
|
||||
SkASSERT(e.isBuiltin());
|
||||
intrinsics->insertOrDie(e.typeName(), std::move(element));
|
||||
intrinsics->insertOrDie(String(e.typeName()), std::move(element));
|
||||
break;
|
||||
}
|
||||
case ProgramElement::Kind::kGlobalVar: {
|
||||
const GlobalVarDeclaration& global = element->as<GlobalVarDeclaration>();
|
||||
const Variable& var = global.declaration()->as<VarDeclaration>().var();
|
||||
SkASSERT(var.isBuiltin());
|
||||
intrinsics->insertOrDie(var.name(), std::move(element));
|
||||
intrinsics->insertOrDie(String(var.name()), std::move(element));
|
||||
break;
|
||||
}
|
||||
case ProgramElement::Kind::kInterfaceBlock: {
|
||||
const Variable& var = element->as<InterfaceBlock>().variable();
|
||||
SkASSERT(var.isBuiltin());
|
||||
intrinsics->insertOrDie(var.name(), std::move(element));
|
||||
intrinsics->insertOrDie(String(var.name()), std::move(element));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -270,7 +270,7 @@ void IRGenerator::checkVarDeclaration(int offset, const Modifiers& modifiers, co
|
||||
offset,
|
||||
"'in uniform' variables only permitted within fragment processors");
|
||||
}
|
||||
if (modifiers.fLayout.fWhen.fLength) {
|
||||
if (modifiers.fLayout.fWhen.length()) {
|
||||
this->errorReporter().error(offset,
|
||||
"'when' is only permitted within fragment processors");
|
||||
}
|
||||
@ -1061,7 +1061,8 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode
|
||||
}
|
||||
}
|
||||
}
|
||||
const Type* type = old->takeOwnershipOfSymbol(Type::MakeStructType(intf.fOffset, id.fTypeName,
|
||||
const Type* type = old->takeOwnershipOfSymbol(Type::MakeStructType(intf.fOffset,
|
||||
String(id.fTypeName),
|
||||
fields));
|
||||
int arraySize = 0;
|
||||
if (id.fIsArray) {
|
||||
@ -1082,14 +1083,14 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode
|
||||
const Variable* var = old->takeOwnershipOfSymbol(
|
||||
std::make_unique<Variable>(intf.fOffset,
|
||||
this->modifiersPool().add(id.fModifiers),
|
||||
id.fInstanceName.fLength ? id.fInstanceName : id.fTypeName,
|
||||
id.fInstanceName.length() ? id.fInstanceName : id.fTypeName,
|
||||
type,
|
||||
fIsBuiltinCode,
|
||||
Variable::Storage::kGlobal));
|
||||
if (foundRTAdjust) {
|
||||
fRTAdjustInterfaceBlock = var;
|
||||
}
|
||||
if (id.fInstanceName.fLength) {
|
||||
if (id.fInstanceName.length()) {
|
||||
old->addWithoutOwnership(var);
|
||||
} else {
|
||||
for (size_t i = 0; i < fields.size(); i++) {
|
||||
@ -1098,8 +1099,8 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode
|
||||
}
|
||||
return std::make_unique<InterfaceBlock>(intf.fOffset,
|
||||
var,
|
||||
id.fTypeName,
|
||||
id.fInstanceName,
|
||||
String(id.fTypeName),
|
||||
String(id.fInstanceName),
|
||||
arraySize,
|
||||
symbols);
|
||||
}
|
||||
@ -1334,8 +1335,7 @@ std::unique_ptr<Section> IRGenerator::convertSection(const ASTNode& s) {
|
||||
}
|
||||
|
||||
const ASTNode::SectionData& section = s.getSectionData();
|
||||
return std::make_unique<Section>(s.fOffset, section.fName, section.fArgument,
|
||||
section.fText);
|
||||
return std::make_unique<Section>(s.fOffset, section.fName, section.fArgument, section.fText);
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr,
|
||||
@ -1526,7 +1526,7 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(const ASTNode&
|
||||
// secondary swizzle to put them back into the right order, so in this case we end up with
|
||||
// 'float4(base.xw, 1, 0).xzyw'.
|
||||
std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expression> base,
|
||||
String fields) {
|
||||
StringFragment fields) {
|
||||
const int offset = base->fOffset;
|
||||
const Type& baseType = base->type();
|
||||
if (!baseType.isVector() && !baseType.isNumber()) {
|
||||
@ -1623,7 +1623,7 @@ std::unique_ptr<Expression> IRGenerator::convertTypeField(int offset, const Type
|
||||
}
|
||||
// ... and if that fails, check the intrinsics, add it to our shared elements
|
||||
if (!enumElement && !fIsBuiltinCode && fIntrinsics) {
|
||||
if (const ProgramElement* found = fIntrinsics->findAndInclude(type.name())) {
|
||||
if (const ProgramElement* found = fIntrinsics->findAndInclude(String(type.name()))) {
|
||||
fSharedElements->push_back(found);
|
||||
enumElement = found;
|
||||
}
|
||||
@ -1792,7 +1792,7 @@ void IRGenerator::findAndDeclareBuiltinVariables() {
|
||||
|
||||
bool visitExpression(const Expression& e) override {
|
||||
if (e.is<VariableReference>() && e.as<VariableReference>().variable()->isBuiltin()) {
|
||||
this->addDeclaringElement(e.as<VariableReference>().variable()->name());
|
||||
this->addDeclaringElement(String(e.as<VariableReference>().variable()->name()));
|
||||
}
|
||||
return INHERITED::visitExpression(e);
|
||||
}
|
||||
|
@ -222,7 +222,8 @@ private:
|
||||
std::unique_ptr<StructDefinition> convertStructDefinition(const ASTNode& expression);
|
||||
std::unique_ptr<Expression> convertTypeField(int offset, const Type& type,
|
||||
StringFragment field);
|
||||
std::unique_ptr<Expression> convertSwizzle(std::unique_ptr<Expression> base, String fields);
|
||||
std::unique_ptr<Expression> convertSwizzle(std::unique_ptr<Expression> base,
|
||||
StringFragment fields);
|
||||
std::unique_ptr<Expression> convertTernaryExpression(const ASTNode& expression);
|
||||
std::unique_ptr<Statement> convertVarDeclarationStatement(const ASTNode& s);
|
||||
std::unique_ptr<Statement> convertWhile(const ASTNode& w);
|
||||
|
@ -541,7 +541,7 @@ std::unique_ptr<Statement> Inliner::inlineStatement(int offset,
|
||||
// regard, but see `InlinerAvoidsVariableNameOverlap` for a counterexample where unique
|
||||
// names are important.
|
||||
const String* name = symbolTableForStatement->takeOwnershipOfString(
|
||||
fMangler.uniqueName(variable.name(), symbolTableForStatement));
|
||||
fMangler.uniqueName(String(variable.name()), symbolTableForStatement));
|
||||
auto clonedVar = std::make_unique<Variable>(
|
||||
offset,
|
||||
&variable.modifiers(),
|
||||
@ -640,7 +640,7 @@ Inliner::InlinedCall Inliner::inlineCall(FunctionCall* call,
|
||||
// for void-return functions, or in cases that are simple enough that we can just replace
|
||||
// the function-call node with the result expression.
|
||||
std::unique_ptr<Expression> noInitialValue;
|
||||
InlineVariable var = this->makeInlineVariable(function.declaration().name(),
|
||||
InlineVariable var = this->makeInlineVariable(String(function.declaration().name()),
|
||||
&function.declaration().returnType(),
|
||||
symbolTable.get(), Modifiers{},
|
||||
caller->isBuiltin(), &noInitialValue);
|
||||
@ -665,7 +665,7 @@ Inliner::InlinedCall Inliner::inlineCall(FunctionCall* call,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
InlineVariable var = this->makeInlineVariable(param->name(), &arguments[i]->type(),
|
||||
InlineVariable var = this->makeInlineVariable(String(param->name()), &arguments[i]->type(),
|
||||
symbolTable.get(), param->modifiers(),
|
||||
caller->isBuiltin(), &arguments[i]);
|
||||
inlineStatements.push_back(std::move(var.fVarDecl));
|
||||
|
@ -283,19 +283,19 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
|
||||
|
||||
SkSL::ProgramKind kind;
|
||||
const SkSL::String& inputPath = args[1];
|
||||
if (inputPath.endsWith(".vert")) {
|
||||
if (inputPath.ends_with(".vert")) {
|
||||
kind = SkSL::ProgramKind::kVertex;
|
||||
} else if (inputPath.endsWith(".frag") || inputPath.endsWith(".sksl")) {
|
||||
} else if (inputPath.ends_with(".frag") || inputPath.ends_with(".sksl")) {
|
||||
kind = SkSL::ProgramKind::kFragment;
|
||||
} else if (inputPath.endsWith(".geom")) {
|
||||
} else if (inputPath.ends_with(".geom")) {
|
||||
kind = SkSL::ProgramKind::kGeometry;
|
||||
} else if (inputPath.endsWith(".fp")) {
|
||||
} else if (inputPath.ends_with(".fp")) {
|
||||
kind = SkSL::ProgramKind::kFragmentProcessor;
|
||||
} else if (inputPath.endsWith(".rtb")) {
|
||||
} else if (inputPath.ends_with(".rtb")) {
|
||||
kind = SkSL::ProgramKind::kRuntimeBlend;
|
||||
} else if (inputPath.endsWith(".rtcf")) {
|
||||
} else if (inputPath.ends_with(".rtcf")) {
|
||||
kind = SkSL::ProgramKind::kRuntimeColorFilter;
|
||||
} else if (inputPath.endsWith(".rts")) {
|
||||
} else if (inputPath.ends_with(".rts")) {
|
||||
kind = SkSL::ProgramKind::kRuntimeShader;
|
||||
} else {
|
||||
printf("input filename must end in '.vert', '.frag', '.geom', '.fp', '.rtb', '.rtcf', "
|
||||
@ -350,13 +350,13 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
|
||||
return ResultCode::kSuccess;
|
||||
};
|
||||
|
||||
if (outputPath.endsWith(".spirv")) {
|
||||
if (outputPath.ends_with(".spirv")) {
|
||||
return compileProgram(
|
||||
[](SkSL::Compiler& compiler, SkSL::Program& program, SkSL::OutputStream& out) {
|
||||
return compiler.toSPIRV(program, out);
|
||||
});
|
||||
} else if (outputPath.endsWith(".asm.frag") || outputPath.endsWith(".asm.vert") ||
|
||||
outputPath.endsWith(".asm.geom")) {
|
||||
} else if (outputPath.ends_with(".asm.frag") || outputPath.ends_with(".asm.vert") ||
|
||||
outputPath.ends_with(".asm.geom")) {
|
||||
return compileProgram(
|
||||
[](SkSL::Compiler& compiler, SkSL::Program& program, SkSL::OutputStream& out) {
|
||||
// Compile program to SPIR-V assembly in a string-stream.
|
||||
@ -376,24 +376,24 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
|
||||
out.write(disassembly.data(), disassembly.size());
|
||||
return true;
|
||||
});
|
||||
} else if (outputPath.endsWith(".glsl")) {
|
||||
} else if (outputPath.ends_with(".glsl")) {
|
||||
return compileProgram(
|
||||
[](SkSL::Compiler& compiler, SkSL::Program& program, SkSL::OutputStream& out) {
|
||||
return compiler.toGLSL(program, out);
|
||||
});
|
||||
} else if (outputPath.endsWith(".metal")) {
|
||||
} else if (outputPath.ends_with(".metal")) {
|
||||
return compileProgram(
|
||||
[](SkSL::Compiler& compiler, SkSL::Program& program, SkSL::OutputStream& out) {
|
||||
return compiler.toMetal(program, out);
|
||||
});
|
||||
} else if (outputPath.endsWith(".h")) {
|
||||
} else if (outputPath.ends_with(".h")) {
|
||||
settings.fReplaceSettings = false;
|
||||
settings.fPermitInvalidStaticTests = true;
|
||||
return compileProgram(
|
||||
[&](SkSL::Compiler& compiler, SkSL::Program& program, SkSL::OutputStream& out) {
|
||||
return compiler.toH(program, base_name(inputPath.c_str(), "Gr", ".fp"), out);
|
||||
});
|
||||
} else if (outputPath.endsWith(".dsl.cpp")) {
|
||||
} else if (outputPath.ends_with(".dsl.cpp")) {
|
||||
settings.fReplaceSettings = false;
|
||||
settings.fPermitInvalidStaticTests = true;
|
||||
return compileProgram(
|
||||
@ -401,14 +401,14 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
|
||||
return compiler.toDSLCPP(program, base_name(inputPath.c_str(), "Gr", ".fp"),
|
||||
out);
|
||||
});
|
||||
} else if (outputPath.endsWith(".cpp")) {
|
||||
} else if (outputPath.ends_with(".cpp")) {
|
||||
settings.fReplaceSettings = false;
|
||||
settings.fPermitInvalidStaticTests = true;
|
||||
return compileProgram(
|
||||
[&](SkSL::Compiler& compiler, SkSL::Program& program, SkSL::OutputStream& out) {
|
||||
return compiler.toCPP(program, base_name(inputPath.c_str(), "Gr", ".fp"), out);
|
||||
});
|
||||
} else if (outputPath.endsWith(".skvm")) {
|
||||
} else if (outputPath.ends_with(".skvm")) {
|
||||
return compileProgram(
|
||||
[](SkSL::Compiler&, SkSL::Program& program, SkSL::OutputStream& out) {
|
||||
skvm::Builder builder{skvm::Features{}};
|
||||
@ -420,7 +420,7 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
|
||||
builder.done().dump(redirect.get());
|
||||
return true;
|
||||
});
|
||||
} else if (outputPath.endsWith(".stage")) {
|
||||
} else if (outputPath.ends_with(".stage")) {
|
||||
return compileProgram(
|
||||
[](SkSL::Compiler&, SkSL::Program& program, SkSL::OutputStream& out) {
|
||||
class Callbacks : public SkSL::PipelineStage::Callbacks {
|
||||
@ -433,7 +433,7 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
|
||||
|
||||
String declareUniform(const SkSL::VarDeclaration* decl) override {
|
||||
fOutput += decl->description();
|
||||
return decl->var().name();
|
||||
return String(decl->var().name());
|
||||
}
|
||||
|
||||
void defineFunction(const char* decl,
|
||||
@ -481,7 +481,7 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
|
||||
out.writeString(GrShaderUtils::PrettyPrint(callbacks.fOutput));
|
||||
return true;
|
||||
});
|
||||
} else if (outputPath.endsWith(".dehydrated.sksl")) {
|
||||
} else if (outputPath.ends_with(".dehydrated.sksl")) {
|
||||
SkSL::FileOutputStream out(outputPath);
|
||||
SkSL::Compiler compiler(caps);
|
||||
if (!out.isValid()) {
|
||||
@ -522,7 +522,7 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
|
||||
*/
|
||||
ResultCode processWorklist(const char* worklistPath) {
|
||||
SkSL::String inputPath(worklistPath);
|
||||
if (!inputPath.endsWith(".worklist")) {
|
||||
if (!inputPath.ends_with(".worklist")) {
|
||||
printf("expected .worklist file, found: %s\n\n", worklistPath);
|
||||
show_usage();
|
||||
return ResultCode::kConfigurationError;
|
||||
|
@ -14,7 +14,7 @@ String Mangler::uniqueName(String baseName, SymbolTable* symbolTable) {
|
||||
SkASSERT(symbolTable);
|
||||
// The inliner runs more than once, so the base name might already have been mangled and have a
|
||||
// prefix like "_123_x". Let's strip that prefix off to make the generated code easier to read.
|
||||
if (baseName.startsWith("_")) {
|
||||
if (baseName.starts_with("_")) {
|
||||
// Determine if we have a string of digits.
|
||||
int offset = 1;
|
||||
while (isdigit(baseName[offset])) {
|
||||
|
@ -335,14 +335,14 @@ ASTNode::ID Parser::section() {
|
||||
if (!this->expect(Token::Kind::TK_LBRACE, "'{'")) {
|
||||
return ASTNode::ID::Invalid();
|
||||
}
|
||||
StringFragment text;
|
||||
Token codeStart = this->nextRawToken();
|
||||
size_t startOffset = codeStart.fOffset;
|
||||
this->pushback(codeStart);
|
||||
text.fChars = fText.begin() + startOffset;
|
||||
int level = 1;
|
||||
for (;;) {
|
||||
Token next = this->nextRawToken();
|
||||
StringFragment text;
|
||||
Token next;
|
||||
while (level > 0) {
|
||||
next = this->nextRawToken();
|
||||
switch (next.fKind) {
|
||||
case Token::Kind::TK_LBRACE:
|
||||
++level;
|
||||
@ -356,14 +356,10 @@ ASTNode::ID Parser::section() {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!level) {
|
||||
text.fLength = next.fOffset - startOffset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
text = StringFragment(fText.begin() + startOffset, next.fOffset - startOffset);
|
||||
StringFragment name = this->text(start);
|
||||
++name.fChars;
|
||||
--name.fLength;
|
||||
name.remove_prefix(1);
|
||||
return this->createNode(start.fOffset, ASTNode::Kind::kSection,
|
||||
ASTNode::SectionData(name, argument, text));
|
||||
}
|
||||
@ -385,7 +381,7 @@ ASTNode::ID Parser::enumDeclaration() {
|
||||
if (!this->expect(Token::Kind::TK_LBRACE, "'{'")) {
|
||||
return ASTNode::ID::Invalid();
|
||||
}
|
||||
fSymbols.add(Type::MakeEnumType(this->text(name)));
|
||||
fSymbols.add(Type::MakeEnumType(String(this->text(name))));
|
||||
ASTNode::ID result = this->createNode(name.fOffset, ASTNode::Kind::kEnum, this->text(name));
|
||||
if (!this->checkNext(Token::Kind::TK_RBRACE)) {
|
||||
Token id;
|
||||
@ -629,7 +625,8 @@ ASTNode::ID Parser::structDeclaration() {
|
||||
"struct '" + this->text(name) + "' must contain at least one field");
|
||||
return ASTNode::ID::Invalid();
|
||||
}
|
||||
std::unique_ptr<Type> newType = Type::MakeStructType(name.fOffset, this->text(name), fields);
|
||||
std::unique_ptr<Type> newType = Type::MakeStructType(name.fOffset, String(this->text(name)),
|
||||
fields);
|
||||
if (struct_is_too_deeply_nested(*newType, kMaxStructDepth)) {
|
||||
this->error(name.fOffset, "struct '" + this->text(name) + "' is too deeply nested");
|
||||
return ASTNode::ID::Invalid();
|
||||
@ -809,7 +806,6 @@ StringFragment Parser::layoutCode() {
|
||||
Token start = this->nextRawToken();
|
||||
this->pushback(start);
|
||||
StringFragment code;
|
||||
code.fChars = fText.begin() + start.fOffset;
|
||||
int level = 1;
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
@ -836,7 +832,7 @@ StringFragment Parser::layoutCode() {
|
||||
done = true;
|
||||
}
|
||||
if (done) {
|
||||
code.fLength = next.fOffset - start.fOffset;
|
||||
code = StringFragment(fText.begin() + start.fOffset, next.fOffset - start.fOffset);
|
||||
this->pushback(std::move(next));
|
||||
}
|
||||
}
|
||||
@ -846,7 +842,7 @@ StringFragment Parser::layoutCode() {
|
||||
Layout::CType Parser::layoutCType() {
|
||||
if (this->expect(Token::Kind::TK_EQ, "'='")) {
|
||||
Token t = this->nextToken();
|
||||
String text = this->text(t);
|
||||
String text(this->text(t));
|
||||
auto found = layoutTokens->find(text);
|
||||
if (found != layoutTokens->end()) {
|
||||
switch (found->second) {
|
||||
@ -885,7 +881,7 @@ Layout Parser::layout() {
|
||||
}
|
||||
for (;;) {
|
||||
Token t = this->nextToken();
|
||||
String text = this->text(t);
|
||||
String text(this->text(t));
|
||||
auto setFlag = [&](Layout::Flag f) {
|
||||
if (flags & f) {
|
||||
this->error(t, "layout qualifier '" + text + "' appears more than once");
|
||||
@ -2021,11 +2017,10 @@ ASTNode::ID Parser::suffix(ASTNode::ID base) {
|
||||
// Swizzles that start with a constant number, e.g. '.000r', will be tokenized as
|
||||
// floating point literals, possibly followed by an identifier. Handle that here.
|
||||
StringFragment field = this->text(next);
|
||||
SkASSERT(field.fChars[0] == '.');
|
||||
++field.fChars;
|
||||
--field.fLength;
|
||||
for (size_t i = 0; i < field.fLength; ++i) {
|
||||
if (field.fChars[i] != '0' && field.fChars[i] != '1') {
|
||||
SkASSERT(field[0] == '.');
|
||||
field.remove_prefix(1);
|
||||
for (auto iter = field.begin(); iter != field.end(); ++iter) {
|
||||
if (*iter != '0' && *iter != '1') {
|
||||
this->error(next, "invalid swizzle");
|
||||
return ASTNode::ID::Invalid();
|
||||
}
|
||||
@ -2034,7 +2029,7 @@ ASTNode::ID Parser::suffix(ASTNode::ID base) {
|
||||
// identifiers that directly follow the float
|
||||
Token id = this->nextRawToken();
|
||||
if (id.fKind == Token::Kind::TK_IDENTIFIER) {
|
||||
field.fLength += id.fLength;
|
||||
field = StringFragment(field.data(), field.length() + id.fLength);
|
||||
} else {
|
||||
this->pushback(id);
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ const Symbol* Rehydrator::symbol() {
|
||||
uint16_t id = this->readU16();
|
||||
const Type* componentType = this->type();
|
||||
int8_t count = this->readS8();
|
||||
String name = componentType->name();
|
||||
String name(componentType->name());
|
||||
if (count == Type::kUnsizedArray) {
|
||||
name += "[]";
|
||||
} else {
|
||||
@ -164,7 +164,8 @@ const Symbol* Rehydrator::symbol() {
|
||||
case kEnumType_Command: {
|
||||
uint16_t id = this->readU16();
|
||||
StringFragment name = this->readString();
|
||||
const Type* result = fSymbolTable->takeOwnershipOfSymbol(Type::MakeEnumType(name));
|
||||
const Type* result =
|
||||
fSymbolTable->takeOwnershipOfSymbol(Type::MakeEnumType(String(name)));
|
||||
this->addSymbol(id, result);
|
||||
return result;
|
||||
}
|
||||
@ -199,7 +200,7 @@ const Symbol* Rehydrator::symbol() {
|
||||
}
|
||||
case kStructType_Command: {
|
||||
uint16_t id = this->readU16();
|
||||
StringFragment name = this->readString();
|
||||
String name(this->readString());
|
||||
uint8_t fieldCount = this->readU8();
|
||||
std::vector<Type::Field> fields;
|
||||
fields.reserve(fieldCount);
|
||||
@ -324,11 +325,12 @@ std::unique_ptr<ProgramElement> Rehydrator::element() {
|
||||
case Rehydrator::kInterfaceBlock_Command: {
|
||||
const Symbol* var = this->symbol();
|
||||
SkASSERT(var && var->is<Variable>());
|
||||
StringFragment typeName = this->readString();
|
||||
StringFragment instanceName = this->readString();
|
||||
String typeName(this->readString());
|
||||
String instanceName(this->readString());
|
||||
int arraySize = this->readS8();
|
||||
return std::make_unique<InterfaceBlock>(/*offset=*/-1, &var->as<Variable>(), typeName,
|
||||
instanceName, arraySize, nullptr);
|
||||
return std::make_unique<InterfaceBlock>(/*offset=*/-1, &var->as<Variable>(),
|
||||
std::move(typeName), std::move(instanceName),
|
||||
arraySize, nullptr);
|
||||
}
|
||||
case Rehydrator::kVarDeclarations_Command: {
|
||||
std::unique_ptr<Statement> decl = this->statement();
|
||||
@ -543,7 +545,7 @@ std::unique_ptr<Expression> Rehydrator::expression() {
|
||||
return PrefixExpression::Make(fContext, op, std::move(operand));
|
||||
}
|
||||
case Rehydrator::kSetting_Command: {
|
||||
StringFragment name = this->readString();
|
||||
String name(this->readString());
|
||||
return Setting::Convert(fContext, /*offset=*/-1, name);
|
||||
}
|
||||
case Rehydrator::kSwizzle_Command: {
|
||||
|
@ -38,15 +38,15 @@ SectionAndParameterHelper::SectionAndParameterHelper(const Program* program, Err
|
||||
}
|
||||
case ProgramElement::Kind::kSection: {
|
||||
const Section& s = p->as<Section>();
|
||||
const String& name = s.name();
|
||||
const String& arg = s.argument();
|
||||
if (IsSupportedSection(name.c_str())) {
|
||||
if (SectionRequiresArgument(name.c_str()) && !arg.size()) {
|
||||
StringFragment name = s.name();
|
||||
StringFragment arg = s.argument();
|
||||
if (IsSupportedSection(name)) {
|
||||
if (SectionRequiresArgument(name) && !arg.size()) {
|
||||
errors.error(s.fOffset,
|
||||
("section '@" + name +
|
||||
"' requires one parameter").c_str());
|
||||
}
|
||||
if (!SectionAcceptsArgument(name.c_str()) && arg.size()) {
|
||||
if (!SectionAcceptsArgument(name) && arg.size()) {
|
||||
errors.error(s.fOffset,
|
||||
("section '@" + name + "' has no parameters").c_str());
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ class SectionAndParameterHelper {
|
||||
public:
|
||||
SectionAndParameterHelper(const Program* program, ErrorReporter& errors);
|
||||
|
||||
const Section* getSection(const char* name) {
|
||||
const Section* getSection(StringFragment name) {
|
||||
auto found = fSections.find(name);
|
||||
if (found == fSections.end()) {
|
||||
return nullptr;
|
||||
@ -48,7 +48,7 @@ public:
|
||||
return found->second[0];
|
||||
}
|
||||
|
||||
std::vector<const Section*> getSections(const char* name) {
|
||||
std::vector<const Section*> getSections(StringFragment name) {
|
||||
auto found = fSections.find(name);
|
||||
if (found == fSections.end()) {
|
||||
return std::vector<const Section*>();
|
||||
@ -65,40 +65,38 @@ public:
|
||||
-1 == var.modifiers().fLayout.fBuiltin;
|
||||
}
|
||||
|
||||
static bool IsSupportedSection(const char* name) {
|
||||
return !strcmp(name, kClassSection) ||
|
||||
!strcmp(name, kCloneSection) ||
|
||||
!strcmp(name, kConstructorSection) ||
|
||||
!strcmp(name, kConstructorCodeSection) ||
|
||||
!strcmp(name, kConstructorParamsSection) ||
|
||||
!strcmp(name, kCppSection) ||
|
||||
!strcmp(name, kCppEndSection) ||
|
||||
!strcmp(name, kDumpInfoSection) ||
|
||||
!strcmp(name, kEmitCodeSection) ||
|
||||
!strcmp(name, kFieldsSection) ||
|
||||
!strcmp(name, kHeaderSection) ||
|
||||
!strcmp(name, kHeaderEndSection) ||
|
||||
!strcmp(name, kInitializersSection) ||
|
||||
!strcmp(name, kMakeSection) ||
|
||||
!strcmp(name, kOptimizationFlagsSection) ||
|
||||
!strcmp(name, kSetDataSection) ||
|
||||
!strcmp(name, kTestCodeSection);
|
||||
static bool IsSupportedSection(StringFragment name) {
|
||||
return name == kClassSection ||
|
||||
name == kCloneSection ||
|
||||
name == kConstructorSection ||
|
||||
name == kConstructorCodeSection ||
|
||||
name == kConstructorParamsSection ||
|
||||
name == kCppSection ||
|
||||
name == kCppEndSection ||
|
||||
name == kDumpInfoSection ||
|
||||
name == kEmitCodeSection ||
|
||||
name == kFieldsSection ||
|
||||
name == kHeaderSection ||
|
||||
name == kHeaderEndSection ||
|
||||
name == kInitializersSection ||
|
||||
name == kMakeSection ||
|
||||
name == kOptimizationFlagsSection ||
|
||||
name == kSetDataSection ||
|
||||
name == kTestCodeSection;
|
||||
}
|
||||
|
||||
static bool SectionAcceptsArgument(const char* name) {
|
||||
return !strcmp(name, kSetDataSection) ||
|
||||
!strcmp(name, kTestCodeSection);
|
||||
static bool SectionAcceptsArgument(StringFragment name) {
|
||||
return name == kSetDataSection || name == kTestCodeSection;
|
||||
}
|
||||
|
||||
static bool SectionRequiresArgument(const char* name) {
|
||||
return !strcmp(name, kSetDataSection) ||
|
||||
!strcmp(name, kTestCodeSection);
|
||||
static bool SectionRequiresArgument(StringFragment name) {
|
||||
return name == kSetDataSection || name == kTestCodeSection;
|
||||
}
|
||||
|
||||
private:
|
||||
const Program& fProgram;
|
||||
std::vector<const Variable*> fParameters;
|
||||
std::unordered_map<String, std::vector<const Section*>> fSections;
|
||||
std::unordered_map<StringFragment, std::vector<const Section*>> fSections;
|
||||
};
|
||||
|
||||
} // namespace SkSL
|
||||
|
@ -49,18 +49,6 @@ void String::vappendf(const char* fmt, va_list args) {
|
||||
va_end(reuse);
|
||||
}
|
||||
|
||||
bool StringFragment::startsWith(const char prefix[]) const {
|
||||
return !strncmp(fChars, prefix, strlen(prefix));
|
||||
}
|
||||
|
||||
bool StringFragment::endsWith(const char suffix[]) const {
|
||||
size_t suffixLength = strlen(suffix);
|
||||
if (fLength < suffixLength) {
|
||||
return false;
|
||||
}
|
||||
return !strncmp(fChars + fLength - suffixLength, suffix, suffixLength);
|
||||
}
|
||||
|
||||
bool String::consumeSuffix(const char suffix[]) {
|
||||
size_t suffixLength = strlen(suffix);
|
||||
if (this->length() < suffixLength) {
|
||||
@ -87,7 +75,7 @@ String String::operator+(const String& s) const {
|
||||
|
||||
String String::operator+(StringFragment s) const {
|
||||
String result(*this);
|
||||
result.append(s.fChars, s.fLength);
|
||||
result.append(s.data(), s.length());
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -107,98 +95,18 @@ String& String::operator+=(const String& s) {
|
||||
}
|
||||
|
||||
String& String::operator+=(StringFragment s) {
|
||||
this->append(s.fChars, s.fLength);
|
||||
this->append(s.data(), s.length());
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool String::operator==(const String& s) const {
|
||||
return this->size() == s.size() && !memcmp(c_str(), s.c_str(), this->size());
|
||||
}
|
||||
|
||||
bool String::operator!=(const String& s) const {
|
||||
return !(*this == s);
|
||||
}
|
||||
|
||||
bool String::operator==(const char* s) const {
|
||||
return this->size() == strlen(s) && !memcmp(c_str(), s, this->size());
|
||||
}
|
||||
|
||||
bool String::operator!=(const char* s) const {
|
||||
return !(*this == s);
|
||||
}
|
||||
|
||||
String operator+(const char* s1, const String& s2) {
|
||||
String result(s1);
|
||||
result.append(s2);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool operator==(const char* s1, const String& s2) {
|
||||
return s2 == s1;
|
||||
}
|
||||
|
||||
bool operator!=(const char* s1, const String& s2) {
|
||||
return s2 != s1;
|
||||
}
|
||||
|
||||
bool StringFragment::operator==(StringFragment s) const {
|
||||
if (fLength != s.fLength) {
|
||||
return false;
|
||||
}
|
||||
return !memcmp(fChars, s.fChars, fLength);
|
||||
}
|
||||
|
||||
bool StringFragment::operator!=(StringFragment s) const {
|
||||
if (fLength != s.fLength) {
|
||||
return true;
|
||||
}
|
||||
return memcmp(fChars, s.fChars, fLength);
|
||||
}
|
||||
|
||||
bool StringFragment::operator==(const char* s) const {
|
||||
for (size_t i = 0; i < fLength; ++i) {
|
||||
if (fChars[i] != s[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return 0 == s[fLength];
|
||||
}
|
||||
|
||||
bool StringFragment::operator!=(const char* s) const {
|
||||
for (size_t i = 0; i < fLength; ++i) {
|
||||
if (fChars[i] != s[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return 0 != s[fLength];
|
||||
}
|
||||
|
||||
bool StringFragment::operator<(StringFragment other) const {
|
||||
int comparison = strncmp(fChars, other.fChars, std::min(fLength, other.fLength));
|
||||
if (comparison) {
|
||||
return comparison < 0;
|
||||
}
|
||||
return fLength < other.fLength;
|
||||
}
|
||||
|
||||
String StringFragment::operator+(const char* other) const {
|
||||
return String(*this) + other;
|
||||
}
|
||||
|
||||
String StringFragment::operator+(const StringFragment& other) const {
|
||||
return String(*this) + other;
|
||||
}
|
||||
|
||||
String StringFragment::operator+(const String& other) const {
|
||||
return String(*this) + other;
|
||||
}
|
||||
|
||||
bool operator==(const char* s1, StringFragment s2) {
|
||||
return s2 == s1;
|
||||
}
|
||||
|
||||
bool operator!=(const char* s1, StringFragment s2) {
|
||||
return s2 != s1;
|
||||
String operator+(StringFragment left, StringFragment right) {
|
||||
return String(left) + right;
|
||||
}
|
||||
|
||||
String to_string(int32_t value) {
|
||||
|
@ -63,7 +63,7 @@ bool CPPCodeGenerator::usesPrecisionModifiers() const {
|
||||
}
|
||||
|
||||
String CPPCodeGenerator::getTypeName(const Type& type) {
|
||||
return type.name();
|
||||
return String(type.name());
|
||||
}
|
||||
|
||||
void CPPCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
|
||||
@ -227,7 +227,7 @@ void CPPCodeGenerator::writeRuntimeValue(const Type& type, const Layout& layout,
|
||||
|
||||
void CPPCodeGenerator::writeVarInitializer(const Variable& var, const Expression& value) {
|
||||
if (is_private(var)) {
|
||||
this->writeRuntimeValue(var.type(), var.modifiers().fLayout, var.name());
|
||||
this->writeRuntimeValue(var.type(), var.modifiers().fLayout, String(var.name()));
|
||||
} else {
|
||||
this->writeExpression(value, Precedence::kTopLevel);
|
||||
}
|
||||
@ -268,11 +268,11 @@ void CPPCodeGenerator::writeVariableReference(const VariableReference& ref) {
|
||||
const Variable& var = *ref.variable();
|
||||
if (var.modifiers().fFlags & Modifiers::kUniform_Flag) {
|
||||
this->write("%s");
|
||||
String name = var.name();
|
||||
String name(var.name());
|
||||
String varCode = String::printf("args.fUniformHandler->getUniformCStr(%sVar)",
|
||||
HCodeGenerator::FieldName(name.c_str()).c_str());
|
||||
String code;
|
||||
if (var.modifiers().fLayout.fWhen.fLength) {
|
||||
if (var.modifiers().fLayout.fWhen.length()) {
|
||||
code = String::printf("%sVar.isValid() ? %s : \"%s\"",
|
||||
HCodeGenerator::FieldName(name.c_str()).c_str(),
|
||||
varCode.c_str(),
|
||||
@ -456,7 +456,7 @@ void CPPCodeGenerator::prepareHelperFunction(const FunctionDeclaration& decl) {
|
||||
return;
|
||||
}
|
||||
|
||||
String funcName = decl.name();
|
||||
String funcName(decl.name());
|
||||
this->addExtraEmitCodeLine(
|
||||
String::printf("SkString %s_name = fragBuilder->getMangledFunctionName(\"%s\");",
|
||||
funcName.c_str(),
|
||||
@ -465,7 +465,7 @@ void CPPCodeGenerator::prepareHelperFunction(const FunctionDeclaration& decl) {
|
||||
String args = String::printf("const GrShaderVar %s_args[] = { ", funcName.c_str());
|
||||
const char* separator = "";
|
||||
for (const Variable* param : decl.parameters()) {
|
||||
String paramName = param->name();
|
||||
String paramName(param->name());
|
||||
args.appendf("%sGrShaderVar(\"%s\", %s)", separator, paramName.c_str(),
|
||||
glsltype_string(fContext, param->type()));
|
||||
separator = ", ";
|
||||
@ -476,7 +476,7 @@ void CPPCodeGenerator::prepareHelperFunction(const FunctionDeclaration& decl) {
|
||||
}
|
||||
|
||||
void CPPCodeGenerator::prototypeHelperFunction(const FunctionDeclaration& decl) {
|
||||
String funcName = decl.name();
|
||||
String funcName(decl.name());
|
||||
this->addExtraEmitCodeLine(String::printf(
|
||||
"fragBuilder->emitFunctionPrototype(%s, %s_name.c_str(), {%s_args, %zu});",
|
||||
glsltype_string(fContext, decl.returnType()),
|
||||
@ -512,7 +512,7 @@ void CPPCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
||||
}
|
||||
|
||||
fOut = oldOut;
|
||||
String funcName = decl.name();
|
||||
String funcName(decl.name());
|
||||
|
||||
String funcImpl;
|
||||
if (!fFormatArgs.empty()) {
|
||||
@ -576,7 +576,7 @@ void CPPCodeGenerator::addUniform(const Variable& var) {
|
||||
if (!needs_uniform_var(var)) {
|
||||
return;
|
||||
}
|
||||
if (var.modifiers().fLayout.fWhen.fLength) {
|
||||
if (var.modifiers().fLayout.fWhen.length()) {
|
||||
this->writef(" if (%s) {\n ", String(var.modifiers().fLayout.fWhen).c_str());
|
||||
}
|
||||
String name(var.name());
|
||||
@ -594,7 +594,7 @@ void CPPCodeGenerator::addUniform(const Variable& var) {
|
||||
name.c_str(),
|
||||
var.type().columns());
|
||||
}
|
||||
if (var.modifiers().fLayout.fWhen.fLength) {
|
||||
if (var.modifiers().fLayout.fWhen.length()) {
|
||||
this->write(" }\n");
|
||||
}
|
||||
}
|
||||
@ -946,7 +946,8 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
|
||||
}
|
||||
|
||||
this->writef("%s%s;\n",
|
||||
indent.c_str(), mapper->setUniform(pdman, uniformName, valueVar).c_str());
|
||||
indent.c_str(),
|
||||
mapper->setUniform(String(pdman), uniformName, valueVar).c_str());
|
||||
|
||||
if (conditionalUniform) {
|
||||
// Close the earlier precheck block
|
||||
@ -1044,7 +1045,7 @@ void CPPCodeGenerator::writeDumpInfo() {
|
||||
String fieldName = HCodeGenerator::FieldName(String(param->name()).c_str());
|
||||
String runtimeValue = this->formatRuntimeValue(param->type(),
|
||||
param->modifiers().fLayout,
|
||||
param->name(),
|
||||
String(param->name()),
|
||||
&argumentList);
|
||||
formatString.appendf("%s%s=%s",
|
||||
formatString.empty() ? "" : ", ",
|
||||
@ -1151,7 +1152,7 @@ void CPPCodeGenerator::writeGetKey() {
|
||||
}
|
||||
this->write(";\n");
|
||||
}
|
||||
if (var.modifiers().fLayout.fWhen.fLength) {
|
||||
if (var.modifiers().fLayout.fWhen.length()) {
|
||||
this->writef("if (%s) {", String(var.modifiers().fLayout.fWhen).c_str());
|
||||
}
|
||||
if (varType == *fContext.fTypes.fHalf4) {
|
||||
@ -1184,7 +1185,7 @@ void CPPCodeGenerator::writeGetKey() {
|
||||
SK_ABORT("NOT YET IMPLEMENTED: automatic key handling for %s\n",
|
||||
varType.displayName().c_str());
|
||||
}
|
||||
if (var.modifiers().fLayout.fWhen.fLength) {
|
||||
if (var.modifiers().fLayout.fWhen.length()) {
|
||||
this->write("}");
|
||||
}
|
||||
}
|
||||
|
@ -546,7 +546,7 @@ void DSLCPPCodeGenerator::writeCppInitialValue(const Variable& var) {
|
||||
// the variable (which we do need, to fill in the Var's initial value).
|
||||
std::vector<String> argumentList;
|
||||
(void) this->formatRuntimeValue(var.type(), var.modifiers().fLayout,
|
||||
var.name(), &argumentList);
|
||||
String(var.name()), &argumentList);
|
||||
|
||||
this->write(this->getTypeName(var.type()));
|
||||
this->write("(");
|
||||
@ -690,7 +690,7 @@ void DSLCPPCodeGenerator::writeAnyConstructor(const AnyConstructor& c,
|
||||
|
||||
String DSLCPPCodeGenerator::getTypeName(const Type& type) {
|
||||
if (fCPPMode) {
|
||||
return type.name();
|
||||
return String(type.name());
|
||||
}
|
||||
switch (type.typeKind()) {
|
||||
case Type::TypeKind::kScalar:
|
||||
@ -711,7 +711,7 @@ String DSLCPPCodeGenerator::getTypeName(const Type& type) {
|
||||
|
||||
default:
|
||||
SK_ABORT("not yet supported: getTypeName of %s", type.displayName().c_str());
|
||||
return type.name();
|
||||
return String(type.name());
|
||||
}
|
||||
}
|
||||
|
||||
@ -741,7 +741,7 @@ String DSLCPPCodeGenerator::getDSLType(const Type& type) {
|
||||
}
|
||||
default:
|
||||
SK_ABORT("not yet supported: getDSLType of %s", type.displayName().c_str());
|
||||
return type.name();
|
||||
return String(type.name());
|
||||
}
|
||||
}
|
||||
|
||||
@ -889,7 +889,7 @@ void DSLCPPCodeGenerator::addUniform(const Variable& var) {
|
||||
}
|
||||
|
||||
const char* varCppName = this->getVariableCppName(var);
|
||||
if (var.modifiers().fLayout.fWhen.fLength) {
|
||||
if (var.modifiers().fLayout.fWhen.length()) {
|
||||
// In cases where the `when` clause is true, we set up the Var normally.
|
||||
this->writef(
|
||||
"Var %s;\n"
|
||||
@ -906,7 +906,7 @@ void DSLCPPCodeGenerator::addUniform(const Variable& var) {
|
||||
this->writef("%.*sVar = VarUniformHandle(%s);\n",
|
||||
(int)var.name().size(), var.name().data(), this->getVariableCppName(var));
|
||||
|
||||
if (var.modifiers().fLayout.fWhen.fLength) {
|
||||
if (var.modifiers().fLayout.fWhen.length()) {
|
||||
this->writef(" DeclareGlobal(%s);\n", varCppName);
|
||||
// In cases where the `when` is false, we declare the Var as a const with a default value.
|
||||
this->writef("} else {\n"
|
||||
@ -1068,7 +1068,8 @@ void DSLCPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
|
||||
}
|
||||
|
||||
this->writef("%s%s;\n",
|
||||
indent.c_str(), mapper->setUniform(pdman, uniformName, valueVar).c_str());
|
||||
indent.c_str(),
|
||||
mapper->setUniform(String(pdman), uniformName, valueVar).c_str());
|
||||
|
||||
if (conditionalUniform) {
|
||||
// Close the earlier precheck block
|
||||
@ -1165,7 +1166,7 @@ void DSLCPPCodeGenerator::writeDumpInfo() {
|
||||
String fieldName = HCodeGenerator::FieldName(String(param->name()).c_str());
|
||||
String runtimeValue = this->formatRuntimeValue(param->type(),
|
||||
param->modifiers().fLayout,
|
||||
param->name(),
|
||||
String(param->name()),
|
||||
&argumentList);
|
||||
formatString.appendf("%s%s=%s",
|
||||
formatString.empty() ? "" : ", ",
|
||||
@ -1271,7 +1272,7 @@ void DSLCPPCodeGenerator::writeGetKey() {
|
||||
}
|
||||
this->write(";\n");
|
||||
}
|
||||
if (var.modifiers().fLayout.fWhen.fLength) {
|
||||
if (var.modifiers().fLayout.fWhen.length()) {
|
||||
this->writef("if (%s) {\n", String(var.modifiers().fLayout.fWhen).c_str());
|
||||
}
|
||||
if (varType == *fContext.fTypes.fHalf4) {
|
||||
@ -1304,7 +1305,7 @@ void DSLCPPCodeGenerator::writeGetKey() {
|
||||
SK_ABORT("NOT YET IMPLEMENTED: automatic key handling for %s\n",
|
||||
varType.displayName().c_str());
|
||||
}
|
||||
if (var.modifiers().fLayout.fWhen.fLength) {
|
||||
if (var.modifiers().fLayout.fWhen.length()) {
|
||||
this->write("}\n");
|
||||
}
|
||||
}
|
||||
|
@ -24,30 +24,8 @@
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
void GLSLCodeGenerator::write(const char* s) {
|
||||
if (s[0] == 0) {
|
||||
return;
|
||||
}
|
||||
if (fAtLineStart) {
|
||||
for (int i = 0; i < fIndentation; i++) {
|
||||
fOut->writeText(" ");
|
||||
}
|
||||
}
|
||||
fOut->writeText(s);
|
||||
fAtLineStart = false;
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeLine(const char* s) {
|
||||
this->write(s);
|
||||
this->writeLine();
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::write(const String& s) {
|
||||
this->write(s.c_str());
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::write(StringFragment s) {
|
||||
if (!s.fLength) {
|
||||
if (!s.length()) {
|
||||
return;
|
||||
}
|
||||
if (fAtLineStart) {
|
||||
@ -55,15 +33,12 @@ void GLSLCodeGenerator::write(StringFragment s) {
|
||||
fOut->writeText(" ");
|
||||
}
|
||||
}
|
||||
fOut->write(s.fChars, s.fLength);
|
||||
fOut->write(s.data(), s.length());
|
||||
fAtLineStart = false;
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeLine(const String& s) {
|
||||
this->writeLine(s.c_str());
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeLine() {
|
||||
void GLSLCodeGenerator::writeLine(StringFragment s) {
|
||||
this->write(s);
|
||||
fOut->writeText(fLineEnding);
|
||||
fAtLineStart = true;
|
||||
}
|
||||
@ -74,13 +49,9 @@ void GLSLCodeGenerator::finishLine() {
|
||||
}
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeExtension(const String& name) {
|
||||
this->writeExtension(name, true);
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeExtension(const String& name, bool require) {
|
||||
void GLSLCodeGenerator::writeExtension(StringFragment name, bool require) {
|
||||
fExtensions.writeText("#extension ");
|
||||
fExtensions.write(name.c_str(), name.length());
|
||||
fExtensions.write(name.data(), name.length());
|
||||
fExtensions.writeText(require ? " : require\n" : " : enable\n");
|
||||
}
|
||||
|
||||
@ -145,14 +116,14 @@ String GLSLCodeGenerator::getTypeName(const Type& type) {
|
||||
return "uint";
|
||||
}
|
||||
else {
|
||||
return type.name();
|
||||
return String(type.name());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Type::TypeKind::kEnum:
|
||||
return "int";
|
||||
default:
|
||||
return type.name();
|
||||
return String(type.name());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,17 +64,9 @@ public:
|
||||
protected:
|
||||
using Precedence = Operator::Precedence;
|
||||
|
||||
void write(const char* s);
|
||||
|
||||
void writeLine();
|
||||
|
||||
void writeLine(const char* s);
|
||||
|
||||
void write(const String& s);
|
||||
|
||||
void write(StringFragment s);
|
||||
|
||||
void writeLine(const String& s);
|
||||
void writeLine(StringFragment s = StringFragment());
|
||||
|
||||
void finishLine();
|
||||
|
||||
@ -88,9 +80,7 @@ protected:
|
||||
|
||||
void writeType(const Type& type);
|
||||
|
||||
void writeExtension(const String& name);
|
||||
|
||||
void writeExtension(const String& name, bool require);
|
||||
void writeExtension(StringFragment name, bool require = true);
|
||||
|
||||
void writeInterfaceBlock(const InterfaceBlock& intf);
|
||||
|
||||
|
@ -41,7 +41,7 @@ String HCodeGenerator::ParameterType(const Context& context, const Type& type,
|
||||
if (ctype != Layout::CType::kDefault) {
|
||||
return Layout::CTypeToStr(ctype);
|
||||
}
|
||||
return type.name();
|
||||
return String(type.name());
|
||||
}
|
||||
|
||||
Layout::CType HCodeGenerator::ParameterCType(const Context& context, const Type& type,
|
||||
@ -122,7 +122,8 @@ void HCodeGenerator::writef(const char* s, ...) {
|
||||
bool HCodeGenerator::writeSection(const char* name, const char* prefix) {
|
||||
const Section* s = fSectionAndParameterHelper.getSection(name);
|
||||
if (s) {
|
||||
this->writef("%s%.*s", prefix, (int)s->text().length(), s->text().data());
|
||||
this->writef("%s", prefix);
|
||||
this->writef("%.*s", (int)s->text().length(), s->text().data());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -38,14 +38,14 @@ const char* MetalCodeGenerator::OperatorName(Operator op) {
|
||||
class MetalCodeGenerator::GlobalStructVisitor {
|
||||
public:
|
||||
virtual ~GlobalStructVisitor() = default;
|
||||
virtual void visitInterfaceBlock(const InterfaceBlock& block, const String& blockName) = 0;
|
||||
virtual void visitTexture(const Type& type, const String& name) = 0;
|
||||
virtual void visitSampler(const Type& type, const String& name) = 0;
|
||||
virtual void visitInterfaceBlock(const InterfaceBlock& block, StringFragment blockName) = 0;
|
||||
virtual void visitTexture(const Type& type, StringFragment name) = 0;
|
||||
virtual void visitSampler(const Type& type, StringFragment name) = 0;
|
||||
virtual void visitVariable(const Variable& var, const Expression* value) = 0;
|
||||
};
|
||||
|
||||
void MetalCodeGenerator::write(const char* s) {
|
||||
if (!s[0]) {
|
||||
void MetalCodeGenerator::write(StringFragment s) {
|
||||
if (s.empty()) {
|
||||
return;
|
||||
}
|
||||
if (fAtLineStart) {
|
||||
@ -53,24 +53,12 @@ void MetalCodeGenerator::write(const char* s) {
|
||||
fOut->writeText(" ");
|
||||
}
|
||||
}
|
||||
fOut->writeText(s);
|
||||
fOut->writeText(String(s).c_str());
|
||||
fAtLineStart = false;
|
||||
}
|
||||
|
||||
void MetalCodeGenerator::writeLine(const char* s) {
|
||||
void MetalCodeGenerator::writeLine(StringFragment s) {
|
||||
this->write(s);
|
||||
this->writeLine();
|
||||
}
|
||||
|
||||
void MetalCodeGenerator::write(const String& s) {
|
||||
this->write(s.c_str());
|
||||
}
|
||||
|
||||
void MetalCodeGenerator::writeLine(const String& s) {
|
||||
this->writeLine(s.c_str());
|
||||
}
|
||||
|
||||
void MetalCodeGenerator::writeLine() {
|
||||
fOut->writeText(fLineEnding);
|
||||
fAtLineStart = true;
|
||||
}
|
||||
@ -108,9 +96,9 @@ String MetalCodeGenerator::typeName(const Type& type) {
|
||||
default:
|
||||
if (type == *fContext.fTypes.fHalf) {
|
||||
// FIXME - Currently only supporting floats in MSL to avoid type coercion issues.
|
||||
return fContext.fTypes.fFloat->name();
|
||||
return String(fContext.fTypes.fFloat->name());
|
||||
} else {
|
||||
return type.name();
|
||||
return String(type.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1872,7 +1860,7 @@ void MetalCodeGenerator::writeVarInitializer(const Variable& var, const Expressi
|
||||
this->writeExpression(value, Precedence::kTopLevel);
|
||||
}
|
||||
|
||||
void MetalCodeGenerator::writeName(const String& name) {
|
||||
void MetalCodeGenerator::writeName(StringFragment name) {
|
||||
if (fReservedWords.find(name) != fReservedWords.end()) {
|
||||
this->write("_"); // adding underscore before name to avoid conflict with reserved words
|
||||
}
|
||||
@ -2207,7 +2195,7 @@ void MetalCodeGenerator::visitGlobalStruct(GlobalStructVisitor* visitor) {
|
||||
if (var.type().typeKind() == Type::TypeKind::kSampler) {
|
||||
// Samplers are represented as a "texture/sampler" duo in the global struct.
|
||||
visitor->visitTexture(var.type(), var.name());
|
||||
visitor->visitSampler(var.type(), String(var.name()) + SAMPLER_SUFFIX);
|
||||
visitor->visitSampler(var.type(), var.name() + SAMPLER_SUFFIX);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2222,7 +2210,7 @@ void MetalCodeGenerator::visitGlobalStruct(GlobalStructVisitor* visitor) {
|
||||
void MetalCodeGenerator::writeGlobalStruct() {
|
||||
class : public GlobalStructVisitor {
|
||||
public:
|
||||
void visitInterfaceBlock(const InterfaceBlock& block, const String& blockName) override {
|
||||
void visitInterfaceBlock(const InterfaceBlock& block, StringFragment blockName) override {
|
||||
this->addElement();
|
||||
fCodeGen->write(" constant ");
|
||||
fCodeGen->write(block.typeName());
|
||||
@ -2230,7 +2218,7 @@ void MetalCodeGenerator::writeGlobalStruct() {
|
||||
fCodeGen->writeName(blockName);
|
||||
fCodeGen->write(";\n");
|
||||
}
|
||||
void visitTexture(const Type& type, const String& name) override {
|
||||
void visitTexture(const Type& type, StringFragment name) override {
|
||||
this->addElement();
|
||||
fCodeGen->write(" ");
|
||||
fCodeGen->writeType(type);
|
||||
@ -2238,7 +2226,7 @@ void MetalCodeGenerator::writeGlobalStruct() {
|
||||
fCodeGen->writeName(name);
|
||||
fCodeGen->write(";\n");
|
||||
}
|
||||
void visitSampler(const Type&, const String& name) override {
|
||||
void visitSampler(const Type&, StringFragment name) override {
|
||||
this->addElement();
|
||||
fCodeGen->write(" sampler ");
|
||||
fCodeGen->writeName(name);
|
||||
@ -2279,16 +2267,16 @@ void MetalCodeGenerator::writeGlobalInit() {
|
||||
class : public GlobalStructVisitor {
|
||||
public:
|
||||
void visitInterfaceBlock(const InterfaceBlock& blockType,
|
||||
const String& blockName) override {
|
||||
StringFragment blockName) override {
|
||||
this->addElement();
|
||||
fCodeGen->write("&");
|
||||
fCodeGen->writeName(blockName);
|
||||
}
|
||||
void visitTexture(const Type&, const String& name) override {
|
||||
void visitTexture(const Type&, StringFragment name) override {
|
||||
this->addElement();
|
||||
fCodeGen->writeName(name);
|
||||
}
|
||||
void visitSampler(const Type&, const String& name) override {
|
||||
void visitSampler(const Type&, StringFragment name) override {
|
||||
this->addElement();
|
||||
fCodeGen->writeName(name);
|
||||
}
|
||||
|
@ -83,15 +83,9 @@ protected:
|
||||
class GlobalStructVisitor;
|
||||
void visitGlobalStruct(GlobalStructVisitor* visitor);
|
||||
|
||||
void write(const char* s);
|
||||
void write(StringFragment s);
|
||||
|
||||
void writeLine();
|
||||
|
||||
void writeLine(const char* s);
|
||||
|
||||
void write(const String& s);
|
||||
|
||||
void writeLine(const String& s);
|
||||
void writeLine(StringFragment s = StringFragment());
|
||||
|
||||
void finishLine();
|
||||
|
||||
@ -149,7 +143,7 @@ protected:
|
||||
|
||||
void writeVarInitializer(const Variable& var, const Expression& value);
|
||||
|
||||
void writeName(const String& name);
|
||||
void writeName(StringFragment name);
|
||||
|
||||
void writeVarDeclaration(const VarDeclaration& decl);
|
||||
|
||||
@ -272,7 +266,7 @@ protected:
|
||||
|
||||
int getUniformSet(const Modifiers& m);
|
||||
|
||||
std::unordered_set<String> fReservedWords;
|
||||
std::unordered_set<StringFragment> fReservedWords;
|
||||
std::unordered_map<const Type::Field*, const InterfaceBlock*> fInterfaceBlockMap;
|
||||
std::unordered_map<const InterfaceBlock*, String> fInterfaceBlockNameMap;
|
||||
int fAnonInterfaceCount = 0;
|
||||
|
@ -57,10 +57,8 @@ public:
|
||||
private:
|
||||
using Precedence = Operator::Precedence;
|
||||
|
||||
void write(const char* s);
|
||||
void writeLine(const char* s = nullptr);
|
||||
void write(const String& s);
|
||||
void write(StringFragment s);
|
||||
void writeLine(StringFragment s = StringFragment());
|
||||
|
||||
String typeName(const Type& type);
|
||||
void writeType(const Type& type);
|
||||
@ -126,23 +124,14 @@ private:
|
||||
bool fCastReturnsToHalf = false;
|
||||
};
|
||||
|
||||
void PipelineStageCodeGenerator::write(const char* s) {
|
||||
fBuffer->writeText(s);
|
||||
}
|
||||
|
||||
void PipelineStageCodeGenerator::writeLine(const char* s) {
|
||||
if (s) {
|
||||
fBuffer->writeText(s);
|
||||
}
|
||||
fBuffer->writeText("\n");
|
||||
}
|
||||
|
||||
void PipelineStageCodeGenerator::write(const String& s) {
|
||||
void PipelineStageCodeGenerator::write(StringFragment s) {
|
||||
fBuffer->write(s.data(), s.length());
|
||||
}
|
||||
|
||||
void PipelineStageCodeGenerator::write(StringFragment s) {
|
||||
fBuffer->write(s.fChars, s.fLength);
|
||||
void PipelineStageCodeGenerator::writeLine(StringFragment s) {
|
||||
fBuffer->write(s.data(), s.length());
|
||||
fBuffer->writeText("\n");
|
||||
}
|
||||
|
||||
void PipelineStageCodeGenerator::writeFunctionCall(const FunctionCall& c) {
|
||||
@ -285,7 +274,7 @@ void PipelineStageCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
||||
fCastReturnsToHalf = false;
|
||||
}
|
||||
|
||||
String fnName = decl.isMain() ? decl.name()
|
||||
String fnName = decl.isMain() ? String(decl.name())
|
||||
: fCallbacks->getMangledName(String(decl.name()).c_str());
|
||||
|
||||
// This is similar to decl.description(), but substitutes a mangled name, and handles modifiers
|
||||
@ -391,7 +380,7 @@ String PipelineStageCodeGenerator::typeName(const Type& type) {
|
||||
}
|
||||
|
||||
auto it = fStructNames.find(&type);
|
||||
return it != fStructNames.end() ? it->second : type.name();
|
||||
return it != fStructNames.end() ? it->second : String(type.name());
|
||||
}
|
||||
|
||||
void PipelineStageCodeGenerator::writeType(const Type& type) {
|
||||
|
@ -273,9 +273,9 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, OutputSt
|
||||
this->writeWord(word1, out);
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeString(const char* string, size_t length, OutputStream& out) {
|
||||
out.write(string, length);
|
||||
switch (length % 4) {
|
||||
void SPIRVCodeGenerator::writeString(StringFragment s, OutputStream& out) {
|
||||
out.write(s.data(), s.length());
|
||||
switch (s.length() % 4) {
|
||||
case 1:
|
||||
out.write8(0);
|
||||
[[fallthrough]];
|
||||
@ -291,24 +291,24 @@ void SPIRVCodeGenerator::writeString(const char* string, size_t length, OutputSt
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, StringFragment string, OutputStream& out) {
|
||||
this->writeOpCode(opCode, 1 + (string.fLength + 4) / 4, out);
|
||||
this->writeString(string.fChars, string.fLength, out);
|
||||
this->writeOpCode(opCode, 1 + (string.length() + 4) / 4, out);
|
||||
this->writeString(string, out);
|
||||
}
|
||||
|
||||
|
||||
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, StringFragment string,
|
||||
OutputStream& out) {
|
||||
this->writeOpCode(opCode, 2 + (string.fLength + 4) / 4, out);
|
||||
this->writeOpCode(opCode, 2 + (string.length() + 4) / 4, out);
|
||||
this->writeWord(word1, out);
|
||||
this->writeString(string.fChars, string.fLength, out);
|
||||
this->writeString(string, out);
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2,
|
||||
StringFragment string, OutputStream& out) {
|
||||
this->writeOpCode(opCode, 3 + (string.fLength + 4) / 4, out);
|
||||
this->writeOpCode(opCode, 3 + (string.length() + 4) / 4, out);
|
||||
this->writeWord(word1, out);
|
||||
this->writeWord(word2, out);
|
||||
this->writeString(string.fChars, string.fLength, out);
|
||||
this->writeString(string, out);
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2,
|
||||
@ -510,7 +510,7 @@ SpvId SPIRVCodeGenerator::getType(const Type& type) {
|
||||
|
||||
SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layout) {
|
||||
const Type& type = this->getActualType(rawType);
|
||||
String key = type.name();
|
||||
String key(type.name());
|
||||
if (type.isStruct() || type.isArray()) {
|
||||
key += to_string((int)layout.fStd);
|
||||
#ifdef SK_DEBUG
|
||||
@ -2065,7 +2065,7 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
/*invocations=*/-1, /*when=*/"", Layout::CType::kDefault),
|
||||
/*flags=*/0),
|
||||
SKSL_RTHEIGHT_NAME, fContext.fTypes.fFloat.get());
|
||||
StringFragment name("sksl_synthetic_uniforms");
|
||||
String name("sksl_synthetic_uniforms");
|
||||
std::unique_ptr<Type> intfStruct = Type::MakeStructType(/*offset=*/-1, name,
|
||||
fields);
|
||||
int binding = fProgram.fConfig->fSettings.fRTHeightBinding;
|
||||
@ -2092,8 +2092,11 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
intfStruct.get(),
|
||||
/*builtin=*/false,
|
||||
Variable::Storage::kGlobal));
|
||||
InterfaceBlock intf(/*offset=*/-1, intfVar, name,
|
||||
/*instanceName=*/"", /*arraySize=*/0,
|
||||
InterfaceBlock intf(/*offset=*/-1,
|
||||
intfVar,
|
||||
name,
|
||||
/*instanceName=*/"",
|
||||
/*arraySize=*/0,
|
||||
std::make_shared<SymbolTable>(&fErrors, /*builtin=*/false));
|
||||
|
||||
fRTHeightStructId = this->writeInterfaceBlock(intf, false);
|
||||
@ -3063,7 +3066,8 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf, bool a
|
||||
fRTHeightStorageClass = storageClass;
|
||||
fields.emplace_back(Modifiers(), StringFragment(SKSL_RTHEIGHT_NAME),
|
||||
fContext.fTypes.fFloat.get());
|
||||
rtHeightStructType = Type::MakeStructType(type->fOffset, type->name(), std::move(fields));
|
||||
rtHeightStructType = Type::MakeStructType(type->fOffset, String(type->name()),
|
||||
std::move(fields));
|
||||
type = rtHeightStructType.get();
|
||||
}
|
||||
SpvId typeId;
|
||||
@ -3626,7 +3630,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
this->writeCapabilities(out);
|
||||
this->writeInstruction(SpvOpExtInstImport, fGLSLExtendedInstructions, "GLSL.std.450", out);
|
||||
this->writeInstruction(SpvOpMemoryModel, SpvAddressingModelLogical, SpvMemoryModelGLSL450, out);
|
||||
this->writeOpCode(SpvOpEntryPoint, (SpvId) (3 + (main->name().fLength + 4) / 4) +
|
||||
this->writeOpCode(SpvOpEntryPoint, (SpvId) (3 + (main->name().length() + 4) / 4) +
|
||||
(int32_t) interfaceVars.size(), out);
|
||||
switch (program.fConfig->fKind) {
|
||||
case ProgramKind::kVertex:
|
||||
@ -3643,7 +3647,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
}
|
||||
SpvId entryPoint = fFunctionMap[main];
|
||||
this->writeWord(entryPoint, out);
|
||||
this->writeString(main->name().fChars, main->name().fLength, out);
|
||||
this->writeString(main->name(), out);
|
||||
for (int var : interfaceVars) {
|
||||
this->writeWord(var, out);
|
||||
}
|
||||
@ -3658,7 +3662,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
}
|
||||
for (const ProgramElement* e : program.elements()) {
|
||||
if (e->is<Extension>()) {
|
||||
this->writeInstruction(SpvOpSourceExtension, e->as<Extension>().name().c_str(), out);
|
||||
this->writeInstruction(SpvOpSourceExtension, e->as<Extension>().name(), out);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,7 @@ private:
|
||||
|
||||
void writeWord(int32_t word, OutputStream& out);
|
||||
|
||||
void writeString(const char* string, size_t length, OutputStream& out);
|
||||
void writeString(StringFragment s, OutputStream& out);
|
||||
|
||||
void writeLabel(SpvId id, OutputStream& out);
|
||||
|
||||
|
@ -1696,7 +1696,7 @@ std::unique_ptr<UniformInfo> Program_GetUniformInfo(const Program& program) {
|
||||
const GlobalVarDeclaration& decl = e->as<GlobalVarDeclaration>();
|
||||
const Variable& var = decl.declaration()->as<VarDeclaration>().var();
|
||||
if (var.modifiers().fFlags & Modifiers::kUniform_Flag) {
|
||||
gather_uniforms(info.get(), var.type(), var.name());
|
||||
gather_uniforms(info.get(), var.type(), String(var.name()));
|
||||
}
|
||||
}
|
||||
return info;
|
||||
|
@ -19,11 +19,11 @@ class Extension final : public ProgramElement {
|
||||
public:
|
||||
static constexpr Kind kProgramElementKind = Kind::kExtension;
|
||||
|
||||
Extension(int offset, String name)
|
||||
Extension(int offset, StringFragment name)
|
||||
: INHERITED(offset, kProgramElementKind)
|
||||
, fName(std::move(name)) {}
|
||||
, fName(name) {}
|
||||
|
||||
const String& name() const {
|
||||
StringFragment name() const {
|
||||
return fName;
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
String fName;
|
||||
StringFragment fName;
|
||||
|
||||
using INHERITED = ProgramElement;
|
||||
};
|
||||
|
@ -319,7 +319,7 @@ FunctionDeclaration::FunctionDeclaration(int offset,
|
||||
, fReturnType(returnType)
|
||||
, fBuiltin(builtin)
|
||||
, fIsMain(name == "main")
|
||||
, fIntrinsicKind(builtin ? identify_intrinsic(name) : kNotIntrinsic) {}
|
||||
, fIntrinsicKind(builtin ? identify_intrinsic(String(name)) : kNotIntrinsic) {}
|
||||
|
||||
const FunctionDeclaration* FunctionDeclaration::Convert(const Context& context,
|
||||
SymbolTable& symbols, int offset, const Modifiers* modifiers,
|
||||
@ -353,10 +353,10 @@ const FunctionDeclaration* FunctionDeclaration::Convert(const Context& context,
|
||||
String FunctionDeclaration::mangledName() const {
|
||||
if ((this->isBuiltin() && !this->definition()) || this->isMain()) {
|
||||
// Builtins without a definition (like `sin` or `sqrt`) must use their real names.
|
||||
return this->name();
|
||||
return String(this->name());
|
||||
}
|
||||
// GLSL forbids two underscores in a row; add an extra character if necessary to avoid this.
|
||||
const char* splitter = this->name().endsWith("_") ? "x_" : "_";
|
||||
const char* splitter = this->name().ends_with("_") ? "x_" : "_";
|
||||
// Rename function to `funcname_returntypeparamtypes`.
|
||||
String result = this->name() + splitter + this->returnType().abbreviatedName();
|
||||
for (const Variable* p : this->parameters()) {
|
||||
|
@ -34,8 +34,8 @@ public:
|
||||
int arraySize, std::shared_ptr<SymbolTable> typeOwner)
|
||||
: INHERITED(offset, kProgramElementKind)
|
||||
, fVariable(var)
|
||||
, fTypeName(std::move(typeName))
|
||||
, fInstanceName(std::move(instanceName))
|
||||
, fTypeName(typeName)
|
||||
, fInstanceName(instanceName)
|
||||
, fArraySize(arraySize)
|
||||
, fTypeOwner(std::move(typeOwner)) {}
|
||||
|
||||
@ -47,11 +47,11 @@ public:
|
||||
fVariable = var;
|
||||
}
|
||||
|
||||
const String& typeName() const {
|
||||
String typeName() const {
|
||||
return fTypeName;
|
||||
}
|
||||
|
||||
const String& instanceName() const {
|
||||
String instanceName() const {
|
||||
return fInstanceName;
|
||||
}
|
||||
|
||||
|
@ -65,13 +65,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
const CapsLookupMethod* lookup(const String& name) const {
|
||||
const CapsLookupMethod* lookup(StringFragment name) const {
|
||||
auto iter = fMap.find(name);
|
||||
return (iter != fMap.end()) ? iter->second.get() : nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<String, std::unique_ptr<CapsLookupMethod>> fMap;
|
||||
std::unordered_map<StringFragment, std::unique_ptr<CapsLookupMethod>> fMap;
|
||||
};
|
||||
|
||||
static const CapsLookupTable& caps_lookup_table() {
|
||||
@ -102,7 +102,7 @@ static const CapsLookupTable& caps_lookup_table() {
|
||||
|
||||
} // namespace
|
||||
|
||||
static const Type* get_type(const Context& context, int offset, const String& name) {
|
||||
static const Type* get_type(const Context& context, int offset, StringFragment name) {
|
||||
if (const CapsLookupMethod* caps = caps_lookup_table().lookup(name)) {
|
||||
return caps->type(context);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
}
|
||||
|
||||
String description() const override {
|
||||
return this->name();
|
||||
return String(this->name());
|
||||
}
|
||||
|
||||
bool hasProperty(Property property) const override {
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
}
|
||||
|
||||
String description() const override {
|
||||
return this->name();
|
||||
return String(this->name());
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -123,7 +123,7 @@ void SymbolTable::addWithoutOwnership(const Symbol* symbol) {
|
||||
|
||||
const Type* SymbolTable::addArrayDimension(const Type* type, int arraySize) {
|
||||
if (arraySize != 0) {
|
||||
String baseName = type->name();
|
||||
String baseName(type->name());
|
||||
String arrayName = (arraySize != Type::kUnsizedArray)
|
||||
? String::printf("%s[%d]", baseName.c_str(), arraySize)
|
||||
: String::printf("%s[]", baseName.c_str());
|
||||
|
@ -205,15 +205,15 @@ const Type* Type::clone(SymbolTable* symbolTable) const {
|
||||
// This type actually needs to be cloned into the destination SymbolTable.
|
||||
switch (this->typeKind()) {
|
||||
case TypeKind::kArray:
|
||||
return symbolTable->add(Type::MakeArrayType(this->name(), this->componentType(),
|
||||
return symbolTable->add(Type::MakeArrayType(String(this->name()), this->componentType(),
|
||||
this->columns()));
|
||||
|
||||
case TypeKind::kStruct:
|
||||
return symbolTable->add(Type::MakeStructType(this->fOffset, this->name(),
|
||||
return symbolTable->add(Type::MakeStructType(this->fOffset, String(this->name()),
|
||||
this->fields()));
|
||||
|
||||
case TypeKind::kEnum:
|
||||
return symbolTable->add(Type::MakeEnumType(this->name()));
|
||||
return symbolTable->add(Type::MakeEnumType(String(this->name())));
|
||||
|
||||
default:
|
||||
SkDEBUGFAILF("don't know how to clone type '%s'", this->description().c_str());
|
||||
|
@ -136,7 +136,7 @@ public:
|
||||
}
|
||||
|
||||
String displayName() const {
|
||||
return this->scalarTypeForLiteral().name();
|
||||
return String(this->scalarTypeForLiteral().name());
|
||||
}
|
||||
|
||||
String description() const override {
|
||||
@ -144,7 +144,7 @@ public:
|
||||
}
|
||||
|
||||
bool isPrivate() const {
|
||||
return this->name().startsWith("$");
|
||||
return this->name().starts_with("$");
|
||||
}
|
||||
|
||||
bool operator==(const Type& other) const {
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
}
|
||||
|
||||
String description() const override {
|
||||
return this->name();
|
||||
return String(this->name());
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -36,7 +36,7 @@ bool VariableReference::isConstantOrUniform() const {
|
||||
}
|
||||
|
||||
String VariableReference::description() const {
|
||||
return this->variable()->name();
|
||||
return String(this->variable()->name());
|
||||
}
|
||||
|
||||
void VariableReference::setRefKind(RefKind refKind) {
|
||||
|
@ -333,7 +333,7 @@ void ParticlesSlide::draw(SkCanvas* canvas) {
|
||||
float* vals = data + uni.fSlot;
|
||||
|
||||
// Skip over builtin uniforms, to reduce clutter
|
||||
if (uni.fName == "dt" || uni.fName.startsWith("effect.")) {
|
||||
if (uni.fName == "dt" || uni.fName.starts_with("effect.")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user