[gtk/wip/otte/color-profiles: 4/28] gl: Move gdk_gl_context_upload_texture() into NGL




commit 061a7fe9a833f75496c236db02427d64da857d5d
Author: Benjamin Otte <otte redhat com>
Date:   Sat Sep 25 21:28:08 2021 +0200

    gl: Move gdk_gl_context_upload_texture() into NGL
    
    It's the only user and the API is kinda clunky, so it's easier to
    refactor it there.
    
    Also make use of gdk_memory_texture_convert().

 gdk/gdkglcontext.c           | 111 +++++--------------------------------------
 gdk/gdkglcontextprivate.h    |  10 ++--
 gsk/ngl/gsknglcommandqueue.c |  90 +++++++++++++++++++++++++++++++++--
 3 files changed, 101 insertions(+), 110 deletions(-)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 11d19e7163..975b4cf58a 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -221,104 +221,6 @@ gdk_gl_context_get_property (GObject    *gobject,
     }
 }
 
-void
-gdk_gl_context_upload_texture (GdkGLContext    *context,
-                               GdkTexture      *texture,
-                               int              x,
-                               int              y,
-                               int              width,
-                               int              height,
-                               guint            texture_target)
-{
-  GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
-  GdkMemoryTexture *memory_texture;
-  GdkMemoryFormat data_format;
-  GdkColorProfile *color_profile;
-  guchar *copy = NULL;
-  GLenum gl_internalformat;
-  GLenum gl_format;
-  GLenum gl_type;
-  gsize bpp, stride;
-  const guchar *data;
-
-  g_return_if_fail (GDK_IS_GL_CONTEXT (context));
-
-  color_profile = gdk_texture_get_color_profile (texture);
-  memory_texture = GDK_MEMORY_TEXTURE (gdk_texture_download_texture (texture));
-  data_format = gdk_memory_texture_get_format (memory_texture);
-  bpp = gdk_memory_format_bytes_per_pixel (data_format);
-  stride = gdk_memory_texture_get_stride (memory_texture);
-  data = gdk_memory_texture_get_data (memory_texture);
-
-  data += x * bpp + y * stride;
-
-  if (!gdk_memory_format_gl_format (data_format,
-                                    priv->use_es,
-                                    &gl_internalformat,
-                                    &gl_format,
-                                    &gl_type))
-    {
-      data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
-      gl_internalformat = GL_RGBA8;
-      gl_format = GL_RGBA;
-      gl_type = GL_UNSIGNED_BYTE;
-      bpp = 4;
-
-      copy = g_malloc_n (width * 4, height);
-    }
-  else if (color_profile != gdk_color_profile_get_srgb ())
-    {
-      copy = g_malloc_n (width * bpp, height);
-    }
-  else
-    {
-      copy = NULL;
-    }
-
-  if (copy)
-    {
-      gdk_memory_convert (copy, width * bpp,
-                          data_format,
-                          gdk_color_profile_get_srgb (),
-                          data, stride,
-                          gdk_memory_texture_get_format (memory_texture),
-                          color_profile,
-                          width, height);
-      data = copy;
-      stride = width * 4;
-    }
-
-  /* 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)
-    {
-      glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
-
-      glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
-      glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
-    }
-  else if ((!priv->use_es ||
-            (priv->use_es && (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));
-    }
-
-  g_free (copy);
-  g_clear_object (&memory_texture);
-}
-
 static gboolean
 gdk_gl_context_real_realize (GdkGLContext  *self,
                              GError       **error)
@@ -1273,6 +1175,19 @@ gdk_gl_context_get_version (GdkGLContext *context,
     *minor = priv->gl_version % 10;
 }
 
+gboolean
+gdk_gl_context_has_version (GdkGLContext *context,
+                            int           major,
+                            int           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 (minor < 10, FALSE);
+
+  return priv->gl_version >= major * 10 + minor;
+}
+
 /**
  * gdk_gl_context_clear_current:
  *
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index 50d8ce0100..e7733f52b1 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -105,13 +105,6 @@ GdkGLContext *          gdk_gl_context_new_for_surface          (GdkSurface
 void                    gdk_gl_context_set_is_legacy            (GdkGLContext    *context,
                                                                  gboolean         is_legacy);
 
-void                    gdk_gl_context_upload_texture           (GdkGLContext    *context,
-                                                                 GdkTexture      *texture,
-                                                                 int              x,
-                                                                 int              y,
-                                                                 int              width,
-                                                                 int              height,
-                                                                 guint            texture_target);
 GdkGLContextPaintData * gdk_gl_context_get_paint_data           (GdkGLContext    *context);
 gboolean                gdk_gl_context_use_texture_rectangle    (GdkGLContext    *context);
 gboolean                gdk_gl_context_has_unpack_subimage      (GdkGLContext    *context);
@@ -131,6 +124,9 @@ void                    gdk_gl_context_label_object_printf      (GdkGLContext
                                                                  const char      *format,
                                                                 ...)  G_GNUC_PRINTF (4, 5);
 
+gboolean                gdk_gl_context_has_version              (GdkGLContext    *context,
+                                                                 int              major,
+                                                                 int              minor);
 gboolean                gdk_gl_context_has_debug                (GdkGLContext    *self) G_GNUC_PURE;
 
 gboolean                gdk_gl_context_use_es_bgra              (GdkGLContext    *context);
diff --git a/gsk/ngl/gsknglcommandqueue.c b/gsk/ngl/gsknglcommandqueue.c
index 51c74e0119..877bae383b 100644
--- a/gsk/ngl/gsknglcommandqueue.c
+++ b/gsk/ngl/gsknglcommandqueue.c
@@ -1320,6 +1320,86 @@ gsk_ngl_command_queue_create_framebuffer (GskNglCommandQueue *self)
   return fbo_id;
 }
 
+static void
+gsk_ngl_command_queue_do_upload_texture (GdkGLContext    *context,
+                                         GdkTexture      *texture,
+                                         int              x,
+                                         int              y,
+                                         int              width,
+                                         int              height,
+                                         guint            texture_target)
+{
+  GdkMemoryTexture *memory_texture;
+  GdkMemoryFormat data_format;
+  GLenum gl_internalformat;
+  GLenum gl_format;
+  GLenum gl_type;
+  gsize bpp, stride;
+  const guchar *data;
+
+  g_return_if_fail (GDK_IS_GL_CONTEXT (context));
+
+  memory_texture = GDK_MEMORY_TEXTURE (gdk_texture_download_texture (texture));
+  data_format = gdk_memory_texture_get_format (memory_texture);
+
+  if (!gdk_memory_format_gl_format (data_format,
+                                    gdk_gl_context_get_use_es (context),
+                                    &gl_internalformat,
+                                    &gl_format,
+                                    &gl_type))
+    {
+      data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
+      if (!gdk_memory_format_gl_format (GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+                                        gdk_gl_context_get_use_es (context),
+                                        &gl_internalformat,
+                                        &gl_format,
+                                        &gl_type))
+        {
+          g_assert_not_reached ();
+        }
+    }
+
+  memory_texture = gdk_memory_texture_convert (memory_texture,
+                                               data_format,
+                                               gdk_color_profile_get_srgb (),
+                                               &(GdkRectangle) { x, y, width, height });
+
+  bpp = gdk_memory_format_bytes_per_pixel (data_format);
+  stride = gdk_memory_texture_get_stride (memory_texture);
+  data = gdk_memory_texture_get_data (memory_texture);
+
+  /* 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)
+    {
+      glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+
+      glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
+      glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
+    }
+  else if ((stride % bpp == 0) &&
+           (!gdk_gl_context_get_use_es (context) ||
+            gdk_gl_context_has_version (context, 3, 0) ||
+            gdk_gl_context_has_unpack_subimage (context)))
+    {
+      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));
+    }
+
+  g_clear_object (&memory_texture);
+}
+
 int
 gsk_ngl_command_queue_upload_texture (GskNglCommandQueue *self,
                                       GdkTexture         *texture,
@@ -1359,11 +1439,11 @@ gsk_ngl_command_queue_upload_texture (GskNglCommandQueue *self,
   glActiveTexture (GL_TEXTURE0);
   glBindTexture (GL_TEXTURE_2D, texture_id);
 
-  gdk_gl_context_upload_texture (gdk_gl_context_get_current (),
-                                 texture,
-                                 x_offset, y_offset,
-                                 width, height,
-                                 GL_TEXTURE_2D);
+  gsk_ngl_command_queue_do_upload_texture (gdk_gl_context_get_current (),
+                                           texture,
+                                           x_offset, y_offset,
+                                           width, height,
+                                           GL_TEXTURE_2D);
 
   /* 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]