From 7ef45a1aeb2c764d41838323f5bcff149c5de756 Mon Sep 17 00:00:00 2001 From: wangyix Date: Thu, 13 Aug 2015 06:51:35 -0700 Subject: Added mangleString member and onBefore*, onAfter* functions to GrGLFragmentShaderBuilder BUILDS! Added mangleString, onBefore, and onAfterChildProcEmitCode() to GrGLFragmentShaderBuilder.cpp BUG=skia:4182 Review URL: https://codereview.chromium.org/1288723002 --- include/core/SkString.h | 9 ++++ src/gpu/GrProcessor.cpp | 3 +- src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp | 12 ++++++ src/gpu/gl/builders/GrGLFragmentShaderBuilder.h | 52 ++++++++++++++++++++++- 4 files changed, 74 insertions(+), 2 deletions(-) diff --git a/include/core/SkString.h b/include/core/SkString.h index e0a51c6515..ea73e09823 100644 --- a/include/core/SkString.h +++ b/include/core/SkString.h @@ -39,6 +39,12 @@ static int SkStrFind(const char string[], const char substring[]) { return SkToS32(first - &string[0]); } +static int SkStrFindLastOf(const char string[], const char subchar) { + const char* last = strrchr(string, subchar); + if (NULL == last) return -1; + return SkToS32(last - &string[0]); +} + static bool SkStrContains(const char string[], const char substring[]) { SkASSERT(string); SkASSERT(substring); @@ -152,6 +158,9 @@ public: int find(const char substring[]) const { return SkStrFind(fRec->data(), substring); } + int findLastOf(const char subchar) const { + return SkStrFindLastOf(fRec->data(), subchar); + } friend bool operator==(const SkString& a, const SkString& b) { return a.equals(b); diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp index 6cc2a20d71..39c55a60e4 100644 --- a/src/gpu/GrProcessor.cpp +++ b/src/gpu/GrProcessor.cpp @@ -150,8 +150,9 @@ int GrFragmentProcessor::registerChildProcessor(const GrFragmentProcessor* child int index = fChildProcessors.count(); fChildProcessors.push_back(GrFragmentStage(child)); - if (child->willReadFragmentPosition()) + if (child->willReadFragmentPosition()) { this->setWillReadFragmentPosition(); + } return index; } diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp index a7a35e3676..20bb3a3893 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp @@ -300,3 +300,15 @@ void GrGLFragmentShaderBuilder::addVarying(GrGLVarying* v, GrSLPrecision fsPrec) } fInputs.push_back().set(v->fType, GrGLShaderVar::kVaryingIn_TypeModifier, v->fFsIn, fsPrec); } + +void GrGLFragmentBuilder::onBeforeChildProcEmitCode() { + fSubstageIndices.back()++; + fSubstageIndices.push_back(0); + fMangleString.append(this->getMangleStringThisLevel()); +} + +void GrGLFragmentBuilder::onAfterChildProcEmitCode() { + fSubstageIndices.pop_back(); + int removeAt = fMangleString.findLastOf('_'); + fMangleString.remove(removeAt, fMangleString.size() - removeAt); +} diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h index 2b3e18d763..8746fffb8b 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h @@ -17,7 +17,10 @@ class GrGLVarying; */ class GrGLFragmentBuilder : public GrGLShaderBuilder { public: - GrGLFragmentBuilder(GrGLProgramBuilder* program) : INHERITED(program) {} + GrGLFragmentBuilder(GrGLProgramBuilder* program) + : INHERITED(program) { + fSubstageIndices.push_back(0); + } virtual ~GrGLFragmentBuilder() {} /** * Use of these features may require a GLSL extension to be enabled. Shaders may not compile @@ -47,7 +50,54 @@ public: is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */ virtual const char* fragmentPosition() = 0; + /** + * Fragment procs with child procs should call these functions before/after calling emitCode + * on a child proc. + */ + void onBeforeChildProcEmitCode(); + void onAfterChildProcEmitCode(); + + int getChildNumberThisLevel() const { + if (fSubstageIndices.count() > 1) { + // second-to-last value in the fSubstageIndices stack is the index of the child proc + // at that level which is currently emitting code. + return fSubstageIndices[fSubstageIndices.count() - 2]; + } + return -1; + } + + const SkString& getMangleString() const { return fMangleString; } + + SkString getMangleStringThisLevel() const { + SkString ret; + int childNumber = this->getChildNumberThisLevel(); + if (childNumber >= 0) { + ret.printf("_c%d", childNumber); + } + return ret; + } + private: + /* + * State that tracks which child proc in the proc tree is currently emitting code. This is + * used to update the fMangleString, which is used to mangle the names of uniforms and functions + * emitted by the proc. fSubstageIndices is a stack: its count indicates how many levels deep + * we are in the tree, and its second-to-last value is the index of the child proc at that + * level which is currently emitting code. For example, if fSubstageIndices = [3, 1, 2, 0], that + * means we're currently emitting code for the base proc's 3rd child's 1st child's 2nd child. + */ + SkTArray fSubstageIndices; + + /* + * The mangle string is used to mangle the names of uniforms/functions emitted by the child + * procs so no duplicate uniforms/functions appear in the generated shader program. The mangle + * string is simply based on fSubstageIndices. For example, if fSubstageIndices = [3, 1, 2, 0], + * then the manglestring will be "_c3_c1_c2", and any uniform/function emitted by that proc will + * have "_c3_c1_c2" appended to its name, which can be interpreted as "base proc's 3rd child's + * 1st child's 2nd child". + */ + SkString fMangleString; + friend class GrGLPathProcessor; typedef GrGLShaderBuilder INHERITED; -- cgit v1.2.3