Use Observer pattern for Buffers in front-end.
This will allow us to react to state change notifications for validation
caching. It also cleans up some of the logic in the D3D11 State Manager.
Bug: angleproject:2747
Change-Id: I85ed6404206c2b9bf504d552cf5751be56e62146
Reviewed-on: https://chromium-review.googlesource.com/1172086
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 59f0e13..4cb2d41 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -41,6 +41,7 @@
#include "libANGLE/formatutils.h"
#include "libANGLE/queryconversions.h"
#include "libANGLE/queryutils.h"
+#include "libANGLE/renderer/BufferImpl.h"
#include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/EGLImplFactory.h"
#include "libANGLE/renderer/Format.h"
@@ -298,11 +299,17 @@
static_assert(static_cast<gl::PrimitiveMode>(11) == gl::PrimitiveMode::EnumCount,
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts.");
-constexpr angle::SubjectIndex kVertexArraySubjectIndex = gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES + 0;
-constexpr angle::SubjectIndex kReadFramebufferSubjectIndex =
- gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES + 1;
-constexpr angle::SubjectIndex kDrawFramebufferSubjectIndex =
- gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES + 2;
+enum SubjectIndexes : angle::SubjectIndex
+{
+ kTexture0SubjectIndex = 0,
+ kTextureMaxSubjectIndex = kTexture0SubjectIndex + gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
+ kUniformBuffer0SubjectIndex = kTextureMaxSubjectIndex,
+ kUniformBufferMaxSubjectIndex =
+ kUniformBuffer0SubjectIndex + gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS,
+ kVertexArraySubjectIndex = kUniformBufferMaxSubjectIndex,
+ kReadFramebufferSubjectIndex,
+ kDrawFramebufferSubjectIndex
+};
} // anonymous namespace
namespace gl
@@ -362,6 +369,12 @@
// Needed to solve a Clang warning of unused variables.
ANGLE_UNUSED_VARIABLE(mSavedArgsType);
ANGLE_UNUSED_VARIABLE(mParamsBuffer);
+
+ for (angle::SubjectIndex uboIndex = kUniformBuffer0SubjectIndex;
+ uboIndex < kUniformBufferMaxSubjectIndex; ++uboIndex)
+ {
+ mUniformBufferObserverBindings.emplace_back(this, uboIndex);
+ }
}
void Context::initialize()
@@ -3233,6 +3246,8 @@
LimitCap(&mCaps.maxShaderUniformBlocks[ShaderType::Vertex],
IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
+ LimitCap(&mCaps.maxUniformBufferBindings, IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS);
+
LimitCap(&mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
LimitCap(&mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
@@ -4937,8 +4952,12 @@
GLintptr offset,
GLsizeiptr size)
{
- Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
- mGLState.setIndexedBufferBinding(this, target, index, bufferObject, offset, size);
+ Buffer *object = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
+ mGLState.setIndexedBufferBinding(this, target, index, object, offset, size);
+ if (target == BufferBinding::Uniform)
+ {
+ mUniformBufferObserverBindings[index].bind(object ? object->getImplementation() : nullptr);
+ }
}
void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
@@ -7633,8 +7652,15 @@
break;
default:
- ASSERT(index < mGLState.getActiveTexturesCache().size());
- mGLState.onActiveTextureStateChange(index);
+ if (index < kTextureMaxSubjectIndex)
+ {
+ mGLState.onActiveTextureStateChange(index);
+ }
+ else
+ {
+ ASSERT(index < kUniformBufferMaxSubjectIndex);
+ mGLState.onUniformBufferStateChange(index - kUniformBuffer0SubjectIndex);
+ }
break;
}
}