From 261780ac51aa353f8db2e87068d22dc166b23399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ball=C3=B3=20Gy=C3=B6rgy?= Date: Wed, 27 Sep 2023 14:08:07 +0200 Subject: [PATCH] OpenGL/ES: Fix 'R' and 'B' bits inverted on all platforms The color channels are swapped on Linux too, not only on Windows. It can be reproduced by running the "OpenGL Area" example from gtk3-demo with GDK_GL=gles, or play a video in totem with GDK_GL=gles. Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/3032 --- gdk/gdkgl.c | 16 ++++------------ gdk/gdkglcontext.c | 10 ++++++++++ gdk/gdkglcontextprivate.h | 1 + 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/gdk/gdkgl.c b/gdk/gdkgl.c index d3b460b4b7..62eeada105 100644 --- a/gdk/gdkgl.c +++ b/gdk/gdkgl.c @@ -22,10 +22,6 @@ #include "gdkinternals.h" -#ifdef GDK_WINDOWING_WIN32 -# include "win32/gdkwin32.h" -#endif - #include #include #include @@ -633,13 +629,6 @@ gdk_cairo_draw_from_gl (cairo_t *cr, { /* Software fallback */ int major, minor, version; - gboolean es_read_bgra = FALSE; - -#ifdef GDK_WINDOWING_WIN32 - /* on ANGLE GLES, we need to set the glReadPixel() format as GL_BGRA instead */ - if (GDK_WIN32_IS_GL_CONTEXT(paint_context)) - es_read_bgra = TRUE; -#endif gdk_gl_context_get_version (paint_context, &major, &minor); version = major * 100 + minor; @@ -681,8 +670,11 @@ gdk_cairo_draw_from_gl (cairo_t *cr, if (!gdk_gl_context_get_use_es (paint_context)) glReadPixels (x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, cairo_image_surface_get_data (image)); + else if (gdk_gl_context_has_texture_format_bgra (paint_context) && G_BYTE_ORDER == G_LITTLE_ENDIAN) + glReadPixels (x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, + cairo_image_surface_get_data (image)); else - glReadPixels (x, y, width, height, es_read_bgra ? GL_BGRA : GL_RGBA, GL_UNSIGNED_BYTE, + glReadPixels (x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, cairo_image_surface_get_data (image)); glPixelStorei (GL_PACK_ROW_LENGTH, 0); diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c index 4c137a8d5d..80d126f2de 100644 --- a/gdk/gdkglcontext.c +++ b/gdk/gdkglcontext.c @@ -102,6 +102,7 @@ typedef struct { guint has_frame_terminator : 1; guint has_unpack_subimage : 1; guint has_sync : 1; + guint has_texture_format_bgra : 1; guint extensions_checked : 1; guint debug_enabled : 1; guint forward_compatible : 1; @@ -450,6 +451,14 @@ gdk_gl_context_has_sync (GdkGLContext *context) return priv->has_sync; } +gboolean +gdk_gl_context_has_texture_format_bgra (GdkGLContext *context) +{ + GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context); + + return priv->has_texture_format_bgra; +} + /** * gdk_gl_context_set_debug_enabled: * @context: a #GdkGLContext @@ -819,6 +828,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context) priv->has_unpack_subimage = epoxy_has_gl_extension ("GL_EXT_unpack_subimage"); priv->has_sync = priv->gl_version >= 30; + priv->has_texture_format_bgra = epoxy_has_gl_extension ("GL_EXT_texture_format_BGRA8888"); } else { diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h index 94ecb34d30..731bf3e384 100644 --- a/gdk/gdkglcontextprivate.h +++ b/gdk/gdkglcontextprivate.h @@ -87,6 +87,7 @@ gboolean gdk_gl_context_has_framebuffer_blit (GdkGLContext gboolean gdk_gl_context_has_frame_terminator (GdkGLContext *context); gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context); gboolean gdk_gl_context_has_sync (GdkGLContext *context); +gboolean gdk_gl_context_has_texture_format_bgra (GdkGLContext *context); void gdk_gl_context_end_frame (GdkGLContext *context, cairo_region_t *painted, cairo_region_t *damage);