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 GrAssert(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) { this->resize(arrayCount); } 53 54 void resize(int newCount) { 55 fAttribArrayStates.resize_back(newCount); 56 for (int i = 0; i < newCount; ++i) { 57 fAttribArrayStates[i].invalidate(); 58 } 59 } 60 61 /** 62 * This function enables and sets vertex attrib state for the specified attrib index. It is 63 * assumed that the GrGLAttribArrayState is tracking the state of the currently bound vertex 64 * array object. 65 */ 66 void set(const GrGpuGL*, 67 int index, 68 GrGLVertexBuffer*, 69 GrGLint size, 70 GrGLenum type, 71 GrGLboolean normalized, 72 GrGLsizei stride, 73 GrGLvoid* offset); 74 75 /** 76 * This function disables vertex attribs not present in the mask. It is assumed that the 77 * GrGLAttribArrayState is tracking the state of the currently bound vertex array object. 78 */ 79 void disableUnusedAttribArrays(const GrGpuGL*, uint64_t usedAttribArrayMask); 80 81 void invalidate() { 82 int count = fAttribArrayStates.count(); 83 for (int i = 0; i < count; ++i) { 84 fAttribArrayStates[i].invalidate(); 85 } 86 } 87 88 void notifyVertexBufferDelete(GrGLuint id) { 89 int count = fAttribArrayStates.count(); 90 for (int i = 0; i < count; ++i) { 91 if (fAttribArrayStates[i].fAttribPointerIsValid && 92 id == fAttribArrayStates[i].fVertexBufferID) { 93 fAttribArrayStates[i].invalidate(); 94 } 95 } 96 } 97 98 /** 99 * The number of attrib arrays that this object is configured to track. 100 */ 101 int count() const { return fAttribArrayStates.count(); } 102 103 private: 104 /** 105 * Tracks the state of glVertexAttribArray for an attribute index. 106 */ 107 struct AttribArrayState { 108 void invalidate() { 109 fEnableIsValid = false; 110 fAttribPointerIsValid = false; 111 } 112 113 bool fEnableIsValid; 114 bool fAttribPointerIsValid; 115 bool fEnabled; 116 GrGLuint fVertexBufferID; 117 GrGLint fSize; 118 GrGLenum fType; 119 GrGLboolean fNormalized; 120 GrGLsizei fStride; 121 GrGLvoid* fOffset; 122 }; 123 124 SkSTArray<16, AttribArrayState, true> fAttribArrayStates; 125 }; 126 127 /** 128 * This class represents an OpenGL vertex array object. It manages the lifetime of the vertex array 129 * and is used to track the state of the vertex array to avoid redundant GL calls. 130 */ 131 class GrGLVertexArray : public GrResource { 132 public: 133 GrGLVertexArray(GrGpuGL* gpu, GrGLint id, int attribCount); 134 135 /** 136 * Binds this vertex array. If the ID has been deleted or abandoned then NULL is returned. 137 * Otherwise, the GrGLAttribArrayState that is tracking this vertex array's attrib bindings is 138 * returned. 139 */ 140 GrGLAttribArrayState* bind(); 141 142 /** 143 * This is a version of the above function that also binds an index buffer to the vertex 144 * array object. 145 */ 146 GrGLAttribArrayState* bindWithIndexBuffer(const GrGLIndexBuffer* indexBuffer); 147 148 void notifyIndexBufferDelete(GrGLuint bufferID); 149 150 void notifyVertexBufferDelete(GrGLuint id) { 151 fAttribArrays.notifyVertexBufferDelete(id); 152 } 153 154 GrGLuint arrayID() const { return fID; } 155 156 void invalidateCachedState(); 157 158 virtual size_t sizeInBytes() const SK_OVERRIDE { return 0; } 159 160 protected: 161 virtual void onAbandon() SK_OVERRIDE; 162 163 virtual void onRelease() SK_OVERRIDE; 164 165 private: 166 GrGLuint fID; 167 GrGLAttribArrayState fAttribArrays; 168 GrGLuint fIndexBufferID; 169 bool fIndexBufferIDIsValid; 170 171 typedef GrResource INHERITED; 172 }; 173 174 #endif 175