Fix leak with binding Framebuffers directly.
Using BindFramebuffer(1) then GenFramebuffers would return 1.
This leads to a memory leak and was something that was obscuring
debugging a bug in my ReadPixels fix for ES3.
This also fixes a bug where running the texture tests along produces
some random failures.
BUG=angleproject:1290
BUG=angleproject:1299
Change-Id: If11e8c743d2ddde725b12749ac012f670cd290e1
Reviewed-on: https://chromium-review.googlesource.com/324820
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 58f39a6..b835c1a 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -686,24 +686,16 @@
mState.setSamplerTexture(target, texture);
}
-void Context::bindReadFramebuffer(GLuint framebuffer)
+void Context::bindReadFramebuffer(GLuint framebufferHandle)
{
- if (!getFramebuffer(framebuffer))
- {
- mFramebufferMap[framebuffer] = new Framebuffer(mCaps, mRenderer, framebuffer);
- }
-
- mState.setReadFramebufferBinding(getFramebuffer(framebuffer));
+ Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
+ mState.setReadFramebufferBinding(framebuffer);
}
-void Context::bindDrawFramebuffer(GLuint framebuffer)
+void Context::bindDrawFramebuffer(GLuint framebufferHandle)
{
- if (!getFramebuffer(framebuffer))
- {
- mFramebufferMap[framebuffer] = new Framebuffer(mCaps, mRenderer, framebuffer);
- }
-
- mState.setDrawFramebufferBinding(getFramebuffer(framebuffer));
+ Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
+ mState.setDrawFramebufferBinding(framebuffer);
}
void Context::bindRenderbuffer(GLuint renderbuffer)
@@ -887,16 +879,8 @@
Framebuffer *Context::getFramebuffer(unsigned int handle) const
{
- FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
-
- if (framebuffer == mFramebufferMap.end())
- {
- return NULL;
- }
- else
- {
- return framebuffer->second;
- }
+ auto framebufferIt = mFramebufferMap.find(handle);
+ return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
}
FenceNV *Context::getFenceNV(unsigned int handle)
@@ -1685,6 +1669,7 @@
void Context::checkVertexArrayAllocation(GLuint vertexArray)
{
+ // Only called after a prior call to Gen.
if (!getVertexArray(vertexArray))
{
VertexArray *vertexArrayObject =
@@ -1695,6 +1680,7 @@
void Context::checkTransformFeedbackAllocation(GLuint transformFeedback)
{
+ // Only called after a prior call to Gen.
if (!getTransformFeedback(transformFeedback))
{
TransformFeedback *transformFeedbackObject =
@@ -1704,6 +1690,27 @@
}
}
+Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
+{
+ // Can be called from Bind without a prior call to Gen.
+ auto framebufferIt = mFramebufferMap.find(framebuffer);
+ bool neverCreated = framebufferIt == mFramebufferMap.end();
+ if (neverCreated || framebufferIt->second == nullptr)
+ {
+ Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
+ if (neverCreated)
+ {
+ mFramebufferHandleAllocator.reserve(framebuffer);
+ mFramebufferMap[framebuffer] = newFBO;
+ return newFBO;
+ }
+
+ framebufferIt->second = newFBO;
+ }
+
+ return framebufferIt->second;
+}
+
bool Context::isVertexArrayGenerated(GLuint vertexArray)
{
return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();