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 #include "GrGLVertexArray.h" 9 #include "GrGLGpu.h" 10 11 12 void GrGLAttribArrayState::set(const GrGLGpu* gpu, 13 int index, 14 GrGLVertexBuffer* buffer, 15 GrGLint size, 16 GrGLenum type, 17 GrGLboolean normalized, 18 GrGLsizei stride, 19 GrGLvoid* offset) { 20 SkASSERT(index >= 0 && index < fAttribArrayStates.count()); 21 AttribArrayState* array = &fAttribArrayStates[index]; 22 if (!array->fEnableIsValid || !array->fEnabled) { 23 GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(index)); 24 array->fEnableIsValid = true; 25 array->fEnabled = true; 26 } 27 if (!array->fAttribPointerIsValid || 28 array->fVertexBufferID != buffer->bufferID() || 29 array->fSize != size || 30 array->fNormalized != normalized || 31 array->fStride != stride || 32 array->fOffset != offset) { 33 34 buffer->bind(); 35 GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index, 36 size, 37 type, 38 normalized, 39 stride, 40 offset)); 41 array->fAttribPointerIsValid = true; 42 array->fVertexBufferID = buffer->bufferID(); 43 array->fSize = size; 44 array->fNormalized = normalized; 45 array->fStride = stride; 46 array->fOffset = offset; 47 } 48 } 49 50 void GrGLAttribArrayState::disableUnusedArrays(const GrGLGpu* gpu, uint64_t usedMask) { 51 int count = fAttribArrayStates.count(); 52 for (int i = 0; i < count; ++i) { 53 if (!(usedMask & 0x1)) { 54 if (!fAttribArrayStates[i].fEnableIsValid || fAttribArrayStates[i].fEnabled) { 55 GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i)); 56 fAttribArrayStates[i].fEnableIsValid = true; 57 fAttribArrayStates[i].fEnabled = false; 58 } 59 } else { 60 SkASSERT(fAttribArrayStates[i].fEnableIsValid && fAttribArrayStates[i].fEnabled); 61 } 62 // if the count is greater than 64 then this will become 0 and we will disable arrays 64+. 63 usedMask >>= 1; 64 } 65 } 66 67 /////////////////////////////////////////////////////////////////////////////////////////////////// 68 69 GrGLVertexArray::GrGLVertexArray(GrGLint id, int attribCount) 70 : fID(id) 71 , fAttribArrays(attribCount) 72 , fIndexBufferIDIsValid(false) { 73 } 74 75 GrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) { 76 if (0 == fID) { 77 return NULL; 78 } 79 gpu->bindVertexArray(fID); 80 return &fAttribArrays; 81 } 82 83 GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, 84 const GrGLIndexBuffer* buffer) { 85 GrGLAttribArrayState* state = this->bind(gpu); 86 if (state && buffer) { 87 GrGLuint bufferID = buffer->bufferID(); 88 if (!fIndexBufferIDIsValid || bufferID != fIndexBufferID) { 89 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, bufferID)); 90 fIndexBufferIDIsValid = true; 91 fIndexBufferID = bufferID; 92 } 93 } 94 return state; 95 } 96 97 void GrGLVertexArray::notifyIndexBufferDelete(GrGLuint bufferID) { 98 if (fIndexBufferIDIsValid && bufferID == fIndexBufferID) { 99 fIndexBufferID = 0; 100 } 101 } 102 103 void GrGLVertexArray::invalidateCachedState() { 104 fAttribArrays.invalidate(); 105 fIndexBufferIDIsValid = false; 106 } 107