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