[gtk/wip/otte/color-profiles: 18/40] gl: Move gdk_gl_context_upload_texture() into NGL
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/color-profiles: 18/40] gl: Move gdk_gl_context_upload_texture() into NGL
- Date: Thu, 30 Sep 2021 23:20:39 +0000 (UTC)
commit dcbeecb0032d49d7a10c536c1c6a10054a12d91f
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]