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