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