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