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