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