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 14 void GrGLSLFragmentProcessor::setData(const GrGLSLProgramDataManager& pdman, 15 const GrFragmentProcessor& processor) { 16 this->onSetData(pdman, processor); 17 } 18 19 void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor, EmitArgs& args) { 20 this->internalEmitChild(childIndex, inputColor, args.fOutputColor, args); 21 } 22 23 void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor, 24 SkString* outputColor, EmitArgs& args) { 25 SkASSERT(outputColor); 26 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 27 outputColor->append(fragBuilder->getMangleString()); 28 fragBuilder->codeAppendf("half4 %s;", outputColor->c_str()); 29 this->internalEmitChild(childIndex, inputColor, outputColor->c_str(), args); 30 } 31 32 void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inputColor, 33 const char* outputColor, EmitArgs& args) { 34 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 35 36 fragBuilder->onBeforeChildProcEmitCode(); // call first so mangleString is updated 37 38 // Prepare a mangled input color variable if the default is not used, 39 // inputName remains the empty string if no variable is needed. 40 SkString inputName; 41 if (inputColor&& strcmp("half4(1.0)", inputColor) != 0 && strcmp("half4(1)", inputColor) != 0) { 42 // The input name is based off of the current mangle string, and 43 // since this is called after onBeforeChildProcEmitCode(), it will be 44 // unique to the child processor (exactly what we want for its input). 45 inputName.appendf("_childInput%s", fragBuilder->getMangleString().c_str()); 46 fragBuilder->codeAppendf("half4 %s = %s;", inputName.c_str(), inputColor); 47 } 48 49 const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex); 50 51 // emit the code for the child in its own scope 52 fragBuilder->codeAppend("{\n"); 53 fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex, 54 fragBuilder->getMangleString().c_str(), childProc.name()); 55 TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex); 56 TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex); 57 58 // EmitArgs properly updates inputColor to half4(1) if it was null 59 EmitArgs childArgs(fragBuilder, 60 args.fUniformHandler, 61 args.fShaderCaps, 62 childProc, 63 outputColor, 64 inputName.size() > 0 ? inputName.c_str() : nullptr, 65 coordVars, 66 textureSamplers); 67 this->childProcessor(childIndex)->emitCode(childArgs); 68 fragBuilder->codeAppend("}\n"); 69 70 fragBuilder->onAfterChildProcEmitCode(); 71 } 72 73 ////////////////////////////////////////////////////////////////////////////// 74 75 GrGLSLFragmentProcessor* GrGLSLFragmentProcessor::Iter::next() { 76 if (fFPStack.empty()) { 77 return nullptr; 78 } 79 GrGLSLFragmentProcessor* back = fFPStack.back(); 80 fFPStack.pop_back(); 81 for (int i = back->numChildProcessors() - 1; i >= 0; --i) { 82 fFPStack.push_back(back->childProcessor(i)); 83 } 84 return back; 85 } 86