[retro-gtk] glsl-filter: Use RetroGLSLShader internally



commit 233bbff9577260ea7ae19e223a284aa13a11727d
Author: Neville <nevilleantony98 gmail com>
Date:   Sat May 23 13:40:55 2020 +0530

    glsl-filter: Use RetroGLSLShader internally
    
    RetroGLSLShader helps simplify RetroGLSLFilter by moving some shader
    related code.
    
    Removes retro_glsl_filter_prepare_program () as shader preparation is
    now done whenever a shader is created and does not require an explicit
    call.

 retro-gtk/retro-gl-display.c          |  30 ++--
 retro-gtk/retro-glsl-filter-private.h |  22 +--
 retro-gtk/retro-glsl-filter.c         | 268 ++++++----------------------------
 3 files changed, 66 insertions(+), 254 deletions(-)
---
diff --git a/retro-gtk/retro-gl-display.c b/retro-gtk/retro-gl-display.c
index 0c07765..ad99370 100644
--- a/retro-gtk/retro-gl-display.c
+++ b/retro-gtk/retro-gl-display.c
@@ -168,12 +168,13 @@ draw_texture (RetroGLDisplay  *self,
   GLfloat source_width, source_height;
   GLfloat target_width, target_height;
   GLfloat output_width, output_height;
+  RetroGLSLShader *shader = retro_glsl_filter_get_shader (filter);
 
-  retro_glsl_filter_use_program (filter);
+  retro_glsl_shader_use_program (shader);
 
-  retro_glsl_filter_apply_texture_params (filter);
+  retro_glsl_shader_apply_texture_params (shader);
 
-  retro_glsl_filter_set_uniform_1f (filter, "relative_aspect_ratio",
+  retro_glsl_shader_set_uniform_1f (shader, "relative_aspect_ratio",
     (gfloat) gtk_widget_get_allocated_width (GTK_WIDGET (self)) /
     (gfloat) gtk_widget_get_allocated_height (GTK_WIDGET (self)) /
     self->aspect_ratio);
@@ -185,15 +186,15 @@ draw_texture (RetroGLDisplay  *self,
   output_width = (GLfloat) gtk_widget_get_allocated_width (GTK_WIDGET (self));
   output_height = (GLfloat) gtk_widget_get_allocated_height (GTK_WIDGET (self));
 
-  retro_glsl_filter_set_uniform_4f (filter, "sourceSize[0]",
+  retro_glsl_shader_set_uniform_4f (shader, "sourceSize[0]",
                                     source_width, source_height,
                                     1.0f / source_width, 1.0f / source_height);
 
-  retro_glsl_filter_set_uniform_4f (filter, "targetSize",
+  retro_glsl_shader_set_uniform_4f (shader, "targetSize",
                                     target_width, target_height,
                                     1.0f / target_width, 1.0f / target_height);
 
-  retro_glsl_filter_set_uniform_4f (filter, "outputSize",
+  retro_glsl_shader_set_uniform_4f (shader, "outputSize",
                                     output_width, output_height,
                                     1.0f / output_width, 1.0f / output_height);
 
@@ -223,8 +224,9 @@ realize (RetroGLDisplay *self)
   glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (elements), elements, GL_STATIC_DRAW);
 
   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], &inner_error);
+    RetroGLSLShader *shader;
+
+    self->glsl_filter[filter] = retro_glsl_filter_new (filter_uris[filter], &inner_error);
     if (G_UNLIKELY (inner_error != NULL)) {
       g_critical ("Shader program %s creation failed: %s",
                   filter_uris[filter],
@@ -235,7 +237,9 @@ realize (RetroGLDisplay *self)
       continue;
     }
 
-    retro_glsl_filter_set_attribute_pointer (self->glsl_filter[filter],
+    shader = retro_glsl_filter_get_shader (self->glsl_filter[filter]);
+
+    retro_glsl_shader_set_attribute_pointer (shader,
                                              "position",
                                              sizeof (((RetroVertex *) NULL)->position) / sizeof (float),
                                              GL_FLOAT,
@@ -243,7 +247,7 @@ realize (RetroGLDisplay *self)
                                              sizeof (RetroVertex),
                                              (const GLvoid *) offsetof (RetroVertex, position));
 
-    retro_glsl_filter_set_attribute_pointer (self->glsl_filter[filter],
+    retro_glsl_shader_set_attribute_pointer (shader,
                                              "texCoord",
                                              sizeof (((RetroVertex *) NULL)->texture_coordinates) / sizeof 
(float),
                                              GL_FLOAT,
@@ -261,8 +265,10 @@ realize (RetroGLDisplay *self)
     RETRO_VIDEO_FILTER_SMOOTH :
     self->filter;
 
-  if (self->glsl_filter[filter] != NULL)
-    retro_glsl_filter_use_program (self->glsl_filter[filter]);
+  if (self->glsl_filter[filter] != NULL) {
+    RetroGLSLShader *shader = retro_glsl_filter_get_shader (self->glsl_filter[filter]);
+    retro_glsl_shader_use_program (shader);
+  }
 
   glClearColor (0, 0, 0, 1);
 }
diff --git a/retro-gtk/retro-glsl-filter-private.h b/retro-gtk/retro-glsl-filter-private.h
index 63d7758..45c4ba9 100644
--- a/retro-gtk/retro-glsl-filter-private.h
+++ b/retro-gtk/retro-glsl-filter-private.h
@@ -6,6 +6,7 @@
 #include <gio/gio.h>
 #include <glib-object.h>
 
+#include "retro-glsl-shader-private.h"
 G_BEGIN_DECLS
 
 #define RETRO_TYPE_GLSL_FILTER (retro_glsl_filter_get_type())
@@ -14,25 +15,6 @@ 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,
-                                        GError          **error);
-void retro_glsl_filter_use_program (RetroGLSLFilter *self);
-void retro_glsl_filter_set_attribute_pointer (RetroGLSLFilter *self,
-                                              const gchar     *name,
-                                              GLint            size,
-                                              GLenum           type,
-                                              GLboolean        normalized,
-                                              GLsizei          stride,
-                                              const GLvoid    *pointer);
-void retro_glsl_filter_set_uniform_1f (RetroGLSLFilter *self,
-                                       const gchar     *name,
-                                       gfloat           v0);
-void retro_glsl_filter_set_uniform_4f (RetroGLSLFilter *self,
-                                       const gchar     *name,
-                                       gfloat           v0,
-                                       gfloat           v1,
-                                       gfloat           v2,
-                                       gfloat           v3);
+RetroGLSLShader *retro_glsl_filter_get_shader (RetroGLSLFilter *self);
 
 G_END_DECLS
diff --git a/retro-gtk/retro-glsl-filter.c b/retro-gtk/retro-glsl-filter.c
index 593c72f..2ab1b1c 100644
--- a/retro-gtk/retro-glsl-filter.c
+++ b/retro-gtk/retro-glsl-filter.c
@@ -5,26 +5,13 @@
 struct _RetroGLSLFilter
 {
   GObject parent_instance;
-  GBytes *vertex;
-  GBytes *fragment;
-  GLenum wrap;
-  GLenum filter;
-  GLuint program;
+  RetroGLSLShader *shader;
 };
 
 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,
@@ -127,11 +114,16 @@ RetroGLSLFilter *
 retro_glsl_filter_new (const char  *uri,
                        GError     **error)
 {
-  RetroGLSLFilter *self;
-  GKeyFile *key_file;
-  GFile *file;
-  GFile *parent;
-  GBytes *bytes;
+  g_autoptr (RetroGLSLFilter) self = NULL;
+  g_autoptr (GBytes) vertex = NULL;
+  g_autoptr (GBytes) fragment = NULL;
+  GLenum wrap;
+  GLenum filter;
+
+  g_autoptr (GKeyFile) key_file = NULL;
+  g_autoptr (GFile) file = NULL;
+  g_autoptr (GFile) parent = NULL;
+  g_autoptr (GBytes) bytes = NULL;
   const gchar *value;
   GError *inner_error = NULL;
 
@@ -139,66 +131,65 @@ retro_glsl_filter_new (const char  *uri,
 
   file = g_file_new_for_uri (uri);
   bytes = g_file_try_read_bytes (file);
-  if (G_UNLIKELY (bytes == NULL)) {
-    g_object_unref (file);
-
+  if (G_UNLIKELY (bytes == NULL))
     return NULL;
-  }
 
   key_file = g_key_file_new ();
   g_key_file_load_from_bytes (key_file, bytes, G_KEY_FILE_NONE, &inner_error);
   if (G_UNLIKELY (inner_error != NULL)) {
     g_propagate_error (error, inner_error);
-    g_object_unref (file);
-    g_bytes_unref (bytes);
-    g_key_file_unref (key_file);
 
     return NULL;
   }
 
-  g_bytes_unref (bytes);
-
   self = g_object_new (RETRO_TYPE_GLSL_FILTER, NULL);
 
   value = g_key_file_try_get_string (key_file, GLSL_FILTER_GROUP, "Filter");
   if (g_strcmp0 (value, "Linear") == 0)
-    self->filter = GL_LINEAR;
+    filter = GL_LINEAR;
   else if (g_strcmp0 (value, "Nearest") == 0)
-    self->filter = GL_NEAREST;
+    filter = GL_NEAREST;
   else
-    self->filter = GL_LINEAR;
+    filter = GL_LINEAR;
 
   value = g_key_file_try_get_string (key_file, GLSL_FILTER_GROUP, "Wrap");
   if (g_strcmp0 (value, "Border") == 0)
-    self->wrap = GL_CLAMP_TO_BORDER;
+    wrap = GL_CLAMP_TO_BORDER;
   else if (g_strcmp0 (value, "Edge") == 0)
-    self->wrap = GL_CLAMP_TO_EDGE;
+    wrap = GL_CLAMP_TO_EDGE;
   else
-    self->wrap = GL_CLAMP_TO_BORDER;
+    wrap = GL_CLAMP_TO_BORDER;
 
   parent = g_file_get_parent (file);
-  g_object_unref (file);
 
-  self->vertex = g_key_file_try_read_child_bytes (key_file,
-                                                  GLSL_FILTER_GROUP,
-                                                  "Vertex",
-                                                  parent);
+  vertex = g_key_file_try_read_child_bytes (key_file,
+                                            GLSL_FILTER_GROUP,
+                                            "Vertex",
+                                            parent);
 
-  if (self->vertex == NULL)
-    self->vertex = g_file_try_read_child_bytes (parent, "sharp.vs");
+  if (vertex == NULL)
+    vertex = g_file_try_read_child_bytes (parent, "sharp.vs");
 
-  self->fragment = g_key_file_try_read_child_bytes (key_file,
-                                                    GLSL_FILTER_GROUP,
-                                                    "Fragment",
-                                                    parent);
+  fragment = g_key_file_try_read_child_bytes (key_file,
+                                              GLSL_FILTER_GROUP,
+                                              "Fragment",
+                                              parent);
 
-  if (self->fragment == NULL)
-    self->fragment = g_file_try_read_child_bytes (parent, "sharp.fs");
+  if (fragment == NULL)
+    fragment = g_file_try_read_child_bytes (parent, "sharp.fs");
 
-  g_object_unref (parent);
-  g_key_file_unref (key_file);
+  self->shader = retro_glsl_shader_new (vertex,
+                                        fragment,
+                                        wrap,
+                                        filter,
+                                        &inner_error);
+  if (G_UNLIKELY (inner_error != NULL)) {
+    g_propagate_error (error, inner_error);
 
-  return self;
+    return NULL;
+  }
+
+  return g_steal_pointer (&self);
 }
 
 static void
@@ -206,12 +197,7 @@ retro_glsl_filter_finalize (GObject *object)
 {
   RetroGLSLFilter *self = (RetroGLSLFilter *) object;
 
-  if (self->vertex != NULL)
-    g_bytes_unref (self->vertex);
-  if (self->fragment != NULL)
-    g_bytes_unref (self->fragment);
-  glDeleteProgram (self->program);
-  self->program = 0;
+  g_clear_object (&self->shader);
 
   G_OBJECT_CLASS (retro_glsl_filter_parent_class)->finalize (object);
 }
@@ -229,172 +215,10 @@ retro_glsl_filter_init (RetroGLSLFilter *self)
 {
 }
 
-void
-retro_glsl_filter_apply_texture_params (RetroGLSLFilter *self)
-{
-  g_return_if_fail (RETRO_IS_GLSL_FILTER (self));
-
-  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, self->wrap);
-  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, self->wrap);
-  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, self->filter);
-  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, self->filter);
-}
-
-static GLuint
-create_shader (GBytes  *source_bytes,
-               GLenum   shader_type,
-               GError **error)
-{
-  const gchar *source;
-  gint size;
-  GLuint shader;
-  gint status;
-  gint log_length;
-  gchar *buffer;
-
-  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);
-
-  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,
-                                   GError          **error)
-{
-  gint status;
-  gint log_length;
-  gchar *buffer;
-  GLuint vertex_shader;
-  GLuint fragment_shader;
-  GError *inner_error = NULL;
-
-  g_return_if_fail (RETRO_IS_GLSL_FILTER (self));
-  g_return_if_fail (self->program == 0);
-
-  vertex_shader = create_shader (self->vertex, GL_VERTEX_SHADER, &inner_error);
-  if (G_UNLIKELY (inner_error != NULL)) {
-    g_propagate_error (error, inner_error);
-    self->program = 0;
-
-    return;
-  }
-
-  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);
-    self->program = 0;
-
-    return;
-  }
-
-  self->program = glCreateProgram();
-  glAttachShader (self->program, vertex_shader);
-  glAttachShader (self->program, 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 (vertex_shader);
-    glDeleteShader (fragment_shader);
-    glDeleteProgram (self->program);
-    self->program = 0;
-
-    return;
-  }
-
-  glDetachShader (self->program, vertex_shader);
-  glDetachShader (self->program, fragment_shader);
-}
-
-void
-retro_glsl_filter_use_program (RetroGLSLFilter *self)
+RetroGLSLShader *
+retro_glsl_filter_get_shader (RetroGLSLFilter *self)
 {
-  g_return_if_fail (RETRO_IS_GLSL_FILTER (self));
-  g_return_if_fail (self->program != 0);
-
-  glUseProgram (self->program);
-}
-
-void
-retro_glsl_filter_set_attribute_pointer (RetroGLSLFilter *self,
-                                         const gchar     *name,
-                                         GLint            size,
-                                         GLenum           type,
-                                         GLboolean        normalized,
-                                         GLsizei          stride,
-                                         const GLvoid    *pointer)
-{
-  GLint location;
-
-  g_return_if_fail (RETRO_IS_GLSL_FILTER (self));
-  g_return_if_fail (self->program != 0);
-
-  location = glGetAttribLocation (self->program, name);
-  glVertexAttribPointer (location, size, type, normalized, stride, pointer);
-  glEnableVertexAttribArray (location);
-}
-
-
-void
-retro_glsl_filter_set_uniform_1f (RetroGLSLFilter *self,
-                                  const gchar     *name,
-                                  gfloat           v0)
-{
-  GLint location;
-
-  g_return_if_fail (RETRO_IS_GLSL_FILTER (self));
-  g_return_if_fail (self->program != 0);
-
-  location = glGetUniformLocation (self->program, name);
-  glUniform1f (location, v0);
-}
-
-void
-retro_glsl_filter_set_uniform_4f (RetroGLSLFilter *self,
-                                  const gchar     *name,
-                                  gfloat           v0,
-                                  gfloat           v1,
-                                  gfloat           v2,
-                                  gfloat           v3)
-{
-  GLint location;
-
-  g_return_if_fail (RETRO_IS_GLSL_FILTER (self));
-  g_return_if_fail (self->program != 0);
+  g_return_val_if_fail (RETRO_IS_GLSL_FILTER (self), NULL);
 
-  location = glGetUniformLocation (self->program, name);
-  glUniform4f (location, v0, v1, v2, v3);
+  return self->shader;
 }


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