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