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 "GrDrawState.h"
     14 #include "GrGLContext.h"
     15 #include "GrGLProgramDesc.h"
     16 #include "GrGLSL.h"
     17 #include "GrGLTexture.h"
     18 #include "GrGLProgramDataManager.h"
     19 
     20 #include "SkString.h"
     21 #include "SkXfermode.h"
     22 
     23 class GrGLProcessor;
     24 class GrGLProgramEffects;
     25 class GrGLProgramBuilder;
     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     static GrGLProgram* Create(GrGpuGL* gpu,
     43                                const GrGLProgramDesc& desc,
     44                                const GrGeometryStage* geometryProcessor,
     45                                const GrFragmentStage* colorStages[],
     46                                const GrFragmentStage* coverageStages[]);
     47 
     48     virtual ~GrGLProgram();
     49 
     50     /**
     51      * Call to abandon GL objects owned by this program.
     52      */
     53     void abandon();
     54 
     55     const GrGLProgramDesc& getDesc() { return fDesc; }
     56 
     57     /**
     58      * Gets the GL program ID for this program.
     59      */
     60     GrGLuint programID() const { return fProgramID; }
     61 
     62     bool hasVertexShader() const { return fHasVertexShader; }
     63 
     64     /**
     65      * Some GL state that is relevant to programs is not stored per-program. In particular color
     66      * and coverage attributes can be global state. This struct is read and updated by
     67      * GrGLProgram::setColor and GrGLProgram::setCoverage to allow us to avoid setting this state
     68      * redundantly.
     69      */
     70     struct SharedGLState {
     71         GrColor fConstAttribColor;
     72         int     fConstAttribColorIndex;
     73         GrColor fConstAttribCoverage;
     74         int     fConstAttribCoverageIndex;
     75 
     76         SharedGLState() { this->invalidate(); }
     77         void invalidate() {
     78             fConstAttribColor = GrColor_ILLEGAL;
     79             fConstAttribColorIndex = -1;
     80             fConstAttribCoverage = GrColor_ILLEGAL;
     81             fConstAttribCoverageIndex = -1;
     82         }
     83     };
     84 
     85     /**
     86      * The GrDrawState's view matrix along with the aspects of the render target determine the
     87      * matrix sent to GL. The size of the render target affects the GL matrix because we must
     88      * convert from Skia device coords to GL's normalized coords. Also the origin of the render
     89      * target may require us to perform a mirror-flip.
     90      */
     91     struct MatrixState {
     92         SkMatrix        fViewMatrix;
     93         SkISize         fRenderTargetSize;
     94         GrSurfaceOrigin fRenderTargetOrigin;
     95 
     96         MatrixState() { this->invalidate(); }
     97         void invalidate() {
     98             fViewMatrix = SkMatrix::InvalidMatrix();
     99             fRenderTargetSize.fWidth = -1;
    100             fRenderTargetSize.fHeight = -1;
    101             fRenderTargetOrigin = (GrSurfaceOrigin) -1;
    102         }
    103 
    104         /**
    105          * Gets a matrix that goes from local coords to Skia's device coordinates.
    106          */
    107         template<int Size> void getGLMatrix(GrGLfloat* destMatrix) {
    108             GrGLGetMatrix<Size>(destMatrix, fViewMatrix);
    109         }
    110 
    111         /**
    112          * Gets a matrix that goes from local coordinates to GL normalized device coords.
    113          */
    114         template<int Size> void getRTAdjustedGLMatrix(GrGLfloat* destMatrix) {
    115             SkMatrix combined;
    116             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
    117                 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
    118                                 0, -SkIntToScalar(2) / fRenderTargetSize.fHeight, SK_Scalar1,
    119                                 0, 0, 1);
    120             } else {
    121                 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
    122                                 0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1,
    123                                 0, 0, 1);
    124             }
    125             combined.preConcat(fViewMatrix);
    126             GrGLGetMatrix<Size>(destMatrix, combined);
    127         }
    128 
    129         /**
    130          * Gets a vec4 that adjusts the position from Skia device coords to GL's normalized device
    131          * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is
    132          * applied as such:
    133          * pos.x = dot(v.xy, pos.xz)
    134          * pos.y = dot(v.zq, pos.yz)
    135          */
    136         void getRTAdjustmentVec(GrGLfloat* destVec) {
    137             destVec[0] = 2.f / fRenderTargetSize.fWidth;
    138             destVec[1] = -1.f;
    139             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
    140                 destVec[2] = -2.f / fRenderTargetSize.fHeight;
    141                 destVec[3] = 1.f;
    142             } else {
    143                 destVec[2] = 2.f / fRenderTargetSize.fHeight;
    144                 destVec[3] = -1.f;
    145             }
    146         }
    147     };
    148 
    149     /**
    150      * This function uploads uniforms and calls each GrGLProcessor's setData. It is called before a
    151      * draw occurs using the program after the program has already been bound. It also uses the
    152      * GrGpuGL object to bind the textures required by the GrGLProcessors. The color and coverage
    153      * stages come from GrGLProgramDesc::Build().
    154      */
    155     void setData(const GrOptDrawState&,
    156                  GrGpu::DrawType,
    157                  const GrGeometryStage* geometryProcessor,
    158                  const GrFragmentStage* colorStages[],
    159                  const GrFragmentStage* coverageStages[],
    160                  const GrDeviceCoordTexture* dstCopy, // can be NULL
    161                  SharedGLState*);
    162 
    163 private:
    164     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
    165 
    166     GrGLProgram(GrGpuGL*,
    167                 const GrGLProgramDesc&,
    168                 const GrGLProgramBuilder&);
    169 
    170     // Sets the texture units for samplers.
    171     void initSamplerUniforms();
    172 
    173     // Helper for setData(). Makes GL calls to specify the initial color when there is not
    174     // per-vertex colors.
    175     void setColor(const GrOptDrawState&, GrColor color, SharedGLState*);
    176 
    177     // Helper for setData(). Makes GL calls to specify the initial coverage when there is not
    178     // per-vertex coverages.
    179     void setCoverage(const GrOptDrawState&, GrColor coverage, SharedGLState*);
    180 
    181     // Helper for setData() that sets the view matrix and loads the render target height uniform
    182     void setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrOptDrawState&);
    183 
    184     // these reflect the current values of uniforms (GL uniform values travel with program)
    185     MatrixState                         fMatrixState;
    186     GrColor                             fColor;
    187     GrColor                             fCoverage;
    188     int                                 fDstCopyTexUnit;
    189 
    190     BuiltinUniformHandles               fBuiltinUniformHandles;
    191     SkAutoTUnref<GrGLProgramEffects>    fGeometryProcessor;
    192     SkAutoTUnref<GrGLProgramEffects>    fColorEffects;
    193     SkAutoTUnref<GrGLProgramEffects>    fCoverageEffects;
    194     GrGLuint                            fProgramID;
    195     bool                                fHasVertexShader;
    196     int                                 fTexCoordSetCnt;
    197 
    198     GrGLProgramDesc                     fDesc;
    199     GrGpuGL*                            fGpu;
    200 
    201     GrGLProgramDataManager              fProgramDataManager;
    202 
    203     typedef SkRefCnt INHERITED;
    204 };
    205 
    206 #endif
    207