Commit 6ae6efca by Geoff Lang

Only sync the VAO state just before the draw call.

BUG=angleproject:880 Change-Id: Ifd59c0f67aeab0e4700b3dca57c1b75e3fae48b8 Reviewed-on: https://chromium-review.googlesource.com/257671Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent fb2a5597
......@@ -23,6 +23,24 @@ VertexAttribute::VertexAttribute()
{
}
bool operator==(const VertexAttribute &a, const VertexAttribute &b)
{
return a.enabled == b.enabled &&
a.type == b.type &&
a.size == b.size &&
a.normalized == b.normalized &&
a.pureInteger == b.pureInteger &&
a.stride == b.stride &&
a.pointer == b.pointer &&
a.buffer.get() == b.buffer.get() &&
a.divisor == b.divisor;
}
bool operator!=(const VertexAttribute &a, const VertexAttribute &b)
{
return !(a == b);
}
size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib)
{
GLuint size = attrib.size;
......
......@@ -36,6 +36,9 @@ struct VertexAttribute
VertexAttribute();
};
bool operator==(const VertexAttribute &a, const VertexAttribute &b);
bool operator!=(const VertexAttribute &a, const VertexAttribute &b);
template <typename T>
T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pname)
{
......
......@@ -103,6 +103,7 @@ void StateManagerGL::setDrawState(const gl::Data &data)
const gl::VertexArray *vao = state.getVertexArray();
const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
vaoGL->syncState();
bindVertexArray(vaoGL->getVertexArrayID());
const gl::Program *program = state.getProgram();
......
......@@ -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 @@ VertexArrayGL::VertexArrayGL(const FunctionsGL *functions, StateManagerGL *state
mFunctions(functions),
mStateManager(stateManager),
mVertexArrayID(0),
mElementArrayBuffer(),
mAttributes(),
mAppliedElementArrayBuffer(0),
mAppliedAttributes()
{
......@@ -32,6 +35,7 @@ VertexArrayGL::VertexArrayGL(const FunctionsGL *functions, StateManagerGL *state
// 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 @@ VertexArrayGL::~VertexArrayGL()
mVertexArrayID = 0;
}
mElementArrayBuffer.set(nullptr);
for (size_t idx = 0; idx < mAppliedAttributes.size(); idx++)
{
mAppliedAttributes[idx].buffer.set(NULL);
......@@ -51,98 +56,83 @@ VertexArrayGL::~VertexArrayGL()
void VertexArrayGL::setElementArrayBuffer(const gl::Buffer *buffer)
{
GLuint elementArrayBufferID = 0;
if (buffer != nullptr)
{
const BufferGL *bufferGL = GetImplAs<BufferGL>(buffer);
elementArrayBufferID = bufferGL->getBufferID();
}
if (elementArrayBufferID != mAppliedElementArrayBuffer)
{
mStateManager->bindVertexArray(mVertexArrayID);
mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferID);
mStateManager->bindVertexArray(0);
mAppliedElementArrayBuffer = elementArrayBufferID;
}
mElementArrayBuffer.set(buffer);
}
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())
{
mStateManager->bindVertexArray(mVertexArrayID);
const gl::Buffer *arrayBuffer = attr.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 (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);
}
mAttributes[idx] = attr;
}
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);
}
mAttributes[idx].divisor = divisor;
}
void VertexArrayGL::enableAttribute(size_t idx, bool enabledState)
{
if (mAppliedAttributes[idx].enabled != enabledState)
mAttributes[idx].enabled = enabledState;
}
void VertexArrayGL::syncState() const
{
mStateManager->bindVertexArray(mVertexArrayID);
GLuint elementArrayBufferID = 0;
if (mElementArrayBuffer.get() != nullptr)
{
const BufferGL *bufferGL = GetImplAs<BufferGL>(mElementArrayBuffer.get());
elementArrayBufferID = bufferGL->getBufferID();
}
if (elementArrayBufferID != mAppliedElementArrayBuffer)
{
mStateManager->bindVertexArray(mVertexArrayID);
mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferID);
mAppliedElementArrayBuffer = elementArrayBufferID;
}
if (enabledState)
{
mFunctions->enableVertexAttribArray(idx);
}
else
for (size_t idx = 0; idx < mAttributes.size(); idx++)
{
if (mAppliedAttributes[idx] != mAttributes[idx])
{
mFunctions->disableVertexAttribArray(idx);
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];
}
mAppliedAttributes[idx].enabled = enabledState;
mStateManager->bindVertexArray(0);
}
}
......
......@@ -28,6 +28,8 @@ class VertexArrayGL : public VertexArrayImpl
void setAttributeDivisor(size_t idx, GLuint divisor) override;
void enableAttribute(size_t idx, bool enabledState) override;
void syncState() const;
GLuint getVertexArrayID() const;
private:
......@@ -38,8 +40,11 @@ class VertexArrayGL : public VertexArrayImpl
GLuint mVertexArrayID;
GLuint mAppliedElementArrayBuffer;
std::vector<gl::VertexAttribute> mAppliedAttributes;
BindingPointer<const gl::Buffer> mElementArrayBuffer;
std::vector<gl::VertexAttribute> mAttributes;
mutable GLuint mAppliedElementArrayBuffer;
mutable std::vector<gl::VertexAttribute> mAppliedAttributes;
};
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment