[gtk] gl renderer: Only compile the vertex shader once



commit b0a8b7da631af595326d6410c0f243a5623a5cfe
Author: Timm Bäder <mail baedert org>
Date:   Sun Jan 6 06:55:31 2019 +0100

    gl renderer: Only compile the vertex shader once
    
    All our programs use the same vertex shader, so don't compile it over
    and over again. This improves startup times by at least 0.001%, I swear.

 gsk/gl/gskglrenderer.c           | 31 +++++++++++++++++--------------
 gsk/gl/gskshaderbuilder.c        | 40 +++++++++++++++++++++++++++++-----------
 gsk/gl/gskshaderbuilderprivate.h |  5 ++++-
 3 files changed, 50 insertions(+), 26 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 11cca74318..945c4dfc5a 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -1994,20 +1994,19 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
   int i;
   static const struct {
     const char *name;
-    const char *vs;
     const char *fs;
   } program_definitions[] = {
-    { "blit",            "blit.vs.glsl",  "blit.fs.glsl" },
-    { "color",           "blit.vs.glsl",  "color.fs.glsl" },
-    { "coloring",        "blit.vs.glsl",  "coloring.fs.glsl" },
-    { "color matrix",    "blit.vs.glsl",  "color_matrix.fs.glsl" },
-    { "linear gradient", "blit.vs.glsl",  "linear_gradient.fs.glsl" },
-    { "blur",            "blit.vs.glsl",  "blur.fs.glsl" },
-    { "inset shadow",    "blit.vs.glsl",  "inset_shadow.fs.glsl" },
-    { "outset shadow",   "blit.vs.glsl",  "outset_shadow.fs.glsl" },
-    { "unblurred outset shadow",   "blit.vs.glsl",  "unblurred_outset_shadow.fs.glsl" },
-    { "border",          "blit.vs.glsl",  "border.fs.glsl" },
-    { "cross fade",      "blit.vs.glsl",  "cross_fade.fs.glsl" },
+    { "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" },
   };
 
   builder = gsk_shader_builder_new ();
@@ -2048,13 +2047,17 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
     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].vs,
                                                     program_definitions[i].fs,
                                                     &shader_error);
 
@@ -2063,7 +2066,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
           g_propagate_prefixed_error (error, shader_error,
                                       "Unable to create '%s' program (from %s and %s):\n",
                                       program_definitions[i].name,
-                                      program_definitions[i].vs,
+                                      "blit.vs.glsl",
                                       program_definitions[i].fs);
 
           g_object_unref (builder);
diff --git a/gsk/gl/gskshaderbuilder.c b/gsk/gl/gskshaderbuilder.c
index a352a0efec..dc00371889 100644
--- a/gsk/gl/gskshaderbuilder.c
+++ b/gsk/gl/gskshaderbuilder.c
@@ -15,6 +15,9 @@ struct _GskShaderBuilder
   char *vertex_preamble;
   char *fragment_preamble;
 
+
+  int common_vertex_shader_id;
+
   int version;
 
   GPtrArray *defines;
@@ -37,6 +40,9 @@ gsk_shader_builder_finalize (GObject *gobject)
 
   g_clear_pointer (&self->defines, g_ptr_array_unref);
 
+  if (self->common_vertex_shader_id > 0)
+    glDeleteShader (self->common_vertex_shader_id);
+
   G_OBJECT_CLASS (gsk_shader_builder_parent_class)->finalize (gobject);
 }
 
@@ -230,27 +236,39 @@ gsk_shader_builder_compile_shader (GskShaderBuilder *builder,
   return shader_id;
 }
 
+void
+gsk_shader_builder_set_common_vertex_shader (GskShaderBuilder  *self,
+                                             const char        *vertex_shader,
+                                             GError           **error)
+{
+  int shader_id;
+
+
+  shader_id = gsk_shader_builder_compile_shader (self,
+                                                 GL_VERTEX_SHADER,
+                                                 self->vertex_preamble,
+                                                 vertex_shader,
+                                                 error);
+
+  g_assert (shader_id > 0);
+  self->common_vertex_shader_id = shader_id;
+}
+
 int
 gsk_shader_builder_create_program (GskShaderBuilder *builder,
-                                   const char       *vertex_shader,
                                    const char       *fragment_shader,
                                    GError          **error)
 {
-  int vertex_id, fragment_id;
+  int vertex_id;
+  int fragment_id;
   int program_id;
   int status;
 
   g_return_val_if_fail (GSK_IS_SHADER_BUILDER (builder), -1);
-  g_return_val_if_fail (vertex_shader != NULL, -1);
   g_return_val_if_fail (fragment_shader != NULL, -1);
+  g_return_val_if_fail (builder->common_vertex_shader_id != 0, -1);
 
-  vertex_id = gsk_shader_builder_compile_shader (builder, GL_VERTEX_SHADER,
-                                                 builder->vertex_preamble,
-                                                 vertex_shader,
-                                                 error);
-  if (vertex_id < 0)
-    return -1;
-
+  vertex_id = builder->common_vertex_shader_id;
   fragment_id = gsk_shader_builder_compile_shader (builder, GL_FRAGMENT_SHADER,
                                                    builder->fragment_preamble,
                                                    fragment_shader,
@@ -290,8 +308,8 @@ gsk_shader_builder_create_program (GskShaderBuilder *builder,
 out:
   if (vertex_id > 0)
     {
+      /* We delete the common vertex shader when destroying the shader builder */
       glDetachShader (program_id, vertex_id);
-      glDeleteShader (vertex_id);
     }
 
   if (fragment_id > 0)
diff --git a/gsk/gl/gskshaderbuilderprivate.h b/gsk/gl/gskshaderbuilderprivate.h
index 73f44736fa..025d7a2028 100644
--- a/gsk/gl/gskshaderbuilderprivate.h
+++ b/gsk/gl/gskshaderbuilderprivate.h
@@ -25,8 +25,11 @@ void                    gsk_shader_builder_add_define                   (GskShad
                                                                          const char       *define_name,
                                                                          const char       *define_value);
 
+void                    gsk_shader_builder_set_common_vertex_shader     (GskShaderBuilder  *self,
+                                                                         const char        *vertex_shader,
+                                                                         GError           **error);
+
 int                     gsk_shader_builder_create_program               (GskShaderBuilder *builder,
-                                                                         const char       *vertex_shader,
                                                                          const char       *fragment_shader,
                                                                          GError          **error);
 


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