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