ANGLE_INLINE void VertexArray::setVertexAttribPointerImpl(const Context *context, ComponentType componentType, bool pureInteger, size_t attribIndex, Buffer *boundBuffer, GLint size, VertexAttribType type, bool normalized, GLsizei stride, const void *pointer) { ASSERT(attribIndex < getMaxAttribs()); GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0; VertexAttribute &attrib = mState.mVertexAttributes[attribIndex]; attrib.pureInteger = pureInteger; SetComponentTypeMask(componentType, attribIndex, &mState.mVertexAttributesTypeMask); setVertexAttribFormatImpl(&attrib, size, type, normalized, 0); setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex)); GLsizei effectiveStride = stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib)); attrib.pointer = pointer; attrib.vertexAttribArrayStride = stride; bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride); setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER); mState.mNullPointerClientMemoryAttribsMask.set(attribIndex, boundBuffer == nullptr && pointer == nullptr); }
void VertexArray::setVertexAttribDivisor(const Context *context, size_t attribIndex, GLuint divisor) { ASSERT(attribIndex < getMaxAttribs()); setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex)); setVertexBindingDivisor(attribIndex, divisor); }
VertexArrayState::~VertexArrayState() { for (size_t i = 0; i < getMaxAttribs(); i++) { mVertexAttributes[i].buffer.set(nullptr); } mElementArrayBuffer.set(nullptr); }
VertexArray::~VertexArray() { SafeDelete(mVertexArray); for (size_t i = 0; i < getMaxAttribs(); i++) { mVertexAttributes[i].buffer.set(NULL); } mElementArrayBuffer.set(NULL); }
void VertexArray::setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type, bool normalized, bool pureInteger, GLsizei stride, const void *pointer) { ASSERT(attributeIndex < getMaxAttribs()); mVertexAttributes[attributeIndex].buffer.set(boundBuffer); mVertexAttributes[attributeIndex].size = size; mVertexAttributes[attributeIndex].type = type; mVertexAttributes[attributeIndex].normalized = normalized; mVertexAttributes[attributeIndex].pureInteger = pureInteger; mVertexAttributes[attributeIndex].stride = stride; mVertexAttributes[attributeIndex].pointer = pointer; mVertexArray->setAttribute(attributeIndex, mVertexAttributes[attributeIndex]); }
void VertexArray::detachBuffer(GLuint bufferName) { for (size_t attribute = 0; attribute < getMaxAttribs(); attribute++) { if (mState.mVertexAttributes[attribute].buffer.id() == bufferName) { mState.mVertexAttributes[attribute].buffer.set(nullptr); } } if (mState.mElementArrayBuffer.id() == bufferName) { mState.mElementArrayBuffer.set(nullptr); } }
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 = &mState.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::enableAttribute(size_t attribIndex, bool enabledState) { ASSERT(attribIndex < getMaxAttribs()); VertexAttribute &attrib = mState.mVertexAttributes[attribIndex]; if (mState.mEnabledAttributesMask.test(attribIndex) == enabledState) { return; } attrib.enabled = enabledState; setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_ENABLED); // Update state cache mState.mEnabledAttributesMask.set(attribIndex, enabledState); mState.mCachedEnabledMappedArrayBuffers = mState.mCachedMappedArrayBuffers & mState.mEnabledAttributesMask; }
void VertexArray::setVertexAttribBinding(const Context *context, size_t attribIndex, GLuint bindingIndex) { ASSERT(attribIndex < getMaxAttribs() && bindingIndex < getMaxBindings()); if (mState.mVertexAttributes[attribIndex].bindingIndex != bindingIndex) { // In ES 3.0 contexts, the binding cannot change, hence the code below is unreachable. ASSERT(context->getClientVersion() >= ES_3_1); mState.setAttribBinding(context, attribIndex, bindingIndex); setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_BINDING); // Update client attribs mask. bool hasBuffer = mState.mVertexBindings[bindingIndex].getBuffer().get() != nullptr; mState.mClientMemoryAttribsMask.set(attribIndex, !hasBuffer); } }
void VertexArray::enableAttribute(size_t attributeIndex, bool enabledState) { ASSERT(attributeIndex < getMaxAttribs()); mState.mVertexAttributes[attributeIndex].enabled = enabledState; mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attributeIndex); // Update state cache if (enabledState) { mState.mMaxEnabledAttribute = std::max(attributeIndex + 1, mState.mMaxEnabledAttribute); } else if (mState.mMaxEnabledAttribute == attributeIndex + 1) { while (mState.mMaxEnabledAttribute > 0 && !mState.mVertexAttributes[mState.mMaxEnabledAttribute - 1].enabled) { --mState.mMaxEnabledAttribute; } } }
const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const { ASSERT(attribIndex < getMaxAttribs()); return mState.mVertexAttributes[attribIndex]; }
void VertexArray::setVertexAttribDivisor(size_t index, GLuint divisor) { ASSERT(index < getMaxAttribs()); mState.mVertexAttributes[index].divisor = divisor; mDirtyBits.set(DIRTY_BIT_ATTRIB_0_DIVISOR + index); }
void VertexArray::enableAttribute(unsigned int attributeIndex, bool enabledState) { ASSERT(attributeIndex < getMaxAttribs()); mVertexAttributes[attributeIndex].enabled = enabledState; mVertexArray->enableAttribute(attributeIndex, enabledState); }
void VertexArray::setVertexAttribDivisor(GLuint index, GLuint divisor) { ASSERT(index < getMaxAttribs()); mVertexAttributes[index].divisor = divisor; mVertexArray->setAttributeDivisor(index, divisor); }