diff options
author | 2015-08-18 07:24:29 -0700 | |
---|---|---|
committer | 2015-08-18 07:24:29 -0700 | |
commit | 69ed114d388c56e83a2385d8b8182e6d05a0b073 (patch) | |
tree | 97d7b6d63ecdafa81d2af8d4dc95bdee2dd51e1c /src/gpu/gl/builders | |
parent | 94c902e63d77641cadd76155c2b248d04f63b560 (diff) |
Added class AutoFragmentChildProcAdvance to be constructed before a child emitCode and destructed after
Fixed wrong indent
Changed auto child advance back to backwards linear search for getting subset of coords and samplers array of a child
Used offset from parent instead of backwards linear search to find a child proc's coords and transforms in Auto...Advance
append mangleString to variable name in nameVariable()
BUILDS! Added AutoFragmentChildProcAdvance class; fixed a few errors from previous commits
BUG=skia:4182
Review URL: https://codereview.chromium.org/1286293002
Diffstat (limited to 'src/gpu/gl/builders')
-rw-r--r-- | src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp | 82 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLFragmentShaderBuilder.h | 31 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.cpp | 2 |
3 files changed, 114 insertions, 1 deletions
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp index 20bb3a3893..71434154dd 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp @@ -312,3 +312,85 @@ void GrGLFragmentBuilder::onAfterChildProcEmitCode() { int removeAt = fMangleString.findLastOf('_'); fMangleString.remove(removeAt, fMangleString.size() - removeAt); } + +GrGLFragmentBuilder::AutoFragmentChildProcAdvance::AutoFragmentChildProcAdvance( + int childProcIndex, + GrGLFPBuilder* builder, + const GrFragmentProcessor& fp, + const char* outputColor, + const TransformedCoordsArray& coords, + const TextureSamplerArray& samplers, + const GrFragmentProcessor** childFp, + SkString* childOutputColor, + TransformedCoordsArray* childCoords, + TextureSamplerArray* childSamplers + ) { + fFsb = builder->getFragmentShaderBuilder(); + fFsb->onBeforeChildProcEmitCode(); // call first so mangleString is updated + + const GrFragmentProcessor& childProc = fp.childProcessor(childProcIndex); + *childFp = &childProc; + + // Mangle the name of the outputColor + childOutputColor->set(outputColor); + childOutputColor->append(fFsb->getMangleStringThisLevel()); + + /* + * We now want to find the subset of coords and samplers that belong to the child and its + * descendants and put that into childCoords and childSamplers. To do so, we must do a + * backwards linear search on coords and samplers. + * + * Explanation: + * Each GrFragmentProcessor has a copy of all the transforms and textures of itself and + * all procs in its subtree. For example, suppose we have frag proc A, who has two children B + * and D. B has a child C, and D has two children E and F. Each frag proc's transforms array + * contains its own transforms, followed by the transforms of all its descendants (i.e. preorder + * traversal). Suppose procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 transforms respectively. + * + * (A) + * [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2] + * / \ + * / \ + * (B) (D) + * [b1,b2,c1] [d1,e1,e2,e3,f1,f2] + * / / \ + * / / \ + * (C) (E) (F) + * [c1] [e1,e2,e3] [f1,f2] + * + * So if we're inside proc A's emitCode, and A is about to call emitCode on proc B, we want the + * EmitArgs that's passed onto B to only contain its and its descendants' coords. The + * EmitArgs given to A would contain the transforms [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2], and we want + * to extract the subset [b1,b2,c1] to pass on to B. We can do this with a backwards linear + * search since we know that D's subtree has 6 transforms and B's subtree has 3 transforms (by + * calling D.numTextures() and B.numTextures()), so we know the start of B's transforms is 9 + * from the end of A's transforms. We cannot do this with a forwards linear search since we + * don't know how many transforms belong to A (A.numTextures() will return 10, not 1), so + * we wouldn't know how many transforms to initially skip in A's array if using a forward linear + * search. + * Textures work the same way as transforms. + */ + SkASSERT(childCoords->empty()); + SkASSERT(childSamplers->empty()); + int firstCoordAt = fp.numTransforms(); + int firstSamplerAt = fp.numTextures(); + for (int i = fp.numChildProcessors() - 1; i >= childProcIndex; --i) { + firstCoordAt -= fp.childProcessor(i).numTransforms(); + firstSamplerAt -= fp.childProcessor(i).numTextures(); + } + if (!coords.empty()) { + childCoords->push_back_n(childProc.numTransforms(), &coords[firstCoordAt]); + } + if (!samplers.empty()) { + childSamplers->push_back_n(childProc.numTextures(), &samplers[firstSamplerAt]); + } + + fFsb->codeAppendf("vec4 %s;\n", childOutputColor->c_str()); + fFsb->codeAppend("{\n"); + fFsb->codeAppendf("// Child %d: %s\n", fFsb->getChildNumberThisLevel(), childProc.name()); +} + +GrGLFragmentBuilder::AutoFragmentChildProcAdvance::~AutoFragmentChildProcAdvance() { + fFsb->codeAppend("}\n"); + fFsb->onAfterChildProcEmitCode(); +} diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h index 8746fffb8b..514bcc6e88 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h @@ -77,6 +77,37 @@ public: return ret; } + /* This class is like AutoStageAdvance but used for the child procs of a fragment proc. + * Before a proc calls emitCode on one of its children, it should instantiate this + * class inside its own scope. This which will update a state in GrGLFragmentBuilder that tracks + * which proc in the tree is about to emit code (it does so by calling GrGLFragmentBuilder:: + * onBeforeChildProcEmitCode() in the constructor). + * + * After the child proc emitCode is called, the parent proc should end the scope so the + * AutoFragmentChildProcAdvance destructor is called, which will again update a state in + * GrGLFragmentShaderBuilder notifying it that the child proc's code has been emitted (it does + * so by calling GrGLFragmentBuilder::onAfterChildProcEmitCode()). + */ + class AutoFragmentChildProcAdvance { + typedef GrGLProcessor::TransformedCoordsArray TransformedCoordsArray; + typedef GrGLProcessor::TextureSamplerArray TextureSamplerArray; + public: + AutoFragmentChildProcAdvance(int childProcIndex, + GrGLFPBuilder* builder, + const GrFragmentProcessor& fp, + const char* outputColor, + const TransformedCoordsArray& coords, + const TextureSamplerArray& samplers, + const GrFragmentProcessor** childFp, + SkString* childOutputColor, + TransformedCoordsArray* childCoords, + TextureSamplerArray* childSamplers); + + ~AutoFragmentChildProcAdvance(); + private: + GrGLFragmentBuilder* fFsb; + }; + private: /* * State that tracks which child proc in the proc tree is currently emitting code. This is diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index 079b129cb1..2db568693d 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -124,7 +124,7 @@ void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* na // Names containing "__" are reserved. out->append("x"); } - out->appendf("_Stage%d", fStageIndex); + out->appendf("_Stage%d%s", fStageIndex, fFS.getMangleString().c_str()); } } |