Towards a simpler SkSL -> GLSL pipeline (and better shader reflection)
The pretty printer didn't actually need the original (separate) strings,
so make it just operate on a single SkSL::String. Also remove the unused
line numbering, and the unit test. (Testing of test code, yay!)
With that done, cut down on passing around arrays of char* + length, and
just do the compaction to a single SkSL::String in the program builder.
Change-Id: Ieef9d9a8e3c5620c011b17477f1b0f9a9faa6273
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/208226
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/gn/tests.gni b/gn/tests.gni
index 9436d7c..1aaf90f 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -105,7 +105,6 @@
"$_tests/GrPorterDuffTest.cpp",
"$_tests/GrQuadListTest.cpp",
"$_tests/GrShapeTest.cpp",
- "$_tests/GrSKSLPrettyPrintTest.cpp",
"$_tests/GrSurfaceTest.cpp",
"$_tests/GrTestingBackendTextureUploadTest.cpp",
"$_tests/GrTextureMipMapInvalidationTest.cpp",
diff --git a/src/gpu/GrSKSLPrettyPrint.cpp b/src/gpu/GrSKSLPrettyPrint.cpp
index cb2da75..f00682f 100644
--- a/src/gpu/GrSKSLPrettyPrint.cpp
+++ b/src/gpu/GrSKSLPrettyPrint.cpp
@@ -13,10 +13,8 @@
public:
GLSLPrettyPrint() {}
- SkSL::String prettify(const char** strings, int* lengths, int count, bool countlines) {
- fCountlines = countlines;
+ SkSL::String prettify(const SkSL::String& string) {
fTabs = 0;
- fLinecount = 1;
fFreshline = true;
// If a string breaks while in the middle 'parse until' we need to continue parsing on the
@@ -26,73 +24,70 @@
int parensDepth = 0;
- // number 1st line
- this->lineNumbering();
- for (int i = 0; i < count; i++) {
- // setup pretty state
- fIndex = 0;
- fLength = lengths[i];
- fInput = strings[i];
+ // setup pretty state
+ fIndex = 0;
+ fLength = string.length();
+ fInput = string.c_str();
- while (fLength > fIndex) {
- /* the heart and soul of our prettification algorithm. The rules should hopefully
- * be self explanatory. For '#' and '//' tokens we parse until we reach a newline.
- *
- * For long style comments like this one, we search for the ending token. We also
- * preserve whitespace in these comments WITH THE CAVEAT that we do the newlines
- * ourselves. This allows us to remain in control of line numbers, and matching
- * tabs Existing tabs in the input string are copied over too, but this will look
- * funny
- *
- * '{' and '}' are handled in basically the same way. We add a newline if we aren't
- * on a fresh line, dirty the line, then add a second newline, ie braces are always
- * on their own lines indented properly. The one funkiness here is structs print
- * with the semicolon on its own line. Its not a problem for a glsl compiler though
- *
- * '(' and ')' are basically ignored, except as a sign we need to ignore ';' ala
- * in for loops.
- *
- * ';' means add a new line
- *
- * '\t' and '\n' are ignored in general parsing for backwards compatability with
- * existing shader code and we also have a special case for handling whitespace
- * at the beginning of fresh lines.
- *
- * Otherwise just add the new character to the pretty string, indenting if
- * necessary.
- */
- if (fInParseUntilNewline) {
- this->parseUntilNewline();
- } else if (fInParseUntil) {
- this->parseUntil(fInParseUntilToken);
- } else if (this->hasToken("#") || this->hasToken("//")) {
- this->parseUntilNewline();
- } else if (this->hasToken("/*")) {
- this->parseUntil("*/");
- } else if ('{' == fInput[fIndex]) {
- this->newline();
- this->appendChar('{');
- fTabs++;
- this->newline();
- } else if ('}' == fInput[fIndex]) {
- fTabs--;
- this->newline();
- this->appendChar('}');
- this->newline();
- } else if (this->hasToken(")")) {
- parensDepth--;
- } else if (this->hasToken("(")) {
- parensDepth++;
- } else if (!parensDepth && this->hasToken(";")) {
- this->newline();
- } else if ('\t' == fInput[fIndex] || '\n' == fInput[fIndex] ||
- (fFreshline && ' ' == fInput[fIndex])) {
- fIndex++;
- } else {
- this->appendChar(fInput[fIndex]);
- }
+ while (fLength > fIndex) {
+ /* the heart and soul of our prettification algorithm. The rules should hopefully
+ * be self explanatory. For '#' and '//' tokens we parse until we reach a newline.
+ *
+ * For long style comments like this one, we search for the ending token. We also
+ * preserve whitespace in these comments WITH THE CAVEAT that we do the newlines
+ * ourselves. This allows us to remain in control of line numbers, and matching
+ * tabs Existing tabs in the input string are copied over too, but this will look
+ * funny
+ *
+ * '{' and '}' are handled in basically the same way. We add a newline if we aren't
+ * on a fresh line, dirty the line, then add a second newline, ie braces are always
+ * on their own lines indented properly. The one funkiness here is structs print
+ * with the semicolon on its own line. Its not a problem for a glsl compiler though
+ *
+ * '(' and ')' are basically ignored, except as a sign we need to ignore ';' ala
+ * in for loops.
+ *
+ * ';' means add a new line
+ *
+ * '\t' and '\n' are ignored in general parsing for backwards compatability with
+ * existing shader code and we also have a special case for handling whitespace
+ * at the beginning of fresh lines.
+ *
+ * Otherwise just add the new character to the pretty string, indenting if
+ * necessary.
+ */
+ if (fInParseUntilNewline) {
+ this->parseUntilNewline();
+ } else if (fInParseUntil) {
+ this->parseUntil(fInParseUntilToken);
+ } else if (this->hasToken("#") || this->hasToken("//")) {
+ this->parseUntilNewline();
+ } else if (this->hasToken("/*")) {
+ this->parseUntil("*/");
+ } else if ('{' == fInput[fIndex]) {
+ this->newline();
+ this->appendChar('{');
+ fTabs++;
+ this->newline();
+ } else if ('}' == fInput[fIndex]) {
+ fTabs--;
+ this->newline();
+ this->appendChar('}');
+ this->newline();
+ } else if (this->hasToken(")")) {
+ parensDepth--;
+ } else if (this->hasToken("(")) {
+ parensDepth++;
+ } else if (!parensDepth && this->hasToken(";")) {
+ this->newline();
+ } else if ('\t' == fInput[fIndex] || '\n' == fInput[fIndex] ||
+ (fFreshline && ' ' == fInput[fIndex])) {
+ fIndex++;
+ } else {
+ this->appendChar(fInput[fIndex]);
}
}
+
return fPretty;
}
@@ -171,18 +166,11 @@
if (!fFreshline) {
fFreshline = true;
fPretty.append("\n");
- this->lineNumbering();
}
}
- void lineNumbering() {
- if (fCountlines) {
- fPretty.appendf("%4d\t", fLinecount++);
- }
- }
-
- bool fCountlines, fFreshline;
- int fTabs, fLinecount;
+ bool fFreshline;
+ int fTabs;
size_t fIndex, fLength;
const char* fInput;
SkSL::String fPretty;
@@ -193,9 +181,9 @@
const char* fInParseUntilToken;
};
-SkSL::String PrettyPrint(const char** strings, int* lengths, int count, bool countlines) {
+SkSL::String PrettyPrint(const SkSL::String& string) {
GLSLPrettyPrint pp;
- return pp.prettify(strings, lengths, count, countlines);
+ return pp.prettify(string);
}
} // namespace GrSKSLPrettyPrint
diff --git a/src/gpu/GrSKSLPrettyPrint.h b/src/gpu/GrSKSLPrettyPrint.h
index 530fcce..2871e95 100644
--- a/src/gpu/GrSKSLPrettyPrint.h
+++ b/src/gpu/GrSKSLPrettyPrint.h
@@ -10,7 +10,7 @@
#include "SkSLString.h"
namespace GrSKSLPrettyPrint {
-SkSL::String PrettyPrint(const char** strings, int* lengths, int count, bool countlines);
+SkSL::String PrettyPrint(const SkSL::String& string);
};
#endif
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index e7ef184..8a847ed 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -3461,24 +3461,19 @@
"}"
);
- const char* str;
- GrGLint length;
-
- str = vshaderTxt.c_str();
- length = SkToInt(vshaderTxt.size());
+ SkSL::String sksl(vshaderTxt.c_str(), vshaderTxt.size());
SkSL::Program::Settings settings;
settings.fCaps = shaderCaps;
SkSL::String glsl;
std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(*fGLContext, GR_GL_VERTEX_SHADER,
- &str, &length, 1, settings, &glsl);
+ sksl, settings, &glsl);
GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
GR_GL_VERTEX_SHADER, glsl.c_str(), glsl.size(),
&fStats, settings);
SkASSERT(program->fInputs.isEmpty());
- str = fshaderTxt.c_str();
- length = SkToInt(fshaderTxt.size());
- program = GrSkSLtoGLSL(*fGLContext, GR_GL_FRAGMENT_SHADER, &str, &length, 1, settings, &glsl);
+ sksl.assign(fshaderTxt.c_str(), fshaderTxt.size());
+ program = GrSkSLtoGLSL(*fGLContext, GR_GL_FRAGMENT_SHADER, sksl, settings, &glsl);
GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
GR_GL_FRAGMENT_SHADER, glsl.c_str(), glsl.size(),
&fStats, settings);
@@ -3620,24 +3615,19 @@
fshaderTxt.append("}");
- const char* str;
- GrGLint length;
-
- str = vshaderTxt.c_str();
- length = SkToInt(vshaderTxt.size());
+ SkSL::String sksl(vshaderTxt.c_str(), vshaderTxt.size());
SkSL::Program::Settings settings;
settings.fCaps = shaderCaps;
SkSL::String glsl;
std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(*fGLContext, GR_GL_VERTEX_SHADER,
- &str, &length, 1, settings, &glsl);
+ sksl, settings, &glsl);
GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram,
GR_GL_VERTEX_SHADER, glsl.c_str(), glsl.size(),
&fStats, settings);
SkASSERT(program->fInputs.isEmpty());
- str = fshaderTxt.c_str();
- length = SkToInt(fshaderTxt.size());
- program = GrSkSLtoGLSL(*fGLContext, GR_GL_FRAGMENT_SHADER, &str, &length, 1, settings, &glsl);
+ sksl.assign(fshaderTxt.c_str(), fshaderTxt.size());
+ program = GrSkSLtoGLSL(*fGLContext, GR_GL_FRAGMENT_SHADER, sksl, settings, &glsl);
GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram,
GR_GL_FRAGMENT_SHADER, glsl.c_str(), glsl.size(),
&fStats, settings);
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index 2d3569d..40968b1 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -253,9 +253,7 @@
}
std::unique_ptr<SkSL::Program> fs = GrSkSLtoGLSL(gpu()->glContext(),
GR_GL_FRAGMENT_SHADER,
- fFS.fCompilerStrings.begin(),
- fFS.fCompilerStringLengths.begin(),
- fFS.fCompilerStrings.count(),
+ fFS.fCompilerString,
settings,
&glsl[kFragment_GrShaderType]);
if (!fs) {
@@ -281,9 +279,7 @@
// Don't have cached GLSL, need to compile SkSL->GLSL
std::unique_ptr<SkSL::Program> vs = GrSkSLtoGLSL(gpu()->glContext(),
GR_GL_VERTEX_SHADER,
- fVS.fCompilerStrings.begin(),
- fVS.fCompilerStringLengths.begin(),
- fVS.fCompilerStrings.count(),
+ fVS.fCompilerString,
settings,
&glsl[kVertex_GrShaderType]);
if (!vs) {
@@ -311,9 +307,7 @@
std::unique_ptr<SkSL::Program> gs;
gs = GrSkSLtoGLSL(gpu()->glContext(),
GR_GL_GEOMETRY_SHADER,
- fGS.fCompilerStrings.begin(),
- fGS.fCompilerStringLengths.begin(),
- fGS.fCompilerStrings.count(),
+ fGS.fCompilerString,
settings,
&glsl[kGeometry_GrShaderType]);
if (!gs) {
@@ -338,24 +332,19 @@
SkDebugf("VS:\n");
GrGLPrintShader(fGpu->glContext(),
GR_GL_VERTEX_SHADER,
- fVS.fCompilerStrings.begin(),
- fVS.fCompilerStringLengths.begin(),
- fVS.fCompilerStrings.count(),
+ fVS.fCompilerString,
settings);
if (primProc.willUseGeoShader()) {
SkDebugf("\nGS:\n");
GrGLPrintShader(fGpu->glContext(),
GR_GL_GEOMETRY_SHADER,
- fGS.fCompilerStrings.begin(),
- fGS.fCompilerStringLengths.begin(),
- fGS.fCompilerStrings.count(), settings);
+ fGS.fCompilerString,
+ settings);
}
SkDebugf("\nFS:\n");
GrGLPrintShader(fGpu->glContext(),
GR_GL_FRAGMENT_SHADER,
- fFS.fCompilerStrings.begin(),
- fFS.fCompilerStringLengths.begin(),
- fFS.fCompilerStrings.count(),
+ fFS.fCompilerString,
settings);
return nullptr;
}
diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
index b23da68..a3e5136 100644
--- a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
@@ -33,13 +33,13 @@
}
// Prints shaders one line at the time. This ensures they don't get truncated by the adb log.
-static void print_sksl_line_by_line(const char** skslStrings, int* lengths, int count,
+static void print_sksl_line_by_line(const SkSL::String& sksl,
std::function<void(const char*)> println = [](const char* ln) {
SkDebugf("%s\n", ln);
}) {
- SkSL::String sksl = GrSKSLPrettyPrint::PrettyPrint(skslStrings, lengths, count, false);
+ SkSL::String pretty = GrSKSLPrettyPrint::PrettyPrint(sksl);
println("SKSL:");
- print_source_lines_with_numbers(sksl.c_str(), println);
+ print_source_lines_with_numbers(pretty.c_str(), println);
}
static void print_glsl_line_by_line(const SkSL::String& glsl,
@@ -61,7 +61,7 @@
}
std::unique_ptr<SkSL::Program> GrSkSLtoGLSL(const GrGLContext& context, GrGLenum type,
- const char** skslStrings, int* lengths, int count,
+ const SkSL::String& sksl,
const SkSL::Program::Settings& settings,
SkSL::String* glsl) {
// Trace event for shader preceding driver compilation
@@ -69,7 +69,7 @@
TRACE_EVENT_CATEGORY_GROUP_ENABLED("skia.gpu", &traceShader);
if (traceShader) {
SkString shaderDebugString;
- print_sksl_line_by_line(skslStrings, lengths, count, [&](const char* ln) {
+ print_sksl_line_by_line(sksl, [&](const char* ln) {
shaderDebugString.append(ln);
shaderDebugString.append("\n");
});
@@ -78,14 +78,6 @@
TRACE_STR_COPY(shaderDebugString.c_str()));
}
- SkSL::String sksl;
-#ifdef SK_DEBUG
- sksl = GrSKSLPrettyPrint::PrettyPrint(skslStrings, lengths, count, false);
-#else
- for (int i = 0; i < count; i++) {
- sksl.append(skslStrings[i], lengths[i]);
- }
-#endif
SkSL::Compiler* compiler = context.compiler();
std::unique_ptr<SkSL::Program> program;
SkSL::Program::Kind programKind;
@@ -98,14 +90,14 @@
program = compiler->convertProgram(programKind, sksl, settings);
if (!program || !compiler->toGLSL(*program, glsl)) {
SkDebugf("SKSL compilation error\n----------------------\n");
- print_sksl_line_by_line(skslStrings, lengths, count);
+ print_sksl_line_by_line(sksl);
SkDebugf("\nErrors:\n%s\n", compiler->errorText().c_str());
SkDEBUGFAIL("SKSL compilation failed!\n");
return nullptr;
}
if (gPrintSKSL) {
print_shader_banner(type);
- print_sksl_line_by_line(skslStrings, lengths, count);
+ print_sksl_line_by_line(sksl);
}
return program;
}
@@ -175,11 +167,11 @@
return shaderId;
}
-void GrGLPrintShader(const GrGLContext& context, GrGLenum type, const char** skslStrings,
- int* lengths, int count, const SkSL::Program::Settings& settings) {
- print_sksl_line_by_line(skslStrings, lengths, count);
+void GrGLPrintShader(const GrGLContext& context, GrGLenum type, const SkSL::String& sksl,
+ const SkSL::Program::Settings& settings) {
+ print_sksl_line_by_line(sksl);
SkSL::String glsl;
- if (GrSkSLtoGLSL(context, type, skslStrings, lengths, count, settings, &glsl)) {
+ if (GrSkSLtoGLSL(context, type, sksl, settings, &glsl)) {
print_glsl_line_by_line(glsl);
}
}
diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.h b/src/gpu/gl/builders/GrGLShaderStringBuilder.h
index c693a39..2dd44c7 100644
--- a/src/gpu/gl/builders/GrGLShaderStringBuilder.h
+++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.h
@@ -15,7 +15,7 @@
#include "SkTypes.h"
std::unique_ptr<SkSL::Program> GrSkSLtoGLSL(const GrGLContext& context, GrGLenum type,
- const char** skslStrings, int* lengths, int count,
+ const SkSL::String& sksl,
const SkSL::Program::Settings& settings,
SkSL::String* glsl);
@@ -27,7 +27,7 @@
GrGpu::Stats*,
const SkSL::Program::Settings& settings);
-void GrGLPrintShader(const GrGLContext&, GrGLenum type, const char** skslStrings, int* lengths,
- int count, const SkSL::Program::Settings&);
+void GrGLPrintShader(const GrGLContext&, GrGLenum type, const SkSL::String& sksl,
+ const SkSL::Program::Settings&);
#endif
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.cpp b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
index 96eb4fd..504c9761 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
@@ -22,8 +22,6 @@
// We push back some dummy pointers which will later become our header
for (int i = 0; i <= kCode; i++) {
fShaderStrings.push_back();
- fCompilerStrings.push_back(nullptr);
- fCompilerStringLengths.push_back(0);
}
this->main() = "void main() {";
@@ -252,8 +250,7 @@
this->code().append("}");
for (int i = 0; i <= fCodeIndex; i++) {
- fCompilerStrings[i] = fShaderStrings[i].c_str();
- fCompilerStringLengths[i] = (int)fShaderStrings[i].size();
+ fCompilerString.append(fShaderStrings[i].c_str(), fShaderStrings[i].size());
}
fFinalized = true;
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h
index 0616997..9312e7c 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.h
@@ -11,6 +11,7 @@
#include "GrAllocator.h"
#include "GrShaderVar.h"
#include "glsl/GrGLSLUniformHandler.h"
+#include "SkSLString.h"
#include "SkTDArray.h"
#include <stdarg.h>
@@ -194,8 +195,6 @@
void nextStage() {
fShaderStrings.push_back();
- fCompilerStrings.push_back(this->code().c_str());
- fCompilerStringLengths.push_back((int)this->code().size());
fCodeIndex++;
}
@@ -230,8 +229,7 @@
};
GrGLSLProgramBuilder* fProgramBuilder;
- SkSTArray<kPrealloc, const char*, true> fCompilerStrings;
- SkSTArray<kPrealloc, int, true> fCompilerStringLengths;
+ SkSL::String fCompilerString;
SkSTArray<kPrealloc, SkString> fShaderStrings;
SkString fCode;
SkString fFunctions;
diff --git a/src/gpu/mtl/GrMtlPipelineStateBuilder.mm b/src/gpu/mtl/GrMtlPipelineStateBuilder.mm
index 0a3d7a5..ed35cdd 100644
--- a/src/gpu/mtl/GrMtlPipelineStateBuilder.mm
+++ b/src/gpu/mtl/GrMtlPipelineStateBuilder.mm
@@ -64,16 +64,8 @@
SkSL::Program::Kind kind,
const SkSL::Program::Settings& settings,
GrProgramDesc* desc) {
- SkString shaderString;
- for (int i = 0; i < builder.fCompilerStrings.count(); ++i) {
- if (builder.fCompilerStrings[i]) {
- shaderString.append(builder.fCompilerStrings[i]);
- shaderString.append("\n");
- }
- }
-
SkSL::Program::Inputs inputs;
- id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, shaderString.c_str(),
+ id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, builder.fCompilerString.c_str(),
kind, settings, &inputs);
if (shaderLibrary == nil) {
return nil;
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
index b7f922f6..d4e5a97 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
@@ -72,15 +72,7 @@
Desc* desc,
SkSL::String* outSPIRV,
SkSL::Program::Inputs* outInputs) {
- SkString shaderString;
- for (int i = 0; i < builder.fCompilerStrings.count(); ++i) {
- if (builder.fCompilerStrings[i]) {
- shaderString.append(builder.fCompilerStrings[i]);
- shaderString.append("\n");
- }
- }
-
- if (!GrCompileVkShaderModule(fGpu, shaderString.c_str(), stage, shaderModule,
+ if (!GrCompileVkShaderModule(fGpu, builder.fCompilerString.c_str(), stage, shaderModule,
stageInfo, settings, outSPIRV, outInputs)) {
return false;
}
diff --git a/tests/GrSKSLPrettyPrintTest.cpp b/tests/GrSKSLPrettyPrintTest.cpp
deleted file mode 100644
index f0ded45..0000000
--- a/tests/GrSKSLPrettyPrintTest.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "Test.h"
-
-#include "GrSKSLPrettyPrint.h"
-
-#define ASSERT(x) REPORTER_ASSERT(r, x)
-
-const SkString input1("#this is not a realshader\nvec4 some stuff;outside of a function;"
- "int i(int b, int c) { { some stuff;} fake block; //comments\n return i;}"
- "void main()");
-const SkString input2("{nowin a function;{indenting;{abit more;dreadedfor((;;)(;)((;;);)){"
- "doingstuff"
- ";for(;;;){and more stufff;mixed garbage\n\n\t\t\t\t\n/*using this"
- " comment\n is");
-const SkString input3(" dangerous\ndo so at your own\n risk*/;\n\n\t\t\t\n"
- "//a comment");
-const SkString input4("breaking in comment");
-const SkString input5("continuing the comment");
-const SkString input6("\n}}a; little ; love; for ; leading; spaces;} "
- "an struct = { int a; int b; };"
- "int[5] arr = int[5](1,2,3,4,5);} some code at the bottom; for(;;) {} }");
-
-const SkSL::String output1(
- " 1\t#this is not a realshader\n"
- " 2\tvec4 some stuff;\n"
- " 3\toutside of a function;\n"
- " 4\tint i(int b, int c) \n"
- " 5\t{\n"
- " 6\t\t{\n"
- " 7\t\t\tsome stuff;\n"
- " 8\t\t}\n"
- " 9\t\tfake block;\n"
- " 10\t\t//comments\n"
- " 11\t\treturn i;\n"
- " 12\t}\n"
- " 13\tvoid main()\n"
- " 14\t{\n"
- " 15\t\tnowin a function;\n"
- " 16\t\t{\n"
- " 17\t\t\tindenting;\n"
- " 18\t\t\t{\n"
- " 19\t\t\t\tabit more;\n"
- " 20\t\t\t\tdreadedfor((;;)(;)((;;);))\n"
- " 21\t\t\t\t{\n"
- " 22\t\t\t\t\tdoingstuff;\n"
- " 23\t\t\t\t\tfor(;;;)\n"
- " 24\t\t\t\t\t{\n"
- " 25\t\t\t\t\t\tand more stufff;\n"
- " 26\t\t\t\t\t\tmixed garbage/*using this comment\n"
- " 27\t\t\t\t\t\t is dangerous\n"
- " 28\t\t\t\t\t\tdo so at your own\n"
- " 29\t\t\t\t\t\t risk*/;\n"
- " 30\t\t\t\t\t\t//a commentbreaking in commentcontinuing the comment\n"
- " 31\t\t\t\t\t}\n"
- " 32\t\t\t\t}\n"
- " 33\t\t\t\ta;\n"
- " 34\t\t\t\tlittle ;\n"
- " 35\t\t\t\tlove;\n"
- " 36\t\t\t\tfor ;\n"
- " 37\t\t\t\tleading;\n"
- " 38\t\t\t\tspaces;\n"
- " 39\t\t\t}\n"
- " 40\t\t\tan struct = \n"
- " 41\t\t\t{\n"
- " 42\t\t\t\tint a;\n"
- " 43\t\t\t\tint b;\n"
- " 44\t\t\t}\n"
- " 45\t\t\t;\n"
- " 46\t\t\tint[5] arr = int[5](1,2,3,4,5);\n"
- " 47\t\t}\n"
- " 48\t\tsome code at the bottom;\n"
- " 49\t\tfor(;;) \n"
- " 50\t\t{\n"
- " 51\t\t}\n"
- " 52\t}\n"
- " 53\t");
-
-const SkString neg1("{;;{{{{;;;{{{{{{{{{{{");
-const SkString neg2("###\n##\n#####(((((((((((((unbalanced verything;;;");
-const SkString neg3("}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}"
- ";;;;;;/////");
-
-DEF_TEST(GrSKSLPrettyPrint, r) {
- SkTArray<const char*> testStr;
- SkTArray<int> lengths;
- testStr.push_back(input1.c_str());
- lengths.push_back((int)input1.size());
- testStr.push_back(input2.c_str());
- lengths.push_back((int)input2.size());
- testStr.push_back(input3.c_str());
- lengths.push_back((int)input3.size());
- testStr.push_back(input4.c_str());
- lengths.push_back((int)input4.size());
- testStr.push_back(input5.c_str());
- lengths.push_back((int)input5.size());
- testStr.push_back(input6.c_str());
- lengths.push_back((int)input6.size());
-
- SkSL::String test = GrSKSLPrettyPrint::PrettyPrint(testStr.begin(), lengths.begin(),
- testStr.count(), true);
- ASSERT(output1 == test);
-
- testStr.reset();
- lengths.reset();
- testStr.push_back(neg1.c_str());
- lengths.push_back((int)neg1.size());
- testStr.push_back(neg2.c_str());
- lengths.push_back((int)neg2.size());
- testStr.push_back(neg3.c_str());
- lengths.push_back((int)neg3.size());
-
- // Just test we don't crash with garbage input
- ASSERT(GrSKSLPrettyPrint::PrettyPrint(testStr.begin(), lengths.begin(), 1,
- true).c_str() != nullptr);
-}