forked from AuroraMiddleware/gtk
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:
parent
e5600ab99b
commit
cf0175ffce
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user