[retro-gtk/gtk-cleanup: 4/12] glsl-shader: Add and use GL autocleanup



commit a51a7548db3a3602eeea26e5cd94afbad94b6114
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Sun May 24 09:34:05 2020 +0200

    glsl-shader: Add and use GL autocleanup
    
    This makes the code safer and more concise.

 retro-gtk/retro-gl-private.h  | 35 +++++++++++++++++++++++++++++++++++
 retro-gtk/retro-glsl-shader.c | 27 ++++++++++-----------------
 2 files changed, 45 insertions(+), 17 deletions(-)
---
diff --git a/retro-gtk/retro-gl-private.h b/retro-gtk/retro-gl-private.h
new file mode 100644
index 0000000..7d43999
--- /dev/null
+++ b/retro-gtk/retro-gl-private.h
@@ -0,0 +1,35 @@
+// 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
+
+static inline GLuint
+retro_gl_steal_object (GLuint *ptr)
+{
+  GLuint ref = *ptr;
+
+  *ptr = 0;
+
+  return ref;
+}
+
+static inline void
+retro_gl_autocleanup_delete_shader (GLuint *ptr)
+{
+  if (*ptr == 0)
+    return;
+
+  glDeleteShader (*ptr);
+}
+
+#define retro_gl_autodelete_shader __attribute__((cleanup(retro_gl_autocleanup_delete_shader)))
+
+G_END_DECLS
diff --git a/retro-gtk/retro-glsl-shader.c b/retro-gtk/retro-glsl-shader.c
index f03ca58..18c2ee5 100644
--- a/retro-gtk/retro-glsl-shader.c
+++ b/retro-gtk/retro-glsl-shader.c
@@ -2,6 +2,8 @@
 
 #include "retro-glsl-shader-private.h"
 
+#include "retro-gl-private.h"
+
 struct _RetroGLSLShader
 {
   GObject parent_instance;
@@ -28,14 +30,11 @@ create_shader (GBytes  *source_bytes,
                GLenum   shader_type,
                GError **error)
 {
-  const gchar *source;
-  gint size;
-  GLuint shader;
+  const gchar *source = g_bytes_get_data (source_bytes, NULL);
+  gint size = g_bytes_get_size (source_bytes);
+  retro_gl_autodelete_shader GLuint shader = glCreateShader (shader_type);
   gint status;
 
-  source = g_bytes_get_data (source_bytes, NULL);
-  size = g_bytes_get_size (source_bytes);
-  shader = glCreateShader (shader_type);
   glShaderSource (shader, 1, &source, &size);
   glCompileShader (shader);
 
@@ -53,12 +52,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
@@ -96,8 +93,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;
   GError *inner_error = NULL;
 
   g_return_val_if_fail (vertex != NULL, NULL);
@@ -122,7 +119,6 @@ retro_glsl_shader_new (GBytes  *vertex,
   fragment_shader = create_shader (self->fragment, GL_FRAGMENT_SHADER, &inner_error);
   if (G_UNLIKELY (inner_error != NULL)) {
     g_propagate_error (error, inner_error);
-    glDeleteShader (vertex_shader);
 
     return NULL;
   }
@@ -144,14 +140,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);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]