| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrGLSLFragmentProcessor.h" | 8 #include "GrGLSLFragmentProcessor.h" |
| 9 #include "GrFragmentProcessor.h" | 9 #include "GrFragmentProcessor.h" |
| 10 #include "GrProcessor.h" | 10 #include "GrProcessor.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 } | 35 } |
| 36 | 36 |
| 37 void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
tColor, | 37 void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
tColor, |
| 38 const char* outputColor, EmitArg
s& args) { | 38 const char* outputColor, EmitArg
s& args) { |
| 39 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; | 39 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; |
| 40 | 40 |
| 41 fragBuilder->onBeforeChildProcEmitCode(); // call first so mangleString is
updated | 41 fragBuilder->onBeforeChildProcEmitCode(); // call first so mangleString is
updated |
| 42 | 42 |
| 43 const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex); | 43 const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex); |
| 44 | 44 |
| 45 /* | |
| 46 * TODO: Move textures and buffers to the iterator model used by coords. | |
| 47 * We now want to find the subset of samplers that belong to the child and i
ts descendants and | |
| 48 * put that into childSamplers. To do so, we'll do a forwards linear search. | |
| 49 * | |
| 50 * Explanation: | |
| 51 * Each GrFragmentProcessor has a copy of all the textures of itself and all
procs in its | |
| 52 * subtree. For example, suppose we have frag proc A, who has two children B
and D. B has a | |
| 53 * child C, and D has two children E and F. Each frag proc's textures array
contains its own | |
| 54 * textures, followed by the textures of all its descendants (i.e. preorder
traversal). Suppose | |
| 55 * procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 textures respectively. | |
| 56 * | |
| 57 * (A) | |
| 58 * [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2] | |
| 59 * / \ | |
| 60 * / \ | |
| 61 * (B) (D) | |
| 62 * [b1,b2,c1] [d1,e1,e2,e3,f1,f2] | |
| 63 * / / \ | |
| 64 * / / \ | |
| 65 * (C) (E) (F) | |
| 66 * [c1] [e1,e2,e3] [f1,f2] | |
| 67 * | |
| 68 * So if we're inside proc A's emitCode, and A is about to call emitCode on
proc D, we want the | |
| 69 * EmitArgs that's passed onto D to only contain its and its descendants' te
xtures. The | |
| 70 * EmitArgs given to A would contain the textures [a1,b1,b2,c1,d1,e1,e2,e3,f
1,f2], and we want | |
| 71 * to extract the subset [d1,e1,e2,e3,f1,f2] to pass on to D. We can do this
with a linear | |
| 72 * search since we know that A has 1 texture (using A.numTexturesExclChildre
n()), and B's | |
| 73 * subtree has 3 textures (using B.numTextures()), so we know the start of D
's textures is | |
| 74 * 4 after the start of A's textures. | |
| 75 * Textures work the same way as textures. | |
| 76 */ | |
| 77 int firstTextureAt = args.fFp.numTexturesExclChildren(); | |
| 78 int firstBufferAt = args.fFp.numBuffersExclChildren(); | |
| 79 for (int i = 0; i < childIndex; ++i) { | |
| 80 firstTextureAt += args.fFp.childProcessor(i).numTextures(); | |
| 81 firstBufferAt += args.fFp.childProcessor(i).numBuffers(); | |
| 82 } | |
| 83 const SamplerHandle* childTexSamplers = nullptr; | |
| 84 const SamplerHandle* childBufferSamplers = nullptr; | |
| 85 if (childProc.numTextures() > 0) { | |
| 86 childTexSamplers = &args.fTexSamplers[firstTextureAt]; | |
| 87 } | |
| 88 if (childProc.numBuffers() > 0) { | |
| 89 childBufferSamplers = &args.fBufferSamplers[firstBufferAt]; | |
| 90 } | |
| 91 | |
| 92 // emit the code for the child in its own scope | 45 // emit the code for the child in its own scope |
| 93 fragBuilder->codeAppend("{\n"); | 46 fragBuilder->codeAppend("{\n"); |
| 94 fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex, | 47 fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex, |
| 95 fragBuilder->getMangleString().c_str(), childProc.n
ame()); | 48 fragBuilder->getMangleString().c_str(), childProc.n
ame()); |
| 96 TransformedCoordVars coordVars = args.fTransformedCoords.childTransforms(chi
ldIndex); | 49 TransformedCoordVars coordVars = args.fTransformedCoords.childValues(childIn
dex); |
| 50 TextureSamplers textureSamplers = args.fTexSamplers.childValues(childIndex); |
| 51 BufferSamplers bufferSamplers = args.fBufferSamplers.childValues(childIndex)
; |
| 97 EmitArgs childArgs(fragBuilder, | 52 EmitArgs childArgs(fragBuilder, |
| 98 args.fUniformHandler, | 53 args.fUniformHandler, |
| 99 args.fGLSLCaps, | 54 args.fGLSLCaps, |
| 100 childProc, | 55 childProc, |
| 101 outputColor, | 56 outputColor, |
| 102 inputColor, | 57 inputColor, |
| 103 coordVars, | 58 coordVars, |
| 104 childTexSamplers, | 59 textureSamplers, |
| 105 childBufferSamplers, | 60 bufferSamplers, |
| 106 args.fGpImplementsDistanceVector); | 61 args.fGpImplementsDistanceVector); |
| 107 this->childProcessor(childIndex)->emitCode(childArgs); | 62 this->childProcessor(childIndex)->emitCode(childArgs); |
| 108 fragBuilder->codeAppend("}\n"); | 63 fragBuilder->codeAppend("}\n"); |
| 109 | 64 |
| 110 fragBuilder->onAfterChildProcEmitCode(); | 65 fragBuilder->onAfterChildProcEmitCode(); |
| 111 } | 66 } |
| 112 | 67 |
| 113 ////////////////////////////////////////////////////////////////////////////// | 68 ////////////////////////////////////////////////////////////////////////////// |
| 114 | 69 |
| 115 using TransformedCoordVars = GrGLSLFragmentProcessor::TransformedCoordVars; | 70 GrGLSLFragmentProcessor* GrGLSLFragmentProcessor::Iter::next() { |
| 116 TransformedCoordVars TransformedCoordVars::childTransforms(int childIdx) const { | 71 if (fFPStack.empty()) { |
| 117 const GrFragmentProcessor* child = &fFP->childProcessor(childIdx); | 72 return nullptr; |
| 118 GrFragmentProcessor::Iter iter(fFP); | |
| 119 int numToSkip = 0; | |
| 120 while (true) { | |
| 121 const GrFragmentProcessor* fp = iter.next(); | |
| 122 if (fp == child) { | |
| 123 return TransformedCoordVars(child, fTransformedVars + numToSkip); | |
| 124 } | |
| 125 numToSkip += fp->numCoordTransforms(); | |
| 126 } | 73 } |
| 74 GrGLSLFragmentProcessor* back = fFPStack.back(); |
| 75 fFPStack.pop_back(); |
| 76 for (int i = back->numChildProcessors() - 1; i >= 0; --i) { |
| 77 fFPStack.push_back(back->childProcessor(i)); |
| 78 } |
| 79 return back; |
| 127 } | 80 } |
| OLD | NEW |