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