Home | History | Annotate | Download | only in gl
      1 /*
      2  * Copyright 2011 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 
      9 #ifndef GrGLProgram_DEFINED
     10 #define GrGLProgram_DEFINED
     11 
     12 #include "builders/GrGLProgramBuilder.h"
     13 #include "GrGLContext.h"
     14 #include "GrGLProgramDesc.h"
     15 #include "GrGLSL.h"
     16 #include "GrGLTexture.h"
     17 #include "GrGLProgramDataManager.h"
     18 
     19 #include "SkString.h"
     20 #include "SkXfermode.h"
     21 
     22 class GrGLProcessor;
     23 class GrGLInstalledProcessors;
     24 class GrGLProgramBuilder;
     25 class GrPipeline;
     26 
     27 /**
     28  * This class manages a GPU program and records per-program information.
     29  * We can specify the attribute locations so that they are constant
     30  * across our shaders. But the driver determines the uniform locations
     31  * at link time. We don't need to remember the sampler uniform location
     32  * because we will bind a texture slot to it and never change it
     33  * Uniforms are program-local so we can't rely on fHWState to hold the
     34  * previous uniform state after a program change.
     35  */
     36 class GrGLProgram : public SkRefCnt {
     37 public:
     38     SK_DECLARE_INST_COUNT(GrGLProgram)
     39 
     40     typedef GrGLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles;
     41 
     42     virtual ~GrGLProgram();
     43 
     44     /**
     45      * Call to abandon GL objects owned by this program.
     46      */
     47     void abandon();
     48 
     49     const GrProgramDesc& getDesc() { return fDesc; }
     50 
     51     /**
     52      * Gets the GL program ID for this program.
     53      */
     54     GrGLuint programID() const { return fProgramID; }
     55 
     56     /**
     57      * We use the RT's size and origin to adjust from Skia device space to OpenGL normalized device
     58      * space and to make device space positions have the correct origin for processors that require
     59      * them.
     60      */
     61     struct RenderTargetState {
     62         SkISize         fRenderTargetSize;
     63         GrSurfaceOrigin fRenderTargetOrigin;
     64 
     65         RenderTargetState() { this->invalidate(); }
     66         void invalidate() {
     67             fRenderTargetSize.fWidth = -1;
     68             fRenderTargetSize.fHeight = -1;
     69             fRenderTargetOrigin = (GrSurfaceOrigin) -1;
     70         }
     71 
     72         /**
     73          * Gets a vec4 that adjusts the position from Skia device coords to GL's normalized device
     74          * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is
     75          * applied as such:
     76          * pos.x = dot(v.xy, pos.xz)
     77          * pos.y = dot(v.zq, pos.yz)
     78          */
     79         void getRTAdjustmentVec(GrGLfloat* destVec) {
     80             destVec[0] = 2.f / fRenderTargetSize.fWidth;
     81             destVec[1] = -1.f;
     82             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
     83                 destVec[2] = -2.f / fRenderTargetSize.fHeight;
     84                 destVec[3] = 1.f;
     85             } else {
     86                 destVec[2] = 2.f / fRenderTargetSize.fHeight;
     87                 destVec[3] = -1.f;
     88             }
     89         }
     90     };
     91 
     92     /**
     93      * This function uploads uniforms and calls each GrGLProcessor's setData. It is called before a
     94      * draw occurs using the program after the program has already been bound. It also uses the
     95      * GrGLGpu object to bind the textures required by the GrGLProcessors. The color and coverage
     96      * stages come from GrGLProgramDesc::Build().
     97      */
     98     void setData(const GrPrimitiveProcessor&, const GrPipeline&, const GrBatchTracker&);
     99 
    100 protected:
    101     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
    102     typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
    103 
    104     GrGLProgram(GrGLGpu*,
    105                 const GrProgramDesc&,
    106                 const BuiltinUniformHandles&,
    107                 GrGLuint programID,
    108                 const UniformInfoArray&,
    109                 GrGLInstalledGeoProc* geometryProcessor,
    110                 GrGLInstalledXferProc* xferProcessor,
    111                 GrGLInstalledFragProcs* fragmentProcessors);
    112 
    113     // Sets the texture units for samplers.
    114     void initSamplerUniforms();
    115     template <class Proc>
    116     void initSamplers(Proc*, int* texUnitIdx);
    117 
    118     // A templated helper to loop over effects, set the transforms(via subclass) and bind textures
    119     void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&);
    120     virtual void setTransformData(const GrPrimitiveProcessor&,
    121                                   const GrPendingFragmentStage&,
    122                                   int index,
    123                                   GrGLInstalledFragProc*);
    124     template <class Proc>
    125     void bindTextures(const Proc*, const GrProcessor&);
    126 
    127     /*
    128      * Legacy NVPR needs a hook here to flush path tex gen settings.
    129      * TODO when legacy nvpr is removed, remove this call.
    130      */
    131     virtual void didSetData() {}
    132 
    133     // Helper for setData() that sets the view matrix and loads the render target height uniform
    134     void setRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&);
    135     virtual void onSetRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&);
    136 
    137     // these reflect the current values of uniforms (GL uniform values travel with program)
    138     RenderTargetState fRenderTargetState;
    139     GrColor fColor;
    140     uint8_t fCoverage;
    141     int fDstCopyTexUnit;
    142     BuiltinUniformHandles fBuiltinUniformHandles;
    143     GrGLuint fProgramID;
    144 
    145     // the installed effects
    146     SkAutoTDelete<GrGLInstalledGeoProc> fGeometryProcessor;
    147     SkAutoTDelete<GrGLInstalledXferProc> fXferProcessor;
    148     SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
    149 
    150     GrProgramDesc fDesc;
    151     GrGLGpu* fGpu;
    152     GrGLProgramDataManager fProgramDataManager;
    153 
    154     friend class GrGLProgramBuilder;
    155 
    156     typedef SkRefCnt INHERITED;
    157 };
    158 
    159 /*
    160  * Below are slight specializations of the program object for the different types of programs
    161  * The default GrGL programs consist of at the very least a vertex and fragment shader.
    162  * Legacy Nvpr only has a fragment shader, 1.3+ Nvpr ignores the vertex shader, but both require
    163  * specialized methods for setting transform data. Both types of NVPR also require setting the
    164  * projection matrix through a special function call
    165  */
    166 class GrGLNvprProgram : public GrGLProgram {
    167 protected:
    168     GrGLNvprProgram(GrGLGpu*,
    169                     const GrProgramDesc&,
    170                     const BuiltinUniformHandles&,
    171                     GrGLuint programID,
    172                     const UniformInfoArray&,
    173                     GrGLInstalledGeoProc*,
    174                     GrGLInstalledXferProc* xferProcessor,
    175                     GrGLInstalledFragProcs* fragmentProcessors);
    176 
    177 private:
    178     void didSetData() override;
    179     virtual void setTransformData(const GrPrimitiveProcessor&,
    180                                   const GrPendingFragmentStage&,
    181                                   int index,
    182                                   GrGLInstalledFragProc*) override;
    183     virtual void onSetRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&);
    184 
    185     friend class GrGLNvprProgramBuilder;
    186 
    187     typedef GrGLProgram INHERITED;
    188 };
    189 
    190 #endif
    191