void VertexArrayGL::applyNumViewsToDivisor(int numViews) { if (numViews != mAppliedNumViews) { mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); mAppliedNumViews = numViews; for (size_t index = 0u; index < mAppliedBindings.size(); ++index) { updateBindingDivisor(index); } } }
void VertexArrayGL::syncState(const gl::Context *context, const VertexArray::DirtyBits &dirtyBits) { mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); for (size_t dirtyBit : dirtyBits) { if (dirtyBit == VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER) { // TODO(jmadill): Element array buffer bindings continue; } size_t index = VertexArray::GetVertexIndexFromDirtyBit(dirtyBit); if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED && dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_ENABLED) { updateAttribEnabled(index); } else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_POINTER && dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_POINTER) { updateAttribPointer(context, index); } else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_FORMAT && dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_FORMAT) { ASSERT(supportVertexAttribBinding()); updateAttribFormat(index); } else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_BINDING && dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_BINDING) { ASSERT(supportVertexAttribBinding()); updateAttribBinding(index); } else if (dirtyBit >= VertexArray::DIRTY_BIT_BINDING_0_BUFFER && dirtyBit < VertexArray::DIRTY_BIT_BINDING_MAX_BUFFER) { ASSERT(supportVertexAttribBinding()); updateBindingBuffer(context, index); } else if (dirtyBit >= VertexArray::DIRTY_BIT_BINDING_0_DIVISOR && dirtyBit < VertexArray::DIRTY_BIT_BINDING_MAX_DIVISOR) { updateBindingDivisor(index); } else UNREACHABLE(); } }
void VertexArrayGL::updateAttribPointer(size_t attribIndex) { const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex); if (mAppliedAttributes[attribIndex] == attrib) { return; } updateNeedsStreaming(attribIndex); // If we need to stream, defer the attribPointer to the draw call. if (mAttributesNeedStreaming[attribIndex]) { return; } mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); const Buffer *arrayBuffer = attrib.buffer.get(); if (arrayBuffer != nullptr) { const BufferGL *arrayBufferGL = GetImplAs<BufferGL>(arrayBuffer); mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID()); } else { mStateManager->bindBuffer(GL_ARRAY_BUFFER, 0); } mAppliedAttributes[attribIndex].buffer = attrib.buffer; if (attrib.pureInteger) { mFunctions->vertexAttribIPointer(static_cast<GLuint>(attribIndex), attrib.size, attrib.type, attrib.stride, attrib.pointer); } else { mFunctions->vertexAttribPointer(static_cast<GLuint>(attribIndex), attrib.size, attrib.type, attrib.normalized, attrib.stride, attrib.pointer); } mAppliedAttributes[attribIndex].size = attrib.size; mAppliedAttributes[attribIndex].type = attrib.type; mAppliedAttributes[attribIndex].normalized = attrib.normalized; mAppliedAttributes[attribIndex].pureInteger = attrib.pureInteger; mAppliedAttributes[attribIndex].stride = attrib.stride; mAppliedAttributes[attribIndex].pointer = attrib.pointer; }
gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttributesMask, GLint first, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instanceCount, bool primitiveRestartEnabled, const GLvoid **outIndices) const { mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); // Check if any attributes need to be streamed, determines if the index range needs to be computed bool attributesNeedStreaming = mAttributesNeedStreaming.any(); // Determine if an index buffer needs to be streamed and the range of vertices that need to be copied IndexRange indexRange; if (type != GL_NONE) { Error error = syncIndexData(count, type, indices, primitiveRestartEnabled, attributesNeedStreaming, &indexRange, outIndices); if (error.isError()) { return error; } } else { // Not an indexed call, set the range to [first, first + count - 1] indexRange.start = first; indexRange.end = first + count - 1; } if (attributesNeedStreaming) { Error error = streamAttributes(activeAttributesMask, instanceCount, indexRange); if (error.isError()) { return error; } } return Error(GL_NO_ERROR); }
void VertexArrayGL::updateAttribEnabled(size_t attribIndex) { const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex); if (mAppliedAttributes[attribIndex].enabled == attrib.enabled) { return; } updateNeedsStreaming(attribIndex); mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); if (attrib.enabled) { mFunctions->enableVertexAttribArray(static_cast<GLuint>(attribIndex)); } else { mFunctions->disableVertexAttribArray(static_cast<GLuint>(attribIndex)); } mAppliedAttributes[attribIndex].enabled = attrib.enabled; }
void VertexArrayGL::syncState(const VertexArray::DirtyBits &dirtyBits) { for (unsigned long dirtyBit : angle::IterateBitSet(dirtyBits)) { if (dirtyBit == VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER) { // TODO(jmadill): Element array buffer bindings } else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED && dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_ENABLED) { size_t attribIndex = static_cast<size_t>(dirtyBit) - VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED; updateAttribEnabled(attribIndex); } else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_POINTER && dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_POINTER) { size_t attribIndex = static_cast<size_t>(dirtyBit) - VertexArray::DIRTY_BIT_ATTRIB_0_POINTER; updateAttribPointer(attribIndex); } else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_DIVISOR && dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_DIVISOR) { size_t attribIndex = static_cast<size_t>(dirtyBit) - VertexArray::DIRTY_BIT_ATTRIB_0_DIVISOR; const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex); if (mAppliedAttributes[attribIndex].divisor != attrib.divisor) { mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); mFunctions->vertexAttribDivisor(static_cast<GLuint>(attribIndex), attrib.divisor); mAppliedAttributes[attribIndex].divisor = attrib.divisor; } } else UNREACHABLE(); } }