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 |