[mutter] cogl: Move some GL-specific GLSL details into the driver



commit 462df7e61a026b5c3b14d146c46e43bad0493b55
Author: Adam Jackson <ajax redhat com>
Date:   Thu Jan 16 15:37:38 2020 -0500

    cogl: Move some GL-specific GLSL details into the driver
    
    _cogl_shader_set_source_with_boilerplate and _cogl_shader_compile_real
    have enough GL assumptions that it makes sense to push them into the
    backend. Taken together their only callers are under driver/gl, so.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194

 cogl/cogl/cogl-glsl-shader-private.h               |  41 -----
 cogl/cogl/cogl-glsl-shader.c                       | 189 ---------------------
 cogl/cogl/deprecated/cogl-shader-private.h         |  12 --
 cogl/cogl/deprecated/cogl-shader.c                 |  96 -----------
 cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c   |   2 +-
 cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h |   9 +
 cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c   |  76 +++++++++
 cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c   | 146 +++++++++++++++-
 cogl/cogl/meson.build                              |   2 -
 9 files changed, 231 insertions(+), 342 deletions(-)
---
diff --git a/cogl/cogl/deprecated/cogl-shader-private.h b/cogl/cogl/deprecated/cogl-shader-private.h
index f19aaa22c8..ae47f18795 100644
--- a/cogl/cogl/deprecated/cogl-shader-private.h
+++ b/cogl/cogl/deprecated/cogl-shader-private.h
@@ -47,16 +47,4 @@ struct _CoglShader
   char *source;
 };
 
-void
-_cogl_shader_compile_real (CoglHandle handle,
-                           CoglPipeline *pipeline);
-
-void
-_cogl_shader_set_source_with_boilerplate (GLuint shader_gl_handle,
-                                          GLenum shader_gl_type,
-                                          int n_tex_coord_attribs,
-                                          GLsizei count_in,
-                                          const char **strings_in,
-                                          const GLint *lengths_in);
-
 #endif /* __COGL_SHADER_H */
diff --git a/cogl/cogl/deprecated/cogl-shader.c b/cogl/cogl/deprecated/cogl-shader.c
index 7015454775..ec899ce34f 100644
--- a/cogl/cogl/deprecated/cogl-shader.c
+++ b/cogl/cogl/deprecated/cogl-shader.c
@@ -32,7 +32,6 @@
 
 #include "cogl-context-private.h"
 #include "cogl-object-private.h"
-#include "cogl-glsl-shader-private.h"
 #include "cogl-glsl-shader-boilerplate.h"
 #include "driver/gl/cogl-util-gl-private.h"
 #include "deprecated/cogl-shader-private.h"
@@ -45,13 +44,6 @@ static void _cogl_shader_free (CoglShader *shader);
 
 COGL_HANDLE_DEFINE (Shader, shader);
 
-#ifndef GL_FRAGMENT_SHADER
-#define GL_FRAGMENT_SHADER 0x8B30
-#endif
-#ifndef GL_VERTEX_SHADER
-#define GL_VERTEX_SHADER 0x8B31
-#endif
-
 static void
 _cogl_shader_free (CoglShader *shader)
 {
@@ -91,23 +83,6 @@ cogl_create_shader (CoglShaderType type)
   return _cogl_shader_handle_new (shader);
 }
 
-static void
-delete_shader (CoglShader *shader)
-{
-  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
-  if (shader->gl_handle)
-    GE (ctx, glDeleteShader (shader->gl_handle));
-
-  shader->gl_handle = 0;
-
-  if (shader->compilation_pipeline)
-    {
-      cogl_object_unref (shader->compilation_pipeline);
-      shader->compilation_pipeline = NULL;
-    }
-}
-
 void
 cogl_shader_source (CoglHandle   handle,
                     const char  *source)
@@ -124,77 +99,6 @@ cogl_shader_source (CoglHandle   handle,
   shader->source = g_strdup (source);
 }
 
-void
-_cogl_shader_compile_real (CoglHandle handle,
-                           CoglPipeline *pipeline)
-{
-  CoglShader *shader = handle;
-  GLenum gl_type;
-  GLint status;
-
-  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
-  if (shader->gl_handle)
-    {
-      CoglPipeline *prev = shader->compilation_pipeline;
-
-      /* XXX: currently the only things that will affect the
-       * boilerplate for user shaders, apart from driver features,
-       * are the pipeline layer-indices and texture-unit-indices
-       */
-      if (pipeline == prev ||
-          _cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline))
-        return;
-    }
-
-  if (shader->gl_handle)
-    delete_shader (shader);
-
-  switch (shader->type)
-    {
-    case COGL_SHADER_TYPE_VERTEX:
-      gl_type = GL_VERTEX_SHADER;
-      break;
-    case COGL_SHADER_TYPE_FRAGMENT:
-      gl_type = GL_FRAGMENT_SHADER;
-      break;
-    default:
-      g_assert_not_reached ();
-      break;
-    }
-
-  shader->gl_handle = ctx->glCreateShader (gl_type);
-
-  _cogl_glsl_shader_set_source_with_boilerplate (ctx,
-                                                 shader->gl_handle,
-                                                 gl_type,
-                                                 pipeline,
-                                                 1,
-                                                 (const char **)
-                                                  &shader->source,
-                                                 NULL);
-
-  GE (ctx, glCompileShader (shader->gl_handle));
-
-  shader->compilation_pipeline = cogl_object_ref (pipeline);
-
-  GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
-  if (!status)
-    {
-      char buffer[512];
-      int len = 0;
-
-      ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
-      buffer[len] = '\0';
-
-      g_warning ("Failed to compile GLSL program:\n"
-                 "src:\n%s\n"
-                 "error:\n%s\n",
-                 shader->source,
-                 buffer);
-    }
-}
-
 CoglShaderType
 cogl_shader_get_type (CoglHandle  handle)
 {
diff --git a/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c 
b/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
index 0e95fb3909..4d754d9b33 100644
--- a/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
+++ b/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
@@ -43,11 +43,11 @@
 #include "cogl-snippet-private.h"
 #include "cogl-list.h"
 #include "driver/gl/cogl-util-gl-private.h"
+#include "driver/gl/cogl-pipeline-opengl-private.h"
 
 #include "cogl-context-private.h"
 #include "cogl-object-private.h"
 #include "cogl-pipeline-cache.h"
-#include "cogl-glsl-shader-private.h"
 #include "driver/gl/cogl-pipeline-fragend-glsl-private.h"
 #include "deprecated/cogl-shader-private.h"
 #include "deprecated/cogl-program-private.h"
diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h 
b/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h
index afcb4460ee..8cae99cc08 100644
--- a/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h
+++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h
@@ -146,5 +146,14 @@ _cogl_pipeline_flush_gl_state (CoglContext *context,
                                gboolean skip_gl_state,
                                gboolean unknown_color_alpha);
 
+void
+_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
+                                               GLuint shader_gl_handle,
+                                               GLenum shader_gl_type,
+                                               CoglPipeline *pipeline,
+                                               GLsizei count_in,
+                                               const char **strings_in,
+                                               const GLint *lengths_in);
+
 #endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */
 
diff --git a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c 
b/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c
index 3a049a70b0..8b318deb59 100644
--- a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c
+++ b/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c
@@ -633,6 +633,82 @@ _cogl_pipeline_progend_glsl_start (CoglPipeline *pipeline)
   return TRUE;
 }
 
+static void
+_cogl_shader_compile_real (CoglHandle handle,
+                           CoglPipeline *pipeline)
+{
+  CoglShader *shader = handle;
+  GLenum gl_type;
+  GLint status;
+
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+  if (shader->gl_handle)
+    {
+      CoglPipeline *prev = shader->compilation_pipeline;
+
+      /* XXX: currently the only things that will affect the
+       * boilerplate for user shaders, apart from driver features,
+       * are the pipeline layer-indices and texture-unit-indices
+       */
+      if (pipeline == prev ||
+          _cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline))
+        return;
+
+      GE (ctx, glDeleteShader (shader->gl_handle));
+      shader->gl_handle = 0;
+
+      if (shader->compilation_pipeline)
+        {
+          cogl_object_unref (shader->compilation_pipeline);
+          shader->compilation_pipeline = NULL;
+        }
+    }
+
+  switch (shader->type)
+    {
+    case COGL_SHADER_TYPE_VERTEX:
+      gl_type = GL_VERTEX_SHADER;
+      break;
+    case COGL_SHADER_TYPE_FRAGMENT:
+      gl_type = GL_FRAGMENT_SHADER;
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
+  shader->gl_handle = ctx->glCreateShader (gl_type);
+
+  _cogl_glsl_shader_set_source_with_boilerplate (ctx,
+                                                 shader->gl_handle,
+                                                 gl_type,
+                                                 pipeline,
+                                                 1,
+                                                 (const char **)
+                                                  &shader->source,
+                                                 NULL);
+  GE (ctx, glCompileShader (shader->gl_handle));
+
+  shader->compilation_pipeline = cogl_object_ref (pipeline);
+
+  GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
+  if (!status)
+    {
+      char buffer[512];
+      int len = 0;
+
+      ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
+      buffer[len] = '\0';
+
+      g_warning ("Failed to compile GLSL program:\n"
+                 "src:\n%s\n"
+                 "error:\n%s\n",
+                 shader->source,
+                 buffer);
+    }
+}
+
 static void
 _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
                                  unsigned long pipelines_difference)
diff --git a/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c 
b/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
index c69f50ae89..7ef7a49937 100644
--- a/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
+++ b/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
@@ -45,7 +45,7 @@
 #include "cogl-context-private.h"
 #include "cogl-object-private.h"
 #include "cogl-pipeline-state-private.h"
-#include "cogl-glsl-shader-private.h"
+#include "cogl-glsl-shader-boilerplate.h"
 #include "driver/gl/cogl-pipeline-vertend-glsl-private.h"
 #include "deprecated/cogl-program-private.h"
 
@@ -132,6 +132,150 @@ dirty_shader_state (CoglPipeline *pipeline)
                              NULL);
 }
 
+static gboolean
+add_layer_vertex_boilerplate_cb (CoglPipelineLayer *layer,
+                                 void *user_data)
+{
+  GString *layer_declarations = user_data;
+  int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
+  g_string_append_printf (layer_declarations,
+                          "attribute vec4 cogl_tex_coord%d_in;\n"
+                          "#define cogl_texture_matrix%i cogl_texture_matrix[%i]\n"
+                          "#define cogl_tex_coord%i_out _cogl_tex_coord[%i]\n",
+                          layer->index,
+                          layer->index,
+                          unit_index,
+                          layer->index,
+                          unit_index);
+  return TRUE;
+}
+
+static gboolean
+add_layer_fragment_boilerplate_cb (CoglPipelineLayer *layer,
+                                   void *user_data)
+{
+  GString *layer_declarations = user_data;
+  g_string_append_printf (layer_declarations,
+                          "#define cogl_tex_coord%i_in _cogl_tex_coord[%i]\n",
+                          layer->index,
+                          _cogl_pipeline_layer_get_unit_index (layer));
+  return TRUE;
+}
+
+void
+_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
+                                               GLuint shader_gl_handle,
+                                               GLenum shader_gl_type,
+                                               CoglPipeline *pipeline,
+                                               GLsizei count_in,
+                                               const char **strings_in,
+                                               const GLint *lengths_in)
+{
+  const char *vertex_boilerplate;
+  const char *fragment_boilerplate;
+
+  const char **strings = g_alloca (sizeof (char *) * (count_in + 4));
+  GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 4));
+  char *version_string;
+  int count = 0;
+
+  int n_layers;
+
+  vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE;
+  fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE;
+
+  version_string = g_strdup_printf ("#version %i\n\n",
+                                    ctx->glsl_version_to_use);
+  strings[count] = version_string;
+  lengths[count++] = -1;
+
+  if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL))
+    {
+      static const char image_external_extension[] =
+        "#extension GL_OES_EGL_image_external : require\n";
+      strings[count] = image_external_extension;
+      lengths[count++] = sizeof (image_external_extension) - 1;
+    }
+
+  if (shader_gl_type == GL_VERTEX_SHADER)
+    {
+      strings[count] = vertex_boilerplate;
+      lengths[count++] = strlen (vertex_boilerplate);
+    }
+  else if (shader_gl_type == GL_FRAGMENT_SHADER)
+    {
+      strings[count] = fragment_boilerplate;
+      lengths[count++] = strlen (fragment_boilerplate);
+    }
+
+  n_layers = cogl_pipeline_get_n_layers (pipeline);
+  if (n_layers)
+    {
+      GString *layer_declarations = ctx->codegen_boilerplate_buffer;
+      g_string_set_size (layer_declarations, 0);
+
+      g_string_append_printf (layer_declarations,
+                              "varying vec4 _cogl_tex_coord[%d];\n",
+                              n_layers);
+
+      if (shader_gl_type == GL_VERTEX_SHADER)
+        {
+          g_string_append_printf (layer_declarations,
+                                  "uniform mat4 cogl_texture_matrix[%d];\n",
+                                  n_layers);
+
+          _cogl_pipeline_foreach_layer_internal (pipeline,
+                                                 add_layer_vertex_boilerplate_cb,
+                                                 layer_declarations);
+        }
+      else if (shader_gl_type == GL_FRAGMENT_SHADER)
+        {
+          _cogl_pipeline_foreach_layer_internal (pipeline,
+                                                 add_layer_fragment_boilerplate_cb,
+                                                 layer_declarations);
+        }
+
+      strings[count] = layer_declarations->str;
+      lengths[count++] = -1; /* null terminated */
+    }
+
+  memcpy (strings + count, strings_in, sizeof (char *) * count_in);
+  if (lengths_in)
+    memcpy (lengths + count, lengths_in, sizeof (GLint) * count_in);
+  else
+    {
+      int i;
+
+      for (i = 0; i < count_in; i++)
+        lengths[count + i] = -1; /* null terminated */
+    }
+  count += count_in;
+
+  if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE)))
+    {
+      GString *buf = g_string_new (NULL);
+      int i;
+
+      g_string_append_printf (buf,
+                              "%s shader:\n",
+                              shader_gl_type == GL_VERTEX_SHADER ?
+                              "vertex" : "fragment");
+      for (i = 0; i < count; i++)
+        if (lengths[i] != -1)
+          g_string_append_len (buf, strings[i], lengths[i]);
+        else
+          g_string_append (buf, strings[i]);
+
+      g_message ("%s", buf->str);
+
+      g_string_free (buf, TRUE);
+    }
+
+  GE( ctx, glShaderSource (shader_gl_handle, count,
+                           (const char **) strings, lengths) );
+
+  g_free (version_string);
+}
 GLuint
 _cogl_pipeline_vertend_glsl_get_shader (CoglPipeline *pipeline)
 {
diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build
index a4383dc3d0..edcac793e3 100644
--- a/cogl/cogl/meson.build
+++ b/cogl/cogl/meson.build
@@ -274,8 +274,6 @@ cogl_sources = [
   'cogl-pipeline-layer-state.c',
   'cogl-pipeline-state-private.h',
   'cogl-pipeline-debug.c',
-  'cogl-glsl-shader.c',
-  'cogl-glsl-shader-private.h',
   'cogl-glsl-shader-boilerplate.h',
   'cogl-pipeline-snippet-private.h',
   'cogl-pipeline-snippet.c',


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