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



commit 9608ade0133ccf36e43ba3734741035bb2845b30
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 b1073483a7..d0bda034b0 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 5919ec4747..378bfa8f0e 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 {
@@ -1194,3 +1198,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]