SkSL workaround for appendf 1024 byte restriction
Bug: skia:
Change-Id: Ibb04e032e27e834b5e3e40c40522e756223f58ec
Reviewed-on: https://skia-review.googlesource.com/59680
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
index 705155e..a7008400 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -443,6 +443,41 @@
}
}
+void CPPCodeGenerator::writeCodeAppend(const String& code) {
+ // codeAppendf can only handle appending 1024 bytes at a time, so we need to break the string
+ // into chunks. Unfortunately we can't tell exactly how long the string is going to end up,
+ // because printf escape sequences get replaced by strings of unknown length, but keeping the
+ // format string below 512 bytes is probably safe.
+ static constexpr size_t maxChunkSize = 512;
+ size_t start = 0;
+ size_t index = 0;
+ size_t argStart = 0;
+ size_t argCount;
+ while (index < code.size()) {
+ argCount = 0;
+ this->write(" fragBuilder->codeAppendf(\"");
+ while (index < code.size() && index < start + maxChunkSize) {
+ if ('%' == code[index]) {
+ if (index == start + maxChunkSize - 1 || index == code.size() - 1) {
+ break;
+ }
+ if (code[index + 1] != '%') {
+ ++argCount;
+ }
+ }
+ ++index;
+ }
+ fOut->write(code.c_str() + start, index - start);
+ this->write("\"");
+ for (size_t i = argStart; i < argStart + argCount; ++i) {
+ this->writef(", %s", fFormatArgs[i].c_str());
+ }
+ this->write(");\n");
+ argStart += argCount;
+ start = index;
+ }
+}
+
bool CPPCodeGenerator::writeEmitCode(std::vector<const Variable*>& uniforms) {
this->write(" void emitCode(EmitArgs& args) override {\n"
" GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;\n");
@@ -468,13 +503,9 @@
fOut = &mainBuffer;
bool result = INHERITED::generateCode();
fOut = old;
- this->writef("%s fragBuilder->codeAppendf(\"%s\"", fExtraEmitCodeCode.c_str(),
- mainBuffer.str().c_str());
- for (const auto& s : fFormatArgs) {
- this->writef(", %s", s.c_str());
- }
- this->write(");\n"
- " }\n");
+ this->writef("%s", fExtraEmitCodeCode.c_str());
+ this->writeCodeAppend(mainBuffer.str());
+ this->write(" }\n");
return result;
}
diff --git a/src/sksl/SkSLCPPCodeGenerator.h b/src/sksl/SkSLCPPCodeGenerator.h
index 6727b9c..ea4d030 100644
--- a/src/sksl/SkSLCPPCodeGenerator.h
+++ b/src/sksl/SkSLCPPCodeGenerator.h
@@ -68,6 +68,8 @@
void writePrivateVarValues();
+ void writeCodeAppend(const String& code);
+
bool writeEmitCode(std::vector<const Variable*>& uniforms);
void writeSetData(std::vector<const Variable*>& uniforms);