OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 "GrGLFragmentShaderBuilder.h" | 8 #include "GrGLFragmentShaderBuilder.h" |
9 #include "GrGLProgramBuilder.h" | 9 #include "GrGLProgramBuilder.h" |
10 #include "gl/GrGLGpu.h" | 10 #include "gl/GrGLGpu.h" |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 fSubstageIndices.back()++; | 305 fSubstageIndices.back()++; |
306 fSubstageIndices.push_back(0); | 306 fSubstageIndices.push_back(0); |
307 fMangleString.append(this->getMangleStringThisLevel()); | 307 fMangleString.append(this->getMangleStringThisLevel()); |
308 } | 308 } |
309 | 309 |
310 void GrGLFragmentBuilder::onAfterChildProcEmitCode() { | 310 void GrGLFragmentBuilder::onAfterChildProcEmitCode() { |
311 fSubstageIndices.pop_back(); | 311 fSubstageIndices.pop_back(); |
312 int removeAt = fMangleString.findLastOf('_'); | 312 int removeAt = fMangleString.findLastOf('_'); |
313 fMangleString.remove(removeAt, fMangleString.size() - removeAt); | 313 fMangleString.remove(removeAt, fMangleString.size() - removeAt); |
314 } | 314 } |
315 | |
316 GrGLFragmentBuilder::AutoFragmentChildProcAdvance::AutoFragmentChildProcAdvance( | |
317 int childProcIndex, | |
318 GrGLFPBuilder* builder, | |
319 const GrFragmentProcessor& f
p, | |
320 const char* outputColor, | |
321 const TransformedCoordsArray
& coords, | |
322 const TextureSamplerArray& s
amplers, | |
323 const GrFragmentProcessor**
childFp, | |
324 SkString* childOutputColor, | |
325 TransformedCoordsArray* chil
dCoords, | |
326 TextureSamplerArray* childSa
mplers | |
327 ) { | |
328 fFsb = builder->getFragmentShaderBuilder(); | |
329 fFsb->onBeforeChildProcEmitCode(); // call first so mangleString is updated | |
330 | |
331 const GrFragmentProcessor& childProc = fp.childProcessor(childProcIndex); | |
332 *childFp = &childProc; | |
333 | |
334 // Mangle the name of the outputColor | |
335 childOutputColor->set(outputColor); | |
336 childOutputColor->append(fFsb->getMangleStringThisLevel()); | |
337 | |
338 /* | |
339 * We now want to find the subset of coords and samplers that belong to the
child and its | |
340 * descendants and put that into childCoords and childSamplers. To do so, we
must do a | |
341 * backwards linear search on coords and samplers. | |
342 * | |
343 * Explanation: | |
344 * Each GrFragmentProcessor has a copy of all the transforms and textures of
itself and | |
345 * all procs in its subtree. For example, suppose we have frag proc A, who h
as two children B | |
346 * and D. B has a child C, and D has two children E and F. Each frag proc's
transforms array | |
347 * contains its own transforms, followed by the transforms of all its descen
dants (i.e. preorder | |
348 * traversal). Suppose procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 transfor
ms respectively. | |
349 * | |
350 * (A) | |
351 * [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2] | |
352 * / \ | |
353 * / \ | |
354 * (B) (D) | |
355 * [b1,b2,c1] [d1,e1,e2,e3,f1,f2] | |
356 * / / \ | |
357 * / / \ | |
358 * (C) (E) (F) | |
359 * [c1] [e1,e2,e3] [f1,f2] | |
360 * | |
361 * So if we're inside proc A's emitCode, and A is about to call emitCode on
proc B, we want the | |
362 * EmitArgs that's passed onto B to only contain its and its descendants' co
ords. The | |
363 * EmitArgs given to A would contain the transforms [a1,b1,b2,c1,d1,e1,e2,e3
,f1,f2], and we want | |
364 * to extract the subset [b1,b2,c1] to pass on to B. We can do this with a b
ackwards linear | |
365 * search since we know that D's subtree has 6 transforms and B's subtree ha
s 3 transforms (by | |
366 * calling D.numTextures() and B.numTextures()), so we know the start of B's
transforms is 9 | |
367 * from the end of A's transforms. We cannot do this with a forwards linear
search since we | |
368 * don't know how many transforms belong to A (A.numTextures() will return 1
0, not 1), so | |
369 * we wouldn't know how many transforms to initially skip in A's array if us
ing a forward linear | |
370 * search. | |
371 * Textures work the same way as transforms. | |
372 */ | |
373 SkASSERT(childCoords->empty()); | |
374 SkASSERT(childSamplers->empty()); | |
375 int firstCoordAt = fp.numTransforms(); | |
376 int firstSamplerAt = fp.numTextures(); | |
377 for (int i = fp.numChildProcessors() - 1; i >= childProcIndex; --i) { | |
378 firstCoordAt -= fp.childProcessor(i).numTransforms(); | |
379 firstSamplerAt -= fp.childProcessor(i).numTextures(); | |
380 } | |
381 if (!coords.empty()) { | |
382 childCoords->push_back_n(childProc.numTransforms(), &coords[firstCoordAt
]); | |
383 } | |
384 if (!samplers.empty()) { | |
385 childSamplers->push_back_n(childProc.numTextures(), &samplers[firstSampl
erAt]); | |
386 } | |
387 | |
388 fFsb->codeAppendf("vec4 %s;\n", childOutputColor->c_str()); | |
389 fFsb->codeAppend("{\n"); | |
390 fFsb->codeAppendf("// Child %d: %s\n", fFsb->getChildNumberThisLevel(), chil
dProc.name()); | |
391 } | |
392 | |
393 GrGLFragmentBuilder::AutoFragmentChildProcAdvance::~AutoFragmentChildProcAdvance
() { | |
394 fFsb->codeAppend("}\n"); | |
395 fFsb->onAfterChildProcEmitCode(); | |
396 } | |
OLD | NEW |