|
1 /* |
|
2 * Copyright 2013 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 GrGLVertexArray_DEFINED |
|
9 #define GrGLVertexArray_DEFINED |
|
10 |
|
11 #include "GrResource.h" |
|
12 #include "GrTypesPriv.h" |
|
13 #include "gl/GrGLDefines.h" |
|
14 #include "gl/GrGLFunctions.h" |
|
15 |
|
16 #include "SkTArray.h" |
|
17 |
|
18 class GrGLVertexBuffer; |
|
19 class GrGLIndexBuffer; |
|
20 class GrGpuGL; |
|
21 |
|
22 struct GrGLAttribLayout { |
|
23 GrGLint fCount; |
|
24 GrGLenum fType; |
|
25 GrGLboolean fNormalized; |
|
26 }; |
|
27 |
|
28 static inline const GrGLAttribLayout& GrGLAttribTypeToLayout(GrVertexAttribType type) { |
|
29 SkASSERT(type >= 0 && type < kGrVertexAttribTypeCount); |
|
30 static const GrGLAttribLayout kLayouts[kGrVertexAttribTypeCount] = { |
|
31 {1, GR_GL_FLOAT, false}, // kFloat_GrVertexAttribType |
|
32 {2, GR_GL_FLOAT, false}, // kVec2f_GrVertexAttribType |
|
33 {3, GR_GL_FLOAT, false}, // kVec3f_GrVertexAttribType |
|
34 {4, GR_GL_FLOAT, false}, // kVec4f_GrVertexAttribType |
|
35 {4, GR_GL_UNSIGNED_BYTE, true}, // kVec4ub_GrVertexAttribType |
|
36 }; |
|
37 GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType); |
|
38 GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType); |
|
39 GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType); |
|
40 GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType); |
|
41 GR_STATIC_ASSERT(4 == kVec4ub_GrVertexAttribType); |
|
42 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kLayouts) == kGrVertexAttribTypeCount); |
|
43 return kLayouts[type]; |
|
44 } |
|
45 |
|
46 /** |
|
47 * This sets and tracks the vertex attribute array state. It is used internally by GrGLVertexArray |
|
48 * (below) but is separate because it is also used to track the state of vertex array object 0. |
|
49 */ |
|
50 class GrGLAttribArrayState { |
|
51 public: |
|
52 explicit GrGLAttribArrayState(int arrayCount = 0) { |
|
53 this->resize(arrayCount); |
|
54 } |
|
55 |
|
56 void resize(int newCount) { |
|
57 fAttribArrayStates.resize_back(newCount); |
|
58 for (int i = 0; i < newCount; ++i) { |
|
59 fAttribArrayStates[i].invalidate(); |
|
60 } |
|
61 } |
|
62 |
|
63 /** |
|
64 * This function enables and sets vertex attrib state for the specified attrib index. It is |
|
65 * assumed that the GrGLAttribArrayState is tracking the state of the currently bound vertex |
|
66 * array object. |
|
67 */ |
|
68 void set(const GrGpuGL*, |
|
69 int index, |
|
70 GrGLVertexBuffer*, |
|
71 GrGLint size, |
|
72 GrGLenum type, |
|
73 GrGLboolean normalized, |
|
74 GrGLsizei stride, |
|
75 GrGLvoid* offset); |
|
76 |
|
77 /** |
|
78 * This function disables vertex attribs not present in the mask. It is assumed that the |
|
79 * GrGLAttribArrayState is tracking the state of the currently bound vertex array object. |
|
80 */ |
|
81 void disableUnusedArrays(const GrGpuGL*, uint64_t usedAttribArrayMask); |
|
82 |
|
83 void invalidate() { |
|
84 int count = fAttribArrayStates.count(); |
|
85 for (int i = 0; i < count; ++i) { |
|
86 fAttribArrayStates[i].invalidate(); |
|
87 } |
|
88 } |
|
89 |
|
90 void notifyVertexBufferDelete(GrGLuint id) { |
|
91 int count = fAttribArrayStates.count(); |
|
92 for (int i = 0; i < count; ++i) { |
|
93 if (fAttribArrayStates[i].fAttribPointerIsValid && |
|
94 id == fAttribArrayStates[i].fVertexBufferID) { |
|
95 fAttribArrayStates[i].invalidate(); |
|
96 } |
|
97 } |
|
98 } |
|
99 |
|
100 /** |
|
101 * The number of attrib arrays that this object is configured to track. |
|
102 */ |
|
103 int count() const { return fAttribArrayStates.count(); } |
|
104 |
|
105 private: |
|
106 /** |
|
107 * Tracks the state of glVertexAttribArray for an attribute index. |
|
108 */ |
|
109 struct AttribArrayState { |
|
110 void invalidate() { |
|
111 fEnableIsValid = false; |
|
112 fAttribPointerIsValid = false; |
|
113 } |
|
114 |
|
115 bool fEnableIsValid; |
|
116 bool fAttribPointerIsValid; |
|
117 bool fEnabled; |
|
118 GrGLuint fVertexBufferID; |
|
119 GrGLint fSize; |
|
120 GrGLenum fType; |
|
121 GrGLboolean fNormalized; |
|
122 GrGLsizei fStride; |
|
123 GrGLvoid* fOffset; |
|
124 }; |
|
125 |
|
126 SkSTArray<16, AttribArrayState, true> fAttribArrayStates; |
|
127 }; |
|
128 |
|
129 /** |
|
130 * This class represents an OpenGL vertex array object. It manages the lifetime of the vertex array |
|
131 * and is used to track the state of the vertex array to avoid redundant GL calls. |
|
132 */ |
|
133 class GrGLVertexArray : public GrResource { |
|
134 public: |
|
135 GrGLVertexArray(GrGpuGL* gpu, GrGLint id, int attribCount); |
|
136 |
|
137 /** |
|
138 * Binds this vertex array. If the ID has been deleted or abandoned then NULL is returned. |
|
139 * Otherwise, the GrGLAttribArrayState that is tracking this vertex array's attrib bindings is |
|
140 * returned. |
|
141 */ |
|
142 GrGLAttribArrayState* bind(); |
|
143 |
|
144 /** |
|
145 * This is a version of the above function that also binds an index buffer to the vertex |
|
146 * array object. |
|
147 */ |
|
148 GrGLAttribArrayState* bindWithIndexBuffer(const GrGLIndexBuffer* indexBuffer); |
|
149 |
|
150 void notifyIndexBufferDelete(GrGLuint bufferID); |
|
151 |
|
152 void notifyVertexBufferDelete(GrGLuint id) { |
|
153 fAttribArrays.notifyVertexBufferDelete(id); |
|
154 } |
|
155 |
|
156 GrGLuint arrayID() const { return fID; } |
|
157 |
|
158 void invalidateCachedState(); |
|
159 |
|
160 virtual size_t sizeInBytes() const SK_OVERRIDE { return 0; } |
|
161 |
|
162 protected: |
|
163 virtual void onAbandon() SK_OVERRIDE; |
|
164 |
|
165 virtual void onRelease() SK_OVERRIDE; |
|
166 |
|
167 private: |
|
168 GrGLuint fID; |
|
169 GrGLAttribArrayState fAttribArrays; |
|
170 GrGLuint fIndexBufferID; |
|
171 bool fIndexBufferIDIsValid; |
|
172 |
|
173 typedef GrResource INHERITED; |
|
174 }; |
|
175 |
|
176 #endif |