[gtk/wip/chergert/glproto] start on texture loading



commit a66b9c1a9c906f68fee0227f9f69a39c659606d2
Author: Christian Hergert <chergert redhat com>
Date:   Mon Jan 4 16:41:08 2021 -0800

    start on texture loading

 gsk/next/gskglcommandqueue.c        |  9 ++++
 gsk/next/gskglcommandqueueprivate.h |  3 +-
 gsk/next/gskgldriver.c              | 97 ++++++++++++++++++++++++++++++++++++-
 gsk/next/gskgldriverprivate.h       |  4 ++
 4 files changed, 110 insertions(+), 3 deletions(-)
---
diff --git a/gsk/next/gskglcommandqueue.c b/gsk/next/gskglcommandqueue.c
index d204a3ed40..a38aa2a6cc 100644
--- a/gsk/next/gskglcommandqueue.c
+++ b/gsk/next/gskglcommandqueue.c
@@ -899,3 +899,12 @@ gsk_gl_command_queue_bind_framebuffer (GskGLCommandQueue *self,
 
   gsk_gl_attachment_state_bind_framebuffer (self->attachments, framebuffer);
 }
+
+guint
+gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
+                                     GdkTexture        *texture,
+                                     guint              width,
+                                     guint              height)
+{
+  return 0;
+}
diff --git a/gsk/next/gskglcommandqueueprivate.h b/gsk/next/gskglcommandqueueprivate.h
index 52988fddd9..0e8b23601f 100644
--- a/gsk/next/gskglcommandqueueprivate.h
+++ b/gsk/next/gskglcommandqueueprivate.h
@@ -118,7 +118,8 @@ void               gsk_gl_command_queue_end_frame            (GskGLCommandQueue
 void               gsk_gl_command_queue_execute              (GskGLCommandQueue        *self);
 guint              gsk_gl_command_queue_upload_texture       (GskGLCommandQueue        *self,
                                                               GdkTexture               *texture,
-                                                              GError                  **error);
+                                                              guint                     width,
+                                                              guint                     height);
 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 6384ccfccc..3334901aba 100644
--- a/gsk/next/gskgldriver.c
+++ b/gsk/next/gskgldriver.c
@@ -23,6 +23,9 @@
 
 #include "config.h"
 
+#include <gdk/gdkglcontextprivate.h>
+#include <gdk/gdktextureprivate.h>
+#include <gdk/gdkgltextureprivate.h>
 #include <gsk/gskdebugprivate.h>
 #include <gsk/gskrendererprivate.h>
 
@@ -40,13 +43,13 @@ G_DEFINE_TYPE (GskNextDriver, gsk_next_driver, G_TYPE_OBJECT)
 
 typedef struct _GskGLTexture
 {
-  GLuint      texture_id;
   int         width;
   int         height;
   GLuint      min_filter;
   GLuint      mag_filter;
-  GdkTexture *user;
   gint64      last_used_in_frame;
+  GdkTexture *user;
+  GLuint      texture_id;
   guint       permanent : 1;
 } GskGLTexture;
 
@@ -103,6 +106,12 @@ remove_texture_key_for_id (GskNextDriver *self,
     g_hash_table_remove (self->key_to_texture_id, key);
 }
 
+static void
+gsk_next_driver_release_texture (gpointer data)
+{
+  ((GskGLTexture *)data)->user = NULL;
+}
+
 static guint
 gsk_next_driver_collect_unused_textures (GskNextDriver *self,
                                          gint64         watermark)
@@ -436,3 +445,87 @@ gsk_next_driver_insert_texture (GskNextDriver       *self,
   g_hash_table_insert (self->key_to_texture_id, k, GUINT_TO_POINTER (texture_id));
   g_hash_table_insert (self->texture_id_to_key, GUINT_TO_POINTER (texture_id), k);
 }
+
+guint
+gsk_next_driver_load_texture (GskNextDriver *self,
+                              GdkTexture    *texture,
+                              int            min_filter,
+                              int            mag_filter)
+{
+  GdkGLContext *context;
+  GdkTexture *downloaded_texture = NULL;
+  GdkTexture *source_texture;
+  GskGLTexture *t;
+
+  g_return_val_if_fail (GSK_IS_NEXT_DRIVER (self), 0);
+  g_return_val_if_fail (GDK_IS_TEXTURE (texture), 0);
+  g_return_val_if_fail (GSK_IS_GL_COMMAND_QUEUE (self->command_queue), 0);
+
+  context = self->command_queue->context;
+
+  if (GDK_IS_GL_TEXTURE (texture))
+    {
+      GdkGLContext *texture_context = gdk_gl_texture_get_context ((GdkGLTexture *)texture);
+      GdkGLContext *shared_context = gdk_gl_context_get_shared_context (context);
+
+      if (texture_context == context ||
+          (shared_context != NULL &&
+           shared_context == gdk_gl_context_get_shared_context (texture_context)))
+
+        {
+          /* A GL texture from the same GL context is a simple task... */
+          return gdk_gl_texture_get_id ((GdkGLTexture *)texture);
+        }
+      else
+        {
+          cairo_surface_t *surface;
+
+          /* In this case, we have to temporarily make the texture's
+           * context the current one, download its data into our context
+           * and then create a texture from it. */
+          if (texture_context != NULL)
+            gdk_gl_context_make_current (texture_context);
+
+          surface = gdk_texture_download_surface (texture);
+          downloaded_texture = gdk_texture_new_for_surface (surface);
+          cairo_surface_destroy (surface);
+
+          gdk_gl_context_make_current (context);
+
+          source_texture = downloaded_texture;
+        }
+    }
+  else
+    {
+      t = gdk_texture_get_render_data (texture, self);
+
+      if (t)
+        {
+          if (t->min_filter == min_filter && t->mag_filter == mag_filter)
+            return t->texture_id;
+        }
+
+      source_texture = texture;
+    }
+
+  t = g_slice_new0 (GskGLTexture);
+  t->width = gdk_texture_get_width (texture);
+  t->height = gdk_texture_get_height (texture);
+  t->last_used_in_frame = self->current_frame_id;
+  t->min_filter = min_filter;
+  t->mag_filter = mag_filter;
+  t->texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
+                                                       source_texture,
+                                                       t->width,
+                                                       t->height);
+
+  if (gdk_texture_set_render_data (texture, self, t, gsk_next_driver_release_texture))
+    t->user = texture;
+
+  gdk_gl_context_label_object_printf (context, GL_TEXTURE, t->texture_id,
+                                      "GdkTexture<%p> %d", texture, t->texture_id);
+
+  g_clear_object (&downloaded_texture);
+
+  return t->texture_id;
+}
diff --git a/gsk/next/gskgldriverprivate.h b/gsk/next/gskgldriverprivate.h
index 16ec0c9328..4a2b1c63bd 100644
--- a/gsk/next/gskgldriverprivate.h
+++ b/gsk/next/gskgldriverprivate.h
@@ -110,6 +110,10 @@ gboolean       gsk_next_driver_lookup_texture          (GskNextDriver        *se
 void           gsk_next_driver_insert_texture          (GskNextDriver        *self,
                                                         const GskTextureKey  *key,
                                                         guint                 texture_id);
+guint          gsk_next_driver_load_texture            (GskNextDriver        *self,
+                                                        GdkTexture           *texture,
+                                                        int                   min_filter,
+                                                        int                   mag_filter);
 
 G_END_DECLS
 


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