[gtk/wip/master.win.egl: 2375/2375] OpenGL/ES: Fix 'R' and 'B' bits inverted on Windows



commit d170c6bac01240715661ccbfdcea7949f904192d
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Tue Jul 31 18:18:59 2018 +0800

    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.

 gdk/gdkgl.c                    |  4 +++-
 gdk/gdkglcontext.c             | 20 ++++++++++++++++++++
 gdk/gdkglcontextprivate.h      |  2 ++
 gdk/win32/gdkglcontext-win32.c | 14 ++++++++++----
 4 files changed, 35 insertions(+), 5 deletions(-)
---
diff --git a/gdk/gdkgl.c b/gdk/gdkgl.c
index 1e24e77687..7f8a28f2dd 100644
--- a/gdk/gdkgl.c
+++ b/gdk/gdkgl.c
@@ -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);
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 48564f3bb9..59d6e783bb 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -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 {
@@ -1218,3 +1222,19 @@ gdk_gl_context_get_current (void)
 
   return current;
 }
+
+/* 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;
+}
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index c7acccba43..0672ba15f6 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -105,6 +105,8 @@ void                    gdk_gl_context_label_object_printf      (GdkGLContext
                                                                  guint            name,
                                                                  const char      *format,
                                                                 ...)  G_GNUC_PRINTF (4, 5);
+gboolean                gdk_gl_context_use_es_bgra              (GdkGLContext    *context);
+
 G_END_DECLS
 
 #endif /* __GDK_GL_CONTEXT_PRIVATE_H__ */
diff --git a/gdk/win32/gdkglcontext-win32.c b/gdk/win32/gdkglcontext-win32.c
index 9b8a5a5659..2d5bf94436 100644
--- a/gdk/win32/gdkglcontext-win32.c
+++ b/gdk/win32/gdkglcontext-win32.c
@@ -215,9 +215,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)};
 
@@ -228,7 +226,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
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]