Only sync the VAO state just before the draw call.
BUG=angleproject:880
Change-Id: Ifd59c0f67aeab0e4700b3dca57c1b75e3fae48b8
Reviewed-on: https://chromium-review.googlesource.com/257671
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/gl/VertexArrayGL.cpp b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
index e66844c..31c264e 100644
--- a/src/libANGLE/renderer/gl/VertexArrayGL.cpp
+++ b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
@@ -9,6 +9,7 @@
#include "libANGLE/renderer/gl/VertexArrayGL.h"
#include "common/debug.h"
+#include "libANGLE/Buffer.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/gl/BufferGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
@@ -22,6 +23,8 @@
mFunctions(functions),
mStateManager(stateManager),
mVertexArrayID(0),
+ mElementArrayBuffer(),
+ mAttributes(),
mAppliedElementArrayBuffer(0),
mAppliedAttributes()
{
@@ -32,6 +35,7 @@
// Set the cached vertex attribute array size
GLint maxVertexAttribs;
mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
+ mAttributes.resize(maxVertexAttribs);
mAppliedAttributes.resize(maxVertexAttribs);
}
@@ -43,6 +47,7 @@
mVertexArrayID = 0;
}
+ mElementArrayBuffer.set(nullptr);
for (size_t idx = 0; idx < mAppliedAttributes.size(); idx++)
{
mAppliedAttributes[idx].buffer.set(NULL);
@@ -51,98 +56,83 @@
void VertexArrayGL::setElementArrayBuffer(const gl::Buffer *buffer)
{
+ mElementArrayBuffer.set(buffer);
+}
+
+void VertexArrayGL::setAttribute(size_t idx, const gl::VertexAttribute &attr)
+{
+ mAttributes[idx] = attr;
+}
+
+void VertexArrayGL::setAttributeDivisor(size_t idx, GLuint divisor)
+{
+ mAttributes[idx].divisor = divisor;
+}
+
+void VertexArrayGL::enableAttribute(size_t idx, bool enabledState)
+{
+ mAttributes[idx].enabled = enabledState;
+}
+
+void VertexArrayGL::syncState() const
+{
+ mStateManager->bindVertexArray(mVertexArrayID);
+
GLuint elementArrayBufferID = 0;
- if (buffer != nullptr)
+ if (mElementArrayBuffer.get() != nullptr)
{
- const BufferGL *bufferGL = GetImplAs<BufferGL>(buffer);
+ const BufferGL *bufferGL = GetImplAs<BufferGL>(mElementArrayBuffer.get());
elementArrayBufferID = bufferGL->getBufferID();
}
if (elementArrayBufferID != mAppliedElementArrayBuffer)
{
- mStateManager->bindVertexArray(mVertexArrayID);
mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferID);
- mStateManager->bindVertexArray(0);
-
mAppliedElementArrayBuffer = elementArrayBufferID;
}
-}
-void VertexArrayGL::setAttribute(size_t idx, const gl::VertexAttribute &attr)
-{
- if (mAppliedAttributes[idx].type != attr.type ||
- mAppliedAttributes[idx].size != attr.size ||
- mAppliedAttributes[idx].normalized != attr.normalized ||
- mAppliedAttributes[idx].pureInteger != attr.pureInteger ||
- mAppliedAttributes[idx].stride != attr.stride ||
- mAppliedAttributes[idx].pointer != attr.pointer ||
- mAppliedAttributes[idx].buffer.get() != attr.buffer.get())
+ for (size_t idx = 0; idx < mAttributes.size(); idx++)
{
- mStateManager->bindVertexArray(mVertexArrayID);
-
- const gl::Buffer *arrayBuffer = attr.buffer.get();
- if (arrayBuffer != nullptr)
+ if (mAppliedAttributes[idx] != mAttributes[idx])
{
- const BufferGL *arrayBufferGL = GetImplAs<BufferGL>(arrayBuffer);
- mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID());
+ if (mAttributes[idx].enabled)
+ {
+ mFunctions->enableVertexAttribArray(idx);
+ }
+ else
+ {
+ mFunctions->disableVertexAttribArray(idx);
+ }
+
+ const gl::Buffer *arrayBuffer = mAttributes[idx].buffer.get();
+ if (arrayBuffer != nullptr)
+ {
+ const BufferGL *arrayBufferGL = GetImplAs<BufferGL>(arrayBuffer);
+ mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID());
+ }
+ else
+ {
+ // This will take some extra work, core OpenGL doesn't support binding raw data pointers
+ // to VAOs
+ UNIMPLEMENTED();
+ }
+
+ if (mAttributes[idx].pureInteger)
+ {
+ mFunctions->vertexAttribIPointer(idx, mAttributes[idx].size, mAttributes[idx].type,
+ mAttributes[idx].stride, mAttributes[idx].pointer);
+ }
+ else
+ {
+ mFunctions->vertexAttribPointer(idx, mAttributes[idx].size, mAttributes[idx].type,
+ mAttributes[idx].normalized, mAttributes[idx].stride,
+ mAttributes[idx].pointer);
+ }
+
+ mFunctions->vertexAttribDivisor(idx, mAttributes[idx].divisor);
+
+ mAppliedAttributes[idx] = mAttributes[idx];
}
- else
- {
- // This will take some extra work, core OpenGL doesn't support binding raw data pointers
- // to VAOs
- UNIMPLEMENTED();
- }
-
- if (attr.pureInteger)
- {
- mFunctions->vertexAttribIPointer(idx, attr.size, attr.type, attr.stride, attr.pointer);
- }
- else
- {
- mFunctions->vertexAttribPointer(idx, attr.size, attr.type, attr.normalized, attr.stride, attr.pointer);
- }
- mAppliedAttributes[idx].type = attr.type;
- mAppliedAttributes[idx].size = attr.size;
- mAppliedAttributes[idx].normalized = attr.normalized;
- mAppliedAttributes[idx].pureInteger = attr.pureInteger;
- mAppliedAttributes[idx].stride = attr.stride;
- mAppliedAttributes[idx].pointer = attr.pointer;
- mAppliedAttributes[idx].buffer.set(attr.buffer.get());
-
- mStateManager->bindVertexArray(0);
- }
-}
-
-void VertexArrayGL::setAttributeDivisor(size_t idx, GLuint divisor)
-{
- if (mAppliedAttributes[idx].divisor != divisor)
- {
- mStateManager->bindVertexArray(mVertexArrayID);
-
- mFunctions->vertexAttribDivisor(idx, divisor);
- mAppliedAttributes[idx].divisor = divisor;
-
- mStateManager->bindVertexArray(0);
- }
-}
-
-void VertexArrayGL::enableAttribute(size_t idx, bool enabledState)
-{
- if (mAppliedAttributes[idx].enabled != enabledState)
- {
- mStateManager->bindVertexArray(mVertexArrayID);
-
- if (enabledState)
- {
- mFunctions->enableVertexAttribArray(idx);
- }
- else
- {
- mFunctions->disableVertexAttribArray(idx);
- }
- mAppliedAttributes[idx].enabled = enabledState;
-
- mStateManager->bindVertexArray(0);
}
}