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