aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar wangyix <wangyix@google.com>2015-08-13 06:51:35 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-08-13 06:51:35 -0700
commit7ef45a1aeb2c764d41838323f5bcff149c5de756 (patch)
treee68b29b4c9caa932bf00461cb53135e4b11e1f50
parentc8d3f577aedda087529e25bc48bc64769e410f5a (diff)
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
-rw-r--r--include/core/SkString.h9
-rw-r--r--src/gpu/GrProcessor.cpp3
-rw-r--r--src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp12
-rw-r--r--src/gpu/gl/builders/GrGLFragmentShaderBuilder.h52
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<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;