Skip to content

Commit bbd0d08

Browse files
Fix VRAM leak with CreateFrameBuffer
1 parent 4cc3d07 commit bbd0d08

1 file changed

Lines changed: 25 additions & 15 deletions

File tree

src/MacSrc/OpenGL.cc

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ extern SDL_Palette *sdlPalette;
4040
}
4141

4242
#include <map>
43+
#include <memory>
4344
#include <sstream>
4445

4546
struct CachedTexture {
@@ -75,7 +76,16 @@ static Shader textureShaderProgram;
7576
static Shader colorShaderProgram;
7677
static Shader starShaderProgram;
7778

78-
static FrameBuffer backupBuffer;
79+
struct FrameBufferDeleter {
80+
void operator()(FrameBuffer* fb) {
81+
glDeleteFramebuffers(1, &fb->frameBuffer);
82+
glDeleteRenderbuffers(1, &fb->stencilBuffer);
83+
glDeleteTextures(1, &fb->texture);
84+
}
85+
};
86+
87+
using SmartFrameBuffer = std::unique_ptr<FrameBuffer, FrameBufferDeleter>;
88+
static SmartFrameBuffer backupBuffer;
7989

8090
static SDL_GLContext context;
8191
static GLuint dynTexture;
@@ -247,24 +257,24 @@ static int CreateShader(const char *vertexShaderFile, const char *fragmentShader
247257
return 0;
248258
}
249259

250-
static FrameBuffer CreateFrameBuffer(int width, int height) {
251-
FrameBuffer newBuffer{};
252-
newBuffer.width = width;
253-
newBuffer.height = height;
260+
static SmartFrameBuffer CreateFrameBuffer(int width, int height) {
261+
SmartFrameBuffer newBuffer{new FrameBuffer{}};
262+
newBuffer->width = width;
263+
newBuffer->height = height;
254264

255265
// Make a frame buffer, texture for color, and render buffer for stencil
256-
glGenFramebuffers(1, &newBuffer.frameBuffer);
257-
glBindFramebuffer(GL_FRAMEBUFFER, newBuffer.frameBuffer);
266+
glGenFramebuffers(1, &newBuffer->frameBuffer);
267+
glBindFramebuffer(GL_FRAMEBUFFER, newBuffer->frameBuffer);
258268

259-
glGenRenderbuffers(1, &newBuffer.stencilBuffer);
260-
glBindRenderbuffer(GL_RENDERBUFFER, newBuffer.stencilBuffer);
269+
glGenRenderbuffers(1, &newBuffer->stencilBuffer);
270+
glBindRenderbuffer(GL_RENDERBUFFER, newBuffer->stencilBuffer);
261271
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
262-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, newBuffer.stencilBuffer);
272+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, newBuffer->stencilBuffer);
263273

264-
glGenTextures(1, &newBuffer.texture);
265-
glBindTexture(GL_TEXTURE_2D, newBuffer.texture);
274+
glGenTextures(1, &newBuffer->texture);
275+
glBindTexture(GL_TEXTURE_2D, newBuffer->texture);
266276
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
267-
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, newBuffer.texture, 0);
277+
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, newBuffer->texture, 0);
268278

269279
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
270280
if (status != GL_FRAMEBUFFER_COMPLETE) {
@@ -424,7 +434,7 @@ void opengl_start_frame() {
424434
SDL_GL_MakeCurrent(window, context);
425435

426436
// Start rendering to our frame buffer canvas
427-
BindFrameBuffer(&backupBuffer);
437+
BindFrameBuffer(backupBuffer.get());
428438

429439
// Setup the render width
430440
int logical_width, logical_height;
@@ -475,7 +485,7 @@ void opengl_swap_and_restore(SDL_Surface *ui) {
475485
glUniformMatrix4fv(textureShaderProgram.uniProj, 1, false, IdentityMatrix);
476486

477487
// Draw the frame buffer to the screen as a quad
478-
bind_texture(backupBuffer.texture);
488+
bind_texture(backupBuffer->texture);
479489
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
480490
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
481491

0 commit comments

Comments
 (0)