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
This commit is contained in:
wangyix 2015-08-13 06:51:35 -07:00 committed by Commit bot
parent c8d3f577ae
commit 7ef45a1aeb
4 changed files with 74 additions and 2 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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<int> 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;