[gtk/wip/baedert/gl-rework: 126/176] gl renderer: Rewrite shader builder



commit 2f20db6d850feec87eb65c08ea7dbc4057dfe495
Author: Timm Bäder <mail baedert org>
Date:   Sat Dec 14 22:06:12 2019 +0100

    gl renderer: Rewrite shader builder
    
    Use a unified approach to write both vertex and fragment shader in the
    same file.

 gsk/gl/gskglrenderer.c                             | 119 ++++----
 gsk/gl/gskglshaderbuilder.c                        | 198 ++++++++++++
 gsk/gl/gskglshaderbuilderprivate.h                 |  38 +++
 gsk/gl/gskshaderbuilder.c                          | 334 ---------------------
 gsk/gl/gskshaderbuilderprivate.h                   |  39 ---
 gsk/meson.build                                    |  37 +--
 gsk/resources/glsl/{blend.fs.glsl => blend.glsl}   |  76 ++---
 gsk/resources/glsl/blit.fs.glsl                    |   5 -
 gsk/resources/glsl/blit.glsl                       |  13 +
 gsk/resources/glsl/blit.vs.glsl                    |   5 -
 gsk/resources/glsl/{blur.fs.glsl => blur.glsl}     |   8 +
 gsk/resources/glsl/{border.fs.glsl => border.glsl} |   9 +
 gsk/resources/glsl/color.fs.glsl                   |   9 -
 gsk/resources/glsl/color.glsl                      |  18 ++
 .../{color_matrix.fs.glsl => color_matrix.glsl}    |   8 +
 .../glsl/{coloring.fs.glsl => coloring.glsl}       |   8 +
 .../glsl/{cross_fade.fs.glsl => cross_fade.glsl}   |   7 +
 gsk/resources/glsl/es2_common.fs.glsl              | 103 -------
 gsk/resources/glsl/es2_common.vs.glsl              |   9 -
 gsk/resources/glsl/gl3_common.vs.glsl              |   7 -
 gsk/resources/glsl/gl_common.fs.glsl               | 100 ------
 gsk/resources/glsl/gl_common.vs.glsl               |   7 -
 .../{inset_shadow.fs.glsl => inset_shadow.glsl}    |   9 +-
 ...inear_gradient.fs.glsl => linear_gradient.glsl} |   8 +
 .../{outset_shadow.fs.glsl => outset_shadow.glsl}  |   8 +
 .../glsl/{gl3_common.fs.glsl => preamble.fs.glsl}  |  22 +-
 gsk/resources/glsl/preamble.vs.glsl                |  17 ++
 gsk/resources/glsl/{repeat.fs.glsl => repeat.glsl} |   8 +
 ...shadow.fs.glsl => unblurred_outset_shadow.glsl} |   8 +
 29 files changed, 477 insertions(+), 760 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 7f77670977..999120cb01 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -10,7 +10,7 @@
 #include "gskrendererprivate.h"
 #include "gskrendernodeprivate.h"
 #include "gsktransformprivate.h"
-#include "gskshaderbuilderprivate.h"
+#include "gskglshaderbuilderprivate.h"
 #include "gskglglyphcacheprivate.h"
 #include "gskgliconcacheprivate.h"
 #include "gskglrenderopsprivate.h"
@@ -411,19 +411,19 @@ struct _GskGLRenderer
   union {
     Program programs[GL_N_PROGRAMS];
     struct {
+      Program blend_program;
       Program blit_program;
+      Program blur_program;
+      Program border_program;
+      Program color_matrix_program;
       Program color_program;
       Program coloring_program;
-      Program color_matrix_program;
-      Program linear_gradient_program;
-      Program blur_program;
+      Program cross_fade_program;
       Program inset_shadow_program;
+      Program linear_gradient_program;
       Program outset_shadow_program;
-      Program unblurred_outset_shadow_program;
-      Program border_program;
-      Program cross_fade_program;
-      Program blend_program;
       Program repeat_program;
+      Program unblurred_outset_shadow_program;
     };
   };
 
@@ -2677,92 +2677,76 @@ static gboolean
 gsk_gl_renderer_create_programs (GskGLRenderer  *self,
                                  GError        **error)
 {
-  GskShaderBuilder *builder;
-  GError *shader_error = NULL;
+  GskGLShaderBuilder shader_builder;
   int i;
   static const struct {
+    const char *resource_path;
     const char *name;
-    const char *fs;
-    const char *vs;
   } program_definitions[] = {
-    { "blit",                      "blit.fs.glsl" },
-    { "color",                     "color.fs.glsl" },
-    { "coloring",                  "coloring.fs.glsl" },
-    { "color matrix",              "color_matrix.fs.glsl" },
-    { "linear gradient",           "linear_gradient.fs.glsl" },
-    { "blur",                      "blur.fs.glsl" },
-    { "inset shadow",              "inset_shadow.fs.glsl" },
-    { "outset shadow",             "outset_shadow.fs.glsl" },
-    { "unblurred outset shadow",   "unblurred_outset_shadow.fs.glsl" },
-    { "border",                    "border.fs.glsl" },
-    { "cross fade",                "cross_fade.fs.glsl" },
-    { "blend",                     "blend.fs.glsl" },
-    { "repeat",                    "repeat.fs.glsl" },
+    { "/org/gtk/libgsk/glsl/blend.glsl",                     "blend" },
+    { "/org/gtk/libgsk/glsl/blit.glsl",                      "blit" },
+    { "/org/gtk/libgsk/glsl/blur.glsl",                      "blur" },
+    { "/org/gtk/libgsk/glsl/border.glsl",                    "border" },
+    { "/org/gtk/libgsk/glsl/color_matrix.glsl",              "color matrix" },
+    { "/org/gtk/libgsk/glsl/color.glsl",                     "color" },
+    { "/org/gtk/libgsk/glsl/coloring.glsl",                  "coloring" },
+    { "/org/gtk/libgsk/glsl/cross_fade.glsl",                "cross fade" },
+    { "/org/gtk/libgsk/glsl/inset_shadow.glsl",              "inset shadow" },
+    { "/org/gtk/libgsk/glsl/linear_gradient.glsl",           "linear gradient" },
+    { "/org/gtk/libgsk/glsl/outset_shadow.glsl",             "outset shadow" },
+    { "/org/gtk/libgsk/glsl/repeat.glsl",                    "repeat" },
+    { "/org/gtk/libgsk/glsl/unblurred_outset_shadow.glsl",   "unblurred_outset shadow" },
   };
+  gboolean success = TRUE;
+
+  gsk_gl_shader_builder_init (&shader_builder,
+                              "/org/gtk/libgsk/glsl/preamble.vs.glsl",
+                              "/org/gtk/libgsk/glsl/preamble.fs.glsl");
 
-  builder = gsk_shader_builder_new ();
+  g_assert (G_N_ELEMENTS (program_definitions) == GL_N_PROGRAMS);
 
-  gsk_shader_builder_set_resource_base_path (builder, "/org/gtk/libgsk/glsl");
+#ifdef G_ENABLE_DEBUG
+  if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), SHADERS))
+    shader_builder.debugging = TRUE;
+#endif
 
   if (gdk_gl_context_get_use_es (self->gl_context))
     {
-      gsk_shader_builder_set_version (builder, SHADER_VERSION_GLES);
-      gsk_shader_builder_set_vertex_preamble (builder, "es2_common.vs.glsl");
-      gsk_shader_builder_set_fragment_preamble (builder, "es2_common.fs.glsl");
-      gsk_shader_builder_add_define (builder, "GSK_GLES", "1");
+
+      gsk_gl_shader_builder_set_glsl_version (&shader_builder, SHADER_VERSION_GLES);
+      shader_builder.gles = TRUE;
     }
   else if (gdk_gl_context_is_legacy (self->gl_context))
     {
       int maj, min;
+
       gdk_gl_context_get_version (self->gl_context, &maj, &min);
 
       if (maj == 3)
-        gsk_shader_builder_set_version (builder, SHADER_VERSION_GL3_LEGACY);
+        gsk_gl_shader_builder_set_glsl_version (&shader_builder, SHADER_VERSION_GL3_LEGACY);
       else
-        gsk_shader_builder_set_version (builder, SHADER_VERSION_GL2_LEGACY);
+        gsk_gl_shader_builder_set_glsl_version (&shader_builder, SHADER_VERSION_GL2_LEGACY);
 
-      gsk_shader_builder_set_vertex_preamble (builder, "gl_common.vs.glsl");
-      gsk_shader_builder_set_fragment_preamble (builder, "gl_common.fs.glsl");
-      gsk_shader_builder_add_define (builder, "GSK_LEGACY", "1");
+      shader_builder.legacy = TRUE;
     }
   else
     {
-      gsk_shader_builder_set_version (builder, SHADER_VERSION_GL3);
-      gsk_shader_builder_set_vertex_preamble (builder, "gl3_common.vs.glsl");
-      gsk_shader_builder_set_fragment_preamble (builder, "gl3_common.fs.glsl");
-      gsk_shader_builder_add_define (builder, "GSK_GL3", "1");
+      gsk_gl_shader_builder_set_glsl_version (&shader_builder, SHADER_VERSION_GL3);
+      shader_builder.gl3 = TRUE;
     }
 
-#ifdef G_ENABLE_DEBUG
-  if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), SHADERS))
-    gsk_shader_builder_add_define (builder, "GSK_DEBUG", "1");
-#endif
-
-  gsk_shader_builder_set_common_vertex_shader (builder, "blit.vs.glsl",
-                                               &shader_error);
-
-  g_assert_no_error (shader_error);
-
   for (i = 0; i < GL_N_PROGRAMS; i ++)
     {
       Program *prog = &self->programs[i];
 
       prog->index = i;
-      prog->id = gsk_shader_builder_create_program (builder,
-                                                    program_definitions[i].fs,
-                                                    program_definitions[i].vs,
-                                                    &shader_error);
-
-      if (shader_error != NULL)
+      prog->id = gsk_gl_shader_builder_create_program (&shader_builder,
+                                                       program_definitions[i].resource_path,
+                                                       error);
+      if (prog->id < 0)
         {
-          g_propagate_prefixed_error (error, shader_error,
-                                      "Unable to create '%s' program (from %s and %s):\n",
-                                      program_definitions[i].name,
-                                      program_definitions[i].fs,
-                                      program_definitions[i].vs);
-
-          g_object_unref (builder);
-          return FALSE;
+          success = FALSE;
+          goto out;
         }
 
       INIT_COMMON_UNIFORM_LOCATION (prog, alpha);
@@ -2772,7 +2756,6 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
       INIT_COMMON_UNIFORM_LOCATION (prog, projection);
       INIT_COMMON_UNIFORM_LOCATION (prog, modelview);
     }
-
   /* color */
   INIT_PROGRAM_UNIFORM_LOCATION (color, color);
 
@@ -2827,8 +2810,10 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
   INIT_PROGRAM_UNIFORM_LOCATION (repeat, child_bounds);
   INIT_PROGRAM_UNIFORM_LOCATION (repeat, texture_rect);
 
-  g_object_unref (builder);
-  return TRUE;
+out:
+  gsk_gl_shader_builder_finish (&shader_builder);
+
+  return success;
 }
 
 static GskGLTextureAtlases *
diff --git a/gsk/gl/gskglshaderbuilder.c b/gsk/gl/gskglshaderbuilder.c
new file mode 100644
index 0000000000..f28bf127f7
--- /dev/null
+++ b/gsk/gl/gskglshaderbuilder.c
@@ -0,0 +1,198 @@
+#include "config.h"
+
+#include "gskglshaderbuilderprivate.h"
+
+#include "gskdebugprivate.h"
+
+#include <gdk/gdk.h>
+#include <epoxy/gl.h>
+
+void
+gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
+                            const char         *vs_preamble_resource_path,
+                            const char         *fs_preamble_resource_path)
+{
+  memset (self, 0, sizeof (*self));
+
+  self->vs_preamble = g_resources_lookup_data (vs_preamble_resource_path, 0, NULL);
+  self->fs_preamble = g_resources_lookup_data (fs_preamble_resource_path, 0, NULL);
+
+  g_assert (self->vs_preamble);
+  g_assert (self->fs_preamble);
+}
+
+void
+gsk_gl_shader_builder_finish (GskGLShaderBuilder *self)
+{
+  g_bytes_unref (self->vs_preamble);
+  g_bytes_unref (self->fs_preamble);
+}
+
+void
+gsk_gl_shader_builder_set_glsl_version (GskGLShaderBuilder *self,
+                                        int                 version)
+{
+  self->version = version;
+}
+
+static gboolean
+check_shader_error (int     shader_id,
+                    GError **error)
+{
+  int status;
+  int log_len;
+  char *buffer;
+  int code_len;
+  char *code;
+
+  glGetShaderiv (shader_id, GL_COMPILE_STATUS, &status);
+
+  if (G_LIKELY (status == GL_TRUE))
+    return TRUE;
+
+  glGetShaderiv (shader_id, GL_INFO_LOG_LENGTH, &log_len);
+  buffer = g_malloc0 (log_len + 1);
+  glGetShaderInfoLog (shader_id, log_len, NULL, buffer);
+
+  glGetShaderiv (shader_id, GL_SHADER_SOURCE_LENGTH, &code_len);
+  code = g_malloc0 (code_len + 1);
+  glGetShaderSource (shader_id, code_len, NULL, code);
+
+  g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_COMPILATION_FAILED,
+               "Compilation failure in shader.\nError message: %s\n\nSource code:\n%s\n\n",
+               buffer,
+               code);
+
+  g_free (buffer);
+  g_free (code);
+
+  return FALSE;
+}
+
+int
+gsk_gl_shader_builder_create_program (GskGLShaderBuilder  *self,
+                                      const char          *resource_path,
+                                      GError             **error)
+{
+
+  GBytes *source_bytes = g_resources_lookup_data (resource_path, 0, NULL);
+  char version_buffer[64];
+  const char *source;
+  const char *vertex_shader_start;
+  const char *fragment_shader_start;
+  int vertex_id;
+  int fragment_id;
+  int program_id = -1;
+  int status;
+
+  g_assert (source_bytes);
+
+  source = g_bytes_get_data (source_bytes, NULL);
+  vertex_shader_start = strstr (source, "VERTEX_SHADER");
+  fragment_shader_start = strstr (source, "FRAGMENT_SHADER");
+
+  g_assert (vertex_shader_start);
+  g_assert (fragment_shader_start);
+
+  /* They both start at the next newline */
+  vertex_shader_start = strstr (vertex_shader_start, "\n");
+  fragment_shader_start = strstr (fragment_shader_start, "\n");
+
+  g_snprintf (version_buffer, sizeof (version_buffer),
+              "#version %d\n", self->version);
+
+  vertex_id = glCreateShader (GL_VERTEX_SHADER);
+  glShaderSource (vertex_id, 7,
+                  (const char *[]) {
+                    version_buffer,
+                    self->debugging ? "#define GSK_DEBUG 1\n" : "",
+                    self->legacy ? "#define GSK_LEGACY 1\n" : "",
+                    self->gl3 ? "#define GSK_GL3 1\n" : "",
+                    self->gles ? "#define GSK_GLES 1\n" : "",
+                    g_bytes_get_data (self->vs_preamble, NULL),
+                    vertex_shader_start
+                  },
+                  (int[]) {
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    fragment_shader_start - vertex_shader_start
+                  });
+  glCompileShader (vertex_id);
+
+  if (!check_shader_error (vertex_id, error))
+    {
+      glDeleteShader (vertex_id);
+      goto out;
+    }
+
+  fragment_id = glCreateShader (GL_FRAGMENT_SHADER);
+  glShaderSource (fragment_id, 7,
+                  (const char *[]) {
+                    version_buffer,
+                    self->debugging ? "#define GSK_DEBUG 1\n" : "",
+                    self->legacy ? "#define GSK_LEGACY 1\n" : "",
+                    self->gl3 ? "#define GSK_GL3 1\n" : "",
+                    self->gles ? "#define GSK_GLES 1\n" : "",
+                    g_bytes_get_data (self->fs_preamble, NULL),
+                    fragment_shader_start
+                  },
+                  (int[]) {
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                  });
+  glCompileShader (fragment_id);
+
+  if (!check_shader_error (fragment_id, error))
+    {
+      glDeleteShader (fragment_id);
+      goto out;
+    }
+
+  program_id = glCreateProgram ();
+  glAttachShader (program_id, vertex_id);
+  glAttachShader (program_id, fragment_id);
+  glLinkProgram (program_id);
+
+  glGetProgramiv (program_id, GL_LINK_STATUS, &status);
+  if (status == GL_FALSE)
+    {
+      char *buffer = NULL;
+      int log_len = 0;
+
+      glGetProgramiv (program_id, GL_INFO_LOG_LENGTH, &log_len);
+
+      buffer = g_malloc0 (log_len + 1);
+      glGetProgramInfoLog (program_id, log_len, NULL, buffer);
+
+      g_warning ("Linking failure in shader:\n%s", buffer);
+      g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_LINK_FAILED,
+                   "Linking failure in shader: %s", buffer);
+
+      g_free (buffer);
+
+      glDeleteProgram (program_id);
+
+      goto out;
+    }
+
+  glDetachShader (program_id, vertex_id);
+  glDeleteShader (vertex_id);
+
+  glDetachShader (program_id, fragment_id);
+  glDeleteShader (fragment_id);
+
+out:
+  g_bytes_unref (source_bytes);
+
+  return program_id;
+}
+
diff --git a/gsk/gl/gskglshaderbuilderprivate.h b/gsk/gl/gskglshaderbuilderprivate.h
new file mode 100644
index 0000000000..209fa5ff91
--- /dev/null
+++ b/gsk/gl/gskglshaderbuilderprivate.h
@@ -0,0 +1,38 @@
+#ifndef __GSK_SHADER_BUILDER_PRIVATE_H__
+#define __GSK_SHADER_BUILDER_PRIVATE_H__
+
+#include <gdk/gdk.h>
+#include <graphene.h>
+
+G_BEGIN_DECLS
+
+typedef struct
+{
+  GBytes *vs_preamble;
+  GBytes *fs_preamble;
+
+  int version;
+
+  guint debugging: 1;
+  guint gles: 1;
+  guint gl3: 1;
+  guint legacy: 1;
+
+} GskGLShaderBuilder;
+
+
+void   gsk_gl_shader_builder_init             (GskGLShaderBuilder  *self,
+                                               const char          *vs_preamble_resource_path,
+                                               const char          *fs_preamble_resource_path);
+void   gsk_gl_shader_builder_finish           (GskGLShaderBuilder  *self);
+
+void   gsk_gl_shader_builder_set_glsl_version (GskGLShaderBuilder  *self,
+                                               int                  version);
+
+int    gsk_gl_shader_builder_create_program   (GskGLShaderBuilder  *self,
+                                               const char          *resource_path,
+                                               GError             **error);
+
+G_END_DECLS
+
+#endif /* __GSK_SHADER_BUILDER_PRIVATE_H__ */
diff --git a/gsk/meson.build b/gsk/meson.build
index c897cabdf6..6dd4925155 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -1,24 +1,19 @@
 gsk_private_gl_shaders = [
-  'resources/glsl/blit.fs.glsl',
-  'resources/glsl/blit.vs.glsl',
-  'resources/glsl/color.fs.glsl',
-  'resources/glsl/coloring.fs.glsl',
-  'resources/glsl/color_matrix.fs.glsl',
-  'resources/glsl/linear_gradient.fs.glsl',
-  'resources/glsl/blur.fs.glsl',
-  'resources/glsl/inset_shadow.fs.glsl',
-  'resources/glsl/outset_shadow.fs.glsl',
-  'resources/glsl/unblurred_outset_shadow.fs.glsl',
-  'resources/glsl/border.fs.glsl',
-  'resources/glsl/cross_fade.fs.glsl',
-  'resources/glsl/blend.fs.glsl',
-  'resources/glsl/repeat.fs.glsl',
-  'resources/glsl/es2_common.fs.glsl',
-  'resources/glsl/es2_common.vs.glsl',
-  'resources/glsl/gl3_common.fs.glsl',
-  'resources/glsl/gl3_common.vs.glsl',
-  'resources/glsl/gl_common.fs.glsl',
-  'resources/glsl/gl_common.vs.glsl',
+  'resources/glsl/preamble.fs.glsl',
+  'resources/glsl/preamble.vs.glsl',
+  'resources/glsl/border.glsl',
+  'resources/glsl/blit.glsl',
+  'resources/glsl/coloring.glsl',
+  'resources/glsl/color.glsl',
+  'resources/glsl/linear_gradient.glsl',
+  'resources/glsl/color_matrix.glsl',
+  'resources/glsl/blur.glsl',
+  'resources/glsl/inset_shadow.glsl',
+  'resources/glsl/outset_shadow.glsl',
+  'resources/glsl/unblurred_outset_shadow.glsl',
+  'resources/glsl/cross_fade.glsl',
+  'resources/glsl/blend.glsl',
+  'resources/glsl/repeat.glsl',
 ]
 
 gsk_public_sources = files([
@@ -38,7 +33,7 @@ gsk_private_sources = files([
   'gskdebug.c',
   'gskprivate.c',
   'gskprofiler.c',
-  'gl/gskshaderbuilder.c',
+  'gl/gskglshaderbuilder.c',
   'gl/gskglprofiler.c',
   'gl/gskglglyphcache.c',
   'gl/gskglimage.c',
diff --git a/gsk/resources/glsl/blend.fs.glsl b/gsk/resources/glsl/blend.glsl
similarity index 84%
rename from gsk/resources/glsl/blend.fs.glsl
rename to gsk/resources/glsl/blend.glsl
index 249b8fe6e4..f1e0c49b5e 100644
--- a/gsk/resources/glsl/blend.fs.glsl
+++ b/gsk/resources/glsl/blend.glsl
@@ -1,3 +1,11 @@
+// VERTEX_SHADER:
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
 uniform int u_mode;
 uniform sampler2D u_source2;
 
@@ -264,73 +272,39 @@ void main() {
 
   vec4 result;
   if (u_mode == 0)
-    {
-      result = normal(top_color, bottom_color);
-    }
+    result = normal(top_color, bottom_color);
   else if (u_mode == 1)
-    {
-      result = multiply(top_color, bottom_color);
-    }
+    result = multiply(top_color, bottom_color);
   else if (u_mode == 2)
-    {
-      result = screen(top_color, bottom_color);
-    }
+    result = screen(top_color, bottom_color);
   else if (u_mode == 3)
-    {
-      result = overlay(top_color, bottom_color);
-    }
+    result = overlay(top_color, bottom_color);
   else if (u_mode == 4)
-    {
-      result = darken(top_color, bottom_color);
-    }
+    result = darken(top_color, bottom_color);
   else if (u_mode == 5)
-    {
-      result = lighten(top_color, bottom_color);
-    }
+    result = lighten(top_color, bottom_color);
   else if (u_mode == 6)
-    {
-      result = color_dodge(top_color, bottom_color);
-    }
+    result = color_dodge(top_color, bottom_color);
   else if (u_mode == 7)
-    {
-      result = color_burn(top_color, bottom_color);
-    }
+    result = color_burn(top_color, bottom_color);
   else if (u_mode == 8)
-    {
-      result = hard_light(top_color, bottom_color);
-    }
+    result = hard_light(top_color, bottom_color);
   else if (u_mode == 9)
-    {
-      result = soft_light(top_color, bottom_color);
-    }
+    result = soft_light(top_color, bottom_color);
   else if (u_mode == 10)
-    {
-      result = difference(top_color, bottom_color);
-    }
+    result = difference(top_color, bottom_color);
   else if (u_mode == 11)
-    {
-      result = exclusion(top_color, bottom_color);
-    }
+    result = exclusion(top_color, bottom_color);
   else if (u_mode == 12)
-    {
-      result = color(top_color, bottom_color);
-    }
+    result = color(top_color, bottom_color);
   else if (u_mode == 13)
-    {
-      result = hue(top_color, bottom_color);
-    }
+    result = hue(top_color, bottom_color);
   else if (u_mode == 14)
-    {
-      result = saturation(top_color, bottom_color);
-    }
+    result = saturation(top_color, bottom_color);
   else if (u_mode == 15)
-    {
-      result = luminosity(top_color, bottom_color);
-    }
+    result = luminosity(top_color, bottom_color);
   else
-    {
-      discard;
-    }
+    discard;
 
   setOutputColor(result * u_alpha);
 }
diff --git a/gsk/resources/glsl/blit.glsl b/gsk/resources/glsl/blit.glsl
new file mode 100644
index 0000000000..0f9fe10067
--- /dev/null
+++ b/gsk/resources/glsl/blit.glsl
@@ -0,0 +1,13 @@
+// VERTEX_SHADER:
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
+void main() {
+  vec4 diffuse = Texture(u_source, vUv);
+
+  setOutputColor(diffuse * u_alpha);
+}
diff --git a/gsk/resources/glsl/blur.fs.glsl b/gsk/resources/glsl/blur.glsl
similarity index 89%
rename from gsk/resources/glsl/blur.fs.glsl
rename to gsk/resources/glsl/blur.glsl
index e4df8fd704..4b0109bbfc 100644
--- a/gsk/resources/glsl/blur.fs.glsl
+++ b/gsk/resources/glsl/blur.glsl
@@ -1,3 +1,11 @@
+// VERTEX_SHADER:
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
 uniform float u_blur_radius;
 uniform vec2 u_blur_size;
 uniform vec2 u_blur_dir;
diff --git a/gsk/resources/glsl/border.fs.glsl b/gsk/resources/glsl/border.glsl
similarity index 77%
rename from gsk/resources/glsl/border.fs.glsl
rename to gsk/resources/glsl/border.glsl
index d83fb23828..e919461cce 100644
--- a/gsk/resources/glsl/border.fs.glsl
+++ b/gsk/resources/glsl/border.glsl
@@ -1,3 +1,12 @@
+// VERTEX_SHADER:
+
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
 uniform vec4 u_color;
 uniform vec4 u_widths;
 uniform RoundedRect u_outline_rect;
diff --git a/gsk/resources/glsl/color.glsl b/gsk/resources/glsl/color.glsl
new file mode 100644
index 0000000000..8163dddfd0
--- /dev/null
+++ b/gsk/resources/glsl/color.glsl
@@ -0,0 +1,18 @@
+// VERTEX_SHADER:
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
+uniform vec4 u_color;
+
+void main() {
+  vec4 color = u_color;
+
+  // Pre-multiply alpha
+  color.rgb *= color.a;
+  setOutputColor(color * u_alpha);
+}
+
diff --git a/gsk/resources/glsl/color_matrix.fs.glsl b/gsk/resources/glsl/color_matrix.glsl
similarity index 70%
rename from gsk/resources/glsl/color_matrix.fs.glsl
rename to gsk/resources/glsl/color_matrix.glsl
index 284e0a9e65..7904eae70c 100644
--- a/gsk/resources/glsl/color_matrix.fs.glsl
+++ b/gsk/resources/glsl/color_matrix.glsl
@@ -1,3 +1,11 @@
+// VERTEX_SHADER:
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
 uniform mat4 u_color_matrix;
 uniform vec4 u_color_offset;
 
diff --git a/gsk/resources/glsl/coloring.fs.glsl b/gsk/resources/glsl/coloring.glsl
similarity index 68%
rename from gsk/resources/glsl/coloring.fs.glsl
rename to gsk/resources/glsl/coloring.glsl
index 9de8a13ba7..a61d9222b4 100644
--- a/gsk/resources/glsl/coloring.fs.glsl
+++ b/gsk/resources/glsl/coloring.glsl
@@ -1,3 +1,11 @@
+// VERTEX_SHADER:
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
 uniform vec4 u_color;
 
 void main() {
diff --git a/gsk/resources/glsl/cross_fade.fs.glsl b/gsk/resources/glsl/cross_fade.glsl
similarity index 69%
rename from gsk/resources/glsl/cross_fade.fs.glsl
rename to gsk/resources/glsl/cross_fade.glsl
index 612673bf66..d3840423fa 100644
--- a/gsk/resources/glsl/cross_fade.fs.glsl
+++ b/gsk/resources/glsl/cross_fade.glsl
@@ -1,4 +1,11 @@
+// VERTEX_SHADER:
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
 
+// FRAGMENT_SHADER:
 uniform float u_progress;
 uniform sampler2D u_source2;
 
diff --git a/gsk/resources/glsl/inset_shadow.fs.glsl b/gsk/resources/glsl/inset_shadow.glsl
similarity index 79%
rename from gsk/resources/glsl/inset_shadow.fs.glsl
rename to gsk/resources/glsl/inset_shadow.glsl
index 44bd4d733d..fa0e46769b 100644
--- a/gsk/resources/glsl/inset_shadow.fs.glsl
+++ b/gsk/resources/glsl/inset_shadow.glsl
@@ -1,9 +1,16 @@
+// VERTEX_SHADER:
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
 uniform float u_spread;
 uniform vec4 u_color;
 uniform vec2 u_offset;
 uniform RoundedRect u_outline_rect;
 
-
 void main() {
   vec4 f = gl_FragCoord;
 
diff --git a/gsk/resources/glsl/linear_gradient.fs.glsl b/gsk/resources/glsl/linear_gradient.glsl
similarity index 89%
rename from gsk/resources/glsl/linear_gradient.fs.glsl
rename to gsk/resources/glsl/linear_gradient.glsl
index 0b1f1cc0c1..f0ba46517f 100644
--- a/gsk/resources/glsl/linear_gradient.fs.glsl
+++ b/gsk/resources/glsl/linear_gradient.glsl
@@ -1,3 +1,11 @@
+// VERTEX_SHADER:
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
 uniform vec4 u_color_stops[8];
 uniform float u_color_offsets[8];
 uniform int u_num_color_stops;
diff --git a/gsk/resources/glsl/outset_shadow.fs.glsl b/gsk/resources/glsl/outset_shadow.glsl
similarity index 66%
rename from gsk/resources/glsl/outset_shadow.fs.glsl
rename to gsk/resources/glsl/outset_shadow.glsl
index be8f78c297..150b5aafce 100644
--- a/gsk/resources/glsl/outset_shadow.fs.glsl
+++ b/gsk/resources/glsl/outset_shadow.glsl
@@ -1,3 +1,11 @@
+// VERTEX_SHADER:
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
 uniform RoundedRect u_outline_rect;
 
 void main() {
diff --git a/gsk/resources/glsl/gl3_common.fs.glsl b/gsk/resources/glsl/preamble.fs.glsl
similarity index 89%
rename from gsk/resources/glsl/gl3_common.fs.glsl
rename to gsk/resources/glsl/preamble.fs.glsl
index bdc2fc92aa..81ee188ef5 100644
--- a/gsk/resources/glsl/gl3_common.fs.glsl
+++ b/gsk/resources/glsl/preamble.fs.glsl
@@ -1,8 +1,11 @@
+
+#if GDK_GL3
 precision highp float;
+#endif
 
 uniform sampler2D u_source;
-uniform mat4 u_projection = mat4(1.0);
-uniform mat4 u_modelview = mat4(1.0);
+uniform mat4 u_projection;
+uniform mat4 u_modelview;
 uniform float u_alpha = 1.0;
 uniform vec4 u_viewport;
 
@@ -14,8 +17,15 @@ struct RoundedRect
 
 uniform RoundedRect u_clip_rect;
 
+#if GSK_GLES
+varying vec2 vUv;
+#elif GSK_LEGACY
+varying vec2 vUv;
+varying vec4 outputColor;
+#else
 in vec2 vUv;
 out vec4 outputColor;
+#endif
 
 float
 ellipsis_dist (vec2 p, vec2 radius)
@@ -103,7 +113,11 @@ rounded_rect_shrink (RoundedRect r, vec4 amount)
 }
 
 vec4 Texture(sampler2D sampler, vec2 texCoords) {
+#if GSK_GLES
+  return texture2D(sampler, texCoords);
+#else
   return texture(sampler, texCoords);
+#endif
 }
 
 void setOutputColor(vec4 color) {
@@ -112,6 +126,10 @@ void setOutputColor(vec4 color) {
   f.x += u_viewport.x;
   f.y = (u_viewport.y + u_viewport.w) - f.y;
 
+#if GSK_GLES
+  gl_FragColor = color * rounded_rect_coverage(u_clip_rect, f.xy);
+#else
   outputColor = color * rounded_rect_coverage(u_clip_rect, f.xy);
+#endif
   /*outputColor = color;*/
 }
diff --git a/gsk/resources/glsl/preamble.vs.glsl b/gsk/resources/glsl/preamble.vs.glsl
new file mode 100644
index 0000000000..2af42e58e1
--- /dev/null
+++ b/gsk/resources/glsl/preamble.vs.glsl
@@ -0,0 +1,17 @@
+uniform mat4 u_projection;
+uniform mat4 u_modelview;
+
+
+#if GSK_GLES
+attribute vec2 aPosition;
+attribute vec2 aUv;
+varying vec2 vUv;
+#elif GSK_LEGACY
+attribute vec2 aPosition;
+attribute vec2 aUv;
+varying vec2 vUv;
+#else
+in vec2 aPosition;
+in vec2 aUv;
+out vec2 vUv;
+#endif
diff --git a/gsk/resources/glsl/repeat.fs.glsl b/gsk/resources/glsl/repeat.glsl
similarity index 85%
rename from gsk/resources/glsl/repeat.fs.glsl
rename to gsk/resources/glsl/repeat.glsl
index 0bd973eea9..4f94ee3506 100644
--- a/gsk/resources/glsl/repeat.fs.glsl
+++ b/gsk/resources/glsl/repeat.glsl
@@ -1,3 +1,11 @@
+// VERTEX_SHADER:
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
 uniform vec4 u_child_bounds;
 uniform vec4 u_texture_rect;
 
diff --git a/gsk/resources/glsl/unblurred_outset_shadow.fs.glsl 
b/gsk/resources/glsl/unblurred_outset_shadow.glsl
similarity index 79%
rename from gsk/resources/glsl/unblurred_outset_shadow.fs.glsl
rename to gsk/resources/glsl/unblurred_outset_shadow.glsl
index ac37d0eadb..fa14f11629 100644
--- a/gsk/resources/glsl/unblurred_outset_shadow.fs.glsl
+++ b/gsk/resources/glsl/unblurred_outset_shadow.glsl
@@ -1,3 +1,11 @@
+// VERTEX_SHADER:
+void main() {
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+  vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
 uniform float u_spread;
 uniform vec4 u_color;
 uniform vec2 u_offset;


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