OpenGL/ES: Fix 'R' and 'B' bits inverted on Windows

We need to use GL_BGRA instead of GL_RGBA when doing glReadPixels() on
EGL on Windows (ANGLE) so that the red and blue bits won't be displayed
inverted.

Also fix the logic where we determine whether to bit blit or redraw
everything.
This commit is contained in:
Chun-wei Fan 2018-07-31 18:18:59 +08:00
parent e5600ab99b
commit cf0175ffce
4 changed files with 36 additions and 5 deletions

View File

@ -334,6 +334,7 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
cairo_region_t *clip_region;
GdkGLContextPaintData *paint_data;
int major, minor, version;
gboolean es_use_bgra = FALSE;
paint_context = gdk_surface_get_paint_gl_context (surface, NULL);
if (paint_context == NULL)
@ -343,6 +344,7 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
}
clip_region = gdk_cairo_region_from_clip (cr);
es_use_bgra = gdk_gl_context_use_es_bgra (paint_context);
gdk_gl_context_make_current (paint_context);
paint_data = gdk_gl_context_get_paint_data (paint_context);
@ -413,7 +415,7 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
glReadPixels (x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
cairo_image_surface_get_data (image));
else
glReadPixels (x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
glReadPixels (x, y, width, height, es_use_bgra ? GL_BGRA : GL_RGBA, GL_UNSIGNED_BYTE,
cairo_image_surface_get_data (image));
glPixelStorei (GL_PACK_ROW_LENGTH, 0);

View File

@ -92,6 +92,10 @@
#include "gdkintl.h"
#include "gdk-private.h"
#ifdef GDK_WINDOWING_WIN32
# include "gdk/win32/gdkwin32.h"
#endif
#include <epoxy/gl.h>
typedef struct {
@ -1226,3 +1230,19 @@ gdk_gl_context_has_debug (GdkGLContext *self)
return priv->debug_enabled || priv->use_khr_debug;
}
/* This is currently private! */
/* When using GL/ES, don't flip the 'R' and 'B' bits on Windows/ANGLE for glReadPixels() */
gboolean
gdk_gl_context_use_es_bgra (GdkGLContext *context)
{
if (!gdk_gl_context_get_use_es (context))
return FALSE;
#ifdef GDK_WINDOWING_WIN32
if (GDK_WIN32_IS_GL_CONTEXT (context))
return TRUE;
#endif
return FALSE;
}

View File

@ -107,6 +107,9 @@ void gdk_gl_context_label_object_printf (GdkGLContext
...) G_GNUC_PRINTF (4, 5);
gboolean gdk_gl_context_has_debug (GdkGLContext *self) G_GNUC_PURE;
gboolean gdk_gl_context_use_es_bgra (GdkGLContext *context);
G_END_DECLS
#endif /* __GDK_GL_CONTEXT_PRIVATE_H__ */

View File

@ -213,9 +213,7 @@ gdk_win32_gl_context_end_frame (GdkDrawContext *draw_context,
EGLSurface egl_surface = _gdk_win32_surface_get_egl_surface (surface, context_win32->egl_config, FALSE);
gboolean force_egl_redraw_all = _get_is_egl_force_redraw (surface);
if (!force_egl_redraw_all)
gdk_gl_blit_region (surface, painted);
else if (force_egl_redraw_all)
if (force_egl_redraw_all)
{
GdkRectangle rect = {0, 0, gdk_surface_get_width (surface), gdk_surface_get_height (surface)};
@ -226,7 +224,15 @@ gdk_win32_gl_context_end_frame (GdkDrawContext *draw_context,
_reset_egl_force_redraw (surface);
}
eglSwapBuffers (display->egl_disp, egl_surface);
if (cairo_region_contains_rectangle (painted, &whole_window) == CAIRO_REGION_OVERLAP_IN || force_egl_redraw_all)
eglSwapBuffers (display->egl_disp, egl_surface);
else if (gdk_gl_context_has_framebuffer_blit (context))
gdk_gl_blit_region (surface, painted);
else
{
g_warning ("Need to swap whole buffer even thouigh not everything was redrawn. Expect artifacts.");
eglSwapBuffers (display->egl_disp, egl_surface);
}
}
#endif
}