Home | History | Annotate | Download | only in glsl
      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 
     22 class GrShaderVar;
     23 class GrGLSLVaryingHandler;
     24 class SkString;
     25 class GrShaderCaps;
     26 
     27 typedef SkSTArray<8, GrGLSLFragmentProcessor*, true> GrGLSLFragProcs;
     28 
     29 class GrGLSLProgramBuilder {
     30 public:
     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 
    105 protected:
    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 
    120 private:
    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