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 "GrGLSLFragmentProcessor.h"
9 #include "GrFragmentProcessor.h"
10 #include "GrProcessor.h"
11 #include "glsl/GrGLSLFragmentShaderBuilder.h"
12 #include "glsl/GrGLSLUniformHandler.h"
13 
setData(const GrGLSLProgramDataManager & pdman,const GrFragmentProcessor & processor)14 void GrGLSLFragmentProcessor::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 
emitChild(int childIndex,const char * inputColor,EmitArgs & args)23 void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor, EmitArgs& args) {
24     this->internalEmitChild(childIndex, inputColor, args.fOutputColor, args);
25 }
26 
emitChild(int childIndex,const char * inputColor,SkString * outputColor,EmitArgs & args)27 void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor,
28                                         SkString* outputColor, EmitArgs& args) {
29 
30     SkASSERT(outputColor);
31     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
32     outputColor->append(fragBuilder->getMangleString());
33     fragBuilder->codeAppendf("vec4 %s;", outputColor->c_str());
34     this->internalEmitChild(childIndex, inputColor, outputColor->c_str(), args);
35 }
36 
internalEmitChild(int childIndex,const char * inputColor,const char * outputColor,EmitArgs & args)37 void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inputColor,
38                                                 const char* outputColor, EmitArgs& args) {
39     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
40 
41     fragBuilder->onBeforeChildProcEmitCode();  // call first so mangleString is updated
42 
43     const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
44 
45     // emit the code for the child in its own scope
46     fragBuilder->codeAppend("{\n");
47     fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex,
48                              fragBuilder->getMangleString().c_str(), childProc.name());
49     TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex);
50     TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex);
51     BufferSamplers bufferSamplers = args.fBufferSamplers.childInputs(childIndex);
52     ImageStorages imageStorages = args.fImageStorages.childInputs(childIndex);
53     EmitArgs childArgs(fragBuilder,
54                        args.fUniformHandler,
55                        args.fShaderCaps,
56                        childProc,
57                        outputColor,
58                        inputColor,
59                        coordVars,
60                        textureSamplers,
61                        bufferSamplers,
62                        imageStorages,
63                        args.fGpImplementsDistanceVector);
64     this->childProcessor(childIndex)->emitCode(childArgs);
65     fragBuilder->codeAppend("}\n");
66 
67     fragBuilder->onAfterChildProcEmitCode();
68 }
69 
70 //////////////////////////////////////////////////////////////////////////////
71 
next()72 GrGLSLFragmentProcessor* GrGLSLFragmentProcessor::Iter::next() {
73     if (fFPStack.empty()) {
74         return nullptr;
75     }
76     GrGLSLFragmentProcessor* back = fFPStack.back();
77     fFPStack.pop_back();
78     for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
79         fFPStack.push_back(back->childProcessor(i));
80     }
81     return back;
82 }
83