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