Context: Cache attributes masks.
This cache is updated in the following locations:
1. GLES1: clientActiveTexture.
2. GLES1: disableClientState/enableClientState.
3. Context: linkProgram/useProgram/programBinary.
4. Context: bindVertexArray.
5. Vertex Array: most state changes.
Improves performance by about 6% in the GL no-op test. Also includes
fixes for keeping the client memory attribs mask in sync. The cache
also includes a boolean if there are any enabled client attributes.
Bug: angleproject:1391
Change-Id: I93b6a2c8492355958fd5483f14b70535729091d6
Reviewed-on: https://chromium-review.googlesource.com/1147437
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 15c44e8..4c9d49d 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -1096,6 +1096,7 @@
{
VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
mGLState.setVertexArrayBinding(this, vertexArray);
+ mStateCache.updateActiveAttribsMask(this);
}
void Context::bindVertexBuffer(GLuint bindingIndex,
@@ -1105,6 +1106,7 @@
{
Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
+ mStateCache.updateActiveAttribsMask(this);
}
void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
@@ -1130,6 +1132,7 @@
void Context::useProgram(GLuint program)
{
mGLState.setProgram(this, getProgram(program));
+ mStateCache.updateActiveAttribsMask(this);
}
void Context::useProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
@@ -2783,6 +2786,7 @@
void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
{
mGLState.setVertexAttribDivisor(this, index, divisor);
+ mStateCache.updateActiveAttribsMask(this);
}
void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
@@ -4389,6 +4393,7 @@
void Context::disableVertexAttribArray(GLuint index)
{
mGLState.setEnableVertexAttribArray(index, false);
+ mStateCache.updateActiveAttribsMask(this);
}
void Context::enable(GLenum cap)
@@ -4399,6 +4404,7 @@
void Context::enableVertexAttribArray(GLuint index)
{
mGLState.setEnableVertexAttribArray(index, true);
+ mStateCache.updateActiveAttribsMask(this);
}
void Context::frontFace(GLenum mode)
@@ -4606,6 +4612,7 @@
{
mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(BufferBinding::Array),
size, type, ConvertToBool(normalized), false, stride, ptr);
+ mStateCache.updateActiveAttribsMask(this);
}
void Context::vertexAttribFormat(GLuint attribIndex,
@@ -4629,6 +4636,7 @@
void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
{
mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
+ mStateCache.updateActiveAttribsMask(this);
}
void Context::vertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
@@ -4649,6 +4657,7 @@
{
mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(BufferBinding::Array),
size, type, false, true, stride, pointer);
+ mStateCache.updateActiveAttribsMask(this);
}
void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
@@ -5534,6 +5543,7 @@
ASSERT(programObject);
handleError(programObject->link(this));
mGLState.onProgramExecutableChange(programObject);
+ mStateCache.updateActiveAttribsMask(this);
}
void Context::releaseShaderCompiler()
@@ -5741,6 +5751,7 @@
ASSERT(programObject != nullptr);
handleError(programObject->loadBinary(this, binaryFormat, binary, length));
+ mStateCache.updateActiveAttribsMask(this);
}
void Context::uniform1ui(GLint location, GLuint v0)
@@ -7536,23 +7547,6 @@
return mState.getClientVersion() < Version(2, 0);
}
-AttributesMask Context::getActiveBufferedAttribsMask() const
-{
- // TODO(jmadill): Cache this. http://anglebug.com/1391
- ASSERT(mGLState.getProgram() || isGLES1());
-
- const AttributesMask &activeAttribs =
- isGLES1() ? mGLState.gles1().getVertexArraysAttributeMask()
- : mGLState.getProgram()->getActiveAttribLocationsMask();
-
- const VertexArray *vao = mGLState.getVertexArray();
- ASSERT(vao);
-
- const AttributesMask &clientAttribs = vao->getEnabledClientMemoryAttribsMask();
-
- return (activeAttribs & vao->getEnabledAttributesMask() & ~clientAttribs);
-}
-
// ErrorSet implementation.
ErrorSet::ErrorSet(Context *context) : mContext(context)
{
@@ -7597,4 +7591,39 @@
mErrors.erase(mErrors.begin());
return error;
}
+
+// StateCache implementation.
+StateCache::StateCache() : mCachedHasAnyEnabledClientAttrib(false)
+{
+}
+
+StateCache::~StateCache() = default;
+
+void StateCache::updateActiveAttribsMask(Context *context)
+{
+ bool isGLES1 = context->isGLES1();
+ const State &glState = context->getGLState();
+
+ if (!isGLES1 && !glState.getProgram())
+ {
+ mCachedActiveBufferedAttribsMask = AttributesMask();
+ mCachedActiveClientAttribsMask = AttributesMask();
+ return;
+ }
+
+ AttributesMask activeAttribs = isGLES1 ? glState.gles1().getVertexArraysAttributeMask()
+ : glState.getProgram()->getActiveAttribLocationsMask();
+
+ const VertexArray *vao = glState.getVertexArray();
+ ASSERT(vao);
+
+ const AttributesMask &clientAttribs = vao->getClientAttribsMask();
+ const AttributesMask &enabledAttribs = vao->getEnabledAttributesMask();
+
+ activeAttribs &= enabledAttribs;
+
+ mCachedActiveClientAttribsMask = activeAttribs & clientAttribs;
+ mCachedActiveBufferedAttribsMask = activeAttribs & ~clientAttribs;
+ mCachedHasAnyEnabledClientAttrib = (clientAttribs & enabledAttribs).any();
+}
} // namespace gl