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 "GrGpuResource.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 GrGpuResource { 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 gpuMemorySize() 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 GrGpuResource INHERITED; 174 }; 175 176 #endif 177