Home | History | Annotate | Download | only in gl
      1 /*
      2  * Copyright 2012 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 GrGLEffectMatrix_DEFINED
      9 #define GrGLEffectMatrix_DEFINED
     10 
     11 #include "GrGLEffect.h"
     12 #include "SkMatrix.h"
     13 
     14 class GrTexture;
     15 
     16 /**
     17  * This is a helper to implement a matrix in a GrGLEffect that operates on incoming coords in the
     18  * vertex shader and writes them to an attribute to be used in the fragment shader. When the input
     19  * coords in the vertex shader are local coordinates this class accounts for the coord change matrix
     20  * communicated via GrDrawEffect. The input coords may also be positions and in this case the coord
     21  * change matrix is ignored. The GrGLEffectMatrix will emit different code based on the type of
     22  * matrix and thus must contribute to the effect's key.
     23  *
     24  * This class cannot be used to apply a matrix to coordinates that come in the form of custom vertex
     25  * attributes.
     26  */
     27 class GrGLEffectMatrix {
     28 private:
     29     // We specialize the generated code for each of these matrix types.
     30     enum MatrixTypes {
     31         kIdentity_MatrixType    = 0,
     32         kTrans_MatrixType       = 1,
     33         kNoPersp_MatrixType     = 2,
     34         kGeneral_MatrixType     = 3,
     35     };
     36     // The key for is made up of a matrix type and a bit that indicates the source of the input
     37     // coords.
     38     enum {
     39         kMatrixTypeKeyBits      = 2,
     40         kMatrixTypeKeyMask      = (1 << kMatrixTypeKeyBits) - 1,
     41         kPositionCoords_Flag    = (1 << kMatrixTypeKeyBits),
     42         kKeyBitsPrivate         = kMatrixTypeKeyBits + 1,
     43     };
     44 
     45 public:
     46 
     47     typedef GrEffect::CoordsType CoordsType;
     48 
     49     typedef GrGLEffect::EffectKey EffectKey;
     50 
     51     /**
     52      * The matrix uses kKeyBits of the effect's EffectKey. A GrGLEffect may place these bits at an
     53      * arbitrary shift in its final key. However, when GrGLEffectMatrix::emitCode*() code is called
     54      * the relevant bits must be in the lower kKeyBits of the key parameter.
     55      */
     56     enum {
     57         kKeyBits = kKeyBitsPrivate,
     58         kKeyMask = (1 << kKeyBits) - 1,
     59     };
     60 
     61     GrGLEffectMatrix(CoordsType coordsType)
     62         : fUni(GrGLUniformManager::kInvalidUniformHandle)
     63         , fCoordsType(coordsType) {
     64         GrAssert(GrEffect::kLocal_CoordsType == coordsType ||
     65                  GrEffect::kPosition_CoordsType == coordsType);
     66         fPrevMatrix = SkMatrix::InvalidMatrix();
     67     }
     68 
     69     /**
     70      * Generates the key for the portion of the code emitted by this class's emitCode() function.
     71      * Pass a texture to make GrGLEffectMatrix automatically adjust for the texture's origin. Pass
     72      * NULL when not using the EffectMatrix for a texture lookup, or if the GrGLEffect subclass
     73      * wants to handle origin adjustments in some other manner. The coords type param must match the
     74      * param that would be used to initialize GrGLEffectMatrix for the generating GrEffect.
     75      */
     76     static EffectKey GenKey(const SkMatrix& effectMatrix,
     77                             const GrDrawEffect&,
     78                             CoordsType,
     79                             const GrTexture*);
     80 
     81     /**
     82      * Emits code to implement the matrix in the VS. A varying is added as an output of the VS and
     83      * input to the FS. The varying may be either a vec2f or vec3f depending upon whether
     84      * perspective interpolation is required or not. The names of the varying in the VS and FS are
     85      * are returned as output parameters and the type of the varying is the return value. The suffix
     86      * is an optional parameter that can be used to make all variables emitted by the object
     87      * unique within a stage. It is only necessary if multiple GrGLEffectMatrix objects are used by
     88      * a GrGLEffect.
     89      */
     90     GrSLType emitCode(GrGLShaderBuilder*,
     91                       EffectKey,
     92                       const char** fsCoordName, /* optional */
     93                       const char** vsCoordName = NULL,
     94                       const char* suffix = NULL);
     95 
     96     /**
     97      * This is similar to emitCode except that it performs perspective division in the FS if the
     98      * texture coordinates have a w coordinate. The fsCoordName always refers to a vec2f.
     99      */
    100     void emitCodeMakeFSCoords2D(GrGLShaderBuilder*,
    101                                 EffectKey,
    102                                 const char** fsCoordName, /* optional */
    103                                 const char** vsVaryingName = NULL,
    104                                 GrSLType* vsVaryingType = NULL,
    105                                 const char* suffix = NULL);
    106     /**
    107      * Call from a GrGLEffect's subclass to update the texture matrix. The effectMatrix and texture
    108      * params should match those used with GenKey.
    109      */
    110     void setData(const GrGLUniformManager& uniformManager,
    111                  const SkMatrix& effectMatrix,
    112                  const GrDrawEffect& drawEffect,
    113                  const GrTexture*);
    114 
    115     GrGLUniformManager::UniformHandle fUni;
    116     GrSLType                          fUniType;
    117     SkMatrix                          fPrevMatrix;
    118     CoordsType                        fCoordsType;
    119 };
    120 
    121 #endif
    122