| OLD | NEW | 
 | (Empty) | 
|    1 /* |  | 
|    2  * Copyright 2015 Google Inc. |  | 
|    3  * |  | 
|    4  * Use of this source code is governed by a BSD-style license that can be |  | 
|    5  * found in the LICENSE file. |  | 
|    6  */ |  | 
|    7  |  | 
|    8 #include "GrGLFragmentProcessor.h" |  | 
|    9 #include "GrFragmentProcessor.h" |  | 
|   10 #include "GrProcessor.h" |  | 
|   11 #include "glsl/GrGLSLFragmentShaderBuilder.h" |  | 
|   12 #include "glsl/GrGLSLProgramBuilder.h" |  | 
|   13  |  | 
|   14 void GrGLFragmentProcessor::setData(const GrGLSLProgramDataManager& pdman, |  | 
|   15                                     const GrFragmentProcessor& processor) { |  | 
|   16     this->onSetData(pdman, processor); |  | 
|   17     SkASSERT(fChildProcessors.count() == processor.numChildProcessors()); |  | 
|   18     for (int i = 0; i < fChildProcessors.count(); ++i) { |  | 
|   19         fChildProcessors[i]->setData(pdman, processor.childProcessor(i)); |  | 
|   20     } |  | 
|   21 } |  | 
|   22  |  | 
|   23 void GrGLFragmentProcessor::emitChild(int childIndex, const char* inputColor, Em
     itArgs& args) { |  | 
|   24     this->internalEmitChild(childIndex, inputColor, args.fOutputColor, args); |  | 
|   25 } |  | 
|   26  |  | 
|   27 void GrGLFragmentProcessor::emitChild(int childIndex, const char* inputColor, |  | 
|   28                                       SkString* outputColor, EmitArgs& args) { |  | 
|   29  |  | 
|   30     SkASSERT(outputColor); |  | 
|   31     GrGLSLFragmentBuilder* fb = args.fBuilder->getFragmentShaderBuilder(); |  | 
|   32     outputColor->append(fb->getMangleString()); |  | 
|   33     fb->codeAppendf("vec4 %s;", outputColor->c_str()); |  | 
|   34     this->internalEmitChild(childIndex, inputColor, outputColor->c_str(), args); |  | 
|   35 } |  | 
|   36  |  | 
|   37 void GrGLFragmentProcessor::internalEmitChild(int childIndex, const char* inputC
     olor, |  | 
|   38                                                const char* outputColor, EmitArgs
     & args) { |  | 
|   39     GrGLSLFragmentBuilder* fb = args.fBuilder->getFragmentShaderBuilder(); |  | 
|   40  |  | 
|   41     fb->onBeforeChildProcEmitCode();  // call first so mangleString is updated |  | 
|   42  |  | 
|   43     const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex); |  | 
|   44  |  | 
|   45     /* |  | 
|   46      * We now want to find the subset of coords and samplers that belong to the 
     child and its |  | 
|   47      * descendants and put that into childCoords and childSamplers. To do so, we
     'll do a forwards |  | 
|   48      * linear search. |  | 
|   49      * |  | 
|   50      * Explanation: |  | 
|   51      * Each GrFragmentProcessor has a copy of all the transforms and textures of
      itself and |  | 
|   52      * all procs in its subtree. For example, suppose we have frag proc A, who h
     as two children B |  | 
|   53      * and D. B has a child C, and D has two children E and F. Each frag proc's 
     transforms array |  | 
|   54      * contains its own transforms, followed by the transforms of all its descen
     dants (i.e. preorder |  | 
|   55      * traversal). Suppose procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 transfor
     ms 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' co
     ords. The |  | 
|   70      * EmitArgs given to A would contain the transforms [a1,b1,b2,c1,d1,e1,e2,e3
     ,f1,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 transform (using A.numTransformsExclChi
     ldren()), and B's |  | 
|   73      * subtree has 3 transforms (using B.numTransforms()), so we know the start 
     of D's transforms is |  | 
|   74      * 4 after the start of A's transforms. |  | 
|   75      * Textures work the same way as transforms. |  | 
|   76      */ |  | 
|   77     int firstCoordAt = args.fFp.numTransformsExclChildren(); |  | 
|   78     int firstSamplerAt = args.fFp.numTexturesExclChildren(); |  | 
|   79     for (int i = 0; i < childIndex; ++i) { |  | 
|   80         firstCoordAt += args.fFp.childProcessor(i).numTransforms(); |  | 
|   81         firstSamplerAt += args.fFp.childProcessor(i).numTextures(); |  | 
|   82     } |  | 
|   83     GrGLSLTransformedCoordsArray childCoords; |  | 
|   84     TextureSamplerArray childSamplers; |  | 
|   85     if (childProc.numTransforms() > 0) { |  | 
|   86         childCoords.push_back_n(childProc.numTransforms(), &args.fCoords[firstCo
     ordAt]); |  | 
|   87     } |  | 
|   88     if (childProc.numTextures() > 0) { |  | 
|   89         childSamplers.push_back_n(childProc.numTextures(), &args.fSamplers[first
     SamplerAt]); |  | 
|   90     } |  | 
|   91  |  | 
|   92     // emit the code for the child in its own scope |  | 
|   93     fb->codeAppend("{\n"); |  | 
|   94     fb->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex, |  | 
|   95                     fb->getMangleString().c_str(), childProc.name()); |  | 
|   96     EmitArgs childArgs(args.fBuilder, |  | 
|   97                        childProc, |  | 
|   98                        outputColor, |  | 
|   99                        inputColor, |  | 
|  100                        childCoords, |  | 
|  101                        childSamplers); |  | 
|  102     this->childProcessor(childIndex)->emitCode(childArgs); |  | 
|  103     fb->codeAppend("}\n"); |  | 
|  104  |  | 
|  105     fb->onAfterChildProcEmitCode(); |  | 
|  106 } |  | 
| OLD | NEW |