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: 24 GrGLSLFragmentBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) {} 25 virtual ~GrGLSLFragmentBuilder() {} 26 27 /** 28 * Use of these features may require a GLSL extension to be enabled. Shaders may not compile 29 * if code is added that uses one of these features without calling enableFeature() 30 */ 31 enum GLSLFeature { 32 kMultisampleInterpolation_GLSLFeature 33 }; 34 35 /** 36 * If the feature is supported then true is returned and any necessary #extension declarations 37 * are added to the shaders. If the feature is not supported then false will be returned. 38 */ 39 virtual bool enableFeature(GLSLFeature) = 0; 40 41 /** 42 * This returns a variable name to access the 2D, perspective correct version of the coords in 43 * the fragment shader. The passed in coordinates must either be of type kVec2f or kVec3f. If 44 * the coordinates are 3-dimensional, it a perspective divide into is emitted into the 45 * fragment shader (xy / z) to convert them to 2D. 46 */ 47 virtual SkString ensureCoords2D(const GrShaderVar&) = 0; 48 49 // TODO: remove this method. 50 void declAppendf(const char* fmt, ...); 51 52 private: 53 typedef GrGLSLShaderBuilder INHERITED; 54 }; 55 56 /* 57 * This class is used by fragment processors to build their fragment code. 58 */ 59 class GrGLSLFPFragmentBuilder : virtual public GrGLSLFragmentBuilder { 60 public: 61 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */ 62 GrGLSLFPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {} 63 64 enum Coordinates { 65 kSkiaDevice_Coordinates, 66 kGLSLWindow_Coordinates, 67 68 kLast_Coordinates = kGLSLWindow_Coordinates 69 }; 70 71 /** 72 * Appends the offset from the center of the pixel to a specified sample. 73 * 74 * @param sampleIdx GLSL expression of the sample index. 75 * @param Coordinates Coordinate space in which to emit the offset. 76 * 77 * A processor must call setWillUseSampleLocations in its constructor before using this method. 78 */ 79 virtual void appendOffsetToSample(const char* sampleIdx, Coordinates) = 0; 80 81 /** 82 * Subtracts sample coverage from the fragment. Any sample whose corresponding bit is not found 83 * in the mask will not be written out to the framebuffer. 84 * 85 * @param mask int that contains the sample mask. Bit N corresponds to the Nth sample. 86 * @param invert perform a bit-wise NOT on the provided mask before applying it? 87 * 88 * Requires GLSL support for sample variables. 89 */ 90 virtual void maskSampleCoverage(const char* mask, bool invert = false) = 0; 91 92 /** Returns a variable name that represents a vector to the nearest edge of the shape, in source 93 space coordinates. */ 94 virtual const char* distanceVectorName() const = 0; 95 96 /** 97 * Fragment procs with child procs should call these functions before/after calling emitCode 98 * on a child proc. 99 */ 100 virtual void onBeforeChildProcEmitCode() = 0; 101 virtual void onAfterChildProcEmitCode() = 0; 102 103 virtual const SkString& getMangleString() const = 0; 104 }; 105 106 /* 107 * This class is used by primitive processors to build their fragment code. 108 */ 109 class GrGLSLPPFragmentBuilder : public GrGLSLFPFragmentBuilder { 110 public: 111 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */ 112 GrGLSLPPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {} 113 114 /** 115 * Overrides the fragment's sample coverage. The provided mask determines which samples will now 116 * be written out to the framebuffer. Note that this mask can be reduced by a future call to 117 * maskSampleCoverage. 118 * 119 * If a primitive processor uses this method, it must guarantee that every codepath through the 120 * shader overrides the sample mask at some point. 121 * 122 * @param mask int that contains the new coverage mask. Bit N corresponds to the Nth sample. 123 * 124 * Requires NV_sample_mask_override_coverage. 125 */ 126 virtual void overrideSampleCoverage(const char* mask) = 0; 127 }; 128 129 /* 130 * This class is used by Xfer processors to build their fragment code. 131 */ 132 class GrGLSLXPFragmentBuilder : virtual public GrGLSLFragmentBuilder { 133 public: 134 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */ 135 GrGLSLXPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {} 136 137 virtual bool hasCustomColorOutput() const = 0; 138 virtual bool hasSecondaryOutput() const = 0; 139 140 /** Returns the variable name that holds the color of the destination pixel. This may be nullptr 141 * if no effect advertised that it will read the destination. */ 142 virtual const char* dstColor() = 0; 143 144 /** Adds any necessary layout qualifiers in order to legalize the supplied blend equation with 145 this shader. It is only legal to call this method with an advanced blend equation, and only 146 if these equations are supported. */ 147 virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0; 148 }; 149 150 /* 151 * This class implements the various fragment builder interfaces. 152 */ 153 class GrGLSLFragmentShaderBuilder : public GrGLSLPPFragmentBuilder, public GrGLSLXPFragmentBuilder { 154 public: 155 /** Returns a nonzero key for a surface's origin. This should only be called if a processor will 156 use the fragment position and/or sample locations. */ 157 static uint8_t KeyForSurfaceOrigin(GrSurfaceOrigin); 158 159 GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program); 160 161 // Shared GrGLSLFragmentBuilder interface. 162 bool enableFeature(GLSLFeature) override; 163 virtual SkString ensureCoords2D(const GrShaderVar&) override; 164 const char* distanceVectorName() const override; 165 166 // GrGLSLFPFragmentBuilder interface. 167 void appendOffsetToSample(const char* sampleIdx, Coordinates) override; 168 void maskSampleCoverage(const char* mask, bool invert = false) override; 169 void overrideSampleCoverage(const char* mask) override; 170 const SkString& getMangleString() const override { return fMangleString; } 171 void onBeforeChildProcEmitCode() override; 172 void onAfterChildProcEmitCode() override; 173 174 // GrGLSLXPFragmentBuilder interface. 175 bool hasCustomColorOutput() const override { return fHasCustomColorOutput; } 176 bool hasSecondaryOutput() const override { return fHasSecondaryOutput; } 177 const char* dstColor() override; 178 void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override; 179 180 private: 181 // Private public interface, used by GrGLProgramBuilder to build a fragment shader 182 void enableCustomOutput(); 183 void enableSecondaryOutput(); 184 const char* getPrimaryColorOutputName() const; 185 const char* getSecondaryColorOutputName() const; 186 187 #ifdef SK_DEBUG 188 // As GLSLProcessors emit code, there are some conditions we need to verify. We use the below 189 // state to track this. The reset call is called per processor emitted. 190 GrProcessor::RequiredFeatures usedProcessorFeatures() const { return fUsedProcessorFeatures; } 191 bool hasReadDstColor() const { return fHasReadDstColor; } 192 void resetVerification() { 193 fUsedProcessorFeatures = GrProcessor::kNone_RequiredFeatures; 194 fHasReadDstColor = false; 195 } 196 #endif 197 198 static const char* DeclaredColorOutputName() { return "sk_FragColor"; } 199 static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; } 200 201 GrSurfaceOrigin getSurfaceOrigin() const; 202 203 void onFinalize() override; 204 void defineSampleOffsetArray(const char* name, const SkMatrix&); 205 206 static const char* kDstColorName; 207 208 /* 209 * State that tracks which child proc in the proc tree is currently emitting code. This is 210 * used to update the fMangleString, which is used to mangle the names of uniforms and functions 211 * emitted by the proc. fSubstageIndices is a stack: its count indicates how many levels deep 212 * we are in the tree, and its second-to-last value is the index of the child proc at that 213 * level which is currently emitting code. For example, if fSubstageIndices = [3, 1, 2, 0], that 214 * means we're currently emitting code for the base proc's 3rd child's 1st child's 2nd child. 215 */ 216 SkTArray<int> fSubstageIndices; 217 218 /* 219 * The mangle string is used to mangle the names of uniforms/functions emitted by the child 220 * procs so no duplicate uniforms/functions appear in the generated shader program. The mangle 221 * string is simply based on fSubstageIndices. For example, if fSubstageIndices = [3, 1, 2, 0], 222 * then the manglestring will be "_c3_c1_c2", and any uniform/function emitted by that proc will 223 * have "_c3_c1_c2" appended to its name, which can be interpreted as "base proc's 3rd child's 224 * 1st child's 2nd child". 225 */ 226 SkString fMangleString; 227 228 bool fSetupFragPosition; 229 bool fHasCustomColorOutput; 230 int fCustomColorOutputIndex; 231 bool fHasSecondaryOutput; 232 uint8_t fUsedSampleOffsetArrays; 233 bool fHasInitializedSampleMask; 234 SkString fDistanceVectorOutput; 235 236 #ifdef SK_DEBUG 237 // some state to verify shaders and effects are consistent, this is reset between effects by 238 // the program creator 239 GrProcessor::RequiredFeatures fUsedProcessorFeatures; 240 bool fHasReadDstColor; 241 #endif 242 243 friend class GrGLSLProgramBuilder; 244 friend class GrGLProgramBuilder; 245 }; 246 247 #endif 248