1 /* 2 * Copyright 2013 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 #ifndef GrGLSLFragmentProcessor_DEFINED 9 #define GrGLSLFragmentProcessor_DEFINED 10 11 #include "GrFragmentProcessor.h" 12 #include "GrShaderVar.h" 13 #include "glsl/GrGLSLProgramDataManager.h" 14 #include "glsl/GrGLSLUniformHandler.h" 15 16 class GrProcessor; 17 class GrProcessorKeyBuilder; 18 class GrGLSLFPBuilder; 19 class GrGLSLFPFragmentBuilder; 20 21 class GrGLSLFragmentProcessor { 22 public: 23 GrGLSLFragmentProcessor() {} 24 25 virtual ~GrGLSLFragmentProcessor() { 26 for (int i = 0; i < fChildProcessors.count(); ++i) { 27 delete fChildProcessors[i]; 28 } 29 } 30 31 using UniformHandle = GrGLSLUniformHandler::UniformHandle; 32 using SamplerHandle = GrGLSLUniformHandler::SamplerHandle; 33 using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle; 34 35 private: 36 /** 37 * This class allows the shader builder to provide each GrGLSLFragmentProcesor with an array of 38 * generated variables where each generated variable corresponds to an element of an array on 39 * the GrFragmentProcessor that generated the GLSLFP. For example, this is used to provide a 40 * variable holding transformed coords for each GrCoordTransform owned by the FP. 41 */ 42 template <typename T, typename FPBASE, int (FPBASE::*COUNT)() const> 43 class BuilderInputProvider { 44 public: 45 BuilderInputProvider(const GrFragmentProcessor* fp, const T* ts) : fFP(fp) , fTs(ts) {} 46 47 const T& operator[] (int i) const { 48 SkASSERT(i >= 0 && i < (fFP->*COUNT)()); 49 return fTs[i]; 50 } 51 52 BuilderInputProvider childInputs(int childIdx) const { 53 const GrFragmentProcessor* child = &fFP->childProcessor(childIdx); 54 GrFragmentProcessor::Iter iter(fFP); 55 int numToSkip = 0; 56 while (true) { 57 const GrFragmentProcessor* fp = iter.next(); 58 if (fp == child) { 59 return BuilderInputProvider(child, fTs + numToSkip); 60 } 61 numToSkip += (fp->*COUNT)(); 62 } 63 } 64 65 private: 66 const GrFragmentProcessor* fFP; 67 const T* fTs; 68 }; 69 70 public: 71 using TransformedCoordVars = BuilderInputProvider<GrShaderVar, GrFragmentProcessor, 72 &GrFragmentProcessor::numCoordTransforms>; 73 using TextureSamplers = BuilderInputProvider<SamplerHandle, GrProcessor, 74 &GrProcessor::numTextureSamplers>; 75 using BufferSamplers = BuilderInputProvider<SamplerHandle, GrProcessor, 76 &GrProcessor::numBuffers>; 77 using ImageStorages = BuilderInputProvider<ImageStorageHandle, GrProcessor, 78 &GrProcessor::numImageStorages>; 79 80 /** Called when the program stage should insert its code into the shaders. The code in each 81 shader will be in its own block ({}) and so locally scoped names will not collide across 82 stages. 83 84 @param fragBuilder Interface used to emit code in the shaders. 85 @param fp The processor that generated this program stage. 86 @param key The key that was computed by GenKey() from the generating 87 GrProcessor. 88 @param outputColor A predefined vec4 in the FS in which the stage should place its 89 output color (or coverage). 90 @param inputColor A vec4 that holds the input color to the stage in the FS. This may 91 be nullptr in which case the implied input is solid white (all 92 ones). TODO: Better system for communicating optimization info 93 (e.g. input color is solid white, trans black, known to be opaque, 94 etc.) that allows the processor to communicate back similar known 95 info about its output. 96 @param transformedCoords Fragment shader variables containing the coords computed using 97 each of the GrFragmentProcessor's GrCoordTransforms. 98 @param texSamplers Contains one entry for each TextureSampler of the GrProcessor. 99 These can be passed to the builder to emit texture reads in the 100 generated code. 101 @param bufferSamplers Contains one entry for each BufferAccess of the GrProcessor. These 102 can be passed to the builder to emit buffer reads in the generated 103 code. 104 @param imageStorages Contains one entry for each ImageStorageAccess of the GrProcessor. 105 These can be passed to the builder to emit image loads and stores 106 in the generated code. 107 @param gpImplementsDistanceVector 108 Does the GrGeometryProcessor implement the feature where it 109 provides a vector to the nearest edge of the shape being rendered. 110 */ 111 struct EmitArgs { 112 EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder, 113 GrGLSLUniformHandler* uniformHandler, 114 const GrShaderCaps* caps, 115 const GrFragmentProcessor& fp, 116 const char* outputColor, 117 const char* inputColor, 118 const TransformedCoordVars& transformedCoordVars, 119 const TextureSamplers& textureSamplers, 120 const BufferSamplers& bufferSamplers, 121 const ImageStorages& imageStorages, 122 bool gpImplementsDistanceVector) 123 : fFragBuilder(fragBuilder) 124 , fUniformHandler(uniformHandler) 125 , fShaderCaps(caps) 126 , fFp(fp) 127 , fOutputColor(outputColor) 128 , fInputColor(inputColor) 129 , fTransformedCoords(transformedCoordVars) 130 , fTexSamplers(textureSamplers) 131 , fBufferSamplers(bufferSamplers) 132 , fImageStorages(imageStorages) 133 , fGpImplementsDistanceVector(gpImplementsDistanceVector) {} 134 GrGLSLFPFragmentBuilder* fFragBuilder; 135 GrGLSLUniformHandler* fUniformHandler; 136 const GrShaderCaps* fShaderCaps; 137 const GrFragmentProcessor& fFp; 138 const char* fOutputColor; 139 const char* fInputColor; 140 const TransformedCoordVars& fTransformedCoords; 141 const TextureSamplers& fTexSamplers; 142 const BufferSamplers& fBufferSamplers; 143 const ImageStorages& fImageStorages; 144 bool fGpImplementsDistanceVector; 145 }; 146 147 virtual void emitCode(EmitArgs&) = 0; 148 149 void setData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor); 150 151 static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*) {} 152 153 int numChildProcessors() const { return fChildProcessors.count(); } 154 155 GrGLSLFragmentProcessor* childProcessor(int index) { 156 return fChildProcessors[index]; 157 } 158 159 /** Will emit the code of a child proc in its own scope. Pass in the parent's EmitArgs and 160 * emitChild will automatically extract the coords and samplers of that child and pass them 161 * on to the child's emitCode(). Also, any uniforms or functions emitted by the child will 162 * have their names mangled to prevent redefinitions. The output color name is also mangled 163 * therefore in an in/out param. It will be declared in mangled form by emitChild(). It is 164 * legal to pass nullptr as inputColor, since all fragment processors are required to work 165 * without an input color. 166 */ 167 void emitChild(int childIndex, const char* inputColor, SkString* outputColor, 168 EmitArgs& parentArgs); 169 170 /** Variation that uses the parent's output color variable to hold the child's output.*/ 171 void emitChild(int childIndex, const char* inputColor, EmitArgs& parentArgs); 172 173 /** 174 * Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of 175 * GLSLFPS. This agrees with the traversal order of GrFragmentProcessor::Iter 176 */ 177 class Iter : public SkNoncopyable { 178 public: 179 explicit Iter(GrGLSLFragmentProcessor* fp) { fFPStack.push_back(fp); } 180 explicit Iter(GrGLSLFragmentProcessor* fps[], int cnt) { 181 for (int i = cnt - 1; i >= 0; --i) { 182 fFPStack.push_back(fps[i]); 183 } 184 } 185 GrGLSLFragmentProcessor* next(); 186 187 private: 188 SkSTArray<4, GrGLSLFragmentProcessor*, true> fFPStack; 189 }; 190 191 protected: 192 /** A GrGLSLFragmentProcessor instance can be reused with any GrFragmentProcessor that produces 193 the same stage key; this function reads data from a GrFragmentProcessor and uploads any 194 uniform variables required by the shaders created in emitCode(). The GrFragmentProcessor 195 parameter is guaranteed to be of the same type that created this GrGLSLFragmentProcessor and 196 to have an identical processor key as the one that created this GrGLSLFragmentProcessor. */ 197 // TODO update this to pass in GrFragmentProcessor 198 virtual void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) {} 199 200 private: 201 void internalEmitChild(int, const char*, const char*, EmitArgs&); 202 203 SkTArray<GrGLSLFragmentProcessor*, true> fChildProcessors; 204 205 friend class GrFragmentProcessor; 206 }; 207 208 #endif 209