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 |