[retro-gtk] Add and use GL autocleanup
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [retro-gtk] Add and use GL autocleanup
- Date: Sun, 18 Apr 2021 06:31:43 +0000 (UTC)
commit 1736b0a90050576493ccad2a5ce4e76295c701d2
Author: Adrien Plazas <kekun plazas laposte net>
Date: Sun May 24 09:34:05 2020 +0200
Add and use GL autocleanup
This makes the code safer and more concise.
retro-gtk/retro-gl-display.c | 10 +++----
retro-gtk/retro-glsl-shader.c | 31 +++++++------------
retro-runner/retro-gl-renderer.c | 18 +++--------
shared/retro-gl-private.h | 65 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 83 insertions(+), 41 deletions(-)
---
diff --git a/retro-gtk/retro-gl-display.c b/retro-gtk/retro-gl-display.c
index b105926..dff5c71 100644
--- a/retro-gtk/retro-gl-display.c
+++ b/retro-gtk/retro-gl-display.c
@@ -11,6 +11,7 @@
#include <epoxy/gl.h>
#include "retro-error-private.h"
+#include "retro-gl-private.h"
#include "retro-glsl-filter-private.h"
#include "retro-pixbuf.h"
#include "retro-pixdata.h"
@@ -254,8 +255,7 @@ realize (RetroGLDisplay *self)
(const GLvoid *) offsetof (RetroVertex, texture_coordinates));
}
- glDeleteTextures (1, &self->texture);
- self->texture = 0;
+ retro_gl_clear_object_n (&self->texture, 1, glDeleteTextures);
glGenTextures (1, &self->texture);
glBindTexture (GL_TEXTURE_2D, self->texture);
@@ -276,8 +276,7 @@ unrealize (RetroGLDisplay *self)
{
gtk_gl_area_make_current (GTK_GL_AREA (self));
- glDeleteTextures (1, &self->texture);
- self->texture = 0;
+ retro_gl_clear_object_n (&self->texture, 1, glDeleteTextures);
for (RetroVideoFilter filter = 0; filter < RETRO_VIDEO_FILTER_COUNT; filter++)
g_clear_object (&self->glsl_filter[filter]);
}
@@ -310,8 +309,7 @@ retro_gl_display_finalize (GObject *object)
{
RetroGLDisplay *self = (RetroGLDisplay *) object;
- glDeleteTextures (1, &self->texture);
- self->texture = 0;
+ retro_gl_clear_object_n (&self->texture, 1, glDeleteTextures);
for (RetroVideoFilter filter = 0; filter < RETRO_VIDEO_FILTER_COUNT; filter++)
g_clear_object (&self->glsl_filter[filter]);
g_clear_object (&self->core);
diff --git a/retro-gtk/retro-glsl-shader.c b/retro-gtk/retro-glsl-shader.c
index b606c1b..df5630c 100644
--- a/retro-gtk/retro-glsl-shader.c
+++ b/retro-gtk/retro-glsl-shader.c
@@ -3,6 +3,7 @@
#include "retro-glsl-shader-private.h"
#include "retro-error-private.h"
+#include "retro-gl-private.h"
struct _RetroGLSLShader
{
@@ -32,7 +33,7 @@ create_shader (GBytes *source_bytes,
{
const gchar *source;
gint size;
- GLuint shader;
+ retro_gl_autodelete_shader GLuint shader = 0;
gint status;
source = g_bytes_get_data (source_bytes, NULL);
@@ -55,12 +56,10 @@ create_shader (GBytes *source_bytes,
shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment",
buffer);
- glDeleteShader (shader);
-
return 0;
}
- return shader;
+ return retro_gl_steal_object (&shader);
}
static void
@@ -68,10 +67,7 @@ retro_glsl_shader_finalize (GObject *object)
{
RetroGLSLShader *self = (RetroGLSLShader *) object;
- if (self->program != 0) {
- glDeleteProgram (self->program);
- self->program = 0;
- }
+ retro_gl_clear_object (&self->program, glDeleteProgram);
G_OBJECT_CLASS (retro_glsl_shader_parent_class)->finalize (object);
}
@@ -98,8 +94,8 @@ retro_glsl_shader_new (GBytes *vertex,
{
g_autoptr (RetroGLSLShader) self = NULL;
gint status = 0;
- GLuint vertex_shader;
- GLuint fragment_shader;
+ retro_gl_autodelete_shader GLuint vertex_shader = 0;
+ retro_gl_autodelete_shader GLuint fragment_shader = 0;
g_return_val_if_fail (vertex != NULL, NULL);
g_return_val_if_fail (fragment != NULL, NULL);
@@ -117,13 +113,9 @@ retro_glsl_shader_new (GBytes *vertex,
vertex_shader = create_shader (self->vertex, GL_VERTEX_SHADER, &catch);
}, catch, error, NULL);
- retro_try ({
+ retro_try_propagate_val ({
fragment_shader = create_shader (self->fragment, GL_FRAGMENT_SHADER, &catch);
- }, catch, {
- glDeleteShader (vertex_shader);
-
- return NULL;
- });
+ }, catch, error, NULL);
self->program = glCreateProgram ();
glAttachShader (self->program, vertex_shader);
@@ -142,14 +134,11 @@ retro_glsl_shader_new (GBytes *vertex,
g_set_error (error, RETRO_GLSL_SHADER_ERROR, RETRO_GLSL_SHADER_ERROR_COULDNT_LINK,
"Linking failure in program: %s", buffer);
- glDeleteShader (vertex_shader);
- glDeleteShader (fragment_shader);
-
return NULL;
}
- glDetachShader (self->program, vertex_shader);
- glDetachShader (self->program, fragment_shader);
+ glDetachShader (self->program, retro_gl_steal_object (&vertex_shader));
+ glDetachShader (self->program, retro_gl_steal_object (&fragment_shader));
return g_steal_pointer (&self);
}
diff --git a/retro-runner/retro-gl-renderer.c b/retro-runner/retro-gl-renderer.c
index f096606..7de5109 100644
--- a/retro-runner/retro-gl-renderer.c
+++ b/retro-runner/retro-gl-renderer.c
@@ -4,6 +4,7 @@
#include <gio/gio.h>
#include "epoxy/egl.h"
+#include "retro-gl-private.h"
#define MAX_EGL_ATTRS 30
@@ -189,20 +190,9 @@ retro_gl_renderer_finalize (GObject *object)
* so that it actually has a chance to run */
self->callback->context_destroy ();
- if (self->texture) {
- glDeleteTextures (1, &self->texture);
- self->texture = 0;
- }
-
- if (self->renderbuffer) {
- glDeleteRenderbuffers (1, &self->renderbuffer);
- self->renderbuffer = 0;
- }
-
- if (self->framebuffer) {
- glDeleteFramebuffers (1, &self->framebuffer);
- self->framebuffer = 0;
- }
+ retro_gl_clear_object_n (&self->texture, 1, glDeleteTextures);
+ retro_gl_clear_object_n (&self->renderbuffer, 1, glDeleteRenderbuffers);
+ retro_gl_clear_object_n (&self->framebuffer, 1, glDeleteFramebuffers);
eglDestroyContext (self->display, self->context);
self->context = EGL_NO_CONTEXT;
diff --git a/shared/retro-gl-private.h b/shared/retro-gl-private.h
new file mode 100644
index 0000000..22bc254
--- /dev/null
+++ b/shared/retro-gl-private.h
@@ -0,0 +1,65 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#pragma once
+
+#if !defined(__RETRO_GTK_INSIDE__) && !defined(RETRO_GTK_COMPILATION)
+# error "Only <retro-gtk.h> can be included directly."
+#endif
+
+#include <epoxy/gl.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef void (*RetroGlDestroyFunc) (GLuint object);
+
+typedef void (*RetroGlArrayDestroyFunc) (GLsizei n_objects,
+ const GLuint *objects);
+
+static inline GLuint
+retro_gl_steal_object (GLuint *object_p)
+{
+ GLuint object = *object_p;
+
+ *object_p = 0;
+
+ return object;
+}
+
+static inline void
+retro_gl_clear_object (GLuint *object_p,
+ RetroGlDestroyFunc destroy)
+{
+ GLuint object = *object_p;
+
+ if (object) {
+ *object_p = 0;
+ destroy (object);
+ }
+}
+
+static inline void
+retro_gl_clear_object_n (GLuint *objects_p,
+ GLsizei n_objects,
+ RetroGlArrayDestroyFunc destroy)
+{
+ GLuint objects = *objects_p;
+
+ if (objects) {
+ *objects_p = 0;
+ destroy (n_objects, &objects);
+ }
+}
+
+static inline void
+retro_gl_autocleanup_delete_shader (GLuint *object_p)
+{
+ if (*object_p == 0)
+ return;
+
+ glDeleteShader (*object_p);
+}
+
+#define retro_gl_autodelete_shader __attribute__((cleanup(retro_gl_autocleanup_delete_shader)))
+
+G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]