Implement dirty bits for Framebuffer.
The dirty bits set the stage for performance improvements in D3D, but
don't actually reduce any of the redundant work just yet.
BUG=angleproject:1260
Change-Id: Ib84e6a9b7aa40c37c41790f492361b22faaf4742
Reviewed-on: https://chromium-review.googlesource.com/318730
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tryjob-Request: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index b9c9f4b..7302a51 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -835,22 +835,44 @@
void State::setReadFramebufferBinding(Framebuffer *framebuffer)
{
+ if (mReadFramebuffer == framebuffer)
+ return;
+
mReadFramebuffer = framebuffer;
+ mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
+
+ if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ }
}
void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
{
+ if (mDrawFramebuffer == framebuffer)
+ return;
+
mDrawFramebuffer = framebuffer;
+ mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
+
+ if (mDrawFramebuffer && mDrawFramebuffer->hasAnyDirtyBit())
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+ }
}
Framebuffer *State::getTargetFramebuffer(GLenum target) const
{
switch (target)
{
- case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
- case GL_DRAW_FRAMEBUFFER_ANGLE:
- case GL_FRAMEBUFFER: return mDrawFramebuffer;
- default: UNREACHABLE(); return NULL;
+ case GL_READ_FRAMEBUFFER_ANGLE:
+ return mReadFramebuffer;
+ case GL_DRAW_FRAMEBUFFER_ANGLE:
+ case GL_FRAMEBUFFER:
+ return mDrawFramebuffer;
+ default:
+ UNREACHABLE();
+ return NULL;
}
}
@@ -879,7 +901,7 @@
if (mReadFramebuffer != nullptr &&
mReadFramebuffer->id() == framebuffer)
{
- mReadFramebuffer = NULL;
+ setReadFramebufferBinding(nullptr);
return true;
}
@@ -891,7 +913,7 @@
if (mReadFramebuffer != nullptr &&
mDrawFramebuffer->id() == framebuffer)
{
- mDrawFramebuffer = NULL;
+ setDrawFramebufferBinding(nullptr);
return true;
}
@@ -1720,17 +1742,25 @@
if (!mDirtyObjects.any())
return;
- for (auto dirtyObject : angle::IterateBitSet(mDirtyObjects))
+ syncDirtyObjects(mDirtyObjects);
+}
+
+void State::syncDirtyObjects(const DirtyObjects &bitset)
+{
+ for (auto dirtyObject : angle::IterateBitSet(bitset))
{
switch (dirtyObject)
{
case DIRTY_OBJECT_READ_FRAMEBUFFER:
- // TODO(jmadill): implement this
+ ASSERT(mReadFramebuffer);
+ mReadFramebuffer->syncState();
break;
case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
- // TODO(jmadill): implement this
+ ASSERT(mDrawFramebuffer);
+ mDrawFramebuffer->syncState();
break;
case DIRTY_OBJECT_VERTEX_ARRAY:
+ ASSERT(mVertexArray);
mVertexArray->syncImplState();
break;
case DIRTY_OBJECT_PROGRAM:
@@ -1742,7 +1772,57 @@
}
}
- mDirtyObjects.reset();
+ mDirtyObjects &= ~bitset;
+}
+
+void State::syncDirtyObject(GLenum target)
+{
+ DirtyObjects localSet;
+
+ switch (target)
+ {
+ case GL_READ_FRAMEBUFFER:
+ localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ break;
+ case GL_DRAW_FRAMEBUFFER:
+ localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+ break;
+ case GL_FRAMEBUFFER:
+ localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+ break;
+ case GL_VERTEX_ARRAY:
+ localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
+ break;
+ case GL_PROGRAM:
+ localSet.set(DIRTY_OBJECT_PROGRAM);
+ break;
+ }
+
+ syncDirtyObjects(localSet);
+}
+
+void State::setObjectDirty(GLenum target)
+{
+ switch (target)
+ {
+ case GL_READ_FRAMEBUFFER:
+ mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ break;
+ case GL_DRAW_FRAMEBUFFER:
+ mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+ break;
+ case GL_FRAMEBUFFER:
+ mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+ break;
+ case GL_VERTEX_ARRAY:
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+ break;
+ case GL_PROGRAM:
+ mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
+ break;
+ }
}
} // namespace gl