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 this->registerWithCache(); 77 } 78 79 void GrGLVertexArray::onAbandon() { 80 fID = 0; 81 INHERITED::onAbandon(); 82 } 83 84 void GrGLVertexArray::onRelease() { 85 if (0 != fID) { 86 GL_CALL(DeleteVertexArrays(1, &fID)); 87 GPUGL->notifyVertexArrayDelete(fID); 88 fID = 0; 89 } 90 INHERITED::onRelease(); 91 } 92 93 GrGLAttribArrayState* GrGLVertexArray::bind() { 94 if (0 == fID) { 95 return NULL; 96 } 97 GPUGL->bindVertexArray(fID); 98 return &fAttribArrays; 99 } 100 101 GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(const GrGLIndexBuffer* buffer) { 102 GrGLAttribArrayState* state = this->bind(); 103 if (state && buffer) { 104 GrGLuint bufferID = buffer->bufferID(); 105 if (!fIndexBufferIDIsValid || bufferID != fIndexBufferID) { 106 GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, bufferID)); 107 fIndexBufferIDIsValid = true; 108 fIndexBufferID = bufferID; 109 } 110 } 111 return state; 112 } 113 114 void GrGLVertexArray::notifyIndexBufferDelete(GrGLuint bufferID) { 115 if (fIndexBufferIDIsValid && bufferID == fIndexBufferID) { 116 fIndexBufferID = 0; 117 } 118 } 119 120 void GrGLVertexArray::invalidateCachedState() { 121 fAttribArrays.invalidate(); 122 fIndexBufferIDIsValid = false; 123 } 124