[gtk/wip/otte/memoryformat] gl: Move texture uploading to the renderer



commit 50c402cbf6992ba7a87fec31873f286238e55a8a
Author: Benjamin Otte <otte redhat com>
Date:   Tue Oct 12 15:04:43 2021 +0200

    gl: Move texture uploading to the renderer
    
    It does not belong in GdkGLContext, it's a renderer thing.
    It's also the only user of that API.
    
    Introduce gdk_gl_context_check_version() private API to make version
    checks simpler.

 gdk/gdkglcontext.c         | 93 +++++++---------------------------------------
 gdk/gdkglcontextprivate.h  | 11 ++----
 gsk/gl/gskglcommandqueue.c | 88 +++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 101 insertions(+), 91 deletions(-)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index f719da3aea..149e93ff14 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -249,86 +249,6 @@ gdk_gl_context_get_property (GObject    *object,
     }
 }
 
-void
-gdk_gl_context_upload_texture (GdkGLContext    *context,
-                               const guchar    *data,
-                               int              width,
-                               int              height,
-                               int              stride,
-                               GdkMemoryFormat  data_format,
-                               guint            texture_target)
-{
-  GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
-  guchar *copy = NULL;
-  GLenum gl_internalformat;
-  GLenum gl_format;
-  GLenum gl_type;
-  gsize bpp;
-
-  g_return_if_fail (GDK_IS_GL_CONTEXT (context));
-
-  if (!gdk_memory_format_gl_format (data_format,
-                                    gdk_gl_context_get_use_es (context),
-                                    &gl_internalformat,
-                                    &gl_format,
-                                    &gl_type))
-    {
-      copy = g_malloc_n (width * 4, height);
-      gdk_memory_convert (copy, width * 4,
-                          GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
-                          data, stride,
-                          data_format,
-                          width, height);
-      data = copy;
-      data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
-      stride = width * 4;
-      if (!gdk_memory_format_gl_format (data_format,
-                                        gdk_gl_context_get_use_es (context),
-                                        &gl_internalformat,
-                                        &gl_format,
-                                        &gl_type))
-        {
-          g_assert_not_reached ();
-        }
-    }
-  else
-    {
-      copy = NULL;
-    }
-
-  bpp = gdk_memory_format_bytes_per_pixel (data_format);
-
-  glPixelStorei (GL_UNPACK_ALIGNMENT, gdk_memory_format_alignment (data_format));
-
-  /* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
-   * the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
-   */
-  if (stride == width * bpp)
-    {
-      glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
-    }
-  else if (stride % bpp == 0 &&
-           (!gdk_gl_context_get_use_es (context) ||
-            (priv->gl_version >= 30 || priv->has_unpack_subimage)))
-    {
-      glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
-
-      glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
-
-      glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
-    }
-  else
-    {
-      int i;
-      glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, NULL);
-      for (i = 0; i < height; i++)
-        glTexSubImage2D (texture_target, 0, 0, i, width, 1, gl_format, gl_type, data + (i * stride));
-    }
-  glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
-
-  g_free (copy);
-}
-
 #define N_EGL_ATTRS     16
 
 static GdkGLAPI
@@ -1067,6 +987,19 @@ gdk_gl_context_set_required_version (GdkGLContext *context,
   priv->minor = version % 100;
 }
 
+gboolean
+gdk_gl_context_check_version (GdkGLContext *context,
+                              int           required_major,
+                              int           required_minor)
+{
+  GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
+
+  g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
+  g_return_val_if_fail (required_minor < 10, FALSE);
+
+  return priv->gl_version >= required_major * 10 + required_minor;
+}
+
 /**
  * gdk_gl_context_get_required_version:
  * @context: a `GdkGLContext`
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index 1879488b4f..6814fec0bf 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -108,13 +108,10 @@ gboolean                gdk_gl_context_is_api_allowed           (GdkGLContext
 void                    gdk_gl_context_set_is_legacy            (GdkGLContext    *context,
                                                                  gboolean         is_legacy);
 
-void                    gdk_gl_context_upload_texture           (GdkGLContext    *context,
-                                                                 const guchar    *data,
-                                                                 int              width,
-                                                                 int              height,
-                                                                 int              stride,
-                                                                 GdkMemoryFormat  data_format,
-                                                                 guint            texture_target);
+gboolean                gdk_gl_context_check_version            (GdkGLContext    *context,
+                                                                 int              required_major,
+                                                                 int              required_minor);
+
 gboolean                gdk_gl_context_has_unpack_subimage      (GdkGLContext    *context);
 void                    gdk_gl_context_push_debug_group         (GdkGLContext    *context,
                                                                  const char      *message);
diff --git a/gsk/gl/gskglcommandqueue.c b/gsk/gl/gskglcommandqueue.c
index 2571804726..38f879c5c1 100644
--- a/gsk/gl/gskglcommandqueue.c
+++ b/gsk/gl/gskglcommandqueue.c
@@ -1339,6 +1339,86 @@ gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self)
   return fbo_id;
 }
 
+static void
+gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self,
+                                        const guchar      *data,
+                                        int                width,
+                                        int                height,
+                                        int                stride,
+                                        GdkMemoryFormat    data_format)
+{
+  GdkGLContext *context;
+  guchar *copy = NULL;
+  GLenum gl_internalformat;
+  GLenum gl_format;
+  GLenum gl_type;
+  gsize bpp;
+  gboolean use_es;
+
+  context = gdk_gl_context_get_current ();
+  use_es = gdk_gl_context_get_use_es (context);
+
+  if (!gdk_memory_format_gl_format (data_format,
+                                    use_es,
+                                    &gl_internalformat,
+                                    &gl_format,
+                                    &gl_type))
+    {
+      copy = g_malloc_n (width * 4, height);
+      gdk_memory_convert (copy, width * 4,
+                          GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+                          data, stride,
+                          data_format,
+                          width, height);
+      data = copy;
+      data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
+      stride = width * 4;
+      if (!gdk_memory_format_gl_format (data_format,
+                                        use_es,
+                                        &gl_internalformat,
+                                        &gl_format,
+                                        &gl_type))
+        {
+          g_assert_not_reached ();
+        }
+    }
+  else
+    {
+      copy = NULL;
+    }
+
+  bpp = gdk_memory_format_bytes_per_pixel (data_format);
+
+  glPixelStorei (GL_UNPACK_ALIGNMENT, gdk_memory_format_alignment (data_format));
+
+  /* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
+   * the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
+   */
+  if (stride == width * bpp)
+    {
+      glTexImage2D (GL_TEXTURE_2D, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
+    }
+  else if (stride % bpp == 0 &&
+           (!use_es || gdk_gl_context_check_version (context, 3, 0) || gdk_gl_context_has_unpack_subimage 
(context)))
+    {
+      glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
+
+      glTexImage2D (GL_TEXTURE_2D, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
+
+      glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+    }
+  else
+    {
+      int i;
+      glTexImage2D (GL_TEXTURE_2D, 0, gl_internalformat, width, height, 0, gl_format, gl_type, NULL);
+      for (i = 0; i < height; i++)
+        glTexSubImage2D (GL_TEXTURE_2D, 0, 0, i, width, 1, gl_format, gl_type, data + (i * stride));
+    }
+  glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
+
+  g_free (copy);
+}
+
 int
 gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
                                      GdkTexture        *texture,
@@ -1402,10 +1482,10 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
   glActiveTexture (GL_TEXTURE0);
   glBindTexture (GL_TEXTURE_2D, texture_id);
 
-  gdk_gl_context_upload_texture (gdk_gl_context_get_current (),
-                                 data + x_offset * bpp + y_offset * data_stride,
-                                 width, height, data_stride,
-                                 data_format, GL_TEXTURE_2D);
+  gsk_gl_command_queue_do_upload_texture (self,
+                                          data + x_offset * bpp + y_offset * data_stride,
+                                          width, height, data_stride,
+                                          data_format);
 
   /* Restore previous texture state if any */
   if (self->attachments->textures[0].id > 0)


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