Home | History | Annotate | Download | only in builders
      1 /*
      2  * Copyright 2014 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 GrGLFullProgramBuilder_DEFINED
      9 #define GrGLFullProgramBuilder_DEFINED
     10 
     11 #include "GrGLProgramBuilder.h"
     12 #include "../GrGLGeometryProcessor.h"
     13 
     14 class GrGLVertexProgramEffects;
     15 
     16 class GrGLFullProgramBuilder : public GrGLProgramBuilder {
     17 public:
     18     GrGLFullProgramBuilder(GrGpuGL*, const GrGLProgramDesc&);
     19 
     20    /** Add a varying variable to the current program to pass values between vertex and fragment
     21         shaders. If the last two parameters are non-NULL, they are filled in with the name
     22         generated. */
     23     void addVarying(GrSLType type,
     24                     const char* name,
     25                     const char** vsOutName = NULL,
     26                     const char** fsInName = NULL,
     27                     GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision);
     28 
     29     /** Add a separable varying input variable to the current program.
     30      * A separable varying (fragment shader input) is a varying that can be used also when vertex
     31      * shaders are not used. With a vertex shader, the operation is same as with other
     32      * varyings. Without a vertex shader, such as with NV_path_rendering, GL APIs are used to
     33      * populate the variable. The APIs can refer to the variable through the returned handle.
     34      */
     35     VaryingHandle addSeparableVarying(GrSLType type,
     36                                       const char* name,
     37                                       const char** vsOutName,
     38                                       const char** fsInName);
     39 
     40     GrGLVertexShaderBuilder* getVertexShaderBuilder() { return &fVS; }
     41 
     42     /*
     43      * This non-virtual call will hide the parent call to prevent GPs from accessing fragment shader
     44      * functionality they shouldn't be using
     45      */
     46     GrGLProcessorFragmentShaderBuilder* getFragmentShaderBuilder() { return &fFS; }
     47 
     48 private:
     49     virtual void createAndEmitEffects(const GrGeometryStage* geometryProcessor,
     50                                       const GrFragmentStage* colorStages[],
     51                                       const GrFragmentStage* coverageStages[],
     52                                       GrGLSLExpr4* inputColor,
     53                                       GrGLSLExpr4* inputCoverage) SK_OVERRIDE;
     54 
     55     GrGLProgramEffects* onCreateAndEmitEffects(const GrFragmentStage* effectStages[],
     56                                                int effectCnt,
     57                                                const GrGLProgramDesc::EffectKeyProvider&,
     58                                                GrGLSLExpr4* inOutFSColor);
     59 
     60     class GrGLGeometryProcessorEmitter : public GrGLProgramBuilder::GrGLProcessorEmitterInterface {
     61         public:
     62             GrGLGeometryProcessorEmitter(GrGLFullProgramBuilder* builder)
     63                 : fBuilder(builder)
     64                 , fGeometryProcessor(NULL)
     65                 , fGLGeometryProcessor(NULL) {}
     66             virtual ~GrGLGeometryProcessorEmitter() {}
     67             void set(const GrGeometryProcessor* gp) {
     68                 SkASSERT(NULL == fGeometryProcessor);
     69                 fGeometryProcessor = gp;
     70             }
     71             virtual GrGLProcessor* createGLInstance() {
     72                 SkASSERT(fGeometryProcessor);
     73                 SkASSERT(NULL == fGLGeometryProcessor);
     74                 fGLGeometryProcessor =
     75                         fGeometryProcessor->getFactory().createGLInstance(*fGeometryProcessor);
     76                 return fGLGeometryProcessor;
     77             }
     78             virtual void emit(const GrProcessorKey& key,
     79                               const char* outColor,
     80                               const char* inColor,
     81                               const GrGLProcessor::TransformedCoordsArray& coords,
     82                               const GrGLProcessor::TextureSamplerArray& samplers) {
     83                 SkASSERT(fGeometryProcessor);
     84                 SkASSERT(fGLGeometryProcessor);
     85                 fGLGeometryProcessor->emitCode(fBuilder, *fGeometryProcessor, key, outColor,
     86                                                inColor, coords, samplers);
     87                 // this will not leak because it has already been used by createGLInstance
     88                 fGLGeometryProcessor = NULL;
     89                 fGeometryProcessor = NULL;
     90             }
     91         private:
     92             GrGLFullProgramBuilder*     fBuilder;
     93             const GrGeometryProcessor*  fGeometryProcessor;
     94             GrGLGeometryProcessor*      fGLGeometryProcessor;
     95         };
     96 
     97     virtual void emitEffect(const GrProcessorStage& stage,
     98                             const GrProcessorKey& key,
     99                             const char* outColor,
    100                             const char* inColor,
    101                             int stageIndex) SK_OVERRIDE;
    102 
    103     /**
    104      * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
    105      * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
    106      * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
    107      * of the varyings in the VS and FS as well their types are appended to the
    108      * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
    109      */
    110     void emitTransforms(const GrProcessorStage& effectStage,
    111                         GrGLProcessor::TransformedCoordsArray* outCoords);
    112 
    113     virtual bool compileAndAttachShaders(GrGLuint programId,
    114                                          SkTDArray<GrGLuint>* shaderIds) const SK_OVERRIDE;
    115 
    116     virtual void bindProgramLocations(GrGLuint programId) SK_OVERRIDE;
    117 
    118     virtual GrGLProgramEffects* getProgramEffects() SK_OVERRIDE { return fProgramEffects.get(); }
    119 
    120     typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider;
    121 
    122     GrGLGeometryProcessorEmitter fGLGeometryProcessorEmitter;
    123     GrGLGeometryShaderBuilder fGS;
    124     GrGLVertexShaderBuilder   fVS;
    125     SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects;
    126 
    127     typedef GrGLProgramBuilder INHERITED;
    128 };
    129 
    130 #endif
    131