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 class is used by fragment processors to build their fragment code. 21 */ 22 class GrGLSLFPFragmentBuilder : virtual public GrGLSLShaderBuilder { 23 public: 24 /** Appease the compiler; the derived class initializes GrGLSLShaderBuilder. */ GrGLSLFPFragmentBuilder()25 GrGLSLFPFragmentBuilder() : GrGLSLShaderBuilder(nullptr) { 26 // Suppress unused warning error 27 (void) fDummyPadding; 28 } 29 30 enum class ScopeFlags { 31 // Every fragment will always execute this code, and will do it exactly once. 32 kTopLevel = 0, 33 // Either all fragments in a given primitive, or none, will execute this code. 34 kInsidePerPrimitiveBranch = (1 << 0), 35 // Any given fragment may or may not execute this code. 36 kInsidePerPixelBranch = (1 << 1), 37 // This code will be executed more than once. 38 kInsideLoop = (1 << 2) 39 }; 40 41 SkString writeProcessorFunction(GrGLSLFragmentProcessor*, GrGLSLFragmentProcessor::EmitArgs&); 42 43 virtual void forceHighPrecision() = 0; 44 45 private: 46 /** 47 * These are called before/after calling emitCode on a child proc to update mangling. 48 */ 49 virtual void onBeforeChildProcEmitCode() = 0; 50 virtual void onAfterChildProcEmitCode() = 0; 51 52 virtual const SkString& getMangleString() const = 0; 53 54 // WARNING: LIke GrRenderTargetProxy, changes to this can cause issues in ASAN. This is caused 55 // by GrGLSLProgramBuilder's GrTBlockLists requiring 16 byte alignment, but since 56 // GrGLSLFragmentShaderBuilder has a virtual diamond hierarchy, ASAN requires all this pointers 57 // to start aligned, even though clang is already correctly offsetting the individual fields 58 // that require the larger alignment. In the current world, this extra padding is sufficient to 59 // correctly initialize GrGLSLXPFragmentBuilder second. 60 char fDummyPadding[4] = {}; 61 }; 62 63 GR_MAKE_BITFIELD_CLASS_OPS(GrGLSLFPFragmentBuilder::ScopeFlags); 64 65 /* 66 * This class is used by Xfer processors to build their fragment code. 67 */ 68 class GrGLSLXPFragmentBuilder : virtual public GrGLSLShaderBuilder { 69 public: 70 /** Appease the compiler; the derived class initializes GrGLSLShaderBuilder. */ GrGLSLXPFragmentBuilder()71 GrGLSLXPFragmentBuilder() : GrGLSLShaderBuilder(nullptr) {} 72 73 virtual bool hasCustomColorOutput() const = 0; 74 virtual bool hasSecondaryOutput() const = 0; 75 76 /** Returns the variable name that holds the color of the destination pixel. This may be nullptr 77 * if no effect advertised that it will read the destination. */ 78 virtual const char* dstColor() = 0; 79 80 /** Adds any necessary layout qualifiers in order to legalize the supplied blend equation with 81 this shader. It is only legal to call this method with an advanced blend equation, and only 82 if these equations are supported. */ 83 virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0; 84 }; 85 86 /* 87 * This class implements the various fragment builder interfaces. 88 */ 89 class GrGLSLFragmentShaderBuilder : public GrGLSLFPFragmentBuilder, public GrGLSLXPFragmentBuilder { 90 public: 91 /** Returns a nonzero key for a surface's origin. This should only be called if a processor will 92 use the fragment position and/or sample locations. */ 93 static uint8_t KeyForSurfaceOrigin(GrSurfaceOrigin); 94 95 GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program); 96 97 // GrGLSLFPFragmentBuilder interface. forceHighPrecision()98 void forceHighPrecision() override { fForceHighPrecision = true; } 99 100 // GrGLSLXPFragmentBuilder interface. hasCustomColorOutput()101 bool hasCustomColorOutput() const override { return SkToBool(fCustomColorOutput); } hasSecondaryOutput()102 bool hasSecondaryOutput() const override { return fHasSecondaryOutput; } 103 const char* dstColor() override; 104 void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override; 105 106 private: 107 using CustomFeatures = GrProcessor::CustomFeatures; 108 109 // GrGLSLFPFragmentBuilder private interface. 110 void onBeforeChildProcEmitCode() override; 111 void onAfterChildProcEmitCode() override; getMangleString()112 const SkString& getMangleString() const override { return fMangleString; } 113 114 // Private public interface, used by GrGLProgramBuilder to build a fragment shader 115 void enableCustomOutput(); 116 void enableSecondaryOutput(); 117 const char* getPrimaryColorOutputName() const; 118 const char* getSecondaryColorOutputName() const; 119 bool primaryColorOutputIsInOut() const; 120 121 #ifdef SK_DEBUG 122 // As GLSLProcessors emit code, there are some conditions we need to verify. We use the below 123 // state to track this. The reset call is called per processor emitted. 124 bool fHasReadDstColorThisStage_DebugOnly = false; 125 CustomFeatures fUsedProcessorFeaturesThisStage_DebugOnly = CustomFeatures::kNone; 126 CustomFeatures fUsedProcessorFeaturesAllStages_DebugOnly = CustomFeatures::kNone; 127 debugOnly_resetPerStageVerification()128 void debugOnly_resetPerStageVerification() { 129 fHasReadDstColorThisStage_DebugOnly = false; 130 fUsedProcessorFeaturesThisStage_DebugOnly = CustomFeatures::kNone; 131 } 132 #endif 133 DeclaredColorOutputName()134 static const char* DeclaredColorOutputName() { return "sk_FragColor"; } DeclaredSecondaryColorOutputName()135 static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; } 136 137 GrSurfaceOrigin getSurfaceOrigin() const; 138 139 void onFinalize() override; 140 141 static const char* kDstColorName; 142 143 /* 144 * State that tracks which child proc in the proc tree is currently emitting code. This is 145 * used to update the fMangleString, which is used to mangle the names of uniforms and functions 146 * emitted by the proc. fSubstageIndices is a stack: its count indicates how many levels deep 147 * we are in the tree, and its second-to-last value is the index of the child proc at that 148 * level which is currently emitting code. For example, if fSubstageIndices = [3, 1, 2, 0], that 149 * means we're currently emitting code for the base proc's 3rd child's 1st child's 2nd child. 150 */ 151 SkTArray<int> fSubstageIndices; 152 153 /* 154 * The mangle string is used to mangle the names of uniforms/functions emitted by the child 155 * procs so no duplicate uniforms/functions appear in the generated shader program. The mangle 156 * string is simply based on fSubstageIndices. For example, if fSubstageIndices = [3, 1, 2, 0], 157 * then the manglestring will be "_c3_c1_c2", and any uniform/function emitted by that proc will 158 * have "_c3_c1_c2" appended to its name, which can be interpreted as "base proc's 3rd child's 159 * 1st child's 2nd child". 160 */ 161 SkString fMangleString; 162 163 GrShaderVar* fCustomColorOutput = nullptr; 164 165 bool fSetupFragPosition = false; 166 bool fHasSecondaryOutput = false; 167 bool fHasModifiedSampleMask = false; 168 bool fForceHighPrecision = false; 169 170 friend class GrGLSLProgramBuilder; 171 friend class GrGLProgramBuilder; 172 friend class GrVkPipelineStateBuilder; 173 }; 174 175 #endif 176