Only sync attributes used by the current program in RendererGL.
Improves draw call overhead of RendererGL.
DrawCallPerf_gl:
Before: 136973 score
After: 153317 score
Improvement: 11.932%
BUG=angleproject:959
Change-Id: Ib75f6fdd756648e4a07f6e970cda03abbdbcf009
Reviewed-on: https://chromium-review.googlesource.com/275409
Reviewed-by: Kenneth Russell <kbr@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 c7b6ace..f345ab1 100644
--- a/src/libANGLE/renderer/gl/VertexArrayGL.cpp
+++ b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
@@ -83,22 +83,23 @@
{
}
-gl::Error VertexArrayGL::syncDrawArraysState(GLint first, GLsizei count) const
+gl::Error VertexArrayGL::syncDrawArraysState(const std::vector<GLuint> &activeAttribLocations, GLint first, GLsizei count) const
{
- return syncDrawState(first, count, GL_NONE, nullptr, nullptr);
+ return syncDrawState(activeAttribLocations, first, count, GL_NONE, nullptr, nullptr);
}
-gl::Error VertexArrayGL::syncDrawElementsState(GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const
+gl::Error VertexArrayGL::syncDrawElementsState(const std::vector<GLuint> &activeAttribLocations, GLsizei count,
+ GLenum type, const GLvoid *indices, const GLvoid **outIndices) const
{
- return syncDrawState(0, count, type, indices, outIndices);
+ return syncDrawState(activeAttribLocations, 0, count, type, indices, outIndices);
}
-gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const
+gl::Error VertexArrayGL::syncDrawState(const std::vector<GLuint> &activeAttribLocations, GLint first, GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const
{
mStateManager->bindVertexArray(mVertexArrayID, mAppliedElementArrayBuffer);
// Check if any attributes need to be streamed, determines if the index range needs to be computed
- bool attributesNeedStreaming = doAttributesNeedStreaming();
+ bool attributesNeedStreaming = doAttributesNeedStreaming(activeAttribLocations);
// Determine if an index buffer needs to be streamed and the range of vertices that need to be copied
gl::RangeUI indexRange(0, 0);
@@ -120,7 +121,8 @@
// Sync the vertex attribute state and track what data needs to be streamed
size_t streamingDataSize = 0;
size_t maxAttributeDataSize = 0;
- gl::Error error = syncAttributeState(attributesNeedStreaming, indexRange, &streamingDataSize, &maxAttributeDataSize);
+ gl::Error error = syncAttributeState(activeAttribLocations, attributesNeedStreaming, indexRange,
+ &streamingDataSize, &maxAttributeDataSize);
if (error.isError())
{
return error;
@@ -130,7 +132,8 @@
{
ASSERT(attributesNeedStreaming);
- gl::Error error = streamAttributes(streamingDataSize, maxAttributeDataSize, indexRange);
+ gl::Error error = streamAttributes(activeAttribLocations, streamingDataSize, maxAttributeDataSize,
+ indexRange);
if (error.isError())
{
return error;
@@ -140,12 +143,13 @@
return gl::Error(GL_NO_ERROR);
}
-bool VertexArrayGL::doAttributesNeedStreaming() const
+bool VertexArrayGL::doAttributesNeedStreaming(const std::vector<GLuint> &activeAttribLocations) const
{
// TODO: if GLES, nothing needs to be streamed
const auto &attribs = mData.getVertexAttributes();
- for (size_t idx = 0; idx < attribs.size(); idx++)
+ for (size_t activeAttrib = 0; activeAttrib < activeAttribLocations.size(); activeAttrib++)
{
+ GLuint idx = activeAttribLocations[activeAttrib];
if (attribs[idx].enabled && attribs[idx].buffer.get() == nullptr)
{
return true;
@@ -155,15 +159,16 @@
return false;
}
-gl::Error VertexArrayGL::syncAttributeState(bool attributesNeedStreaming, const gl::RangeUI &indexRange,
- size_t *outStreamingDataSize, size_t *outMaxAttributeDataSize) const
+gl::Error VertexArrayGL::syncAttributeState(const std::vector<GLuint> &activeAttribLocations, bool attributesNeedStreaming,
+ const gl::RangeUI &indexRange, size_t *outStreamingDataSize, size_t *outMaxAttributeDataSize) const
{
*outStreamingDataSize = 0;
*outMaxAttributeDataSize = 0;
const auto &attribs = mData.getVertexAttributes();
- for (size_t idx = 0; idx < attribs.size(); idx++)
+ for (size_t activeAttrib = 0; activeAttrib < activeAttribLocations.size(); activeAttrib++)
{
+ GLuint idx = activeAttribLocations[activeAttrib];
const auto &attrib = attribs[idx];
// Always sync the enabled and divisor state, they are required for both streaming and buffered
@@ -310,7 +315,8 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error VertexArrayGL::streamAttributes(size_t streamingDataSize, size_t maxAttributeDataSize, const gl::RangeUI &indexRange) const
+gl::Error VertexArrayGL::streamAttributes(const std::vector<GLuint> &activeAttribLocations, size_t streamingDataSize,
+ size_t maxAttributeDataSize, const gl::RangeUI &indexRange) const
{
if (mStreamingArrayBuffer == 0)
{
@@ -343,8 +349,9 @@
const size_t streamedVertexCount = indexRange.end - indexRange.start + 1;
const auto &attribs = mData.getVertexAttributes();
- for (size_t idx = 0; idx < attribs.size(); idx++)
+ for (size_t activeAttrib = 0; activeAttrib < activeAttribLocations.size(); activeAttrib++)
{
+ GLuint idx = activeAttribLocations[activeAttrib];
const auto &attrib = attribs[idx];
if (attrib.enabled && attrib.buffer.get() == nullptr)