[retro-gtk/wip/aplazas/gl-errors] errors



commit 1ee94433dbf5471a0c10506b8cf667176986d2c2
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Thu Nov 16 11:42:35 2017 +0100

    errors

 retro-gtk/retro-gl-display.c  |    7 +++-
 retro-gtk/retro-glsl-filter.c |   96 ++++++++++++++++++++++++++++++++++++++--
 retro-gtk/retro-glsl-filter.h |    3 +-
 3 files changed, 99 insertions(+), 7 deletions(-)
---
diff --git a/retro-gtk/retro-gl-display.c b/retro-gtk/retro-gl-display.c
index 34f5dc1..a4a43aa 100644
--- a/retro-gtk/retro-gl-display.c
+++ b/retro-gtk/retro-gl-display.c
@@ -104,6 +104,7 @@ retro_gl_display_realize (RetroGLDisplay *self)
   GLuint vertex_array_object;
   GLuint element_buffer_object;
   RetroVideoFilter filter;
+  GError *inner_error = NULL;
 
   gtk_gl_area_make_current (GTK_GL_AREA (self));
 
@@ -120,7 +121,11 @@ retro_gl_display_realize (RetroGLDisplay *self)
 
   for (filter = 0; filter < RETRO_VIDEO_FILTER_COUNT; filter++) {
     self->glsl_filter[filter] = retro_glsl_filter_new (filter_uris[filter], NULL);
-    retro_glsl_filter_prepare_program (self->glsl_filter[filter]);
+    retro_glsl_filter_prepare_program (self->glsl_filter[filter], &inner_error);
+    if (G_UNLIKELY (inner_error) != NULL) {
+      g_message ("%s", inner_error->message);
+      g_clear_error (&inner_error);
+    }
 
     retro_glsl_filter_set_attribute_pointer (self->glsl_filter[filter],
                                              "position",
diff --git a/retro-gtk/retro-glsl-filter.c b/retro-gtk/retro-glsl-filter.c
index 1620b8c..791d187 100644
--- a/retro-gtk/retro-glsl-filter.c
+++ b/retro-gtk/retro-glsl-filter.c
@@ -18,6 +18,15 @@ G_DEFINE_TYPE (RetroGLSLFilter, retro_glsl_filter, G_TYPE_OBJECT)
 
 #define GLSL_FILTER_GROUP "GLSL Filter"
 
+#define RETRO_GLSL_FILTER_ERROR (retro_glsl_filter_error_quark ())
+
+typedef enum {
+  RETRO_GLSL_FILTER_ERROR_SHADER_COMPILATION,
+  RETRO_GLSL_FILTER_ERROR_SHADER_LINK
+} RetroGLSLFilterError;
+
+G_DEFINE_QUARK (retro-glsl-filter-error, retro_glsl_filter_error)
+
 static const gchar *
 g_key_file_try_get_string (GKeyFile    *key_file,
                            const gchar *group,
@@ -248,32 +257,109 @@ retro_glsl_filter_apply_texture_params (RetroGLSLFilter *self)
 }
 
 static GLuint
-create_shader (GBytes *source_bytes,
-               GLenum  shader_type)
+create_shader (GBytes  *source_bytes,
+               GLenum   shader_type,
+               GError **error)
 {
   const gchar *source;
   GLuint shader;
+  gint status;
+  gint log_length;
+  gchar *buffer;
 
   source = g_bytes_get_data (source_bytes, NULL);
   shader = glCreateShader (shader_type);
   glShaderSource (shader, 1, &source, NULL);
   glCompileShader (shader);
 
+  status = 0;
+  glGetShaderiv (shader, GL_COMPILE_STATUS, &status);
+  if (status == GL_FALSE) {
+    glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &log_length);
+    buffer = g_malloc (log_length + 1);
+    glGetShaderInfoLog (shader, log_length, NULL, buffer);
+
+    g_set_error (error, RETRO_GLSL_FILTER_ERROR, RETRO_GLSL_FILTER_ERROR_SHADER_COMPILATION,
+                 "Compilation failure in %s shader: %s",
+                 shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment",
+                 buffer);
+
+    g_free (buffer);
+    glDeleteShader (shader);
+
+    return 0;
+  }
+
   return shader;
 }
 
 void
-retro_glsl_filter_prepare_program (RetroGLSLFilter *self)
+retro_glsl_filter_prepare_program (RetroGLSLFilter  *self,
+                                   GError          **error)
 {
+  gint status;
+  gint log_length;
+  gchar *buffer;
+  GError *inner_error = NULL;
+
   g_return_if_fail (RETRO_IS_GLSL_FILTER (self));
 
-  self->vertex_shader = create_shader (self->vertex, GL_VERTEX_SHADER);
-  self->fragment_shader = create_shader (self->fragment, GL_FRAGMENT_SHADER);
+  self->vertex_shader = create_shader (self->vertex,
+                                       GL_VERTEX_SHADER,
+                                       &inner_error);
+  if (G_UNLIKELY (inner_error != NULL)) {
+    g_propagate_error (error, inner_error);
+    self->vertex_shader = 0;
+    self->fragment_shader = 0;
+    self->program = 0;
+
+    return;
+  }
+
+  self->fragment_shader = create_shader (self->fragment,
+                                         GL_FRAGMENT_SHADER,
+                                         &inner_error);
+  if (G_UNLIKELY (inner_error != NULL)) {
+    g_propagate_error (error, inner_error);
+    glDeleteShader (self->vertex_shader);
+    self->vertex_shader = 0;
+    self->fragment_shader = 0;
+    self->program = 0;
+
+    return;
+  }
 
   self->program = glCreateProgram();
   glAttachShader (self->program, self->vertex_shader);
   glAttachShader (self->program, self->fragment_shader);
   glLinkProgram (self->program);
+
+  status = 0;
+  glGetProgramiv (self->program, GL_LINK_STATUS, &status);
+  if (status == GL_FALSE) {
+    log_length = 0;
+    glGetProgramiv (self->program, GL_INFO_LOG_LENGTH, &log_length);
+    buffer = g_malloc (log_length + 1);
+    glGetProgramInfoLog (self->program, log_length, NULL, buffer);
+
+    g_set_error (error, RETRO_GLSL_FILTER_ERROR, RETRO_GLSL_FILTER_ERROR_SHADER_LINK,
+                 "Linking failure in program: %s", buffer);
+    g_free (buffer);
+
+    glDeleteShader (self->vertex_shader);
+    glDeleteShader (self->fragment_shader);
+    glDeleteProgram (self->program);
+    self->vertex_shader = 0;
+    self->fragment_shader = 0;
+    self->program = 0;
+
+    return;
+  }
+
+  glDetachShader (self->program, self->vertex_shader);
+  glDetachShader (self->program, self->fragment_shader);
+  self->vertex_shader = 0;
+  self->fragment_shader = 0;
 }
 
 void
diff --git a/retro-gtk/retro-glsl-filter.h b/retro-gtk/retro-glsl-filter.h
index a9d0e11..d468626 100644
--- a/retro-gtk/retro-glsl-filter.h
+++ b/retro-gtk/retro-glsl-filter.h
@@ -14,7 +14,8 @@ G_DECLARE_FINAL_TYPE (RetroGLSLFilter, retro_glsl_filter, RETRO, GLSL_FILTER, GO
 RetroGLSLFilter *retro_glsl_filter_new (const char  *uri,
                                         GError     **error);
 void retro_glsl_filter_apply_texture_params (RetroGLSLFilter *self);
-void retro_glsl_filter_prepare_program (RetroGLSLFilter *self);
+void retro_glsl_filter_prepare_program (RetroGLSLFilter  *self,
+                                        GError          **error);
 void retro_glsl_filter_use_program (RetroGLSLFilter *self);
 void retro_glsl_filter_set_attribute_pointer (RetroGLSLFilter *self,
                                               const gchar     *name,


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