• 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 "GrGeometryProcessor.h"
12 #include "GrGpu.h"
13 #include "glsl/GrGLSLFragmentShaderBuilder.h"
14 #include "glsl/GrGLSLGeometryShaderBuilder.h"
15 #include "glsl/GrGLSLPrimitiveProcessor.h"
16 #include "glsl/GrGLSLProgramDataManager.h"
17 #include "glsl/GrGLSLUniformHandler.h"
18 #include "glsl/GrGLSLTextureSampler.h"
19 #include "glsl/GrGLSLVertexShaderBuilder.h"
20 #include "glsl/GrGLSLXferProcessor.h"
21 
22 class GrGLSLCaps;
23 class GrGLSLShaderVar;
24 class GrGLSLVaryingHandler;
25 
26 typedef SkSTArray<8, GrGLSLFragmentProcessor*, true> GrGLSLFragProcs;
27 
28 class GrGLSLProgramBuilder {
29 public:
30     typedef GrGpu::DrawArgs DrawArgs;
31     typedef GrGLSLUniformHandler::UniformHandle UniformHandle;
32 
~GrGLSLProgramBuilder()33     virtual ~GrGLSLProgramBuilder() {}
34 
35     virtual const GrCaps* caps() const = 0;
36     virtual const GrGLSLCaps* glslCaps() const = 0;
37 
primitiveProcessor()38     const GrPrimitiveProcessor& primitiveProcessor() const { return *fArgs.fPrimitiveProcessor; }
pipeline()39     const GrPipeline& pipeline() const { return *fArgs.fPipeline; }
desc()40     const GrProgramDesc& desc() const { return *fArgs.fDesc; }
header()41     const GrProgramDesc::KeyHeader& header() const { return fArgs.fDesc->header(); }
42 
43     void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
44 
45     // Handles for program uniforms (other than per-effect uniforms)
46     struct BuiltinUniformHandles {
47         UniformHandle       fRTAdjustmentUni;
48 
49         // We use the render target height to provide a y-down frag coord when specifying
50         // origin_upper_left is not supported.
51         UniformHandle       fRTHeightUni;
52     };
53 
54     // Used to add a uniform in the vertex shader for transforming into normalized device space.
55     void addRTAdjustmentUniform(GrSLPrecision precision, const char* name, const char** outName);
rtAdjustment()56     const char* rtAdjustment() const { return "rtAdjustment"; }
57 
58     // Used to add a uniform for the RenderTarget height (used for frag position) without mangling
59     // the name of the uniform inside of a stage.
60     void addRTHeightUniform(const char* name, const char** outName);
61 
62     // Generates a name for a variable. The generated string will be name prefixed by the prefix
63     // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless
64     // explicitly asked not to.
65     void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true);
66 
67     virtual GrGLSLUniformHandler* uniformHandler() = 0;
68     virtual const GrGLSLUniformHandler* uniformHandler() const = 0;
69     virtual GrGLSLVaryingHandler* varyingHandler() = 0;
70 
71     // Used for backend customization of the output color and secondary color variables from the
72     // fragment processor. Only used if the outputs are explicitly declared in the shaders
finalizeFragmentOutputColor(GrGLSLShaderVar & outputColor)73     virtual void finalizeFragmentOutputColor(GrGLSLShaderVar& outputColor) {}
finalizeFragmentSecondaryColor(GrGLSLShaderVar & outputColor)74     virtual void finalizeFragmentSecondaryColor(GrGLSLShaderVar& outputColor) {}
75 
76     // number of each input/output type in a single allocation block, used by many builders
77     static const int kVarsPerBlock;
78 
79     GrGLSLVertexBuilder         fVS;
80     GrGLSLGeometryBuilder       fGS;
81     GrGLSLFragmentShaderBuilder fFS;
82 
83     int fStageIndex;
84 
85     const DrawArgs& fArgs;
86 
87     BuiltinUniformHandles fUniformHandles;
88 
89     GrGLSLPrimitiveProcessor* fGeometryProcessor;
90     GrGLSLXferProcessor* fXferProcessor;
91     GrGLSLFragProcs fFragmentProcessors;
92 
93 protected:
94     explicit GrGLSLProgramBuilder(const DrawArgs& args);
95 
96     bool emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage, int maxTextures);
97 
98     void cleanupFragmentProcessors();
99 
100     void finalizeShaders();
101 
102 private:
103     // reset is called by program creator between each processor's emit code.  It increments the
104     // stage offset for variable name mangling, and also ensures verfication variables in the
105     // fragment shader are cleared.
reset()106     void reset() {
107         this->addStage();
108         fFS.reset();
109     }
addStage()110     void addStage() { fStageIndex++; }
111 
112     class AutoStageAdvance {
113     public:
AutoStageAdvance(GrGLSLProgramBuilder * pb)114         AutoStageAdvance(GrGLSLProgramBuilder* pb)
115             : fPB(pb) {
116             fPB->reset();
117             // Each output to the fragment processor gets its own code section
118             fPB->fFS.nextStage();
119         }
~AutoStageAdvance()120         ~AutoStageAdvance() {}
121     private:
122         GrGLSLProgramBuilder* fPB;
123     };
124 
125     // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
126     // If GrGLSLExpr4 has a valid name then it will use that instead
127     void nameExpression(GrGLSLExpr4*, const char* baseName);
128 
129     void emitAndInstallPrimProc(const GrPrimitiveProcessor&,
130                                 GrGLSLExpr4* outputColor,
131                                 GrGLSLExpr4* outputCoverage);
132     void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
133     void emitAndInstallFragProc(const GrFragmentProcessor&,
134                                 int index,
135                                 const GrGLSLExpr4& input,
136                                 GrGLSLExpr4* output);
137     void emitAndInstallXferProc(const GrXferProcessor&,
138                                 const GrGLSLExpr4& colorIn,
139                                 const GrGLSLExpr4& coverageIn,
140                                 bool ignoresCoverage,
141                                 GrPixelLocalStorageState plsState);
142     void emitFSOutputSwizzle(bool hasSecondaryOutput);
143 
144     void verify(const GrPrimitiveProcessor&);
145     void verify(const GrXferProcessor&);
146     void verify(const GrFragmentProcessor&);
147 
148     virtual void emitSamplers(const GrProcessor& processor,
149                               GrGLSLTextureSampler::TextureSamplerArray* outSamplers) = 0;
150 
151     GrGLSLPrimitiveProcessor::TransformsIn  fCoordTransforms;
152     GrGLSLPrimitiveProcessor::TransformsOut fOutCoords;
153 };
154 
155 #endif
156