Fix Linux Impeller support broken by incorrect deletion of stencil buffer. (#168668)

The buffer was leaking and deleted in
9d8e5e0b2f. This fixes the location where
the buffer is deleted.
This commit is contained in:
Robert Ancell 2025-05-14 20:31:16 +12:00 committed by GitHub
parent 9a67219ea0
commit 0b9f9288ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 58 additions and 8 deletions

View File

@ -20,6 +20,9 @@ struct _FlFramebuffer {
// Texture backing framebuffer.
GLuint texture_id;
// Stencil buffer associated with this framebuffer.
GLuint depth_stencil;
};
G_DEFINE_TYPE(FlFramebuffer, fl_framebuffer, G_TYPE_OBJECT)
@ -29,6 +32,7 @@ static void fl_framebuffer_dispose(GObject* object) {
glDeleteFramebuffers(1, &self->framebuffer_id);
glDeleteTextures(1, &self->texture_id);
glDeleteRenderbuffers(1, &self->depth_stencil);
G_OBJECT_CLASS(fl_framebuffer_parent_class)->dispose(object);
}
@ -63,19 +67,17 @@ FlFramebuffer* fl_framebuffer_new(GLint format, size_t width, size_t height) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
provider->texture_id, 0);
GLuint depth_stencil;
glGenRenderbuffers(1, &depth_stencil);
glBindRenderbuffer(GL_RENDERBUFFER, depth_stencil);
glGenRenderbuffers(1, &provider->depth_stencil);
glBindRenderbuffer(GL_RENDERBUFFER, provider->depth_stencil);
glRenderbufferStorage(GL_RENDERBUFFER, // target
GL_DEPTH24_STENCIL8, // internal format
width, // width
height // height
);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_stencil);
GL_RENDERBUFFER, provider->depth_stencil);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, depth_stencil);
glDeleteRenderbuffers(1, &depth_stencil);
GL_RENDERBUFFER, provider->depth_stencil);
return provider;
}

View File

@ -24,3 +24,17 @@ TEST(FlFramebufferTest, HasDepthStencil) {
&stencil_type);
EXPECT_NE(stencil_type, GL_NONE);
}
TEST(FlFramebufferTest, ResourcesRemoved) {
::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
EXPECT_CALL(epoxy, glGenFramebuffers);
EXPECT_CALL(epoxy, glGenTextures);
EXPECT_CALL(epoxy, glGenRenderbuffers);
FlFramebuffer* framebuffer = fl_framebuffer_new(GL_RGB, 100, 100);
EXPECT_CALL(epoxy, glDeleteFramebuffers);
EXPECT_CALL(epoxy, glDeleteTextures);
EXPECT_CALL(epoxy, glDeleteRenderbuffers);
g_object_unref(framebuffer);
}

View File

@ -401,11 +401,25 @@ GLuint _glCreateShader(GLenum shaderType) {
return 0;
}
void _glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) {}
void _glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) {
if (mock) {
mock->glDeleteFramebuffers(n, framebuffers);
}
}
void _glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) {
if (mock) {
mock->glDeleteRenderbuffers(n, renderbuffers);
}
}
void _glDeleteShader(GLuint shader) {}
void _glDeleteTextures(GLsizei n, const GLuint* textures) {}
void _glDeleteTextures(GLsizei n, const GLuint* textures) {
if (mock) {
mock->glDeleteTextures(n, textures);
}
}
static void _glFramebufferRenderbuffer(GLenum target,
GLenum attachment,
@ -424,18 +438,27 @@ static void _glGenTextures(GLsizei n, GLuint* textures) {
for (GLsizei i = 0; i < n; i++) {
textures[i] = 0;
}
if (mock) {
mock->glGenTextures(n, textures);
}
}
static void _glGenFramebuffers(GLsizei n, GLuint* framebuffers) {
for (GLsizei i = 0; i < n; i++) {
framebuffers[i] = 0;
}
if (mock) {
mock->glGenFramebuffers(n, framebuffers);
}
}
static void _glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) {
for (GLsizei i = 0; i < n; i++) {
renderbuffers[i] = 0;
}
if (mock) {
mock->glGenRenderbuffers(n, renderbuffers);
}
}
static void _glGetFramebufferAttachmentParameteriv(GLenum target,
@ -659,6 +682,7 @@ static void library_init() {
epoxy_glCreateProgram = _glCreateProgram;
epoxy_glCreateShader = _glCreateShader;
epoxy_glDeleteFramebuffers = _glDeleteFramebuffers;
epoxy_glDeleteRenderbuffers = _glDeleteRenderbuffers;
epoxy_glDeleteShader = _glDeleteShader;
epoxy_glDeleteTextures = _glDeleteTextures;
epoxy_glFramebufferRenderbuffer = _glFramebufferRenderbuffer;

View File

@ -34,6 +34,16 @@ class MockEpoxy {
GLint dstY1,
GLbitfield mask,
GLenum filter));
MOCK_METHOD(void,
glDeleteFramebuffers,
(GLsizei n, const GLuint* framebuffers));
MOCK_METHOD(void,
glDeleteRenderbuffers,
(GLsizei n, const GLuint* renderbuffers));
MOCK_METHOD(void, glDeleteTextures, (GLsizei n, const GLuint* textures));
MOCK_METHOD(void, glGenFramebuffers, (GLsizei n, GLuint* framebuffers));
MOCK_METHOD(void, glGenRenderbuffers, (GLsizei n, GLuint* renderbuffers));
MOCK_METHOD(void, glGenTextures, (GLsizei n, GLuint* textures));
MOCK_METHOD(const GLubyte*, glGetString, (GLenum pname));
};