| /* | |
| * Copyright 2013 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "GrGLVertexArray.h" | |
| #include "GrGLGpu.h" | |
| #define GPUGL static_cast<GrGLGpu*>(this->getGpu()) | |
| #define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X); | |
| void GrGLAttribArrayState::set(const GrGLGpu* gpu, | |
| int index, | |
| GrGLVertexBuffer* buffer, | |
| GrGLint size, | |
| GrGLenum type, | |
| GrGLboolean normalized, | |
| GrGLsizei stride, | |
| GrGLvoid* offset) { | |
| SkASSERT(index >= 0 && index < fAttribArrayStates.count()); | |
| AttribArrayState* array = &fAttribArrayStates[index]; | |
| if (!array->fEnableIsValid || !array->fEnabled) { | |
| GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(index)); | |
| array->fEnableIsValid = true; | |
| array->fEnabled = true; | |
| } | |
| if (!array->fAttribPointerIsValid || | |
| array->fVertexBufferID != buffer->bufferID() || | |
| array->fSize != size || | |
| array->fNormalized != normalized || | |
| array->fStride != stride || | |
| array->fOffset != offset) { | |
| buffer->bind(); | |
| GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index, | |
| size, | |
| type, | |
| normalized, | |
| stride, | |
| offset)); | |
| array->fAttribPointerIsValid = true; | |
| array->fVertexBufferID = buffer->bufferID(); | |
| array->fSize = size; | |
| array->fNormalized = normalized; | |
| array->fStride = stride; | |
| array->fOffset = offset; | |
| } | |
| } | |
| void GrGLAttribArrayState::disableUnusedArrays(const GrGLGpu* gpu, uint64_t usedMask) { | |
| int count = fAttribArrayStates.count(); | |
| for (int i = 0; i < count; ++i) { | |
| if (!(usedMask & 0x1)) { | |
| if (!fAttribArrayStates[i].fEnableIsValid || fAttribArrayStates[i].fEnabled) { | |
| GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i)); | |
| fAttribArrayStates[i].fEnableIsValid = true; | |
| fAttribArrayStates[i].fEnabled = false; | |
| } | |
| } else { | |
| SkASSERT(fAttribArrayStates[i].fEnableIsValid && fAttribArrayStates[i].fEnabled); | |
| } | |
| // if the count is greater than 64 then this will become 0 and we will disable arrays 64+. | |
| usedMask >>= 1; | |
| } | |
| } | |
| /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| GrGLVertexArray::GrGLVertexArray(GrGLGpu* gpu, GrGLint id, int attribCount) | |
| : INHERITED(gpu, kCached_LifeCycle) | |
| , fID(id) | |
| , fAttribArrays(attribCount) | |
| , fIndexBufferIDIsValid(false) { | |
| this->registerWithCache(); | |
| } | |
| void GrGLVertexArray::onAbandon() { | |
| fID = 0; | |
| INHERITED::onAbandon(); | |
| } | |
| void GrGLVertexArray::onRelease() { | |
| if (0 != fID) { | |
| GL_CALL(DeleteVertexArrays(1, &fID)); | |
| GPUGL->notifyVertexArrayDelete(fID); | |
| fID = 0; | |
| } | |
| INHERITED::onRelease(); | |
| } | |
| GrGLAttribArrayState* GrGLVertexArray::bind() { | |
| if (0 == fID) { | |
| return NULL; | |
| } | |
| GPUGL->bindVertexArray(fID); | |
| return &fAttribArrays; | |
| } | |
| GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(const GrGLIndexBuffer* buffer) { | |
| GrGLAttribArrayState* state = this->bind(); | |
| if (state && buffer) { | |
| GrGLuint bufferID = buffer->bufferID(); | |
| if (!fIndexBufferIDIsValid || bufferID != fIndexBufferID) { | |
| GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, bufferID)); | |
| fIndexBufferIDIsValid = true; | |
| fIndexBufferID = bufferID; | |
| } | |
| } | |
| return state; | |
| } | |
| void GrGLVertexArray::notifyIndexBufferDelete(GrGLuint bufferID) { | |
| if (fIndexBufferIDIsValid && bufferID == fIndexBufferID) { | |
| fIndexBufferID = 0; | |
| } | |
| } | |
| void GrGLVertexArray::invalidateCachedState() { | |
| fAttribArrays.invalidate(); | |
| fIndexBufferIDIsValid = false; | |
| } |