From b8a82f2bce265a09173a90dfbe4ce78e52347ba4 Mon Sep 17 00:00:00 2001 From: joshualitt Date: Fri, 13 Feb 2015 16:31:46 -0800 Subject: [PATCH] Revert of Multi-string shaders (patchset #4 id:60001 of https://codereview.chromium.org/929503002/) Reason for revert: windows warnings Original issue's description: > Multi-string shaders > > BUG=skia: > > Committed: https://skia.googlesource.com/skia/+/1c3c2d83364ee228e0751df0e1b9c161c0ba8c1e TBR=bsalomon@google.com,joshualitt@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia: Review URL: https://codereview.chromium.org/924973002 --- include/gpu/gl/GrGLSLPrettyPrint.h | 5 +- src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp | 31 +++-- src/gpu/gl/builders/GrGLFragmentShaderBuilder.h | 2 +- src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp | 35 +++++- src/gpu/gl/builders/GrGLGeometryShaderBuilder.h | 2 +- src/gpu/gl/builders/GrGLProgramBuilder.h | 7 +- src/gpu/gl/builders/GrGLSLPrettyPrint.cpp | 147 +++++++++------------- src/gpu/gl/builders/GrGLShaderBuilder.cpp | 69 +++------- src/gpu/gl/builders/GrGLShaderBuilder.h | 45 +------ src/gpu/gl/builders/GrGLShaderStringBuilder.cpp | 30 ++--- src/gpu/gl/builders/GrGLShaderStringBuilder.h | 4 +- src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp | 27 ++-- src/gpu/gl/builders/GrGLVertexShaderBuilder.h | 2 +- tests/GrGLSLPrettyPrintTest.cpp | 51 ++------ 14 files changed, 178 insertions(+), 279 deletions(-) diff --git a/include/gpu/gl/GrGLSLPrettyPrint.h b/include/gpu/gl/GrGLSLPrettyPrint.h index 52fb745..7273aaa 100644 --- a/include/gpu/gl/GrGLSLPrettyPrint.h +++ b/include/gpu/gl/GrGLSLPrettyPrint.h @@ -10,10 +10,7 @@ #include "SkString.h" namespace GrGLSLPrettyPrint { - SkString PrettyPrintGLSL(const char** strings, - int* lengths, - int count, - bool countlines); + SkString PrettyPrintGLSL(const SkString& input, bool countlines); }; #endif /* GRGLPRETTYPRINTSL_H_ */ diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp index c739f11..86c622d 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp @@ -6,6 +6,7 @@ */ #include "GrGLFragmentShaderBuilder.h" +#include "GrGLShaderStringBuilder.h" #include "GrGLProgramBuilder.h" #include "../GrGLGpu.h" @@ -209,19 +210,33 @@ const char* GrGLFragmentShaderBuilder::getSecondaryColorOutputName() const { } bool GrGLFragmentShaderBuilder::compileAndAttachShaders(GrGLuint programId, - SkTDArray* shaderIds) { + SkTDArray* shaderIds) const { GrGLGpu* gpu = fProgramBuilder->gpu(); - this->versionDecl() = GrGetGLSLVersionDecl(gpu->ctxInfo()); + SkString fragShaderSrc(GrGetGLSLVersionDecl(gpu->ctxInfo())); + fragShaderSrc.append(fExtensions); append_default_precision_qualifier(kDefault_GrSLPrecision, gpu->glStandard(), - &this->precisionQualifier()); - fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kFragment_Visibility, - &this->uniforms()); - this->appendDecls(fInputs, &this->inputs()); + &fragShaderSrc); + fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kFragment_Visibility, &fragShaderSrc); + this->appendDecls(fInputs, &fragShaderSrc); // We shouldn't have declared outputs on 1.10 SkASSERT(k110_GrGLSLGeneration != gpu->glslGeneration() || fOutputs.empty()); - this->appendDecls(fOutputs, &this->outputs()); - return this->finalize(programId, GR_GL_FRAGMENT_SHADER, shaderIds); + this->appendDecls(fOutputs, &fragShaderSrc); + fragShaderSrc.append(fFunctions); + fragShaderSrc.append("void main() {\n"); + fragShaderSrc.append(fCode); + fragShaderSrc.append("}\n"); + + GrGLuint fragShaderId = GrGLCompileAndAttachShader(gpu->glContext(), programId, + GR_GL_FRAGMENT_SHADER, fragShaderSrc, + gpu->stats()); + if (!fragShaderId) { + return false; + } + + *shaderIds->append() = fragShaderId; + + return true; } void GrGLFragmentShaderBuilder::bindFragmentShaderLocations(GrGLuint programID) { diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h index f294257..903c5e1 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h @@ -101,7 +101,7 @@ private: void enableSecondaryOutput(); const char* getPrimaryColorOutputName() const; const char* getSecondaryColorOutputName() const; - bool compileAndAttachShaders(GrGLuint programId, SkTDArray* shaderIds); + bool compileAndAttachShaders(GrGLuint programId, SkTDArray* shaderIds) const; void bindFragmentShaderLocations(GrGLuint programID); // As GLProcessors emit code, there are some conditions we need to verify. We use the below diff --git a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp index b205752..8be2531 100644 --- a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp @@ -6,6 +6,7 @@ */ #include "GrGLGeometryShaderBuilder.h" +#include "GrGLShaderStringBuilder.h" #include "GrGLProgramBuilder.h" #include "../GrGLGpu.h" @@ -36,7 +37,35 @@ void GrGLGeometryBuilder::addVarying(const char* name, GrGLVarying* v) { } bool GrGLGeometryBuilder::compileAndAttachShaders(GrGLuint programId, - SkTDArray* shaderIds) { - SkFAIL("Geometry shaders are not currently supported"); - return false; + SkTDArray* shaderIds) const { + const GrGLContext& glCtx = fProgramBuilder->gpu()->glContext(); + SkASSERT(fProgramBuilder->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration); + SkString geomShaderSrc(GrGetGLSLVersionDecl(fProgramBuilder->ctxInfo())); + geomShaderSrc.append("layout(triangles) in;\n" + "layout(triangle_strip, max_vertices = 6) out;\n"); + this->appendDecls(fInputs, &geomShaderSrc); + this->appendDecls(fOutputs, &geomShaderSrc); + geomShaderSrc.append("void main() {\n"); + geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n" + "\t\tgl_Position = gl_in[i].gl_Position;\n"); + geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n"); + SkASSERT(fInputs.count() == fOutputs.count()); + for (int i = 0; i < fInputs.count(); ++i) { + geomShaderSrc.appendf("\t\t%s = %s[i];\n", + fOutputs[i].getName().c_str(), + fInputs[i].getName().c_str()); + } + geomShaderSrc.append("\t\tEmitVertex();\n" + "\t}\n" + "\tEndPrimitive();\n"); + geomShaderSrc.append("}\n"); + GrGLuint geomShaderId = + GrGLCompileAndAttachShader(glCtx, programId, + GR_GL_GEOMETRY_SHADER, geomShaderSrc, + fProgramBuilder->gpu()->stats()); + if (!geomShaderId) { + return false; + } + *shaderIds->append() = geomShaderId; + return true; } diff --git a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h index c4c019b..88fa298 100644 --- a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h @@ -22,7 +22,7 @@ private: */ void addVarying(const char* name, GrGLVarying*); - bool compileAndAttachShaders(GrGLuint programId, SkTDArray* shaderIds); + bool compileAndAttachShaders(GrGLuint programId, SkTDArray* shaderIds) const; friend class GrGLProgramBuilder; diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h index 46d2816..37908f9 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -356,12 +356,7 @@ protected: }; class AutoStageAdvance { public: - AutoStageAdvance(GrGLProgramBuilder* pb) - : fPB(pb) { - fPB->reset(); - // Each output to the fragment processor gets its own code section - fPB->fFS.nextStage(); - } + AutoStageAdvance(GrGLProgramBuilder* pb) : fPB(pb) { fPB->reset(); } ~AutoStageAdvance() { fPB->exitStage(); } private: GrGLProgramBuilder* fPB; diff --git a/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp b/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp index 0280298..27f4b44 100644 --- a/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp +++ b/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp @@ -12,86 +12,69 @@ class GLSLPrettyPrint { public: GLSLPrettyPrint() {} - SkString prettify(const char** strings, - int* lengths, - int count, - bool countlines) { + SkString prettify(const SkString& input, bool countlines) { + // setup pretty state + fIndex = 0; + fLength = input.size(); + fInput = input; fCountlines = countlines; fTabs = 0; fLinecount = 1; fFreshline = true; - // If a string breaks while in the middle 'parse until' we need to continue parsing on the - // next string - fInParseUntilNewline = false; - fInParseUntil = false; - 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]; - - 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 (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(input[fIndex]); } } return fPretty; @@ -124,11 +107,9 @@ private: if ('\n' == fInput[fIndex]) { fIndex++; this->newline(); - fInParseUntilNewline = false; break; } fPretty.appendf("%c", fInput[fIndex++]); - fInParseUntilNewline = true; } } @@ -146,13 +127,10 @@ private: fIndex++; } if (this->hasToken(token)) { - fInParseUntil = false; break; } fFreshline = false; fPretty.appendf("%c", fInput[fIndex++]); - fInParseUntil = true; - fInParseUntilToken = token; } } @@ -184,21 +162,12 @@ private: bool fCountlines, fFreshline; int fTabs, fLinecount; size_t fIndex, fLength; - const char* fInput; - SkString fPretty; - - // Some helpers for parseUntil when we go over a string length - bool fInParseUntilNewline; - bool fInParseUntil; - const char* fInParseUntilToken; + SkString fInput, fPretty; }; -SkString PrettyPrintGLSL(const char** strings, - int* lengths, - int count, - bool countlines) { +SkString PrettyPrintGLSL(const SkString& input, bool countlines) { GLSLPrettyPrint pp; - return pp.prettify(strings, lengths, count, countlines); + return pp.prettify(input, countlines); } } // end namespace diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.cpp b/src/gpu/gl/builders/GrGLShaderBuilder.cpp index 0711c91..4887225 100644 --- a/src/gpu/gl/builders/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLShaderBuilder.cpp @@ -7,7 +7,7 @@ #include "GrGLShaderBuilder.h" #include "GrGLProgramBuilder.h" -#include "GrGLShaderStringBuilder.h" +#include "GrGLProgramBuilder.h" #include "../GrGLGpu.h" #include "../GrGLShaderVar.h" @@ -59,17 +59,7 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGLProgramBuilder* program) : fProgramBuilder(program) , fInputs(GrGLProgramBuilder::kVarsPerBlock) , fOutputs(GrGLProgramBuilder::kVarsPerBlock) - , fFeaturesAddedMask(0) - , fCodeIndex(kCode) - , fFinalized(false) { - // 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(NULL); - fCompilerStringLengths.push_back(0); - } - - this->main() = "void main() {"; + , fFeaturesAddedMask(0) { } void GrGLShaderBuilder::declAppend(const GrGLShaderVar& var) { @@ -84,20 +74,20 @@ void GrGLShaderBuilder::emitFunction(GrSLType returnType, const GrGLShaderVar* args, const char* body, SkString* outName) { - this->functions().append(GrGLSLTypeString(returnType)); + fFunctions.append(GrGLSLTypeString(returnType)); fProgramBuilder->nameVariable(outName, '\0', name); - this->functions().appendf(" %s", outName->c_str()); - this->functions().append("("); + fFunctions.appendf(" %s", outName->c_str()); + fFunctions.append("("); const GrGLContextInfo& ctxInfo = fProgramBuilder->gpu()->ctxInfo(); for (int i = 0; i < argCnt; ++i) { - args[i].appendDecl(ctxInfo, &this->functions()); + args[i].appendDecl(ctxInfo, &fFunctions); if (i < argCnt - 1) { - this->functions().append(", "); + fFunctions.append(", "); } } - this->functions().append(") {\n"); - this->functions().append(body); - this->functions().append("}\n\n"); + fFunctions.append(") {\n"); + fFunctions.append(body); + fFunctions.append("}\n\n"); } void GrGLShaderBuilder::appendTextureLookup(SkString* out, @@ -116,7 +106,7 @@ void GrGLShaderBuilder::appendTextureLookup(SkString* out, void GrGLShaderBuilder::appendTextureLookup(const TextureSampler& sampler, const char* coordName, GrSLType varyingType) { - this->appendTextureLookup(&this->code(), sampler, coordName, varyingType); + this->appendTextureLookup(&fCode, sampler, coordName, varyingType); } void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation, @@ -147,8 +137,8 @@ const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, cons void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) { if (!(featureBit & fFeaturesAddedMask)) { - this->extensions().appendf("#extension %s: require\n", extensionName); - fFeaturesAddedMask |= featureBit; + fExtensions.appendf("#extension %s: require\n", extensionName); + fFeaturesAddedMask |= featureBit; } } @@ -163,7 +153,7 @@ void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, const char* coordName, uint32_t configComponentMask, const char* swizzle) { - append_texture_lookup(&this->code(), + append_texture_lookup(&fCode, fProgramBuilder->gpu(), samplerName, coordName, @@ -171,34 +161,3 @@ void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, swizzle, kVec2f_GrSLType); } - -bool -GrGLShaderBuilder::finalize(GrGLuint programId, GrGLenum type, SkTDArray* shaderIds) { - SkASSERT(!fFinalized); - // append the 'footer' to code - this->code().append("}"); - - for (int i = 0; i <= fCodeIndex; i++) { - fCompilerStrings[i] = fShaderStrings[i].c_str(); - fCompilerStringLengths[i] = fShaderStrings[i].size(); - } - - GrGLGpu* gpu = fProgramBuilder->gpu(); - GrGLuint shaderId = GrGLCompileAndAttachShader(gpu->glContext(), - programId, - type, - fCompilerStrings.begin(), - fCompilerStringLengths.begin(), - fCompilerStrings.count(), - gpu->stats()); - - fFinalized = true; - - if (!shaderId) { - return false; - } - - *shaderIds->append() = shaderId; - - return true; -} diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.h b/src/gpu/gl/builders/GrGLShaderBuilder.h index 86db597..8b7b9f9 100644 --- a/src/gpu/gl/builders/GrGLShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLShaderBuilder.h @@ -8,7 +8,6 @@ #ifndef GrGLShaderBuilder_DEFINED #define GrGLShaderBuilder_DEFINED -#include "SkTArray.h" #include "gl/GrGLProcessor.h" #include "gl/GrGLProgramDesc.h" #include "gl/GrGLProgramDataManager.h" @@ -74,16 +73,16 @@ public: void codeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { va_list args; va_start(args, format); - this->code().appendVAList(format, args); + fCode.appendVAList(format, args); va_end(args); } - void codeAppend(const char* str) { this->code().append(str); } + void codeAppend(const char* str) { fCode.append(str); } void codePrependf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { va_list args; va_start(args, format); - this->code().prependVAList(format, args); + fCode.prependVAList(format, args); va_end(args); } @@ -139,40 +138,8 @@ protected: */ void addFeature(uint32_t featureBit, const char* extensionName); - void nextStage() { - fShaderStrings.push_back(); - fCompilerStrings.push_back(this->code().c_str()); - fCompilerStringLengths.push_back(this->code().size()); - fCodeIndex++; - } - - SkString& versionDecl() { return fShaderStrings[kVersionDecl]; } - SkString& extensions() { return fShaderStrings[kExtensions]; } - SkString& precisionQualifier() { return fShaderStrings[kPrecisionQualifier]; } - SkString& uniforms() { return fShaderStrings[kUniforms]; } - SkString& inputs() { return fShaderStrings[kInputs]; } - SkString& outputs() { return fShaderStrings[kOutputs]; } - SkString& functions() { return fShaderStrings[kFunctions]; } - SkString& main() { return fShaderStrings[kMain]; } - SkString& code() { return fShaderStrings[fCodeIndex]; } - bool finalize(GrGLuint programId, GrGLenum type, SkTDArray* shaderIds); - - enum { - kVersionDecl, - kExtensions, - kPrecisionQualifier, - kUniforms, - kInputs, - kOutputs, - kFunctions, - kMain, - kCode, - }; - GrGLProgramBuilder* fProgramBuilder; - SkSTArray fCompilerStrings; - SkSTArray fCompilerStringLengths; - SkSTArray fShaderStrings; + SkString fCode; SkString fFunctions; SkString fExtensions; @@ -180,9 +147,5 @@ protected: VarArray fInputs; VarArray fOutputs; uint32_t fFeaturesAddedMask; - int fCodeIndex; - bool fFinalized; - - friend class GrGLProgramBuilder; }; #endif diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp index 59e0cd8..1e75048 100644 --- a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp +++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp @@ -20,9 +20,7 @@ SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, GrGLuint programId, GrGLenum type, - const char** strings, - int* lengths, - int count, + const SkString& shaderSrc, GrGpu::Stats* stats) { const GrGLInterface* gli = glCtx.interface(); @@ -33,23 +31,14 @@ GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, } #ifdef SK_DEBUG - SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, count, false); + SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, false); const GrGLchar* sourceStr = prettySource.c_str(); GrGLint sourceLength = static_cast(prettySource.size()); - GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); #else - GR_GL_CALL(gli, ShaderSource(shaderId, count, strings, lengths)); + GrGLint sourceLength = static_cast(shaderSrc.size()); + const GrGLchar* sourceStr = shaderSrc.c_str(); #endif - - // If tracing is enabled in chrome then we pretty print - bool traceShader; - TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), &traceShader); - if (traceShader) { - SkString shader = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, count, false); - TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::GLShader", - TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(shader.c_str())); - } - + GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); stats->incShaderCompilations(); GR_GL_CALL(gli, CompileShader(shaderId)); @@ -70,8 +59,9 @@ GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, // retrieve length even though we don't need it to workaround bug in Chromium cmd // buffer param validation. GrGLsizei length = GR_GL_INIT_ZERO; - GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, &length, (char*)log.get())); - SkDebugf(GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, count, true).c_str()); + GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, + &length, (char*)log.get())); + SkDebugf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str()); SkDebugf("\n%s", log.get()); } SkDEBUGFAIL("Shader compilation failed!"); @@ -80,8 +70,10 @@ GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, } } + TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::GLShader", + TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(shaderSrc.c_str())); if (c_PrintShaders) { - SkDebugf(GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, count, true).c_str()); + SkDebugf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str()); SkDebugf("\n"); } diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.h b/src/gpu/gl/builders/GrGLShaderStringBuilder.h index 062e229..cf54253 100644 --- a/src/gpu/gl/builders/GrGLShaderStringBuilder.h +++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.h @@ -16,9 +16,7 @@ GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, GrGLuint programId, GrGLenum type, - const char** strings, - int* lengths, - int count, + const SkString& shaderSrc, GrGpu::Stats*); #endif diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp index 00e96a5..f1671af 100644 --- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp @@ -7,6 +7,7 @@ #include "GrGLVertexShaderBuilder.h" #include "GrGLProgramBuilder.h" +#include "GrGLShaderStringBuilder.h" #include "../GrGLGpu.h" #define GL_CALL(X) GR_GL_CALL(fProgramBuilder->gpu()->glInterface(), X) @@ -72,13 +73,25 @@ void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) { return; } -bool -GrGLVertexBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArray* shaderIds) { - this->versionDecl() = GrGetGLSLVersionDecl(fProgramBuilder->ctxInfo()); - fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kVertex_Visibility, &this->uniforms()); - this->appendDecls(fInputs, &this->inputs()); - this->appendDecls(fOutputs, &this->outputs()); - return this->finalize(programId, GR_GL_VERTEX_SHADER, shaderIds); +bool GrGLVertexBuilder::compileAndAttachShaders(GrGLuint programId, + SkTDArray* shaderIds) const { + GrGLGpu* gpu = fProgramBuilder->gpu(); + const GrGLContext& glCtx = gpu->glContext(); + const GrGLContextInfo& ctxInfo = gpu->ctxInfo(); + SkString vertShaderSrc(GrGetGLSLVersionDecl(ctxInfo)); + fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kVertex_Visibility, &vertShaderSrc); + this->appendDecls(fInputs, &vertShaderSrc); + this->appendDecls(fOutputs, &vertShaderSrc); + vertShaderSrc.append("void main() {"); + vertShaderSrc.append(fCode); + vertShaderSrc.append("}\n"); + GrGLuint vertShaderId = GrGLCompileAndAttachShader(glCtx, programId, GR_GL_VERTEX_SHADER, + vertShaderSrc, gpu->stats()); + if (!vertShaderId) { + return false; + } + *shaderIds->append() = vertShaderId; + return true; } bool GrGLVertexBuilder::addAttribute(const GrShaderVar& var) { diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h index 71a60a0..4c99a7b 100644 --- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h @@ -35,7 +35,7 @@ private: * private helpers for compilation by GrGLProgramBuilder */ void bindVertexAttributes(GrGLuint programID); - bool compileAndAttachShaders(GrGLuint programId, SkTDArray* shaderIds); + bool compileAndAttachShaders(GrGLuint programId, SkTDArray* shaderIds) const; // an internal call which checks for uniquness of a var before adding it to the list of inputs bool addAttribute(const GrShaderVar& var); diff --git a/tests/GrGLSLPrettyPrintTest.cpp b/tests/GrGLSLPrettyPrintTest.cpp index 37aa5a8..9977488 100644 --- a/tests/GrGLSLPrettyPrintTest.cpp +++ b/tests/GrGLSLPrettyPrintTest.cpp @@ -13,16 +13,12 @@ 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" + "void main()" + "{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;} " + " comment\n is" + " dangerous\ndo so at your own\n risk*/;\n\n\t\t\t\n" + "//a comment\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(;;) {} }"); @@ -56,7 +52,7 @@ const SkString output1( " 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" + " 30\t\t\t\t\t\t//a comment\n" " 31\t\t\t\t\t}\n" " 32\t\t\t\t}\n" " 33\t\t\t\ta;\n" @@ -81,43 +77,16 @@ const SkString output1( " 52\t}\n" " 53\t"); -const SkString neg1("{;;{{{{;;;{{{{{{{{{{{"); -const SkString neg2("###\n##\n#####(((((((((((((unbalanced verything;;;"); -const SkString neg3("}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}" +const SkString input2("{;;{{{{;;;{{{{{{{{{{{###\n##\n#####(((((((((((((unbalanced verything;;;" + "}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}" ";;;;;;/////"); DEF_TEST(GrGLSLPrettyPrint, r) { - SkTArray testStr; - SkTArray lengths; - testStr.push_back(input1.c_str()); - lengths.push_back(input1.size()); - testStr.push_back(input2.c_str()); - lengths.push_back(input2.size()); - testStr.push_back(input3.c_str()); - lengths.push_back(input3.size()); - testStr.push_back(input4.c_str()); - lengths.push_back(input4.size()); - testStr.push_back(input5.c_str()); - lengths.push_back(input5.size()); - testStr.push_back(input6.c_str()); - lengths.push_back(input6.size()); - - SkString test = GrGLSLPrettyPrint::PrettyPrintGLSL(testStr.begin(), lengths.begin(), - testStr.count(), true); + SkString test = GrGLSLPrettyPrint::PrettyPrintGLSL(input1, true); ASSERT(output1 == test); - testStr.reset(); - lengths.reset(); - testStr.push_back(neg1.c_str()); - lengths.push_back(neg1.size()); - testStr.push_back(neg2.c_str()); - lengths.push_back(neg2.size()); - testStr.push_back(neg3.c_str()); - lengths.push_back(neg3.size()); - // Just test we don't crash with garbage input - ASSERT(GrGLSLPrettyPrint::PrettyPrintGLSL(testStr.begin(), lengths.begin(), 1, - true).c_str() != NULL); + ASSERT(GrGLSLPrettyPrint::PrettyPrintGLSL(input2, true).c_str() != NULL); } #endif -- 2.7.4