• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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