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;
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 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl:
{
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 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl:
return mColorAttachmentsForRender.value();
}
void FramebufferD3D::destroy(const gl::Context *context)
{
if (mDummyAttachment.isAttached())
{
mDummyAttachment.detach(context);
}
}
} // namespace rx
......@@ -102,6 +102,8 @@ class FramebufferD3D : public FramebufferImpl
const gl::AttachmentList &getColorAttachmentsForRender(const gl::Context *context);
void destroy(const gl::Context *context) override;
private:
virtual gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) = 0;
......@@ -128,6 +130,8 @@ class FramebufferD3D : public FramebufferImpl
RendererD3D *mRenderer;
Optional<gl::AttachmentList> mColorAttachmentsForRender;
gl::DrawBufferMask mCurrentActiveProgramOutputs;
gl::FramebufferAttachment mDummyAttachment;
};
}
......
......@@ -693,27 +693,49 @@ TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
// anglebug.com/2253
ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
const std::string &vertexShader =
"#version 310 es\n"
"in layout(location = 0) highp vec2 a_position;\n\n"
"void main()\n"
"{\n"
" gl_Position = vec4(a_position, 0.0, 1.0);\n"
"}\n";
const std::string &fragShader =
"#version 310 es\n"
"uniform layout(location = 0) highp ivec2 u_expectedSize;\n"
"out layout(location = 5) mediump vec4 f_color;\n\n"
"void main()\n"
"{\n"
" if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;\n"
" f_color = vec4(1.0, 0.5, 0.25, 1.0);\n"
"}\n";
GLuint program = CompileProgram(vertexShader, fragShader);
ASSERT_NE(program, 0u);
glUseProgram(program);
const std::string &vertexShader1 =
R"(#version 310 es
in layout(location = 0) highp vec2 a_position;
void main()
{
gl_Position = vec4(a_position, 0.0, 1.0);
})";
const std::string &fragShader1 =
R"(#version 310 es
uniform layout(location = 0) highp ivec2 u_expectedSize;
out layout(location = 5) 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);
})";
const std::string &vertexShader2 =
R"(#version 310 es
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;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
......@@ -747,6 +769,10 @@ TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
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.
GLTexture mTexture;
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