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 "GrCaps.h"
12#include "GrGeometryProcessor.h"
13#include "GrProgramDesc.h"
14#include "glsl/GrGLSLFragmentProcessor.h"
15#include "glsl/GrGLSLFragmentShaderBuilder.h"
16#include "glsl/GrGLSLPrimitiveProcessor.h"
17#include "glsl/GrGLSLProgramDataManager.h"
18#include "glsl/GrGLSLUniformHandler.h"
19#include "glsl/GrGLSLVertexGeoBuilder.h"
20#include "glsl/GrGLSLXferProcessor.h"
21
22class GrShaderVar;
23class GrGLSLVaryingHandler;
24class SkString;
25class GrShaderCaps;
26
27typedef SkSTArray<8, GrGLSLFragmentProcessor*, true> GrGLSLFragProcs;
28
29class GrGLSLProgramBuilder {
30public:
31    using UniformHandle      = GrGLSLUniformHandler::UniformHandle;
32    using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
33    using TexelBufferHandle  = GrGLSLUniformHandler::TexelBufferHandle;
34
35    virtual ~GrGLSLProgramBuilder() {}
36
37    virtual const GrCaps* caps() const = 0;
38    const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
39
40    const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; }
41    const GrPipeline& pipeline() const { return fPipeline; }
42    GrProgramDesc* desc() { return fDesc; }
43    const GrProgramDesc::KeyHeader& header() const { return fDesc->header(); }
44
45    void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
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    const GrShaderVar& texelBufferVariable(TexelBufferHandle handle) const {
56        return this->uniformHandler()->texelBufferVariable(handle);
57    }
58
59    // Handles for program uniforms (other than per-effect uniforms)
60    struct BuiltinUniformHandles {
61        UniformHandle       fRTAdjustmentUni;
62
63        // We use the render target height to provide a y-down frag coord when specifying
64        // origin_upper_left is not supported.
65        UniformHandle       fRTHeightUni;
66    };
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);
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    GrProgramDesc*              fDesc;
98
99    BuiltinUniformHandles fUniformHandles;
100
101    std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
102    std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
103    GrGLSLFragProcs fFragmentProcessors;
104
105protected:
106    explicit GrGLSLProgramBuilder(const GrPipeline&,
107                                  const GrPrimitiveProcessor&,
108                                  GrProgramDesc*);
109
110    void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
111
112    bool emitAndInstallProcs();
113
114    void cleanupFragmentProcessors();
115
116    void finalizeShaders();
117
118    bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); }
119
120private:
121    // reset is called by program creator between each processor's emit code.  It increments the
122    // stage offset for variable name mangling, and also ensures verfication variables in the
123    // fragment shader are cleared.
124    void reset() {
125        this->addStage();
126        SkDEBUGCODE(fFS.resetVerification();)
127    }
128    void addStage() { fStageIndex++; }
129
130    class AutoStageAdvance {
131    public:
132        AutoStageAdvance(GrGLSLProgramBuilder* pb)
133            : fPB(pb) {
134            fPB->reset();
135            // Each output to the fragment processor gets its own code section
136            fPB->fFS.nextStage();
137        }
138        ~AutoStageAdvance() {}
139    private:
140        GrGLSLProgramBuilder* fPB;
141    };
142
143    // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
144    void nameExpression(SkString*, const char* baseName);
145
146    void emitAndInstallPrimProc(const GrPrimitiveProcessor&,
147                                SkString* outputColor,
148                                SkString* outputCoverage);
149    void emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut);
150    SkString emitAndInstallFragProc(const GrFragmentProcessor&,
151                                    int index,
152                                    int transformedCoordVarsIdx,
153                                    const SkString& input,
154                                    SkString output);
155    void emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
156    void emitSamplers(const GrResourceIOProcessor& processor,
157                      SkTArray<SamplerHandle>* outTexSamplerHandles,
158                      SkTArray<TexelBufferHandle>* outTexelBufferHandles);
159    SamplerHandle emitSampler(GrSLType samplerType, GrPixelConfig, const char* name,
160                              GrShaderFlags visibility);
161    TexelBufferHandle emitTexelBuffer(GrPixelConfig, const char* name, GrShaderFlags visibility);
162    void emitFSOutputSwizzle(bool hasSecondaryOutput);
163    void updateSamplerCounts(GrShaderFlags visibility);
164    bool checkSamplerCounts();
165
166#ifdef SK_DEBUG
167    void verify(const GrPrimitiveProcessor&);
168    void verify(const GrXferProcessor&);
169    void verify(const GrFragmentProcessor&);
170#endif
171
172    // These are used to check that we don't excede the allowable number of resources in a shader.
173    // The sampler counts include both normal texure samplers as well as texel buffers.
174    int                         fNumVertexSamplers;
175    int                         fNumGeometrySamplers;
176    int                         fNumFragmentSamplers;
177    SkSTArray<4, GrShaderVar>   fTransformedCoordVars;
178};
179
180#endif
181