Commit 10d41397 by JiangYizhou Committed by Commit Bot

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: 's avatarJamie Madill <jmadill@chromium.org>
parent 89c422ad
...@@ -92,7 +92,7 @@ ClearParameters::ClearParameters() = default; ...@@ -92,7 +92,7 @@ ClearParameters::ClearParameters() = default;
ClearParameters::ClearParameters(const ClearParameters &other) = default; ClearParameters::ClearParameters(const ClearParameters &other) = default;
FramebufferD3D::FramebufferD3D(const gl::FramebufferState &data, RendererD3D *renderer) FramebufferD3D::FramebufferD3D(const gl::FramebufferState &data, RendererD3D *renderer)
: FramebufferImpl(data), mRenderer(renderer) : FramebufferImpl(data), mRenderer(renderer), mDummyAttachment()
{ {
} }
...@@ -381,18 +381,35 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl: ...@@ -381,18 +381,35 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl:
{ {
static_assert(static_cast<size_t>(activeProgramOutputs.size()) <= 32, static_assert(static_cast<size_t>(activeProgramOutputs.size()) <= 32,
"Size of active program outputs should less or equal than 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::ScanForward(static_cast<uint32_t>(activeProgramOutputs.bits())));
gl::Texture *dummyTex = nullptr; if (mDummyAttachment.isAttached() &&
// TODO(Jamie): Handle error if dummy texture can't be created. (mDummyAttachment.getBinding() - GL_COLOR_ATTACHMENT0) == activeProgramLocation)
ANGLE_SWALLOW_ERR(mRenderer->getIncompleteTexture(context, GL_TEXTURE_2D, &dummyTex));
if (dummyTex)
{ {
gl::ImageIndex index = gl::ImageIndex::Make2D(0); colorAttachmentsForRender.push_back(&mDummyAttachment);
gl::FramebufferAttachment *dummyAttach = new gl::FramebufferAttachment( }
context, GL_TEXTURE, GL_COLOR_ATTACHMENT0_EXT + i, index, dummyTex); else
colorAttachmentsForRender.push_back(dummyAttach); {
// 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 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl: ...@@ -402,4 +419,12 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl:
return mColorAttachmentsForRender.value(); return mColorAttachmentsForRender.value();
} }
void FramebufferD3D::destroy(const gl::Context *context)
{
if (mDummyAttachment.isAttached())
{
mDummyAttachment.detach(context);
}
}
} // namespace rx } // namespace rx
...@@ -102,6 +102,8 @@ class FramebufferD3D : public FramebufferImpl ...@@ -102,6 +102,8 @@ class FramebufferD3D : public FramebufferImpl
const gl::AttachmentList &getColorAttachmentsForRender(const gl::Context *context); const gl::AttachmentList &getColorAttachmentsForRender(const gl::Context *context);
void destroy(const gl::Context *context) override;
private: private:
virtual gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) = 0; virtual gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) = 0;
...@@ -128,6 +130,8 @@ class FramebufferD3D : public FramebufferImpl ...@@ -128,6 +130,8 @@ class FramebufferD3D : public FramebufferImpl
RendererD3D *mRenderer; RendererD3D *mRenderer;
Optional<gl::AttachmentList> mColorAttachmentsForRender; Optional<gl::AttachmentList> mColorAttachmentsForRender;
gl::DrawBufferMask mCurrentActiveProgramOutputs; gl::DrawBufferMask mCurrentActiveProgramOutputs;
gl::FramebufferAttachment mDummyAttachment;
}; };
} }
......
...@@ -693,27 +693,49 @@ TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments) ...@@ -693,27 +693,49 @@ TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
// anglebug.com/2253 // anglebug.com/2253
ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL()); ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
const std::string &vertexShader = const std::string &vertexShader1 =
"#version 310 es\n" R"(#version 310 es
"in layout(location = 0) highp vec2 a_position;\n\n" in layout(location = 0) highp vec2 a_position;
"void main()\n" void main()
"{\n" {
" gl_Position = vec4(a_position, 0.0, 1.0);\n" gl_Position = vec4(a_position, 0.0, 1.0);
"}\n"; })";
const std::string &fragShader =
"#version 310 es\n" const std::string &fragShader1 =
"uniform layout(location = 0) highp ivec2 u_expectedSize;\n" R"(#version 310 es
"out layout(location = 5) mediump vec4 f_color;\n\n" uniform layout(location = 0) highp ivec2 u_expectedSize;
"void main()\n" out layout(location = 5) mediump vec4 f_color;
"{\n" void main()
" if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;\n" {
" f_color = vec4(1.0, 0.5, 0.25, 1.0);\n" if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
"}\n"; f_color = vec4(1.0, 0.5, 0.25, 1.0);
})";
GLuint program = CompileProgram(vertexShader, fragShader);
ASSERT_NE(program, 0u); const std::string &vertexShader2 =
R"(#version 310 es
glUseProgram(program); in layout(location = 0) highp vec2 a_position;
void main()
{
gl_Position = vec4(a_position, 0.0, 1.0);
})";
const std::string &fragShader2 =
R"(#version 310 es
uniform layout(location = 0) highp ivec2 u_expectedSize;
out layout(location = 2) mediump vec4 f_color;
void main()
{
if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
f_color = vec4(1.0, 0.5, 0.25, 1.0);
})";
GLuint program1 = CompileProgram(vertexShader1, fragShader1);
ASSERT_NE(program1, 0u);
GLuint program2 = CompileProgram(vertexShader2, fragShader2);
ASSERT_NE(program2, 0u);
glUseProgram(program1);
GLFramebuffer mFramebuffer; GLFramebuffer mFramebuffer;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
...@@ -747,6 +769,10 @@ TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments) ...@@ -747,6 +769,10 @@ TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
validateSamplePass(query, passedCount, defaultWidth, defaultHeight); validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
glUseProgram(program2);
validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
glUseProgram(program1);
// If fbo has attachments, the rendering size should be the same as its attachment. // If fbo has attachments, the rendering size should be the same as its attachment.
GLTexture mTexture; GLTexture mTexture;
GLuint width = 2; GLuint width = 2;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment