From ef8c8357624f8f05391d85b9d74ed68d2c3c0c02 Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Fri, 26 May 2023 14:45:05 +0200 Subject: [PATCH] gsk: Support swizzle for gray and alpha formats Swizzling is needed to display one channel memory formats as gray etc. --- gdk/gdkgltexture.c | 6 ++++-- gdk/gdkmemoryformat.c | 4 +++- gdk/gdkmemoryformatprivate.h | 5 ++++- gsk/gl/gskglcommandqueue.c | 32 ++++++++++++++++++++++++++------ gsk/gskrendernodeparser.c | 8 ++++++++ 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/gdk/gdkgltexture.c b/gdk/gdkgltexture.c index e08711aaf2..59244f4422 100644 --- a/gdk/gdkgltexture.c +++ b/gdk/gdkgltexture.c @@ -147,8 +147,9 @@ gdk_gl_texture_find_format (gboolean use_es, for (format = 0; format < GDK_MEMORY_N_FORMATS; format++) { GLenum q_internal_format, q_format, q_type; + GLint q_swizzle[4]; - if (!gdk_memory_format_gl_format (format, use_es, gl_major, gl_minor, &q_internal_format, &q_format, &q_type)) + if (!gdk_memory_format_gl_format (format, use_es, gl_major, gl_minor, &q_internal_format, &q_format, &q_type, &q_swizzle)) continue; if (q_format != gl_format || q_type != gl_type) @@ -170,6 +171,7 @@ gdk_gl_texture_do_download (GdkGLTexture *self, gsize expected_stride; Download *download = download_; GLenum gl_internal_format, gl_format, gl_type; + GLint gl_swizzle[4]; int major, minor; expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format); @@ -177,7 +179,7 @@ gdk_gl_texture_do_download (GdkGLTexture *self, if (download->stride == expected_stride && !gdk_gl_context_get_use_es (context) && - gdk_memory_format_gl_format (download->format, TRUE, major, minor, &gl_internal_format, &gl_format, &gl_type)) + gdk_memory_format_gl_format (download->format, TRUE, major, minor, &gl_internal_format, &gl_format, &gl_type, &gl_swizzle)) { glGetTexImage (GL_TEXTURE_2D, 0, diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c index 4e92efe980..9493f10eb6 100644 --- a/gdk/gdkmemoryformat.c +++ b/gdk/gdkmemoryformat.c @@ -592,11 +592,13 @@ gdk_memory_format_gl_format (GdkMemoryFormat format, guint gl_minor, guint *out_internal_format, guint *out_format, - guint *out_type) + guint *out_type, + GLint (*out_swizzle)[4]) { *out_internal_format = memory_formats[format].gl.internal_format; *out_format = memory_formats[format].gl.format; *out_type = memory_formats[format].gl.type; + memcpy (out_swizzle, &memory_formats[format].gl.swizzle, sizeof(GLint) * 4); if (memory_formats[format].alpha == GDK_MEMORY_ALPHA_STRAIGHT) return FALSE; diff --git a/gdk/gdkmemoryformatprivate.h b/gdk/gdkmemoryformatprivate.h index 477baef25e..5f2b4c06ad 100644 --- a/gdk/gdkmemoryformatprivate.h +++ b/gdk/gdkmemoryformatprivate.h @@ -21,6 +21,8 @@ #include "gdkenums.h" +#include + G_BEGIN_DECLS typedef enum { @@ -39,7 +41,8 @@ gboolean gdk_memory_format_gl_format (GdkMemoryFormat guint gl_minor, guint *out_internal_format, guint *out_format, - guint *out_type); + guint *out_type, + GLint (*out_gizzle)[4]); void gdk_memory_convert (guchar *dest_data, gsize dest_stride, diff --git a/gsk/gl/gskglcommandqueue.c b/gsk/gl/gskglcommandqueue.c index 204d2555d9..4a19f59c4f 100644 --- a/gsk/gl/gskglcommandqueue.c +++ b/gsk/gl/gskglcommandqueue.c @@ -1454,7 +1454,8 @@ memory_format_gl_format (GdkMemoryFormat data_format, guint minor, guint *gl_internalformat, guint *gl_format, - guint *gl_type) + guint *gl_type, + GLint (*gl_swizzle)[4]) { if (gdk_memory_format_gl_format (data_format, use_es, @@ -1462,7 +1463,8 @@ memory_format_gl_format (GdkMemoryFormat data_format, minor, gl_internalformat, gl_format, - gl_type)) + gl_type, + gl_swizzle)) return data_format; if (gdk_memory_format_prefers_high_depth (data_format)) @@ -1474,7 +1476,8 @@ memory_format_gl_format (GdkMemoryFormat data_format, minor, gl_internalformat, gl_format, - gl_type)) + gl_type, + gl_swizzle)) return data_format; } @@ -1485,7 +1488,8 @@ memory_format_gl_format (GdkMemoryFormat data_format, minor, gl_internalformat, gl_format, - gl_type)) + gl_type, + gl_swizzle)) { g_assert_not_reached (); } @@ -1508,6 +1512,7 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self, GLenum gl_internalformat; GLenum gl_format; GLenum gl_type; + GLint gl_swizzle[4]; gsize bpp; gboolean use_es; int major, minor; @@ -1524,7 +1529,8 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self, minor, &gl_internalformat, &gl_format, - &gl_type); + &gl_type, + &gl_swizzle); gdk_texture_downloader_init (&downloader, texture); gdk_texture_downloader_set_format (&downloader, data_format); @@ -1559,6 +1565,18 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self, glPixelStorei (GL_UNPACK_ALIGNMENT, 4); + /* Only apply swizzle if really needed, might not even be + * supported if default values are set + */ + if (gl_swizzle[0] != GL_RED || gl_swizzle[1] != GL_GREEN || gl_swizzle[2] != GL_BLUE) + { + /* Set each channel independently since GLES 3.0 doesn't support the iv method */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, gl_swizzle[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, gl_swizzle[1]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, gl_swizzle[2]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, gl_swizzle[3]); + } + g_bytes_unref (bytes); } @@ -1573,6 +1591,7 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self, GLenum gl_internalformat; GLenum gl_format; GLenum gl_type; + GLint gl_swizzle[4]; gboolean use_es; int texture_id; int major, minor; @@ -1617,7 +1636,8 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self, minor, &gl_internalformat, &gl_format, - &gl_type); + &gl_type, + &gl_swizzle); glTexImage2D (GL_TEXTURE_2D, 0, gl_internalformat, width, height, 0, gl_format, gl_type, NULL); diff --git a/gsk/gskrendernodeparser.c b/gsk/gskrendernodeparser.c index c8ffad4bd1..fc1e1cd422 100644 --- a/gsk/gskrendernodeparser.c +++ b/gsk/gskrendernodeparser.c @@ -2892,6 +2892,14 @@ append_texture_param (Printer *p, case GDK_MEMORY_R16G16B16: case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED: case GDK_MEMORY_R16G16B16A16: + case GDK_MEMORY_G8A8_PREMULTIPLIED: + case GDK_MEMORY_G8A8: + case GDK_MEMORY_G8: + case GDK_MEMORY_G16A16_PREMULTIPLIED: + case GDK_MEMORY_G16A16: + case GDK_MEMORY_G16: + case GDK_MEMORY_A8: + case GDK_MEMORY_A16: bytes = gdk_texture_save_to_png_bytes (texture); g_string_append (p->str, "url(\"data:image/png;base64,"); break; -- 2.30.2