Cache VertexArray::hasMappedBuffer.
This can be updated in several places. Also adds a test which covers
some of the paths.
Bug: angleproject:2746
Change-Id: Id119e527fd0064998d7ad5011a9d8376e7b9dab0
Reviewed-on: https://chromium-review.googlesource.com/1153569
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/VertexArray.cpp b/src/libANGLE/VertexArray.cpp
index 040772a..272debc 100644
--- a/src/libANGLE/VertexArray.cpp
+++ b/src/libANGLE/VertexArray.cpp
@@ -15,6 +15,14 @@
namespace gl
{
+namespace
+{
+bool IsElementArrayBufferSubjectIndex(angle::SubjectIndex subjectIndex)
+{
+ return (subjectIndex == MAX_VERTEX_ATTRIBS);
+}
+} // anonymous namespce
+
// VertexArrayState implementation.
VertexArrayState::VertexArrayState(size_t maxAttribs, size_t maxAttribBindings)
: mLabel(), mVertexBindings()
@@ -57,15 +65,22 @@
const GLuint oldBindingIndex = attrib.bindingIndex;
ASSERT(oldBindingIndex != newBindingIndex);
- ASSERT(mVertexBindings[oldBindingIndex].getBoundAttributesMask().test(attribIndex) &&
- !mVertexBindings[newBindingIndex].getBoundAttributesMask().test(attribIndex));
+ VertexBinding &oldBinding = mVertexBindings[oldBindingIndex];
+ VertexBinding &newBinding = mVertexBindings[newBindingIndex];
- mVertexBindings[oldBindingIndex].resetBoundAttribute(attribIndex);
- mVertexBindings[newBindingIndex].setBoundAttribute(attribIndex);
+ ASSERT(oldBinding.getBoundAttributesMask().test(attribIndex) &&
+ !newBinding.getBoundAttributesMask().test(attribIndex));
+
+ oldBinding.resetBoundAttribute(attribIndex);
+ newBinding.setBoundAttribute(attribIndex);
// Set the attribute using the new binding.
attrib.bindingIndex = newBindingIndex;
- attrib.updateCachedElementLimit(mVertexBindings[newBindingIndex]);
+ attrib.updateCachedElementLimit(newBinding);
+
+ bool isMapped = newBinding.getBuffer().get() && newBinding.getBuffer()->isMapped();
+ mCachedMappedArrayBuffers.set(attribIndex, isMapped);
+ mCachedEnabledMappedArrayBuffers.set(attribIndex, isMapped && attrib.enabled);
}
// VertexArray implementation.
@@ -76,7 +91,7 @@
: mId(id),
mState(maxAttribs, maxAttribBindings),
mVertexArray(factory->createVertexArray(mState)),
- mElementArrayBufferObserverBinding(this, maxAttribBindings)
+ mElementArrayBufferObserverBinding(this, MAX_VERTEX_ATTRIBS)
{
for (size_t attribIndex = 0; attribIndex < maxAttribBindings; ++attribIndex)
{
@@ -190,6 +205,7 @@
updateObserverBinding(bindingIndex);
updateCachedBufferBindingSize(binding);
updateCachedTransformFeedbackBindingValidation(bindingIndex, boundBuffer);
+ updateCachedMappedArrayBuffers(binding);
// Update client memory attribute pointers. Affects all bound attributes.
if (boundBuffer)
@@ -303,6 +319,8 @@
// Update state cache
mState.mEnabledAttributesMask.set(attribIndex, enabledState);
+ mState.mCachedEnabledMappedArrayBuffers =
+ mState.mCachedMappedArrayBuffers & mState.mEnabledAttributesMask;
}
void VertexArray::setVertexAttribPointer(const Context *context,
@@ -385,7 +403,7 @@
VertexArray::DirtyBitType VertexArray::getDirtyBitFromIndex(bool contentsChanged,
angle::SubjectIndex index) const
{
- if (index == mArrayBufferObserverBindings.size())
+ if (IsElementArrayBufferSubjectIndex(index))
{
return contentsChanged ? DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA
: DIRTY_BIT_ELEMENT_ARRAY_BUFFER;
@@ -410,7 +428,7 @@
break;
case angle::SubjectMessage::STORAGE_CHANGED:
- if (index < mArrayBufferObserverBindings.size())
+ if (!IsElementArrayBufferSubjectIndex(index))
{
updateCachedBufferBindingSize(&mState.mVertexBindings[index]);
}
@@ -418,13 +436,29 @@
break;
case angle::SubjectMessage::BINDING_CHANGED:
- if (index < mArrayBufferObserverBindings.size())
+ if (!IsElementArrayBufferSubjectIndex(index))
{
const Buffer *buffer = mState.mVertexBindings[index].getBuffer().get();
updateCachedTransformFeedbackBindingValidation(index, buffer);
}
break;
+ case angle::SubjectMessage::RESOURCE_MAPPED:
+ if (!IsElementArrayBufferSubjectIndex(index))
+ {
+ updateCachedMappedArrayBuffers(&mState.mVertexBindings[index]);
+ }
+ break;
+
+ case angle::SubjectMessage::RESOURCE_UNMAPPED:
+ setDependentDirtyBit(context, true, index);
+
+ if (!IsElementArrayBufferSubjectIndex(index))
+ {
+ updateCachedMappedArrayBuffers(&mState.mVertexBindings[index]);
+ }
+ break;
+
default:
UNREACHABLE();
break;
@@ -486,21 +520,19 @@
return false;
}
-bool VertexArray::hasMappedEnabledArrayBuffer() const
+void VertexArray::updateCachedMappedArrayBuffers(VertexBinding *binding)
{
- // TODO(jmadill): Cache this. http://anglebug.com/2746
- for (size_t attribIndex : mState.mEnabledAttributesMask)
+ Buffer *buffer = binding->getBuffer().get();
+ if (buffer && buffer->isMapped())
{
- const VertexAttribute &vertexAttrib = mState.mVertexAttributes[attribIndex];
- ASSERT(vertexAttrib.enabled);
- const VertexBinding &vertexBinding = mState.mVertexBindings[vertexAttrib.bindingIndex];
- gl::Buffer *boundBuffer = vertexBinding.getBuffer().get();
- if (boundBuffer && boundBuffer->isMapped())
- {
- return true;
- }
+ mState.mCachedMappedArrayBuffers |= binding->getBoundAttributesMask();
+ }
+ else
+ {
+ mState.mCachedMappedArrayBuffers &= ~binding->getBoundAttributesMask();
}
- return false;
+ mState.mCachedEnabledMappedArrayBuffers =
+ mState.mCachedMappedArrayBuffers & mState.mEnabledAttributesMask;
}
} // namespace gl