| // | |
| // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // | |
| // Implementation of the state class for mananging GLES 3 Vertex Array Objects. | |
| // | |
| #include "libANGLE/VertexArray.h" | |
| #include "libANGLE/Buffer.h" | |
| #include "libANGLE/renderer/ImplFactory.h" | |
| #include "libANGLE/renderer/VertexArrayImpl.h" | |
| namespace gl | |
| { | |
| VertexArray::Data::Data(size_t maxAttribs) | |
| : mLabel(), mVertexAttributes(maxAttribs), mMaxEnabledAttribute(0) | |
| { | |
| } | |
| VertexArray::Data::~Data() | |
| { | |
| for (size_t i = 0; i < getMaxAttribs(); i++) | |
| { | |
| mVertexAttributes[i].buffer.set(nullptr); | |
| } | |
| mElementArrayBuffer.set(nullptr); | |
| } | |
| VertexArray::VertexArray(rx::ImplFactory *factory, GLuint id, size_t maxAttribs) | |
| : mId(id), | |
| mVertexArray(factory->createVertexArray(mData)), | |
| mData(maxAttribs) | |
| { | |
| } | |
| VertexArray::~VertexArray() | |
| { | |
| SafeDelete(mVertexArray); | |
| } | |
| GLuint VertexArray::id() const | |
| { | |
| return mId; | |
| } | |
| void VertexArray::setLabel(const std::string &label) | |
| { | |
| mData.mLabel = label; | |
| } | |
| const std::string &VertexArray::getLabel() const | |
| { | |
| return mData.mLabel; | |
| } | |
| void VertexArray::detachBuffer(GLuint bufferName) | |
| { | |
| for (size_t attribute = 0; attribute < getMaxAttribs(); attribute++) | |
| { | |
| if (mData.mVertexAttributes[attribute].buffer.id() == bufferName) | |
| { | |
| mData.mVertexAttributes[attribute].buffer.set(nullptr); | |
| } | |
| } | |
| if (mData.mElementArrayBuffer.id() == bufferName) | |
| { | |
| mData.mElementArrayBuffer.set(nullptr); | |
| } | |
| } | |
| const VertexAttribute &VertexArray::getVertexAttribute(size_t attributeIndex) const | |
| { | |
| ASSERT(attributeIndex < getMaxAttribs()); | |
| return mData.mVertexAttributes[attributeIndex]; | |
| } | |
| void VertexArray::setVertexAttribDivisor(size_t index, GLuint divisor) | |
| { | |
| ASSERT(index < getMaxAttribs()); | |
| mData.mVertexAttributes[index].divisor = divisor; | |
| mDirtyBits.set(DIRTY_BIT_ATTRIB_0_DIVISOR + index); | |
| } | |
| void VertexArray::enableAttribute(size_t attributeIndex, bool enabledState) | |
| { | |
| ASSERT(attributeIndex < getMaxAttribs()); | |
| mData.mVertexAttributes[attributeIndex].enabled = enabledState; | |
| mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attributeIndex); | |
| // Update state cache | |
| if (enabledState) | |
| { | |
| mData.mMaxEnabledAttribute = std::max(attributeIndex + 1, mData.mMaxEnabledAttribute); | |
| } | |
| else if (mData.mMaxEnabledAttribute == attributeIndex + 1) | |
| { | |
| while (mData.mMaxEnabledAttribute > 0 && | |
| !mData.mVertexAttributes[mData.mMaxEnabledAttribute - 1].enabled) | |
| { | |
| --mData.mMaxEnabledAttribute; | |
| } | |
| } | |
| } | |
| void VertexArray::setAttributeState(size_t attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type, | |
| bool normalized, bool pureInteger, GLsizei stride, const void *pointer) | |
| { | |
| ASSERT(attributeIndex < getMaxAttribs()); | |
| VertexAttribute *attrib = &mData.mVertexAttributes[attributeIndex]; | |
| attrib->buffer.set(boundBuffer); | |
| attrib->size = size; | |
| attrib->type = type; | |
| attrib->normalized = normalized; | |
| attrib->pureInteger = pureInteger; | |
| attrib->stride = stride; | |
| attrib->pointer = pointer; | |
| mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attributeIndex); | |
| } | |
| void VertexArray::setElementArrayBuffer(Buffer *buffer) | |
| { | |
| mData.mElementArrayBuffer.set(buffer); | |
| mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER); | |
| } | |
| void VertexArray::syncImplState() | |
| { | |
| if (mDirtyBits.any()) | |
| { | |
| mVertexArray->syncState(mDirtyBits); | |
| mDirtyBits.reset(); | |
| } | |
| } | |
| } |