| 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 |