| OLD | NEW |
| (Empty) |
| 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 GrGLFragmentShaderBuilder_DEFINED | |
| 9 #define GrGLFragmentShaderBuilder_DEFINED | |
| 10 | |
| 11 #include "GrGLShaderBuilder.h" | |
| 12 | |
| 13 #include "glsl/GrGLSLProcessorTypes.h" | |
| 14 | |
| 15 class GrRenderTarget; | |
| 16 class GrGLSLVarying; | |
| 17 | |
| 18 /* | |
| 19 * This base class encapsulates the functionality which the GP uses to build fra
gment shaders | |
| 20 */ | |
| 21 class GrGLFragmentBuilder : public GrGLShaderBuilder { | |
| 22 public: | |
| 23 GrGLFragmentBuilder(GrGLSLProgramBuilder* program) | |
| 24 : INHERITED(program) | |
| 25 , fHasCustomColorOutput(false) | |
| 26 , fHasSecondaryOutput(false) { | |
| 27 fSubstageIndices.push_back(0); | |
| 28 } | |
| 29 virtual ~GrGLFragmentBuilder() {} | |
| 30 /** | |
| 31 * Use of these features may require a GLSL extension to be enabled. Shaders
may not compile | |
| 32 * if code is added that uses one of these features without calling enableFe
ature() | |
| 33 */ | |
| 34 enum GLSLFeature { | |
| 35 kStandardDerivatives_GLSLFeature = 0, | |
| 36 kLastGLSLFeature = kStandardDerivatives_GLSLFeature | |
| 37 }; | |
| 38 | |
| 39 /** | |
| 40 * If the feature is supported then true is returned and any necessary #exte
nsion declarations | |
| 41 * are added to the shaders. If the feature is not supported then false will
be returned. | |
| 42 */ | |
| 43 virtual bool enableFeature(GLSLFeature) = 0; | |
| 44 | |
| 45 /** | |
| 46 * This returns a variable name to access the 2D, perspective correct versio
n of the coords in | |
| 47 * the fragment shader. If the coordinates at index are 3-dimensional, it im
mediately emits a | |
| 48 * perspective divide into the fragment shader (xy / z) to convert them to 2
D. | |
| 49 */ | |
| 50 virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords
, int index) = 0; | |
| 51 | |
| 52 | |
| 53 /** Returns a variable name that represents the position of the fragment in
the FS. The position | |
| 54 is in device space (e.g. 0,0 is the top left and pixel centers are at ha
lf-integers). */ | |
| 55 virtual const char* fragmentPosition() = 0; | |
| 56 | |
| 57 /** | |
| 58 * Fragment procs with child procs should call these functions before/after
calling emitCode | |
| 59 * on a child proc. | |
| 60 */ | |
| 61 void onBeforeChildProcEmitCode(); | |
| 62 void onAfterChildProcEmitCode(); | |
| 63 | |
| 64 const SkString& getMangleString() const { return fMangleString; } | |
| 65 | |
| 66 bool hasCustomColorOutput() const { return fHasCustomColorOutput; } | |
| 67 bool hasSecondaryOutput() const { return fHasSecondaryOutput; } | |
| 68 | |
| 69 protected: | |
| 70 bool fHasCustomColorOutput; | |
| 71 bool fHasSecondaryOutput; | |
| 72 | |
| 73 private: | |
| 74 /* | |
| 75 * State that tracks which child proc in the proc tree is currently emitting
code. This is | |
| 76 * used to update the fMangleString, which is used to mangle the names of un
iforms and functions | |
| 77 * emitted by the proc. fSubstageIndices is a stack: its count indicates ho
w many levels deep | |
| 78 * we are in the tree, and its second-to-last value is the index of the chil
d proc at that | |
| 79 * level which is currently emitting code. For example, if fSubstageIndices
= [3, 1, 2, 0], that | |
| 80 * means we're currently emitting code for the base proc's 3rd child's 1st c
hild's 2nd child. | |
| 81 */ | |
| 82 SkTArray<int> fSubstageIndices; | |
| 83 | |
| 84 /* | |
| 85 * The mangle string is used to mangle the names of uniforms/functions emitt
ed by the child | |
| 86 * procs so no duplicate uniforms/functions appear in the generated shader p
rogram. The mangle | |
| 87 * string is simply based on fSubstageIndices. For example, if fSubstageIndi
ces = [3, 1, 2, 0], | |
| 88 * then the manglestring will be "_c3_c1_c2", and any uniform/function emitt
ed by that proc will | |
| 89 * have "_c3_c1_c2" appended to its name, which can be interpreted as "base
proc's 3rd child's | |
| 90 * 1st child's 2nd child". | |
| 91 */ | |
| 92 SkString fMangleString; | |
| 93 | |
| 94 friend class GrGLPathProcessor; | |
| 95 | |
| 96 typedef GrGLShaderBuilder INHERITED; | |
| 97 }; | |
| 98 | |
| 99 /* | |
| 100 * Fragment processor's, in addition to all of the above, may need to use dst co
lor so they use | |
| 101 * this builder to create their shader. Because this is the only shader builder
the FP sees, we | |
| 102 * just call it FPShaderBuilder | |
| 103 */ | |
| 104 class GrGLXPFragmentBuilder : public GrGLFragmentBuilder { | |
| 105 public: | |
| 106 GrGLXPFragmentBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) {} | |
| 107 | |
| 108 /** Returns the variable name that holds the color of the destination pixel.
This may be nullptr if | |
| 109 no effect advertised that it will read the destination. */ | |
| 110 virtual const char* dstColor() = 0; | |
| 111 | |
| 112 /** Adds any necessary layout qualifiers in order to legalize the supplied b
lend equation with | |
| 113 this shader. It is only legal to call this method with an advanced blend
equation, and only | |
| 114 if these equations are supported. */ | |
| 115 virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0; | |
| 116 | |
| 117 private: | |
| 118 typedef GrGLFragmentBuilder INHERITED; | |
| 119 }; | |
| 120 | |
| 121 // TODO rename to Fragment Builder | |
| 122 class GrGLFragmentShaderBuilder : public GrGLXPFragmentBuilder { | |
| 123 public: | |
| 124 typedef uint8_t FragPosKey; | |
| 125 | |
| 126 /** Returns a key for reading the fragment location. This should only be cal
led if there is an | |
| 127 effect that will requires the fragment position. If the fragment position
is not required, | |
| 128 the key is 0. */ | |
| 129 static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst); | |
| 130 | |
| 131 GrGLFragmentShaderBuilder(GrGLSLProgramBuilder* program, uint8_t fragPosKey)
; | |
| 132 | |
| 133 // true public interface, defined explicitly in the abstract interfaces abov
e | |
| 134 bool enableFeature(GLSLFeature) override; | |
| 135 virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords
, | |
| 136 int index) override; | |
| 137 const char* fragmentPosition() override; | |
| 138 const char* dstColor() override; | |
| 139 | |
| 140 void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override; | |
| 141 | |
| 142 private: | |
| 143 // Private public interface, used by GrGLProgramBuilder to build a fragment
shader | |
| 144 void enableCustomOutput(); | |
| 145 void enableSecondaryOutput(); | |
| 146 const char* getPrimaryColorOutputName() const; | |
| 147 const char* getSecondaryColorOutputName() const; | |
| 148 | |
| 149 // As GLProcessors emit code, there are some conditions we need to verify.
We use the below | |
| 150 // state to track this. The reset call is called per processor emitted. | |
| 151 bool hasReadDstColor() const { return fHasReadDstColor; } | |
| 152 bool hasReadFragmentPosition() const { return fHasReadFragmentPosition; } | |
| 153 void reset() { | |
| 154 fHasReadDstColor = false; | |
| 155 fHasReadFragmentPosition = false; | |
| 156 } | |
| 157 | |
| 158 static const char* DeclaredColorOutputName() { return "fsColorOut"; } | |
| 159 static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryC
olorOut"; } | |
| 160 | |
| 161 /* | |
| 162 * An internal call for GrGLProgramBuilder to use to add varyings to the ver
tex shader | |
| 163 */ | |
| 164 void addVarying(GrGLSLVarying*, GrSLPrecision); | |
| 165 | |
| 166 void onFinalize() override; | |
| 167 | |
| 168 /** | |
| 169 * Features that should only be enabled by GrGLFragmentShaderBuilder itself. | |
| 170 */ | |
| 171 enum GLSLPrivateFeature { | |
| 172 kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1, | |
| 173 kBlendEquationAdvanced_GLSLPrivateFeature, | |
| 174 kBlendFuncExtended_GLSLPrivateFeature, | |
| 175 kLastGLSLPrivateFeature = kBlendFuncExtended_GLSLPrivateFeature | |
| 176 }; | |
| 177 | |
| 178 // Interpretation of FragPosKey when generating code | |
| 179 enum { | |
| 180 kNoFragPosRead_FragPosKey = 0, // The fragment positition wil
l not be needed. | |
| 181 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to t
op-left. | |
| 182 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to b
ottom-left. | |
| 183 }; | |
| 184 | |
| 185 static const char* kDstTextureColorName; | |
| 186 | |
| 187 bool fSetupFragPosition; | |
| 188 bool fTopLeftFragPosRead; | |
| 189 int fCustomColorOutputIndex; | |
| 190 | |
| 191 // some state to verify shaders and effects are consistent, this is reset be
tween effects by | |
| 192 // the program creator | |
| 193 bool fHasReadDstColor; | |
| 194 bool fHasReadFragmentPosition; | |
| 195 | |
| 196 friend class GrGLProgramBuilder; | |
| 197 | |
| 198 typedef GrGLXPFragmentBuilder INHERITED; | |
| 199 }; | |
| 200 | |
| 201 #endif | |
| OLD | NEW |