| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 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; |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 15 | |
| 16 | /** |
| bsalomon@google.com | c781888 | 2013-03-20 19:19:53 +0000 | [diff] [blame] | 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. |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 26 | */ |
| 27 | class GrGLEffectMatrix { |
| bsalomon@google.com | c781888 | 2013-03-20 19:19:53 +0000 | [diff] [blame] | 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 | |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 45 | public: |
| bsalomon@google.com | c781888 | 2013-03-20 19:19:53 +0000 | [diff] [blame] | 46 | |
| 47 | typedef GrEffect::CoordsType CoordsType; |
| 48 | |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 49 | typedef GrGLEffect::EffectKey EffectKey; |
| bsalomon@google.com | c781888 | 2013-03-20 19:19:53 +0000 | [diff] [blame] | 50 | |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 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 { |
| bsalomon@google.com | c781888 | 2013-03-20 19:19:53 +0000 | [diff] [blame] | 57 | kKeyBits = kKeyBitsPrivate, |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 58 | kKeyMask = (1 << kKeyBits) - 1, |
| 59 | }; |
| 60 | |
| bsalomon@google.com | c781888 | 2013-03-20 19:19:53 +0000 | [diff] [blame] | 61 | GrGLEffectMatrix(CoordsType coordsType) |
| commit-bot@chromium.org | 7425c12 | 2013-08-14 18:14:19 +0000 | [diff] [blame] | 62 | : fCoordsType(coordsType) { |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 63 | fPrevMatrix = SkMatrix::InvalidMatrix(); |
| 64 | } |
| 65 | |
| 66 | /** |
| 67 | * Generates the key for the portion of the code emitted by this class's emitCode() function. |
| 68 | * Pass a texture to make GrGLEffectMatrix automatically adjust for the texture's origin. Pass |
| bsalomon@google.com | c781888 | 2013-03-20 19:19:53 +0000 | [diff] [blame] | 69 | * NULL when not using the EffectMatrix for a texture lookup, or if the GrGLEffect subclass |
| 70 | * wants to handle origin adjustments in some other manner. The coords type param must match the |
| 71 | * param that would be used to initialize GrGLEffectMatrix for the generating GrEffect. |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 72 | */ |
| 73 | static EffectKey GenKey(const SkMatrix& effectMatrix, |
| bsalomon@google.com | c781888 | 2013-03-20 19:19:53 +0000 | [diff] [blame] | 74 | const GrDrawEffect&, |
| 75 | CoordsType, |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 76 | const GrTexture*); |
| 77 | |
| 78 | /** |
| 79 | * Emits code to implement the matrix in the VS. A varying is added as an output of the VS and |
| 80 | * input to the FS. The varying may be either a vec2f or vec3f depending upon whether |
| 81 | * perspective interpolation is required or not. The names of the varying in the VS and FS are |
| 82 | * are returned as output parameters and the type of the varying is the return value. The suffix |
| 83 | * is an optional parameter that can be used to make all variables emitted by the object |
| 84 | * unique within a stage. It is only necessary if multiple GrGLEffectMatrix objects are used by |
| commit-bot@chromium.org | 7ab7ca4 | 2013-08-28 15:59:13 +0000 | [diff] [blame] | 85 | * a single GrGLEffect. |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 86 | */ |
| 87 | GrSLType emitCode(GrGLShaderBuilder*, |
| 88 | EffectKey, |
| commit-bot@chromium.org | 7ab7ca4 | 2013-08-28 15:59:13 +0000 | [diff] [blame] | 89 | SkString* fsCoordName, /* optional */ |
| 90 | SkString* vsCoordName = NULL, |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 91 | const char* suffix = NULL); |
| 92 | |
| 93 | /** |
| 94 | * This is similar to emitCode except that it performs perspective division in the FS if the |
| 95 | * texture coordinates have a w coordinate. The fsCoordName always refers to a vec2f. |
| 96 | */ |
| 97 | void emitCodeMakeFSCoords2D(GrGLShaderBuilder*, |
| 98 | EffectKey, |
| commit-bot@chromium.org | 7ab7ca4 | 2013-08-28 15:59:13 +0000 | [diff] [blame] | 99 | SkString* fsCoordName, /* optional */ |
| 100 | SkString* vsVaryingName = NULL, |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 101 | GrSLType* vsVaryingType = NULL, |
| 102 | const char* suffix = NULL); |
| 103 | /** |
| bsalomon@google.com | c781888 | 2013-03-20 19:19:53 +0000 | [diff] [blame] | 104 | * Call from a GrGLEffect's subclass to update the texture matrix. The effectMatrix and texture |
| 105 | * params should match those used with GenKey. |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 106 | */ |
| 107 | void setData(const GrGLUniformManager& uniformManager, |
| 108 | const SkMatrix& effectMatrix, |
| bsalomon@google.com | c781888 | 2013-03-20 19:19:53 +0000 | [diff] [blame] | 109 | const GrDrawEffect& drawEffect, |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 110 | const GrTexture*); |
| 111 | |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 112 | GrGLUniformManager::UniformHandle fUni; |
| 113 | GrSLType fUniType; |
| 114 | SkMatrix fPrevMatrix; |
| bsalomon@google.com | c781888 | 2013-03-20 19:19:53 +0000 | [diff] [blame] | 115 | CoordsType fCoordsType; |
| bsalomon@google.com | d8b5fac | 2012-11-01 17:02:46 +0000 | [diff] [blame] | 116 | }; |
| 117 | |
| bsalomon@google.com | 8171288 | 2012-11-01 17:12:34 +0000 | [diff] [blame] | 118 | #endif |