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