• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "src/gpu/GrFragmentProcessor.h"
9 #include "src/gpu/GrProcessor.h"
10 #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
11 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
12 #include "src/gpu/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 }
18 
invokeChild(int childIndex,const char * inputColor,EmitArgs & args)19 void GrGLSLFragmentProcessor::invokeChild(int childIndex, const char* inputColor, EmitArgs& args) {
20     while (childIndex >= (int) fFunctionNames.size()) {
21         fFunctionNames.emplace_back();
22     }
23     this->internalInvokeChild(childIndex, inputColor, args.fOutputColor, args);
24 }
25 
invokeChild(int childIndex,const char * inputColor,SkString * outputColor,EmitArgs & args)26 void GrGLSLFragmentProcessor::invokeChild(int childIndex, const char* inputColor,
27                                           SkString* outputColor, EmitArgs& args) {
28     SkASSERT(outputColor);
29     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
30     outputColor->append(fragBuilder->getMangleString());
31     fragBuilder->codeAppendf("half4 %s;", outputColor->c_str());
32     while (childIndex >= (int) fFunctionNames.size()) {
33         fFunctionNames.emplace_back();
34     }
35     if (fFunctionNames[childIndex].size() == 0) {
36         this->internalInvokeChild(childIndex, inputColor, outputColor->c_str(), args);
37     } else {
38         fragBuilder->codeAppendf("%s = %s(%s);", outputColor->c_str(),
39                                  fFunctionNames[childIndex].c_str(),
40                                  inputColor ? inputColor : "half4(1)");
41     }
42 }
43 
internalInvokeChild(int childIndex,const char * inputColor,const char * outputColor,EmitArgs & args)44 void GrGLSLFragmentProcessor::internalInvokeChild(int childIndex, const char* inputColor,
45                                                   const char* outputColor, EmitArgs& args) {
46     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
47 
48     fragBuilder->onBeforeChildProcEmitCode();  // call first so mangleString is updated
49 
50     // Prepare a mangled input color variable if the default is not used,
51     // inputName remains the empty string if no variable is needed.
52     SkString inputName;
53     if (inputColor&& strcmp("half4(1.0)", inputColor) != 0 && strcmp("half4(1)", inputColor) != 0) {
54         // The input name is based off of the current mangle string, and
55         // since this is called after onBeforeChildProcEmitCode(), it will be
56         // unique to the child processor (exactly what we want for its input).
57         inputName.appendf("_childInput%s", fragBuilder->getMangleString().c_str());
58         fragBuilder->codeAppendf("half4 %s = %s;", inputName.c_str(), inputColor);
59     }
60 
61     const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
62 
63     TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex);
64     TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex);
65 
66     EmitArgs childArgs(fragBuilder,
67                        args.fUniformHandler,
68                        args.fShaderCaps,
69                        childProc,
70                        outputColor,
71                        "_input",
72                        coordVars,
73                        textureSamplers);
74     fFunctionNames[childIndex] = fragBuilder->writeProcessorFunction(
75                                                                this->childProcessor(childIndex),
76                                                                childArgs);
77     fragBuilder->codeAppendf("%s = %s(%s);\n", outputColor,
78                                                fFunctionNames[childIndex].c_str(),
79                                                inputName.size() > 0 ? inputName.c_str()
80                                                                     : "half4(1)");
81 
82     fragBuilder->onAfterChildProcEmitCode();
83 }
84 
85 //////////////////////////////////////////////////////////////////////////////
86 
next()87 GrGLSLFragmentProcessor* GrGLSLFragmentProcessor::Iter::next() {
88     if (fFPStack.empty()) {
89         return nullptr;
90     }
91     GrGLSLFragmentProcessor* back = fFPStack.back();
92     fFPStack.pop_back();
93     for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
94         fFPStack.push_back(back->childProcessor(i));
95     }
96     return back;
97 }
98