[gtk/wip/otte/color-profiles: 1/18] gl: Refactor texture upload code




commit 11556327bcd09d55662f4603f6278ca14a1c705b
Author: Benjamin Otte <otte redhat com>
Date:   Thu Sep 23 03:23:13 2021 +0200

    gl: Refactor texture upload code
    
    Do the texture unpacking at the target, not at the source.
    
    Also handle color profiles.

 gdk/gdkglcontext.c           | 34 ++++++++++++++++++++++++++--------
 gdk/gdkglcontextprivate.h    |  7 +++----
 gsk/ngl/gsknglcommandqueue.c | 33 +++------------------------------
 3 files changed, 32 insertions(+), 42 deletions(-)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index afeb3b5358..527ba318ec 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -76,6 +76,7 @@
 
 #include "gdkglcontextprivate.h"
 
+#include "gdkcolorprofile.h"
 #include "gdkdebug.h"
 #include "gdkdisplayprivate.h"
 #include "gdkintl.h"
@@ -222,24 +223,40 @@ gdk_gl_context_get_property (GObject    *gobject,
 
 void
 gdk_gl_context_upload_texture (GdkGLContext    *context,
-                               const guchar    *data,
+                               GdkTexture      *texture,
+                               int              x,
+                               int              y,
                                int              width,
                                int              height,
-                               int              stride,
-                               GdkMemoryFormat  data_format,
-                               GdkColorProfile *color_profile,
                                guint            texture_target)
 {
   GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
+  GdkMemoryTexture *memory_texture;
+  GdkMemoryFormat data_format;
+  GdkColorProfile *color_profile;
   guchar *copy = NULL;
   GLint gl_internalformat;
   GLint gl_format;
   GLint gl_type;
-  gsize bpp;
+  gsize bpp, stride;
+  const guchar *data;
 
   g_return_if_fail (GDK_IS_GL_CONTEXT (context));
 
-  if (!priv->use_es && data_format == GDK_MEMORY_DEFAULT) /* Cairo surface format */
+  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 (color_profile != gdk_color_profile_get_srgb ())
+    {
+      goto fallback;
+    }
+  else if (!priv->use_es && data_format == GDK_MEMORY_DEFAULT) /* Cairo surface format */
     {
       gl_internalformat = GL_RGBA8;
       gl_format = GL_BGRA;
@@ -295,6 +312,7 @@ gdk_gl_context_upload_texture (GdkGLContext    *context,
     }
   else /* Fall-back, convert to GLES format */
     {
+fallback:
       copy = g_malloc (width * height * 4);
       gdk_memory_convert (copy, width * 4,
                           GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
@@ -306,13 +324,12 @@ gdk_gl_context_upload_texture (GdkGLContext    *context,
       data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
       stride = width * 4;
       data = copy;
+      bpp = 4;
       gl_internalformat = GL_RGBA8;
       gl_format = GL_RGBA;
       gl_type = GL_UNSIGNED_BYTE;
     }
 
-  bpp = gdk_memory_format_bytes_per_pixel (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
    */
@@ -341,6 +358,7 @@ gdk_gl_context_upload_texture (GdkGLContext    *context,
     }
 
   g_free (copy);
+  g_clear_object (&memory_texture);
 }
 
 static gboolean
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index abe8ae43b9..50d8ce0100 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -106,12 +106,11 @@ void                    gdk_gl_context_set_is_legacy            (GdkGLContext
                                                                  gboolean         is_legacy);
 
 void                    gdk_gl_context_upload_texture           (GdkGLContext    *context,
-                                                                 const guchar    *data,
+                                                                 GdkTexture      *texture,
+                                                                 int              x,
+                                                                 int              y,
                                                                  int              width,
                                                                  int              height,
-                                                                 int              stride,
-                                                                 GdkMemoryFormat  data_format,
-                                                                 GdkColorProfile *color_profile,
                                                                  guint            texture_target);
 GdkGLContextPaintData * gdk_gl_context_get_paint_data           (GdkGLContext    *context);
 gboolean                gdk_gl_context_use_texture_rectangle    (GdkGLContext    *context);
diff --git a/gsk/ngl/gsknglcommandqueue.c b/gsk/ngl/gsknglcommandqueue.c
index e8c44243aa..51c74e0119 100644
--- a/gsk/ngl/gsknglcommandqueue.c
+++ b/gsk/ngl/gsknglcommandqueue.c
@@ -1331,11 +1331,6 @@ gsk_ngl_command_queue_upload_texture (GskNglCommandQueue *self,
                                       int                 mag_filter)
 {
   G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
-  cairo_surface_t *surface = NULL;
-  GdkMemoryFormat data_format;
-  const guchar *data;
-  gsize data_stride;
-  gsize bpp;
   int texture_id;
 
   g_assert (GSK_IS_NGL_COMMAND_QUEUE (self));
@@ -1358,36 +1353,16 @@ gsk_ngl_command_queue_upload_texture (GskNglCommandQueue *self,
   if (texture_id == -1)
     return texture_id;
 
-  if (GDK_IS_MEMORY_TEXTURE (texture))
-    {
-      GdkMemoryTexture *memory_texture = GDK_MEMORY_TEXTURE (texture);
-      data = gdk_memory_texture_get_data (memory_texture);
-      data_format = gdk_memory_texture_get_format (memory_texture);
-      data_stride = gdk_memory_texture_get_stride (memory_texture);
-    }
-  else
-    {
-      /* Fall back to downloading to a surface */
-      surface = gdk_texture_download_surface (texture);
-      cairo_surface_flush (surface);
-      data = cairo_image_surface_get_data (surface);
-      data_format = GDK_MEMORY_DEFAULT;
-      data_stride = cairo_image_surface_get_stride (surface);
-    }
-
   self->n_uploads++;
 
-  bpp = gdk_memory_format_bytes_per_pixel (data_format);
-
   /* Switch to texture0 as 2D. We'll restore it later. */
   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,
-                                 gdk_color_profile_get_srgb (),
+                                 texture,
+                                 x_offset, y_offset,
+                                 width, height,
                                  GL_TEXTURE_2D);
 
   /* Restore previous texture state if any */
@@ -1395,8 +1370,6 @@ gsk_ngl_command_queue_upload_texture (GskNglCommandQueue *self,
     glBindTexture (self->attachments->textures[0].target,
                    self->attachments->textures[0].id);
 
-  g_clear_pointer (&surface, cairo_surface_destroy);
-
   if (gdk_profiler_is_running ())
     gdk_profiler_add_markf (start_time, GDK_PROFILER_CURRENT_TIME-start_time,
                             "Upload Texture",


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