[gtk/wip/chergert/glproto: 133/493] implement uploading from command queue




commit 790033fe26e9d73bd3895f618ee2f4607012b2b7
Author: Christian Hergert <chergert redhat com>
Date:   Mon Jan 4 17:20:38 2021 -0800

    implement uploading from command queue

 gsk/next/gskglcommandqueue.c        | 73 +++++++++++++++++++++++++++++++++++--
 gsk/next/gskglcommandqueueprivate.h |  8 +++-
 gsk/next/gskgldriver.c              |  6 ++-
 3 files changed, 81 insertions(+), 6 deletions(-)
---
diff --git a/gsk/next/gskglcommandqueue.c b/gsk/next/gskglcommandqueue.c
index a38aa2a6cc..6a84adc6b7 100644
--- a/gsk/next/gskglcommandqueue.c
+++ b/gsk/next/gskglcommandqueue.c
@@ -21,6 +21,7 @@
 #include "config.h"
 
 #include <gdk/gdkglcontextprivate.h>
+#include <gdk/gdkmemorytextureprivate.h>
 #include <gsk/gskdebugprivate.h>
 #include <epoxy/gl.h>
 #include <string.h>
@@ -900,11 +901,77 @@ gsk_gl_command_queue_bind_framebuffer (GskGLCommandQueue *self,
   gsk_gl_attachment_state_bind_framebuffer (self->attachments, framebuffer);
 }
 
-guint
+int
 gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
                                      GdkTexture        *texture,
+                                     guint              x_offset,
+                                     guint              y_offset,
                                      guint              width,
-                                     guint              height)
+                                     guint              height,
+                                     int                min_filter,
+                                     int                mag_filter)
 {
-  return 0;
+  cairo_surface_t *surface = NULL;
+  GdkMemoryFormat data_format;
+  const guchar *data;
+  gsize data_stride;
+  gsize bpp;
+  int texture_id;
+
+  g_return_val_if_fail (GSK_IS_GL_COMMAND_QUEUE (self), 0);
+  g_return_val_if_fail (!GDK_IS_GL_TEXTURE (texture), 0);
+  g_return_val_if_fail (x_offset + width <= gdk_texture_get_width (texture), 0);
+  g_return_val_if_fail (y_offset + height <= gdk_texture_get_height (texture), 0);
+  g_return_val_if_fail (min_filter == GL_LINEAR || min_filter == GL_NEAREST, 0);
+  g_return_val_if_fail (mag_filter == GL_LINEAR || min_filter == GL_NEAREST, 0);
+
+  if (width > self->max_texture_size || height > self->max_texture_size)
+    {
+      g_warning ("Attempt to create texture of size %ux%u but max size is %d. "
+                 "Clipping will occur.",
+                 width, height, self->max_texture_size);
+      width = MAX (width, self->max_texture_size);
+      height = MAX (height, self->max_texture_size);
+    }
+
+  texture_id = gsk_gl_command_queue_create_texture (self, width, height, min_filter, mag_filter);
+  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);
+    }
+
+  bpp = gdk_memory_format_bytes_per_pixel (data_format);
+
+  /* Swtich 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, GL_TEXTURE_2D);
+
+  /* Restore previous texture state if any */
+  if (self->attachments->textures[0].id > 0)
+    glBindTexture (self->attachments->textures[0].target,
+                   self->attachments->textures[0].id);
+
+  g_clear_pointer (&surface, cairo_surface_destroy);
+
+  return texture_id;
 }
diff --git a/gsk/next/gskglcommandqueueprivate.h b/gsk/next/gskglcommandqueueprivate.h
index 0e8b23601f..2ecbaa27cf 100644
--- a/gsk/next/gskglcommandqueueprivate.h
+++ b/gsk/next/gskglcommandqueueprivate.h
@@ -116,10 +116,14 @@ void               gsk_gl_command_queue_make_current         (GskGLCommandQueue
 void               gsk_gl_command_queue_begin_frame          (GskGLCommandQueue        *self);
 void               gsk_gl_command_queue_end_frame            (GskGLCommandQueue        *self);
 void               gsk_gl_command_queue_execute              (GskGLCommandQueue        *self);
-guint              gsk_gl_command_queue_upload_texture       (GskGLCommandQueue        *self,
+int                gsk_gl_command_queue_upload_texture       (GskGLCommandQueue        *self,
                                                               GdkTexture               *texture,
+                                                              guint                     x_offset,
+                                                              guint                     y_offset,
                                                               guint                     width,
-                                                              guint                     height);
+                                                              guint                     height,
+                                                              int                       min_filter,
+                                                              int                       mag_filter);
 int                gsk_gl_command_queue_create_texture       (GskGLCommandQueue        *self,
                                                               int                       width,
                                                               int                       height,
diff --git a/gsk/next/gskgldriver.c b/gsk/next/gskgldriver.c
index 3334901aba..79c931e24f 100644
--- a/gsk/next/gskgldriver.c
+++ b/gsk/next/gskgldriver.c
@@ -516,8 +516,12 @@ gsk_next_driver_load_texture (GskNextDriver *self,
   t->mag_filter = mag_filter;
   t->texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
                                                        source_texture,
+                                                       0,
+                                                       0,
                                                        t->width,
-                                                       t->height);
+                                                       t->height,
+                                                       t->min_filter,
+                                                       t->mag_filter);
 
   if (gdk_texture_set_render_data (texture, self, t, gsk_next_driver_release_texture))
     t->user = texture;


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