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