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
16class GrRenderTarget;
17class GrGLSLVarying;
18
19/*
20 * This class is used by fragment processors to build their fragment code.
21 */
22class GrGLSLFPFragmentBuilder : virtual public GrGLSLShaderBuilder {
23public:
24 /** Appease the compiler; the derived class initializes GrGLSLShaderBuilder. */
25 GrGLSLFPFragmentBuilder() : GrGLSLShaderBuilder(nullptr) {
26 // Suppress unused warning error
27 (void) fDummyPadding;
28 }
29
30 /**
31 * Returns the variable name that holds the array of sample offsets from pixel center to each
32 * sample location. Before this is called, a processor must have advertised that it will use
33 * CustomFeatures::kSampleLocations.
34 */
35 virtual const char* sampleOffsets() = 0;
36
37 enum class ScopeFlags {
38 // Every fragment will always execute this code, and will do it exactly once.
39 kTopLevel = 0,
40 // Either all fragments in a given primitive, or none, will execute this code.
41 kInsidePerPrimitiveBranch = (1 << 0),
42 // Any given fragment may or may not execute this code.
43 kInsidePerPixelBranch = (1 << 1),
44 // This code will be executed more than once.
45 kInsideLoop = (1 << 2)
46 };
47
48 /**
49 * Subtracts multisample coverage by AND-ing the sample mask with the provided "mask".
50 * Sample N corresponds to bit "1 << N".
51 *
52 * If the given scope is "kTopLevel" and the sample mask has not yet been modified, this method
53 * assigns the sample mask in place rather than pre-initializing it to ~0 then AND-ing it.
54 *
55 * Requires MSAA and GLSL support for sample variables.
56 */
57 virtual void maskOffMultisampleCoverage(const char* mask, ScopeFlags) = 0;
58
59 /**
60 * Turns off coverage at each sample where the implicit function fn > 0.
61 *
62 * The provided "fn" value represents the implicit function at pixel center. We then approximate
63 * the implicit at each sample by riding the gradient, "grad", linearly from pixel center to
64 * each sample location.
65 *
66 * If "grad" is null, we approximate the gradient using HW derivatives.
67 *
68 * Requires MSAA and GLSL support for sample variables. Also requires HW derivatives if not
69 * providing a gradient.
70 */
71 virtual void applyFnToMultisampleMask(const char* fn, const char* grad, ScopeFlags) = 0;
72
73 SkString writeProcessorFunction(GrGLSLFragmentProcessor*, GrGLSLFragmentProcessor::EmitArgs&);
74
75 virtual void forceHighPrecision() = 0;
76
77private:
78 /**
79 * These are called before/after calling emitCode on a child proc to update mangling.
80 */
81 virtual void onBeforeChildProcEmitCode() = 0;
82 virtual void onAfterChildProcEmitCode() = 0;
83
84 virtual const SkString& getMangleString() const = 0;
85
86 // WARNING: LIke GrRenderTargetProxy, changes to this can cause issues in ASAN. This is caused
87 // by GrGLSLProgramBuilder's GrTBlockLists requiring 16 byte alignment, but since
88 // GrGLSLFragmentShaderBuilder has a virtual diamond hierarchy, ASAN requires all this pointers
89 // to start aligned, even though clang is already correctly offsetting the individual fields
90 // that require the larger alignment. In the current world, this extra padding is sufficient to
91 // correctly initialize GrGLSLXPFragmentBuilder second.
92 char fDummyPadding[4] = {};
93};
94
95GR_MAKE_BITFIELD_CLASS_OPS(GrGLSLFPFragmentBuilder::ScopeFlags);
96
97/*
98 * This class is used by Xfer processors to build their fragment code.
99 */
100class GrGLSLXPFragmentBuilder : virtual public GrGLSLShaderBuilder {
101public:
102 /** Appease the compiler; the derived class initializes GrGLSLShaderBuilder. */
103 GrGLSLXPFragmentBuilder() : GrGLSLShaderBuilder(nullptr) {}
104
105 virtual bool hasCustomColorOutput() const = 0;
106 virtual bool hasSecondaryOutput() const = 0;
107
108 /** Returns the variable name that holds the color of the destination pixel. This may be nullptr
109 * if 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 blend 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
118/*
119 * This class implements the various fragment builder interfaces.
120 */
121class GrGLSLFragmentShaderBuilder : public GrGLSLFPFragmentBuilder, public GrGLSLXPFragmentBuilder {
122public:
123 /** Returns a nonzero key for a surface's origin. This should only be called if a processor will
124 use the fragment position and/or sample locations. */
125 static uint8_t KeyForSurfaceOrigin(GrSurfaceOrigin);
126
127 GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program);
128
129 // GrGLSLFPFragmentBuilder interface.
130 const char* sampleOffsets() override;
131 void maskOffMultisampleCoverage(const char* mask, ScopeFlags) override;
132 void applyFnToMultisampleMask(const char* fn, const char* grad, ScopeFlags) override;
133 void forceHighPrecision() override { fForceHighPrecision = true; }
134
135 // GrGLSLXPFragmentBuilder interface.
136 bool hasCustomColorOutput() const override { return SkToBool(fCustomColorOutput); }
137 bool hasSecondaryOutput() const override { return fHasSecondaryOutput; }
138 const char* dstColor() override;
139 void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override;
140
141private:
142 using CustomFeatures = GrProcessor::CustomFeatures;
143
144 // GrGLSLFPFragmentBuilder private interface.
145 void onBeforeChildProcEmitCode() override;
146 void onAfterChildProcEmitCode() override;
147 const SkString& getMangleString() const override { return fMangleString; }
148
149 // Private public interface, used by GrGLProgramBuilder to build a fragment shader
150 void enableCustomOutput();
151 void enableSecondaryOutput();
152 const char* getPrimaryColorOutputName() const;
153 const char* getSecondaryColorOutputName() const;
154 bool primaryColorOutputIsInOut() const;
155
156#ifdef SK_DEBUG
157 // As GLSLProcessors emit code, there are some conditions we need to verify. We use the below
158 // state to track this. The reset call is called per processor emitted.
159 bool fHasReadDstColorThisStage_DebugOnly = false;
160 CustomFeatures fUsedProcessorFeaturesThisStage_DebugOnly = CustomFeatures::kNone;
161 CustomFeatures fUsedProcessorFeaturesAllStages_DebugOnly = CustomFeatures::kNone;
162
163 void debugOnly_resetPerStageVerification() {
164 fHasReadDstColorThisStage_DebugOnly = false;
165 fUsedProcessorFeaturesThisStage_DebugOnly = CustomFeatures::kNone;
166 }
167#endif
168
169 static const char* DeclaredColorOutputName() { return "sk_FragColor"; }
170 static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; }
171
172 GrSurfaceOrigin getSurfaceOrigin() const;
173
174 void onFinalize() override;
175
176 static const char* kDstColorName;
177
178 /*
179 * State that tracks which child proc in the proc tree is currently emitting code. This is
180 * used to update the fMangleString, which is used to mangle the names of uniforms and functions
181 * emitted by the proc. fSubstageIndices is a stack: its count indicates how many levels deep
182 * we are in the tree, and its second-to-last value is the index of the child proc at that
183 * level which is currently emitting code. For example, if fSubstageIndices = [3, 1, 2, 0], that
184 * means we're currently emitting code for the base proc's 3rd child's 1st child's 2nd child.
185 */
186 SkTArray<int> fSubstageIndices;
187
188 /*
189 * The mangle string is used to mangle the names of uniforms/functions emitted by the child
190 * procs so no duplicate uniforms/functions appear in the generated shader program. The mangle
191 * string is simply based on fSubstageIndices. For example, if fSubstageIndices = [3, 1, 2, 0],
192 * then the manglestring will be "_c3_c1_c2", and any uniform/function emitted by that proc will
193 * have "_c3_c1_c2" appended to its name, which can be interpreted as "base proc's 3rd child's
194 * 1st child's 2nd child".
195 */
196 SkString fMangleString;
197
198 GrShaderVar* fCustomColorOutput = nullptr;
199
200 bool fSetupFragPosition = false;
201 bool fHasSecondaryOutput = false;
202 bool fHasModifiedSampleMask = false;
203 bool fForceHighPrecision = false;
204
205 friend class GrGLSLProgramBuilder;
206 friend class GrGLProgramBuilder;
207};
208
209#endif
210