Fix addDummyTextureNoRenderTarget workaround memory leak
Add dummy attachment in FramebufferD3D as a private member and release
the dummy attchment in destory of FramebufferD3D.
BUG=angleproject:2282
TEST=FramebufferTest_ES31.RenderingLimitToDefaultFBOSizeWithNoAttachments/ES3_1_D3D11
TEST=dEQP-GLES31.functional.fbo.no_attachments.*
Change-Id: I3a17282ef132185fbc25f4076f624e53661d4b20
Reviewed-on: https://chromium-review.googlesource.com/831847
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
index fbe8cdf..aea2b28 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -92,7 +92,7 @@
ClearParameters::ClearParameters(const ClearParameters &other) = default;
FramebufferD3D::FramebufferD3D(const gl::FramebufferState &data, RendererD3D *renderer)
- : FramebufferImpl(data), mRenderer(renderer)
+ : FramebufferImpl(data), mRenderer(renderer), mDummyAttachment()
{
}
@@ -381,18 +381,35 @@
{
static_assert(static_cast<size_t>(activeProgramOutputs.size()) <= 32,
"Size of active program outputs should less or equal than 32.");
- GLenum i = static_cast<GLenum>(
+ const GLuint activeProgramLocation = static_cast<GLuint>(
gl::ScanForward(static_cast<uint32_t>(activeProgramOutputs.bits())));
- gl::Texture *dummyTex = nullptr;
- // TODO(Jamie): Handle error if dummy texture can't be created.
- ANGLE_SWALLOW_ERR(mRenderer->getIncompleteTexture(context, GL_TEXTURE_2D, &dummyTex));
- if (dummyTex)
+ if (mDummyAttachment.isAttached() &&
+ (mDummyAttachment.getBinding() - GL_COLOR_ATTACHMENT0) == activeProgramLocation)
{
- gl::ImageIndex index = gl::ImageIndex::Make2D(0);
- gl::FramebufferAttachment *dummyAttach = new gl::FramebufferAttachment(
- context, GL_TEXTURE, GL_COLOR_ATTACHMENT0_EXT + i, index, dummyTex);
- colorAttachmentsForRender.push_back(dummyAttach);
+ colorAttachmentsForRender.push_back(&mDummyAttachment);
+ }
+ else
+ {
+ // Remove dummy attachment to prevents us from leaking it, and the program may require
+ // it to be attached to a new binding point.
+ if (mDummyAttachment.isAttached())
+ {
+ mDummyAttachment.detach(context);
+ }
+
+ gl::Texture *dummyTex = nullptr;
+ // TODO(Jamie): Handle error if dummy texture can't be created.
+ ANGLE_SWALLOW_ERR(mRenderer->getIncompleteTexture(context, GL_TEXTURE_2D, &dummyTex));
+ if (dummyTex)
+ {
+
+ gl::ImageIndex index = gl::ImageIndex::Make2D(0);
+ mDummyAttachment = gl::FramebufferAttachment(
+ context, GL_TEXTURE, GL_COLOR_ATTACHMENT0_EXT + activeProgramLocation, index,
+ dummyTex);
+ colorAttachmentsForRender.push_back(&mDummyAttachment);
+ }
}
}
@@ -402,4 +419,12 @@
return mColorAttachmentsForRender.value();
}
+void FramebufferD3D::destroy(const gl::Context *context)
+{
+ if (mDummyAttachment.isAttached())
+ {
+ mDummyAttachment.detach(context);
+ }
+}
+
} // namespace rx