[gtk/wip/chergert/glproto: 194/526] start on texture loading
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/glproto: 194/526] start on texture loading
- Date: Tue, 16 Feb 2021 01:14:29 +0000 (UTC)
commit 0cec02b62e918ff97a4dc8819739367d6b7fb24e
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]