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
This commit is contained in:
Balló György
2023-09-27 14:08:07 +02:00
parent 9e45d0cef6
commit 261780ac51
3 changed files with 15 additions and 12 deletions

View File

@ -22,10 +22,6 @@
#include "gdkinternals.h"
#ifdef GDK_WINDOWING_WIN32
# include "win32/gdkwin32.h"
#endif
#include <epoxy/gl.h>
#include <math.h>
#include <string.h>
@ -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);

View File

@ -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
{

View File

@ -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);