1 /* 2 * Copyright 2014 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 GrGLSLFragmentShaderBuilder_DEFINED 9 #define GrGLSLFragmentShaderBuilder_DEFINED 10 11 #include "src/gpu/GrBlend.h" 12 #include "src/gpu/GrProcessor.h" 13 #include "src/gpu/glsl/GrGLSLFragmentProcessor.h" 14 #include "src/gpu/glsl/GrGLSLShaderBuilder.h" 15 16 class GrRenderTarget; 17 class GrGLSLVarying; 18 19 /* 20 * This base class encapsulates the common functionality which all processors use to build fragment 21 * shaders. 22 */ 23 class GrGLSLFragmentBuilder : public GrGLSLShaderBuilder { 24 public: GrGLSLFragmentBuilder(GrGLSLProgramBuilder * program)25 GrGLSLFragmentBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) {} ~GrGLSLFragmentBuilder()26 virtual ~GrGLSLFragmentBuilder() {} 27 28 /** 29 * This returns a variable name to access the 2D, perspective correct version of the coords in 30 * the fragment shader. The passed in coordinates must either be of type kHalf2 or kHalf3. If 31 * the coordinates are 3-dimensional, it a perspective divide into is emitted into the 32 * fragment shader (xy / z) to convert them to 2D. 33 */ 34 virtual SkString ensureCoords2D(const GrShaderVar&) = 0; 35 36 // TODO: remove this method. 37 void declAppendf(const char* fmt, ...); 38 39 private: 40 typedef GrGLSLShaderBuilder INHERITED; 41 }; 42 43 /* 44 * This class is used by fragment processors to build their fragment code. 45 */ 46 class GrGLSLFPFragmentBuilder : virtual public GrGLSLFragmentBuilder { 47 public: 48 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */ GrGLSLFPFragmentBuilder()49 GrGLSLFPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {} 50 51 /** 52 * Returns the variable name that holds the array of sample offsets from pixel center to each 53 * sample location. Before this is called, a processor must have advertised that it will use 54 * CustomFeatures::kSampleLocations. 55 */ 56 virtual const char* sampleOffsets() = 0; 57 58 enum class ScopeFlags { 59 // Every fragment will always execute this code, and will do it exactly once. 60 kTopLevel = 0, 61 // Either all fragments in a given primitive, or none, will execute this code. 62 kInsidePerPrimitiveBranch = (1 << 0), 63 // Any given fragment may or may not execute this code. 64 kInsidePerPixelBranch = (1 << 1), 65 // This code will be executed more than once. 66 kInsideLoop = (1 << 2) 67 }; 68 69 /** 70 * Subtracts multisample coverage by AND-ing the sample mask with the provided "mask". 71 * Sample N corresponds to bit "1 << N". 72 * 73 * If the given scope is "kTopLevel" and the sample mask has not yet been modified, this method 74 * assigns the sample mask in place rather than pre-initializing it to ~0 then AND-ing it. 75 * 76 * Requires MSAA and GLSL support for sample variables. 77 */ 78 virtual void maskOffMultisampleCoverage(const char* mask, ScopeFlags) = 0; 79 80 /** 81 * Turns off coverage at each sample where the implicit function fn > 0. 82 * 83 * The provided "fn" value represents the implicit function at pixel center. We then approximate 84 * the implicit at each sample by riding the gradient, "grad", linearly from pixel center to 85 * each sample location. 86 * 87 * If "grad" is null, we approximate the gradient using HW derivatives. 88 * 89 * Requires MSAA and GLSL support for sample variables. Also requires HW derivatives if not 90 * providing a gradient. 91 */ 92 virtual void applyFnToMultisampleMask(const char* fn, const char* grad, ScopeFlags) = 0; 93 94 /** 95 * Fragment procs with child procs should call these functions before/after calling emitCode 96 * on a child proc. 97 */ 98 virtual void onBeforeChildProcEmitCode() = 0; 99 virtual void onAfterChildProcEmitCode() = 0; 100 101 virtual SkString writeProcessorFunction(GrGLSLFragmentProcessor* fp, 102 GrGLSLFragmentProcessor::EmitArgs& args); 103 104 virtual const SkString& getMangleString() const = 0; 105 106 virtual void forceHighPrecision() = 0; 107 }; 108 109 GR_MAKE_BITFIELD_CLASS_OPS(GrGLSLFPFragmentBuilder::ScopeFlags); 110 111 /* 112 * This class is used by Xfer processors to build their fragment code. 113 */ 114 class GrGLSLXPFragmentBuilder : virtual public GrGLSLFragmentBuilder { 115 public: 116 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */ GrGLSLXPFragmentBuilder()117 GrGLSLXPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {} 118 119 virtual bool hasCustomColorOutput() const = 0; 120 virtual bool hasSecondaryOutput() const = 0; 121 122 /** Returns the variable name that holds the color of the destination pixel. This may be nullptr 123 * if no effect advertised that it will read the destination. */ 124 virtual const char* dstColor() = 0; 125 126 /** Adds any necessary layout qualifiers in order to legalize the supplied blend equation with 127 this shader. It is only legal to call this method with an advanced blend equation, and only 128 if these equations are supported. */ 129 virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0; 130 }; 131 132 /* 133 * This class implements the various fragment builder interfaces. 134 */ 135 class GrGLSLFragmentShaderBuilder : public GrGLSLFPFragmentBuilder, public GrGLSLXPFragmentBuilder { 136 public: 137 /** Returns a nonzero key for a surface's origin. This should only be called if a processor will 138 use the fragment position and/or sample locations. */ 139 static uint8_t KeyForSurfaceOrigin(GrSurfaceOrigin); 140 141 GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program); 142 143 // Shared GrGLSLFragmentBuilder interface. 144 virtual SkString ensureCoords2D(const GrShaderVar&) override; 145 146 // GrGLSLFPFragmentBuilder interface. 147 const char* sampleOffsets() override; 148 void maskOffMultisampleCoverage(const char* mask, ScopeFlags) override; 149 void applyFnToMultisampleMask(const char* fn, const char* grad, ScopeFlags) override; getMangleString()150 const SkString& getMangleString() const override { return fMangleString; } 151 void onBeforeChildProcEmitCode() override; 152 void onAfterChildProcEmitCode() override; forceHighPrecision()153 void forceHighPrecision() override { fForceHighPrecision = true; } 154 155 // GrGLSLXPFragmentBuilder interface. hasCustomColorOutput()156 bool hasCustomColorOutput() const override { return fHasCustomColorOutput; } hasSecondaryOutput()157 bool hasSecondaryOutput() const override { return fHasSecondaryOutput; } 158 const char* dstColor() override; 159 void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override; 160 161 private: 162 using CustomFeatures = GrProcessor::CustomFeatures; 163 164 // Private public interface, used by GrGLProgramBuilder to build a fragment shader 165 void enableCustomOutput(); 166 void enableSecondaryOutput(); 167 const char* getPrimaryColorOutputName() const; 168 const char* getSecondaryColorOutputName() const; 169 bool primaryColorOutputIsInOut() const; 170 171 #ifdef SK_DEBUG 172 // As GLSLProcessors emit code, there are some conditions we need to verify. We use the below 173 // state to track this. The reset call is called per processor emitted. 174 bool fHasReadDstColorThisStage_DebugOnly = false; 175 CustomFeatures fUsedProcessorFeaturesThisStage_DebugOnly = CustomFeatures::kNone; 176 CustomFeatures fUsedProcessorFeaturesAllStages_DebugOnly = CustomFeatures::kNone; 177 debugOnly_resetPerStageVerification()178 void debugOnly_resetPerStageVerification() { 179 fHasReadDstColorThisStage_DebugOnly = false; 180 fUsedProcessorFeaturesThisStage_DebugOnly = CustomFeatures::kNone; 181 } 182 #endif 183 DeclaredColorOutputName()184 static const char* DeclaredColorOutputName() { return "sk_FragColor"; } DeclaredSecondaryColorOutputName()185 static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; } 186 187 GrSurfaceOrigin getSurfaceOrigin() const; 188 189 void onFinalize() override; 190 191 static const char* kDstColorName; 192 193 /* 194 * State that tracks which child proc in the proc tree is currently emitting code. This is 195 * used to update the fMangleString, which is used to mangle the names of uniforms and functions 196 * emitted by the proc. fSubstageIndices is a stack: its count indicates how many levels deep 197 * we are in the tree, and its second-to-last value is the index of the child proc at that 198 * level which is currently emitting code. For example, if fSubstageIndices = [3, 1, 2, 0], that 199 * means we're currently emitting code for the base proc's 3rd child's 1st child's 2nd child. 200 */ 201 SkTArray<int> fSubstageIndices; 202 203 /* 204 * The mangle string is used to mangle the names of uniforms/functions emitted by the child 205 * procs so no duplicate uniforms/functions appear in the generated shader program. The mangle 206 * string is simply based on fSubstageIndices. For example, if fSubstageIndices = [3, 1, 2, 0], 207 * then the manglestring will be "_c3_c1_c2", and any uniform/function emitted by that proc will 208 * have "_c3_c1_c2" appended to its name, which can be interpreted as "base proc's 3rd child's 209 * 1st child's 2nd child". 210 */ 211 SkString fMangleString; 212 213 bool fSetupFragPosition = false; 214 bool fHasCustomColorOutput = false; 215 int fCustomColorOutputIndex = -1; 216 bool fHasSecondaryOutput = false; 217 bool fHasModifiedSampleMask = false; 218 bool fForceHighPrecision = false; 219 220 friend class GrGLSLProgramBuilder; 221 friend class GrGLProgramBuilder; 222 }; 223 224 #endif 225