1 /*
2  * Copyright 2015 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 GrGLSLProgramBuilder_DEFINED
9 #define GrGLSLProgramBuilder_DEFINED
10 
11 #include "src/gpu/GrCaps.h"
12 #include "src/gpu/GrGeometryProcessor.h"
13 #include "src/gpu/GrProgramDesc.h"
14 #include "src/gpu/GrProgramInfo.h"
15 #include "src/gpu/GrRenderTarget.h"
16 #include "src/gpu/GrRenderTargetPriv.h"
17 #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
18 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
19 #include "src/gpu/glsl/GrGLSLPrimitiveProcessor.h"
20 #include "src/gpu/glsl/GrGLSLProgramDataManager.h"
21 #include "src/gpu/glsl/GrGLSLUniformHandler.h"
22 #include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
23 #include "src/gpu/glsl/GrGLSLXferProcessor.h"
24 
25 class GrShaderVar;
26 class GrGLSLVaryingHandler;
27 class SkString;
28 class GrShaderCaps;
29 
30 class GrGLSLProgramBuilder {
31 public:
32     using UniformHandle      = GrGLSLUniformHandler::UniformHandle;
33     using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
34 
~GrGLSLProgramBuilder()35     virtual ~GrGLSLProgramBuilder() {}
36 
37     virtual const GrCaps* caps() const = 0;
shaderCaps()38     const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
39 
numSamples()40     int numSamples() const { return fProgramInfo.numSamples(); }
origin()41     GrSurfaceOrigin origin() const { return fProgramInfo.origin(); }
pipeline()42     const GrPipeline& pipeline() const { return fProgramInfo.pipeline(); }
primitiveProcessor()43     const GrPrimitiveProcessor& primitiveProcessor() const { return fProgramInfo.primProc(); }
processorFeatures()44     GrProcessor::CustomFeatures processorFeatures() const {
45         return fProgramInfo.requestedFeatures();
46     }
snapVerticesToPixelCenters()47     bool snapVerticesToPixelCenters() const {
48         return fProgramInfo.pipeline().snapVerticesToPixelCenters();
49     }
50     // TODO: remove this usage of the descriptor's header
hasPointSize()51     bool hasPointSize() const { return fDesc->hasPointSize(); }
52 
53     // TODO: stop passing in the renderTarget for just the sampleLocations
effectiveSampleCnt()54     int effectiveSampleCnt() const {
55         SkASSERT(GrProcessor::CustomFeatures::kSampleLocations & fProgramInfo.requestedFeatures());
56         return fRenderTarget->renderTargetPriv().getSampleLocations().count();
57     }
getSampleLocations()58     const SkTArray<SkPoint>& getSampleLocations() const {
59         return fRenderTarget->renderTargetPriv().getSampleLocations();
60     }
61 
desc()62     const GrProgramDesc* desc() const { return fDesc; }
63 
64     void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
65 
samplerVariable(SamplerHandle handle)66     const char* samplerVariable(SamplerHandle handle) const {
67         return this->uniformHandler()->samplerVariable(handle);
68     }
69 
samplerSwizzle(SamplerHandle handle)70     GrSwizzle samplerSwizzle(SamplerHandle handle) const {
71         if (this->caps()->shaderCaps()->textureSwizzleAppliedInShader()) {
72             return this->uniformHandler()->samplerSwizzle(handle);
73         }
74         return GrSwizzle::RGBA();
75     }
76 
77     // Used to add a uniform for the RenderTarget width (used for sk_Width) without mangling
78     // the name of the uniform inside of a stage.
79     void addRTWidthUniform(const char* name);
80 
81     // Used to add a uniform for the RenderTarget height (used for sk_Height and frag position)
82     // without mangling the name of the uniform inside of a stage.
83     void addRTHeightUniform(const char* name);
84 
85     // Generates a name for a variable. The generated string will be name prefixed by the prefix
86     // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless
87     // explicitly asked not to.
88     void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true);
89 
90     virtual GrGLSLUniformHandler* uniformHandler() = 0;
91     virtual const GrGLSLUniformHandler* uniformHandler() const = 0;
92     virtual GrGLSLVaryingHandler* varyingHandler() = 0;
93 
94     // Used for backend customization of the output color and secondary color variables from the
95     // fragment processor. Only used if the outputs are explicitly declared in the shaders
finalizeFragmentOutputColor(GrShaderVar & outputColor)96     virtual void finalizeFragmentOutputColor(GrShaderVar& outputColor) {}
finalizeFragmentSecondaryColor(GrShaderVar & outputColor)97     virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {}
98 
99     // number of each input/output type in a single allocation block, used by many builders
100     static const int kVarsPerBlock;
101 
102     GrGLSLVertexBuilder          fVS;
103     GrGLSLGeometryBuilder        fGS;
104     GrGLSLFragmentShaderBuilder  fFS;
105 
106     int fStageIndex;
107 
108     const GrRenderTarget*        fRenderTarget; // TODO: remove this
109     const GrProgramInfo&         fProgramInfo;
110 
111     const GrProgramDesc*         fDesc;
112 
113     GrGLSLBuiltinUniformHandles  fUniformHandles;
114 
115     std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
116     std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
117     std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors;
118     int fFragmentProcessorCnt;
119 
120 protected:
121     explicit GrGLSLProgramBuilder(GrRenderTarget*, const GrProgramInfo&, const GrProgramDesc*);
122 
123     void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
124 
125     bool emitAndInstallProcs();
126 
127     void finalizeShaders();
128 
fragColorIsInOut()129     bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); }
130 
131 private:
132     // reset is called by program creator between each processor's emit code.  It increments the
133     // stage offset for variable name mangling, and also ensures verfication variables in the
134     // fragment shader are cleared.
reset()135     void reset() {
136         this->addStage();
137         SkDEBUGCODE(fFS.debugOnly_resetPerStageVerification();)
138     }
addStage()139     void addStage() { fStageIndex++; }
140 
141     class AutoStageAdvance {
142     public:
AutoStageAdvance(GrGLSLProgramBuilder * pb)143         AutoStageAdvance(GrGLSLProgramBuilder* pb)
144             : fPB(pb) {
145             fPB->reset();
146             // Each output to the fragment processor gets its own code section
147             fPB->fFS.nextStage();
148         }
~AutoStageAdvance()149         ~AutoStageAdvance() {}
150     private:
151         GrGLSLProgramBuilder* fPB;
152     };
153 
154     // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
155     void nameExpression(SkString*, const char* baseName);
156 
157     void emitAndInstallPrimProc(SkString* outputColor, SkString* outputCoverage);
158     void emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut);
159     SkString emitAndInstallFragProc(const GrFragmentProcessor&,
160                                     int index,
161                                     int transformedCoordVarsIdx,
162                                     const SkString& input,
163                                     SkString output,
164                                     SkTArray<std::unique_ptr<GrGLSLFragmentProcessor>>*);
165     void emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
166     SamplerHandle emitSampler(const GrTextureProxy*, const GrSamplerState&, const GrSwizzle&,
167                               const char* name);
168     bool checkSamplerCounts();
169 
170 #ifdef SK_DEBUG
171     void verify(const GrPrimitiveProcessor&);
172     void verify(const GrFragmentProcessor&);
173     void verify(const GrXferProcessor&);
174 #endif
175 
176     // These are used to check that we don't excede the allowable number of resources in a shader.
177     int fNumFragmentSamplers;
178     SkSTArray<4, GrGLSLPrimitiveProcessor::TransformVar> fTransformedCoordVars;
179 };
180 
181 #endif
182