[gtk/win32-gl-reorg-3] GDK-Win32: Reorganize gdkgdlcontext-win32.c




commit 35f845b809bbb8eec1441285a745fd980c0e0f5a
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Wed Aug 18 18:47:15 2021 +0800

    GDK-Win32: Reorganize gdkgdlcontext-win32.c
    
    Group the WGL-specific code and GLES-specific code together, so that we
    can reduce the number of #ifdef ... in the code, to make the code more
    readable and easily maintained.  This will pave the way to add a
    fallback mode to use libANGLE (OpenGL/ES) in case the Desktop OpenGL
    support is inadequte, if OpenGL/ES support is enabled in the build.
    
    This is somewhat based on the updates that were done in GTK master, so
    we are using one subclass for WGL-based GdkGLContexts, and another for
    GLES-based GdkGLContexts.
    
    Also remove the underscores in many of the functions in
    gdkglcontext-win32.*.
    
    Clean up the code a bit as a result.

 gdk/win32/gdkdisplay-win32.c   |    2 +-
 gdk/win32/gdkdisplay-win32.h   |   31 +-
 gdk/win32/gdkevents-win32.c    |    4 +-
 gdk/win32/gdkglcontext-win32.c | 1500 ++++++++++++++++++++++------------------
 gdk/win32/gdkglcontext-win32.h |   59 +-
 gdk/win32/gdkwindow-win32.c    |   12 +-
 6 files changed, 857 insertions(+), 751 deletions(-)
---
diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c
index c2b572b402..2598c8ccd7 100644
--- a/gdk/win32/gdkdisplay-win32.c
+++ b/gdk/win32/gdkdisplay-win32.c
@@ -1299,7 +1299,7 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
   display_class->convert_selection = _gdk_win32_display_convert_selection;
   display_class->text_property_to_utf8_list = _gdk_win32_display_text_property_to_utf8_list;
   display_class->utf8_to_string_target = _gdk_win32_display_utf8_to_string_target;
-  display_class->make_gl_context_current = _gdk_win32_display_make_gl_context_current;
+  display_class->make_gl_context_current = gdk_win32_display_make_gl_context_current;
 
   display_class->get_n_monitors = gdk_win32_display_get_n_monitors;
   display_class->get_monitor = gdk_win32_display_get_monitor;
diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h
index 67201582ed..7a7e898ff8 100644
--- a/gdk/win32/gdkdisplay-win32.h
+++ b/gdk/win32/gdkdisplay-win32.h
@@ -33,6 +33,15 @@ typedef enum _GdkWin32ProcessDpiAwareness {
   PROCESS_PER_MONITOR_DPI_AWARE = 2
 } GdkWin32ProcessDpiAwareness;
 
+/* Define values for GL type used */
+typedef enum _GdkWin32GLContextType
+{
+  GDK_WIN32_GL_PENDING,
+  GDK_WIN32_GL_NONE,
+  GDK_WIN32_GL_WGL,
+  GDK_WIN32_GL_EGL
+} GdkWin32GLContextType;
+
 /* APIs from shcore.dll */
 typedef HRESULT (WINAPI *funcSetProcessDpiAwareness) (GdkWin32ProcessDpiAwareness value);
 typedef HRESULT (WINAPI *funcGetProcessDpiAwareness) (HANDLE                       handle,
@@ -81,20 +90,11 @@ struct _GdkWin32Display
   HWND hwnd;
   HWND clipboard_hwnd;
 
-  /* WGL/OpenGL Items */
-  guint have_wgl : 1;
+  /* OpenGL Items */
+  GdkWin32GLContextType gl_type;
   guint gl_version;
 
-#ifdef GDK_WIN32_ENABLE_EGL
-  /* EGL (Angle) Items */
-  guint have_egl : 1;
-  guint egl_version;
-  EGLDisplay egl_disp;
-  HDC hdc_egl_temp;
-#endif
-
-  GPtrArray *monitors;
-
+  /* WGL Items */
   guint hasWglARBCreateContext : 1;
   guint hasWglEXTSwapControl : 1;
   guint hasWglOMLSyncControl : 1;
@@ -104,12 +104,19 @@ struct _GdkWin32Display
   /* compensate around Intel OpenGL driver issues on blitting, see issue #3487 */
   guint needIntelGLWorkaround : 1; 
 
+  /* EGL (Angle) Items */
+  HDC hdc_egl_temp;
+
 #ifdef GDK_WIN32_ENABLE_EGL
+  EGLDisplay egl_disp;
+  EGLConfig egl_config;
   guint hasEglKHRCreateContext : 1;
   guint hasEglSurfacelessContext : 1;
   EGLint egl_min_swap_interval;
 #endif
 
+  GPtrArray *monitors;
+
   /* HiDPI Items */
   guint have_at_least_win81 : 1;
   GdkWin32ProcessDpiAwareness dpi_aware_type;
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index a7cc3e2394..84ea9792f3 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -3348,7 +3348,7 @@ gdk_event_translate (MSG  *msg,
          do_show_window (window, msg->wParam == SC_MINIMIZE ? TRUE : FALSE);
 
     if (msg->wParam == SC_RESTORE)
-      _gdk_win32_window_invalidate_egl_framebuffer (window);
+      gdk_win32_window_invalidate_egl_framebuffer (window);
          break;
         case SC_MAXIMIZE:
           impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
@@ -3436,7 +3436,7 @@ gdk_event_translate (MSG  *msg,
             {
               MINMAXINFO our_mmi;
 
-              _gdk_win32_window_invalidate_egl_framebuffer (window);
+              gdk_win32_window_invalidate_egl_framebuffer (window);
 
               if (_gdk_win32_window_fill_min_max_info (window, &our_mmi))
                 {
diff --git a/gdk/win32/gdkglcontext-win32.c b/gdk/win32/gdkglcontext-win32.c
index 24d2b6facd..9574244ddd 100644
--- a/gdk/win32/gdkglcontext-win32.c
+++ b/gdk/win32/gdkglcontext-win32.c
@@ -45,51 +45,34 @@
 # include <epoxy/egl.h>
 #endif
 
-G_DEFINE_TYPE (GdkWin32GLContext, gdk_win32_gl_context, GDK_TYPE_GL_CONTEXT)
-
-static void
-_gdk_win32_gl_context_dispose (GObject *gobject)
+struct _GdkWin32GLContext
 {
-  GdkGLContext *context = GDK_GL_CONTEXT (gobject);
-  GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (gobject);
-  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context));
-  GdkWindow *window = gdk_gl_context_get_window (context);
-  GdkWindowImplWin32 *impl = NULL;
+  GdkGLContext parent_instance;
 
-  if (context_win32->hglrc != NULL)
-    {
-      if (wglGetCurrentContext () == context_win32->hglrc)
-        wglMakeCurrent (NULL, NULL);
+  HDC gl_hdc;
+  guint need_alpha_bits : 1;
+  guint is_attached : 1;
+  guint do_frame_sync : 1;
+  guint do_blit_swap : 1;
+};
 
-      GDK_NOTE (OPENGL, g_print ("Destroying WGL context\n"));
+struct _GdkWin32GLContextClass
+{
+  GdkGLContextClass parent_class;
+};
 
-      wglDeleteContext (context_win32->hglrc);
-      context_win32->hglrc = NULL;
+G_DEFINE_TYPE (GdkWin32GLContext, gdk_win32_gl_context, GDK_TYPE_GL_CONTEXT)
 
-      ReleaseDC (GDK_WINDOW_HWND (window), context_win32->gl_hdc);
-    }
+static void
+gdk_win32_gl_context_cleanup (GdkGLContext *context)
+{
+  GdkWindow *window = gdk_gl_context_get_window (context);
 
-#ifdef GDK_WIN32_ENABLE_EGL
-  if (context_win32->egl_context != EGL_NO_CONTEXT)
+  if (window != NULL)
     {
-      if (eglGetCurrentContext () == context_win32->egl_context)
-        eglMakeCurrent(display_win32->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                       EGL_NO_CONTEXT);
-
-      GDK_NOTE (OPENGL, g_message ("Destroying EGL (ANGLE) context"));
-
-      eglDestroyContext (display_win32->egl_disp,
-                         context_win32->egl_context);
-      context_win32->egl_context = EGL_NO_CONTEXT;
-
-      impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+      GdkWindowImplWin32 *impl = NULL;
 
-      ReleaseDC (GDK_WINDOW_HWND (window), context_win32->gl_hdc);
-    }
-#endif
-
-  if (window != NULL && window->impl != NULL)
-    {
+      ReleaseDC (GDK_WINDOW_HWND (window), GDK_WIN32_GL_CONTEXT(context)->gl_hdc);
       impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 
       if (impl->suppress_layered > 0)
@@ -101,25 +84,6 @@ _gdk_win32_gl_context_dispose (GObject *gobject)
       if (impl->suppress_layered == 0)
         _gdk_win32_window_update_style_bits (window);
     }
-
-  G_OBJECT_CLASS (gdk_win32_gl_context_parent_class)->dispose (gobject);
-}
-
-static void
-gdk_win32_gl_context_class_init (GdkWin32GLContextClass *klass)
-{
-  GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
-  context_class->end_frame = _gdk_win32_gl_context_end_frame;
-  context_class->realize = _gdk_win32_gl_context_realize;
-
-  gobject_class->dispose = _gdk_win32_gl_context_dispose;
-}
-
-static void
-gdk_win32_gl_context_init (GdkWin32GLContext *self)
-{
 }
 
 static void
@@ -154,142 +118,22 @@ gdk_gl_blit_region (GdkWindow      *window,
     }
 }
 
-static gboolean
-_get_is_egl_force_redraw (GdkWindow *window)
-{
-  /* We only need to call gdk_window_invalidate_rect () if necessary */
-#ifdef GDK_WIN32_ENABLE_EGL
-  if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
-    {
-      GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
-
-      return impl->egl_force_redraw_all;
-    }
-#endif
-  return FALSE;
-}
-
-static void
-_reset_egl_force_redraw (GdkWindow *window)
-{
-#ifdef GDK_WIN32_ENABLE_EGL
-  if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
-    {
-      GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
-
-      if (impl->egl_force_redraw_all)
-        impl->egl_force_redraw_all = FALSE;
-    }
-#endif
-}
-
-void
-_gdk_win32_gl_context_end_frame (GdkGLContext *context,
-                                 cairo_region_t *painted,
-                                 cairo_region_t *damage)
-{
-  GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
-  GdkWindow *window = gdk_gl_context_get_window (context);
-  GdkWin32Display *display = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
-
-  gdk_gl_context_make_current (context);
-
-  if (!gdk_gl_context_get_use_es (context))
-    {
-      gboolean can_wait = display->hasWglOMLSyncControl;
-
-      if (context_win32->do_frame_sync)
-        {
-          glFinish ();
-
-          if (can_wait)
-            {
-              gint64 ust, msc, sbc;
-
-              wglGetSyncValuesOML (context_win32->gl_hdc, &ust, &msc, &sbc);
-              wglWaitForMscOML (context_win32->gl_hdc,
-                                0,
-                                2,
-                                (msc + 1) % 2,
-                                &ust, &msc, &sbc);
-            }
-        }
-
-      if (context_win32->do_blit_swap)
-        {
-          glDrawBuffer(GL_FRONT);
-          glReadBuffer(GL_BACK);
-          gdk_gl_blit_region (window, painted, display->needIntelGLWorkaround);
-          glDrawBuffer(GL_BACK);
-          glFlush();
-
-          if (gdk_gl_context_has_frame_terminator (context))
-            glFrameTerminatorGREMEDY ();
-        }
-      else
-        SwapBuffers (context_win32->gl_hdc);
-    }
-
-#ifdef GDK_WIN32_ENABLE_EGL
-  else
-    {
-      EGLSurface egl_surface = _gdk_win32_window_get_egl_surface (window, context_win32->egl_config, FALSE);
-      gboolean force_egl_redraw_all = _get_is_egl_force_redraw (window);
-
-      if (context_win32->do_blit_swap && !force_egl_redraw_all)
-        gdk_gl_blit_region (window, painted, FALSE);
-      else if (force_egl_redraw_all)
-        {
-          GdkRectangle rect = {0, 0, gdk_window_get_width (window), gdk_window_get_height (window)};
-
-          /* We need to do gdk_window_invalidate_rect() so that we don't get glitches after maximizing or
-           *  restoring or using aerosnap
-           */
-          gdk_window_invalidate_rect (window, &rect, TRUE);
-          _reset_egl_force_redraw (window);
-        }
-
-      eglSwapBuffers (display->egl_disp, egl_surface);
-    }
-#endif
-}
-
-void
-_gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
-                                            cairo_region_t *update_area)
+/* Section on WGL usage */
+struct _GdkWin32GLContextWGL
 {
-  cairo_rectangle_int_t window_rect;
-  gboolean invalidate_all = FALSE;
-  GdkWin32GLContext *context_win32;
-  cairo_rectangle_int_t whole_window = { 0, 0, gdk_window_get_width (window), gdk_window_get_height (window) 
};
-
-  /* Minimal update is ok if we're not drawing with gl */
-  if (window->gl_paint_context == NULL)
-    return;
+  GdkWin32GLContext parent_instance;
 
-  context_win32 = GDK_WIN32_GL_CONTEXT (window->gl_paint_context);
-  context_win32->do_blit_swap = FALSE;
+  HGLRC wgl_context;
+};
 
-  if (gdk_gl_context_has_framebuffer_blit (window->gl_paint_context) &&
-      cairo_region_contains_rectangle (update_area, &whole_window) != CAIRO_REGION_OVERLAP_IN)
-    {
-      context_win32->do_blit_swap = TRUE;
-    }
-  else
-    invalidate_all = TRUE;
+typedef struct _GdkWin32GLContextClass GdkWin32GLContextWGLClass;
+typedef struct _GdkWin32GLContextWGL   GdkWin32GLContextWGL;
 
-  if (invalidate_all)
-    {
-      window_rect.x = 0;
-      window_rect.y = 0;
-      window_rect.width = gdk_window_get_width (window);
-      window_rect.height = gdk_window_get_height (window);
+G_DEFINE_TYPE (GdkWin32GLContextWGL, gdk_win32_gl_context_wgl, GDK_TYPE_WIN32_GL_CONTEXT)
 
-      /* If nothing else is known, repaint everything so that the back
-         buffer is fully up-to-date for the swapbuffer */
-      cairo_region_union_rectangle (update_area, &window_rect);
-    }
-}
+#define GDK_TYPE_WIN32_GL_CONTEXT_WGL     (gdk_win32_gl_context_wgl_get_type())
+#define GDK_WIN32_GL_CONTEXT_WGL(obj)     (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_WIN32_GL_CONTEXT_WGL, 
GdkWin32GLContextWGL))
+#define GDK_IS_WIN32_GL_CONTEXT_WGL(obj)  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_WIN32_GL_CONTEXT_WGL))
 
 typedef struct
 {
@@ -301,7 +145,7 @@ typedef struct
 } GdkWGLDummy;
 
 static void
-_destroy_dummy_gl_context (GdkWGLDummy dummy)
+destroy_dummy_gl_context (GdkWGLDummy dummy)
 {
   if (dummy.hglrc != NULL)
     {
@@ -328,7 +172,7 @@ _destroy_dummy_gl_context (GdkWGLDummy dummy)
 
 /* Yup, we need to create a dummy window for the dummy WGL context */
 static void
-_get_dummy_window_hwnd (GdkWGLDummy *dummy)
+get_dummy_window_hwnd (GdkWGLDummy *dummy)
 {
   WNDCLASSEX dummy_wc;
 
@@ -365,16 +209,16 @@ _get_dummy_window_hwnd (GdkWGLDummy *dummy)
 }
 
 static gint
-_gdk_init_dummy_context (GdkWGLDummy    *dummy,
+gdk_init_dummy_context (GdkWGLDummy    *dummy,
                          const gboolean  need_alpha_bits);
 
 #define PIXEL_ATTRIBUTES 19
 
 static gint
-_get_wgl_pfd (HDC                    hdc,
-              const gboolean         need_alpha_bits,
-              PIXELFORMATDESCRIPTOR *pfd,
-              GdkWin32Display       *display)
+get_wgl_pfd (HDC                    hdc,
+             const gboolean         need_alpha_bits,
+             PIXELFORMATDESCRIPTOR *pfd,
+             GdkWin32Display       *display)
 {
   gint best_pf = 0;
 
@@ -444,7 +288,7 @@ _get_wgl_pfd (HDC                    hdc,
       /* acquire and cache dummy Window (HWND & HDC) and
        * dummy GL Context, we need it for wglChoosePixelFormatARB()
        */
-      best_pf = _gdk_init_dummy_context (&dummy, need_alpha_bits);
+      best_pf = gdk_init_dummy_context (&dummy, need_alpha_bits);
 
       if (best_pf == 0 || !wglMakeCurrent (dummy.hdc, dummy.hglrc))
         {
@@ -481,7 +325,7 @@ _get_wgl_pfd (HDC                    hdc,
 
       /* Go back to the HDC that we were using, since we are done with the dummy HDC and GL Context */
       wglMakeCurrent (hdc_current, hglrc_current);
-      _destroy_dummy_gl_context (dummy);
+      destroy_dummy_gl_context (dummy);
     }
   else
     {
@@ -512,19 +356,19 @@ _get_wgl_pfd (HDC                    hdc,
  * one and cache it for later use
  */
 static gint
-_gdk_init_dummy_context (GdkWGLDummy    *dummy,
+gdk_init_dummy_context (GdkWGLDummy    *dummy,
                          const gboolean  need_alpha_bits)
 {
   PIXELFORMATDESCRIPTOR pfd;
   gboolean set_pixel_format_result = FALSE;
   gint best_idx = 0;
 
-  _get_dummy_window_hwnd (dummy);
+  get_dummy_window_hwnd (dummy);
 
   dummy->hdc = GetDC (dummy->hwnd);
   memset (&pfd, 0, sizeof (PIXELFORMATDESCRIPTOR));
 
-  best_idx = _get_wgl_pfd (dummy->hdc, need_alpha_bits, &pfd, NULL);
+  best_idx = get_wgl_pfd (dummy->hdc, need_alpha_bits, &pfd, NULL);
 
   if (best_idx != 0)
     set_pixel_format_result = SetPixelFormat (dummy->hdc,
@@ -543,183 +387,154 @@ _gdk_init_dummy_context (GdkWGLDummy    *dummy,
   return best_idx;
 }
 
-#ifdef GDK_WIN32_ENABLE_EGL
-
-#ifndef EGL_PLATFORM_ANGLE_ANGLE
-#define EGL_PLATFORM_ANGLE_ANGLE          0x3202
-#endif
-
-#ifndef EGL_PLATFORM_ANGLE_TYPE_ANGLE
-#define EGL_PLATFORM_ANGLE_TYPE_ANGLE     0x3203
-#endif
-
-#ifndef EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE
-#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
-#endif
-
-static EGLDisplay
-_gdk_win32_get_egl_display (GdkWin32Display *display)
+static void
+gdk_win32_gl_context_dispose_wgl (GObject *gobject)
 {
-  EGLDisplay disp;
-  gboolean success = FALSE;
+  GdkGLContext *context = GDK_GL_CONTEXT (gobject);
+  GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (context);
 
-  if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
+  if (context_wgl->wgl_context != NULL)
     {
-      PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = (void *) eglGetProcAddress 
("eglGetPlatformDisplayEXT");
-      if (getPlatformDisplay)
-        {
-          EGLint disp_attr[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 
EGL_NONE};
-
-          disp = getPlatformDisplay (EGL_PLATFORM_ANGLE_ANGLE, display->hdc_egl_temp, disp_attr);
-
-          if (disp != EGL_NO_DISPLAY)
-            return disp;
-        }
-    }
-  return eglGetDisplay (display->hdc_egl_temp);
-}
-#endif
-
-static gboolean
-_gdk_win32_display_init_gl (GdkDisplay *display,
-                            const gboolean need_alpha_bits)
-{
-  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
-  gint best_idx = 0;
-  gboolean disable_wgl = FALSE;
+      GdkWindow *window = gdk_gl_context_get_window (context);
 
-#ifdef GDK_WIN32_ENABLE_EGL
-  disable_wgl = ((_gdk_gl_flags & GDK_GL_GLES) != 0) ||
-                display_win32->running_on_arm64;
-#endif
+      if (wglGetCurrentContext () == context_wgl->wgl_context)
+        wglMakeCurrent (NULL, NULL);
 
-  if (display_win32->have_wgl
-#ifdef GDK_WIN32_ENABLE_EGL
-      || display_win32->have_egl
-#endif
-     )
-    return TRUE;
+      GDK_NOTE (OPENGL, g_print ("Destroying WGL context\n"));
 
-  if (!disable_wgl)
-    {
-      /* acquire and cache dummy Window (HWND & HDC) and
-       * dummy GL Context, it is used to query functions
-       * and used for other stuff as well
-       */
-      GdkWGLDummy dummy;
-      memset (&dummy, 0, sizeof (GdkWGLDummy));
+      wglDeleteContext (context_wgl->wgl_context);
+      context_wgl->wgl_context = NULL;
 
-      best_idx = _gdk_init_dummy_context (&dummy, need_alpha_bits);
+      gdk_win32_gl_context_cleanup (context);
+    }
 
-      if (best_idx == 0 || !wglMakeCurrent (dummy.hdc, dummy.hglrc))
-        return FALSE;
+  G_OBJECT_CLASS (gdk_win32_gl_context_parent_class)->dispose (gobject);
+}
 
-      display_win32->have_wgl = TRUE;
-      display_win32->gl_version = epoxy_gl_version ();
-
-      display_win32->hasWglARBCreateContext =
-        epoxy_has_wgl_extension (dummy.hdc, "WGL_ARB_create_context");
-      display_win32->hasWglEXTSwapControl =
-        epoxy_has_wgl_extension (dummy.hdc, "WGL_EXT_swap_control");
-      display_win32->hasWglOMLSyncControl =
-        epoxy_has_wgl_extension (dummy.hdc, "WGL_OML_sync_control");
-      display_win32->hasWglARBPixelFormat =
-        epoxy_has_wgl_extension (dummy.hdc, "WGL_ARB_pixel_format");
-      display_win32->hasWglARBmultisample =
-        epoxy_has_wgl_extension (dummy.hdc, "WGL_ARB_multisample");
-      display_win32->needIntelGLWorkaround =
-        (g_ascii_strcasecmp (glGetString (GL_VENDOR), "intel") == 0);
+static void
+gdk_win32_gl_context_end_frame_wgl (GdkGLContext   *context,
+                                    cairo_region_t *painted,
+                                    cairo_region_t *damage)
+{
+  GdkWin32Display *display_win32 = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
+  GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
 
-      GDK_NOTE (OPENGL,
-                g_print ("WGL API version %d.%d found\n"
-                         " - Vendor: %s\n"
-                         " - Intel OpenGL workaround: %s\n"
-                         " - Checked extensions:\n"
-                         "\t* WGL_ARB_pixel_format: %s\n"
-                         "\t* WGL_ARB_create_context: %s\n"
-                         "\t* WGL_EXT_swap_control: %s\n"
-                         "\t* WGL_OML_sync_control: %s\n"
-                         "\t* WGL_ARB_multisample: %s\n",
-                         display_win32->gl_version / 10,
-                         display_win32->gl_version % 10,
-                         glGetString (GL_VENDOR),
-                         display_win32->needIntelGLWorkaround ? "yes" : "no",
-                         display_win32->hasWglARBPixelFormat ? "yes" : "no",
-                         display_win32->hasWglARBCreateContext ? "yes" : "no",
-                         display_win32->hasWglEXTSwapControl ? "yes" : "no",
-                         display_win32->hasWglOMLSyncControl ? "yes" : "no",
-                         display_win32->hasWglARBmultisample ? "yes" : "no"));
-
-      wglMakeCurrent (NULL, NULL);
-
-      _destroy_dummy_gl_context (dummy);
-    }
+  gdk_gl_context_make_current (context);
 
-#ifdef GDK_WIN32_ENABLE_EGL
-  else
+  if (context_win32->do_frame_sync)
     {
-      EGLDisplay egl_disp = _gdk_win32_get_egl_display (display_win32);
+      glFinish ();
 
-      if (egl_disp == EGL_NO_DISPLAY ||
-          !eglInitialize (egl_disp, NULL, NULL))
+      if (display_win32->hasWglOMLSyncControl)
         {
-          if (egl_disp != EGL_NO_DISPLAY)
-            {
-              eglTerminate (egl_disp);
-              egl_disp = EGL_NO_DISPLAY;
-            }
-
-          return FALSE;
+          gint64 ust, msc, sbc;
+
+          wglGetSyncValuesOML (context_win32->gl_hdc, &ust, &msc, &sbc);
+          wglWaitForMscOML (context_win32->gl_hdc,
+                            0,
+                            2,
+                            (msc + 1) % 2,
+                            &ust, &msc, &sbc);
         }
+    }
 
-      display_win32->egl_disp = egl_disp;
-      display_win32->have_egl = TRUE;
-      display_win32->egl_version = epoxy_egl_version (egl_disp);
-
-      eglBindAPI(EGL_OPENGL_ES_API);
-
-      display_win32->hasEglSurfacelessContext =
-        epoxy_has_egl_extension (egl_disp, "EGL_KHR_surfaceless_context");
+  if (context_win32->do_blit_swap)
+    {
+      GdkWindow *window = gdk_gl_context_get_window (context);
 
+      glDrawBuffer(GL_FRONT);
+      glReadBuffer(GL_BACK);
+      gdk_gl_blit_region (window, painted, display_win32->needIntelGLWorkaround);
+      glDrawBuffer(GL_BACK);
+      glFlush();
 
-      GDK_NOTE (OPENGL,
-                g_print ("EGL API version %d.%d found\n"
-                         " - Vendor: %s\n"
-                         " - Checked extensions:\n"
-                         "\t* EGL_KHR_surfaceless_context: %s\n",
-                         display_win32->egl_version / 10,
-                         display_win32->egl_version % 10,
-                         eglQueryString (display_win32->egl_disp, EGL_VENDOR),
-                         display_win32->hasEglSurfacelessContext ? "yes" : "no"));
+      if (gdk_gl_context_has_frame_terminator (context))
+        glFrameTerminatorGREMEDY ();
     }
-#endif
+  else
+    SwapBuffers (context_win32->gl_hdc);
+}
 
-  return TRUE;
+static GdkWin32GLContextType
+gdk_win32_display_init_wgl (GdkWin32Display *display_win32,
+                            const gboolean   need_alpha_bits)
+{
+  /* acquire and cache dummy Window (HWND & HDC) and
+   * dummy GL Context, it is used to query functions
+   * and used for other stuff as well
+   */
+  GdkWGLDummy dummy;
+  gint best_idx = 0;
+
+  memset (&dummy, 0, sizeof (GdkWGLDummy));
+
+  best_idx = gdk_init_dummy_context (&dummy, need_alpha_bits);
+
+  if (best_idx == 0 || !wglMakeCurrent (dummy.hdc, dummy.hglrc))
+    return GDK_WIN32_GL_NONE;
+
+  display_win32->gl_version = epoxy_gl_version ();
+
+  display_win32->hasWglARBCreateContext =
+    epoxy_has_wgl_extension (dummy.hdc, "WGL_ARB_create_context");
+  display_win32->hasWglEXTSwapControl =
+    epoxy_has_wgl_extension (dummy.hdc, "WGL_EXT_swap_control");
+  display_win32->hasWglOMLSyncControl =
+    epoxy_has_wgl_extension (dummy.hdc, "WGL_OML_sync_control");
+  display_win32->hasWglARBPixelFormat =
+    epoxy_has_wgl_extension (dummy.hdc, "WGL_ARB_pixel_format");
+  display_win32->hasWglARBmultisample =
+    epoxy_has_wgl_extension (dummy.hdc, "WGL_ARB_multisample");
+  display_win32->needIntelGLWorkaround =
+    (g_ascii_strcasecmp (glGetString (GL_VENDOR), "intel") == 0);
+
+  GDK_NOTE (OPENGL,
+            g_print ("WGL API version %d.%d found\n"
+                     " - Vendor: %s\n"
+                     " - Intel OpenGL workaround: %s\n"
+                     " - Checked extensions:\n"
+                     "\t* WGL_ARB_pixel_format: %s\n"
+                     "\t* WGL_ARB_create_context: %s\n"
+                     "\t* WGL_EXT_swap_control: %s\n"
+                     "\t* WGL_OML_sync_control: %s\n"
+                     "\t* WGL_ARB_multisample: %s\n",
+                     display_win32->gl_version / 10,
+                     display_win32->gl_version % 10,
+                     glGetString (GL_VENDOR),
+                     display_win32->needIntelGLWorkaround ? "yes" : "no",
+                     display_win32->hasWglARBPixelFormat ? "yes" : "no",
+                     display_win32->hasWglARBCreateContext ? "yes" : "no",
+                     display_win32->hasWglEXTSwapControl ? "yes" : "no",
+                     display_win32->hasWglOMLSyncControl ? "yes" : "no",
+                     display_win32->hasWglARBmultisample ? "yes" : "no"));
+
+  wglMakeCurrent (NULL, NULL);
+  destroy_dummy_gl_context (dummy);
+
+  return GDK_WIN32_GL_WGL;
 }
 
-/* Setup the legacy context after creating it */
+/* Setup the legacy WGL context after creating it */
 static gboolean
-_ensure_legacy_gl_context (HDC           hdc,
+ensure_legacy_wgl_context (HDC           hdc,
                            HGLRC         hglrc_legacy,
                            GdkGLContext *share)
 {
-  GdkWin32GLContext *context_win32;
-
   if (!wglMakeCurrent (hdc, hglrc_legacy))
     return FALSE;
 
   if (share != NULL)
     {
-      context_win32 = GDK_WIN32_GL_CONTEXT (share);
+      GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
 
-      return wglShareLists (hglrc_legacy, context_win32->hglrc);
+      return wglShareLists (hglrc_legacy, context_wgl->wgl_context);
     }
 
   return TRUE;
 }
 
 static HGLRC
-_create_gl_context_with_attribs (HDC           hdc,
+create_wgl_context_with_attribs (HDC           hdc,
                                  HGLRC         hglrc_base,
                                  GdkGLContext *share,
                                  int           flags,
@@ -728,7 +543,7 @@ _create_gl_context_with_attribs (HDC           hdc,
                                  gboolean     *is_legacy)
 {
   HGLRC hglrc;
-  GdkWin32GLContext *context_win32;
+  GdkWin32GLContextWGL *context_wgl;
 
   /* if we have wglCreateContextAttribsARB(), create a
   * context with the compatibility profile if a legacy
@@ -746,17 +561,17 @@ _create_gl_context_with_attribs (HDC           hdc,
   };
 
   if (share != NULL)
-    context_win32 = GDK_WIN32_GL_CONTEXT (share);
+    context_wgl= GDK_WIN32_GL_CONTEXT_WGL (share);
 
   hglrc = wglCreateContextAttribsARB (hdc,
-                                      share != NULL ? context_win32->hglrc : NULL,
+                                      share != NULL ? context_wgl->wgl_context : NULL,
                                       attribs);
 
   return hglrc;
 }
 
 static HGLRC
-_create_gl_context (HDC           hdc,
+create_wgl_context (HDC           hdc,
                     GdkGLContext *share,
                     int           flags,
                     int           major,
@@ -764,7 +579,7 @@ _create_gl_context (HDC           hdc,
                     gboolean     *is_legacy,
                     gboolean      hasWglARBCreateContext)
 {
-  /* We need a legacy context for *all* cases */
+  /* We need a legacy WGL context for *all* cases */
   HGLRC hglrc_base = wglCreateContext (hdc);
   gboolean success = TRUE;
 
@@ -775,7 +590,7 @@ _create_gl_context (HDC           hdc,
   /* if we have no wglCreateContextAttribsARB(), return the legacy context when all is set */
   if (*is_legacy && !hasWglARBCreateContext)
     {
-      if (_ensure_legacy_gl_context (hdc, hglrc_base, share))
+      if (ensure_legacy_wgl_context (hdc, hglrc_base, share))
         {
           wglMakeCurrent (hdc_current, hglrc_current);
           return hglrc_base;
@@ -794,7 +609,7 @@ _create_gl_context (HDC           hdc,
           goto gl_fail;
         }
 
-      hglrc = _create_gl_context_with_attribs (hdc,
+      hglrc = create_wgl_context_with_attribs (hdc,
                                                hglrc_base,
                                                share,
                                                flags,
@@ -808,7 +623,7 @@ _create_gl_context (HDC           hdc,
           if (!(*is_legacy))
             {
               /* If we aren't using a legacy context in the beginning, try again with a compatibility 
profile 3.0 context */
-              hglrc = _create_gl_context_with_attribs (hdc,
+              hglrc = create_wgl_context_with_attribs (hdc,
                                                        hglrc_base,
                                                        share,
                                                        flags,
@@ -820,7 +635,7 @@ _create_gl_context (HDC           hdc,
 
           if (hglrc == NULL)
             {
-              if (!_ensure_legacy_gl_context (hdc, hglrc_base, share))
+              if (!ensure_legacy_wgl_context (hdc, hglrc_base, share))
                 success = FALSE;
             }
 
@@ -850,10 +665,10 @@ gl_fail:
 }
 
 static gboolean
-_set_pixformat_for_hdc (HDC              hdc,
-                        gint            *best_idx,
-                        const gboolean   need_alpha_bits,
-                        GdkWin32Display *display)
+set_pixformat_for_hdc (HDC              hdc,
+                       gint            *best_idx,
+                       const gboolean   need_alpha_bits,
+                       GdkWin32Display *display)
 {
   gboolean already_checked = TRUE;
   *best_idx = GetPixelFormat (hdc);
@@ -868,7 +683,7 @@ _set_pixformat_for_hdc (HDC              hdc,
 
       GDK_NOTE (OPENGL, g_print ("requesting pixel format...\n"));
          already_checked = FALSE;
-      *best_idx = _get_wgl_pfd (hdc, need_alpha_bits, &pfd, display);
+      *best_idx = get_wgl_pfd (hdc, need_alpha_bits, &pfd, display);
 
       if (*best_idx != 0)
         set_pixel_format_result = SetPixelFormat (hdc, *best_idx, &pfd);
@@ -883,41 +698,392 @@ _set_pixformat_for_hdc (HDC              hdc,
   return TRUE;
 }
 
-#ifdef GDK_WIN32_ENABLE_EGL
-
-#define MAX_EGL_ATTRS   30
-
 static gboolean
-find_eglconfig_for_window (GdkWin32Display  *display,
-                           EGLConfig        *egl_config_out,
-                           EGLint           *min_swap_interval_out,
-                           gboolean          need_alpha_bits,
-                           GError          **error)
+gdk_win32_gl_context_realize_wgl (GdkGLContext  *context,
+                                  GError       **error)
 {
-  EGLint attrs[MAX_EGL_ATTRS];
-  EGLint count;
-  EGLConfig *configs, chosen_config;
-
-  int i = 0;
-
-  EGLDisplay egl_disp = display->egl_disp;
+  GdkGLContext *share = gdk_gl_context_get_shared_context (context);
+  GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
+  GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (context);
+  GdkWindow *window = gdk_gl_context_get_window (context);
+  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_window_get_display (window));
 
-  attrs[i++] = EGL_CONFORMANT;
-  attrs[i++] = EGL_OPENGL_ES2_BIT;
-  attrs[i++] = EGL_SURFACE_TYPE;
-  attrs[i++] = EGL_WINDOW_BIT;
+  /* These are the real WGL context items that we will want to use later */
+  gboolean debug_bit, compat_bit;
+  gboolean legacy_bit = FALSE;
+  HGLRC hglrc;
+  gint pixel_format;
 
-  attrs[i++] = EGL_COLOR_BUFFER_TYPE;
-  attrs[i++] = EGL_RGB_BUFFER;
+  /* request flags and specific versions for core (3.2+) WGL context */
+  gint flags = 0;
+  gint major = 0;
+  gint minor = 0;
 
-  attrs[i++] = EGL_RED_SIZE;
-  attrs[i++] = 1;
-  attrs[i++] = EGL_GREEN_SIZE;
-  attrs[i++] = 1;
-  attrs[i++] = EGL_BLUE_SIZE;
-  attrs[i++] = 1;
+  /*
+   * A legacy context cannot be shared with core profile ones, this means we
+   * must stick to a legacy context if the shared context is a legacy context.  We
+   * also use a legacy context if we use GDK_GL=legacy or if we do not have
+   * the WGL_ARB_create_context extension
+   */
+  if ((_gdk_gl_flags & GDK_GL_LEGACY) != 0 ||
+      !display_win32->hasWglARBCreateContext ||
+      share != NULL && gdk_gl_context_is_legacy (share))
+    legacy_bit = TRUE;
 
-  if (need_alpha_bits)
+  gdk_gl_context_get_required_version (context, &major, &minor);
+  debug_bit = gdk_gl_context_get_debug_enabled (context);
+  compat_bit = gdk_gl_context_get_forward_compatible (context);
+  
+  if (!set_pixformat_for_hdc (context_win32->gl_hdc,
+                             &pixel_format,
+                              context_win32->need_alpha_bits,
+                              display_win32))
+    {
+      g_set_error_literal (error, GDK_GL_ERROR,
+                           GDK_GL_ERROR_UNSUPPORTED_FORMAT,
+                           _("No available configurations for the given pixel format"));
+
+      return FALSE;
+    }
+
+  if (debug_bit)
+    flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
+  if (compat_bit)
+    flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+
+  GDK_NOTE (OPENGL,
+            g_print ("Creating %s WGL context (version:%d.%d, debug:%s, forward:%s, legacy: %s)\n",
+                     compat_bit ? "core" : "compat",
+                     major,
+                     minor,
+                     debug_bit ? "yes" : "no",
+                     compat_bit ? "yes" : "no",
+                     legacy_bit ? "yes" : "no"));
+
+  hglrc = create_wgl_context (context_win32->gl_hdc,
+                              share,
+                              flags,
+                              major,
+                              minor,
+                             &legacy_bit,
+                              display_win32->hasWglARBCreateContext);
+
+  if (hglrc == NULL)
+    {
+      g_set_error_literal (error, GDK_GL_ERROR,
+                           GDK_GL_ERROR_NOT_AVAILABLE,
+                           _("Unable to create a GL context"));
+      return FALSE;
+    }
+
+  GDK_NOTE (OPENGL,
+            g_print ("Created WGL context[%p], pixel_format=%d\n",
+                     hglrc,
+                     pixel_format));
+
+  context_wgl->wgl_context = hglrc;
+
+  /* set whether we are using GLES */
+  gdk_gl_context_set_use_es (context, FALSE);
+
+  /* OpenGL does not work with WS_EX_LAYERED enabled, so we need to
+   * disable WS_EX_LAYERED when we acquire a valid HGLRC
+   */
+  impl->suppress_layered++;
+
+  /* if this is the first time a GL context is acquired for the window,
+   * disable layered windows by triggering update_style_bits()
+   */
+  if (impl->suppress_layered == 1)
+    _gdk_win32_window_update_style_bits (window);
+
+  /* Ensure that any other context is created with a legacy bit set */
+  gdk_gl_context_set_is_legacy (context, legacy_bit);
+
+  return TRUE;
+}
+
+static gboolean
+gdk_win32_display_make_wgl_context_current (GdkDisplay   *display,
+                                            GdkGLContext *context)
+{
+  GdkWin32GLContext *context_win32;
+  GdkWin32GLContextWGL *context_wgl;
+  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+  GdkWindow *window;
+
+  if (context == NULL)
+    {
+      wglMakeCurrent(NULL, NULL);
+
+      return TRUE;
+    }
+
+  context_win32 = GDK_WIN32_GL_CONTEXT (context);
+  context_wgl = GDK_WIN32_GL_CONTEXT_WGL (context);
+  window = gdk_gl_context_get_window (context);
+
+  if (!wglMakeCurrent (context_win32->gl_hdc, context_wgl->wgl_context))
+    {
+      GDK_NOTE (OPENGL,
+                g_print ("Making WGL context current failed\n"));
+      return FALSE;
+    }
+
+  if (context_win32->is_attached)
+    {
+      if (display_win32->hasWglEXTSwapControl)
+        {
+          /* If there is compositing there is no particular need to delay
+           * the swap when drawing on the offscreen, rendering to the screen
+           * happens later anyway, and its up to the compositor to sync that
+           * to the vblank. */
+          gboolean do_frame_sync = !gdk_screen_is_composited (gdk_window_get_screen (window));
+
+          if (do_frame_sync != context_win32->do_frame_sync)
+            {
+              context_win32->do_frame_sync = do_frame_sync;
+
+              if (do_frame_sync)
+                wglSwapIntervalEXT (1);
+              else
+                wglSwapIntervalEXT (0);
+            }
+        }
+    }
+
+  return TRUE;
+}
+
+static void
+gdk_win32_gl_context_wgl_class_init (GdkWin32GLContextWGLClass *klass)
+{
+  GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  context_class->end_frame = gdk_win32_gl_context_end_frame_wgl;
+  context_class->realize = gdk_win32_gl_context_realize_wgl;
+
+  gobject_class->dispose = gdk_win32_gl_context_dispose_wgl;
+}
+
+static void
+gdk_win32_gl_context_wgl_init (GdkWin32GLContextWGL *wgl_context)
+{
+}
+
+/* End section on WGL support */
+/* Section on EGL/libANGLE support */
+#ifdef GDK_WIN32_ENABLE_EGL
+
+#ifndef EGL_PLATFORM_ANGLE_ANGLE
+#define EGL_PLATFORM_ANGLE_ANGLE          0x3202
+#endif
+
+#ifndef EGL_PLATFORM_ANGLE_TYPE_ANGLE
+#define EGL_PLATFORM_ANGLE_TYPE_ANGLE     0x3203
+#endif
+
+#ifndef EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE
+#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
+#endif
+
+struct _GdkWin32GLContextEGL
+{
+  GdkWin32GLContext parent_instance;
+
+  EGLContext egl_context;
+};
+
+#define GDK_TYPE_WIN32_GL_CONTEXT_EGL     (gdk_win32_gl_context_egl_get_type())
+#define GDK_WIN32_GL_CONTEXT_EGL(obj)     (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_WIN32_GL_CONTEXT_EGL, 
GdkWin32GLContextEGL))
+#define GDK_IS_WIN32_GL_CONTEXT_EGL(obj)  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_WIN32_GL_CONTEXT_EGL))
+
+typedef struct _GdkWin32GLContextClass GdkWin32GLContextEGLClass;
+typedef struct _GdkWin32GLContextEGL      GdkWin32GLContextEGL;
+
+G_DEFINE_TYPE (GdkWin32GLContextEGL, gdk_win32_gl_context_egl, GDK_TYPE_WIN32_GL_CONTEXT)
+
+static EGLDisplay
+gdk_win32_get_egl_display (GdkWin32Display *display)
+{
+  EGLDisplay disp;
+  gboolean success = FALSE;
+
+  if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
+    {
+      PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = (void *) eglGetProcAddress 
("eglGetPlatformDisplayEXT");
+      if (getPlatformDisplay)
+        {
+          EGLint disp_attr[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 
EGL_NONE};
+
+          disp = getPlatformDisplay (EGL_PLATFORM_ANGLE_ANGLE, display->hdc_egl_temp, disp_attr);
+
+          if (disp != EGL_NO_DISPLAY)
+            return disp;
+        }
+    }
+
+  return eglGetDisplay (display->hdc_egl_temp);
+}
+
+static void
+gdk_win32_gl_context_dispose_egl (GObject *gobject)
+{
+  GdkGLContext *context = GDK_GL_CONTEXT (gobject);
+  GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
+
+  if (context_egl->egl_context != EGL_NO_CONTEXT)
+    {
+      GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context));
+
+      if (eglGetCurrentContext () == context_egl->egl_context)
+        eglMakeCurrent(display_win32->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+      GDK_NOTE (OPENGL, g_message ("Destroying EGL (ANGLE) context"));
+
+      eglDestroyContext (display_win32->egl_disp, context_egl->egl_context);
+      context_egl->egl_context = EGL_NO_CONTEXT;
+
+      gdk_win32_gl_context_cleanup (context);
+    }
+
+  G_OBJECT_CLASS (gdk_win32_gl_context_parent_class)->dispose (gobject);
+}
+
+static gboolean
+get_is_egl_force_redraw (GdkWindow *window)
+{
+  /* We only need to call gdk_window_invalidate_rect () if necessary */
+  if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
+    {
+      GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
+      return impl->egl_force_redraw_all;
+    }
+
+  return FALSE;
+}
+
+static void
+reset_egl_force_redraw (GdkWindow *window)
+{
+  if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
+    {
+      GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
+      if (impl->egl_force_redraw_all)
+        impl->egl_force_redraw_all = FALSE;
+    }
+}
+
+static void
+gdk_win32_gl_context_end_frame_egl (GdkGLContext *context,
+                                    cairo_region_t *painted,
+                                    cairo_region_t *damage)
+{
+  GdkWindow *window = gdk_gl_context_get_window (context);
+  GdkWin32Display *display_win32 = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
+  GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
+
+  EGLSurface egl_surface = _gdk_win32_window_get_egl_surface (window, display_win32->egl_config, FALSE);
+  gboolean force_egl_redraw_all = get_is_egl_force_redraw (window);
+
+  gdk_gl_context_make_current (context);
+
+  if (context_win32->do_blit_swap && !force_egl_redraw_all)
+    gdk_gl_blit_region (window, painted, FALSE);
+  else if (force_egl_redraw_all)
+    {
+      GdkRectangle rect = {0, 0, gdk_window_get_width (window), gdk_window_get_height (window)};
+
+      /* We need to do gdk_window_invalidate_rect() so that we don't get glitches after maximizing or
+       *  restoring or using aerosnap
+       */
+      gdk_window_invalidate_rect (window, &rect, TRUE);
+      reset_egl_force_redraw (window);
+    }
+
+  eglSwapBuffers (display_win32->egl_disp, egl_surface);
+}
+
+static GdkWin32GLContextType
+gdk_win32_display_init_egl (GdkWin32Display *display_win32)
+{
+  EGLDisplay egl_disp = gdk_win32_get_egl_display (display_win32);
+
+  if (egl_disp == EGL_NO_DISPLAY ||
+     !eglInitialize (egl_disp, NULL, NULL))
+    {
+      if (egl_disp != EGL_NO_DISPLAY)
+        {
+          eglTerminate (egl_disp);
+          egl_disp = EGL_NO_DISPLAY;
+        }
+
+      return GDK_WIN32_GL_NONE;
+    }
+
+  display_win32->egl_disp = egl_disp;
+
+  eglBindAPI(EGL_OPENGL_ES_API);
+
+  display_win32->gl_version = epoxy_egl_version (egl_disp);
+
+  display_win32->hasEglSurfacelessContext =
+    epoxy_has_egl_extension (egl_disp, "EGL_KHR_surfaceless_context");
+
+  GDK_NOTE (OPENGL,
+            g_print ("EGL API version %d.%d found\n"
+                     " - Vendor: %s\n"
+                     " - Checked extensions:\n"
+                     "\t* EGL_KHR_surfaceless_context: %s\n",
+                     display_win32->gl_version / 10,
+                     display_win32->gl_version % 10,
+                     eglQueryString (display_win32->egl_disp, EGL_VENDOR),
+                     display_win32->hasEglSurfacelessContext ? "yes" : "no"));
+
+  return GDK_WIN32_GL_EGL;
+}
+
+#define MAX_EGL_ATTRS   30
+
+static gboolean
+find_eglconfig_for_window (GdkWin32Display  *display_win32,
+                           gboolean          need_alpha_bits,
+                           GError          **error)
+{
+  EGLint attrs[MAX_EGL_ATTRS];
+  EGLint count;
+  EGLConfig *configs, chosen_config;
+
+  int i = 0;
+
+  EGLDisplay egl_disp;
+
+  if (display_win32->egl_min_swap_interval != 0 &&
+      display_win32->egl_config != NULL)
+    return TRUE;
+
+  egl_disp = display_win32->egl_disp;
+
+  attrs[i++] = EGL_CONFORMANT;
+  attrs[i++] = EGL_OPENGL_ES2_BIT;
+  attrs[i++] = EGL_SURFACE_TYPE;
+  attrs[i++] = EGL_WINDOW_BIT;
+
+  attrs[i++] = EGL_COLOR_BUFFER_TYPE;
+  attrs[i++] = EGL_RGB_BUFFER;
+
+  attrs[i++] = EGL_RED_SIZE;
+  attrs[i++] = 1;
+  attrs[i++] = EGL_GREEN_SIZE;
+  attrs[i++] = 1;
+  attrs[i++] = EGL_BLUE_SIZE;
+  attrs[i++] = 1;
+
+  if (need_alpha_bits)
     {
       attrs[i++] = EGL_ALPHA_SIZE;
       attrs[i++] = 1;
@@ -931,7 +1097,7 @@ find_eglconfig_for_window (GdkWin32Display  *display,
   attrs[i++] = EGL_NONE;
   g_assert (i < MAX_EGL_ATTRS);
 
-  if (!eglChooseConfig (display->egl_disp, attrs, NULL, 0, &count) || count < 1)
+  if (!eglChooseConfig (display_win32->egl_disp, attrs, NULL, 0, &count) || count < 1)
     {
       g_set_error_literal (error, GDK_GL_ERROR,
                            GDK_GL_ERROR_UNSUPPORTED_FORMAT,
@@ -941,7 +1107,7 @@ find_eglconfig_for_window (GdkWin32Display  *display,
 
   configs = g_new (EGLConfig, count);
 
-  if (!eglChooseConfig (display->egl_disp, attrs, configs, count, &count) || count < 1)
+  if (!eglChooseConfig (display_win32->egl_disp, attrs, configs, count, &count) || count < 1)
     {
       g_set_error_literal (error, GDK_GL_ERROR,
                            GDK_GL_ERROR_UNSUPPORTED_FORMAT,
@@ -952,8 +1118,8 @@ find_eglconfig_for_window (GdkWin32Display  *display,
   /* Pick first valid configuration i guess? */
   chosen_config = configs[0];
 
-  if (!eglGetConfigAttrib (display->egl_disp, chosen_config,
-                           EGL_MIN_SWAP_INTERVAL, min_swap_interval_out))
+  if (!eglGetConfigAttrib (display_win32->egl_disp, chosen_config,
+                           EGL_MIN_SWAP_INTERVAL, &display_win32->egl_min_swap_interval))
     {
       g_set_error_literal (error, GDK_GL_ERROR,
                            GDK_GL_ERROR_NOT_AVAILABLE,
@@ -962,8 +1128,7 @@ find_eglconfig_for_window (GdkWin32Display  *display,
       return FALSE;
     }
 
-  if (egl_config_out != NULL)
-    *egl_config_out = chosen_config;
+  display_win32->egl_config = chosen_config;
 
   g_free (configs);
 
@@ -973,21 +1138,26 @@ find_eglconfig_for_window (GdkWin32Display  *display,
 #define N_EGL_ATTRS     16
 
 static EGLContext
-_create_egl_context (EGLDisplay    display,
-                     EGLConfig     config,
-                     GdkGLContext *share,
-                     int           flags,
-                     int           major,
-                     int           minor,
-                     gboolean     *is_legacy)
+create_egl_context (EGLDisplay    display,
+                    EGLConfig     config,
+                    GdkGLContext *share,
+                    int           flags,
+                    int           major,
+                    int           minor)
 {
   EGLContext ctx;
   EGLint context_attribs[N_EGL_ATTRS];
   int i = 0;
 
-  /* ANGLE does not support the GL_OES_vertex_array_object extension, so we need to use ES3 directly */
-  context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
-  context_attribs[i++] = 3;
+  /*
+   * ANGLE does not support the GL_OES_vertex_array_object extension, so we need to use ES3 directly
+   * if we do not request for ES3 or later
+   */
+  if (major < 3)
+    {
+      context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
+      context_attribs[i++] = 3;
+    }
 
   /* Specify the flags */
   context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
@@ -998,161 +1168,72 @@ _create_egl_context (EGLDisplay    display,
 
   ctx = eglCreateContext (display,
                           config,
-                          share != NULL ? GDK_WIN32_GL_CONTEXT (share)->egl_context
+                          share != NULL ? GDK_WIN32_GL_CONTEXT_EGL (share)->egl_context
                                         : EGL_NO_CONTEXT,
                           context_attribs);
 
-  if (ctx != EGL_NO_CONTEXT)
-    GDK_NOTE (OPENGL, g_message ("Created EGL context[%p]", ctx));
-
   return ctx;
 }
-#endif /* GDK_WIN32_ENABLE_EGL */
 
-gboolean
-_gdk_win32_gl_context_realize (GdkGLContext *context,
-                               GError **error)
+static gboolean
+gdk_win32_gl_context_realize_egl (GdkGLContext  *context,
+                                  GError       **error)
 {
   GdkGLContext *share = gdk_gl_context_get_shared_context (context);
   GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
+  GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
+  GdkWindow *window = gdk_gl_context_get_window (context);
+  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_window_get_display (window));
 
-  /* These are the real WGL/EGL context items that we will want to use later */
-  gboolean debug_bit, compat_bit, legacy_bit;
-
-  /* These are the real WGL context items that we will want to use later */
-  HGLRC hglrc;
-  gint pixel_format;
-  gboolean use_es = FALSE;
+  /* These are the real EGL context items that we will want to use later */
+  EGLContext ctx;
+  gboolean debug_bit, compat_bit;
+  gboolean legacy_bit = FALSE;
 
-  /* request flags and specific versions for core (3.2+) WGL context */
+  /* request flags and specific versions for EGL context */
   gint flags = 0;
   gint major = 0;
   gint minor = 0;
 
-#ifdef GDK_WIN32_ENABLE_EGL
-  EGLContext egl_context;
-#endif
-
-  GdkWindow *window = gdk_gl_context_get_window (context);
-  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
-  GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (gdk_window_get_display (window));
-
-  /*
-   * A legacy context cannot be shared with core profile ones, so this means we
-   * must stick to a legacy context if the shared context is a legacy context
-   */
-  if ((_gdk_gl_flags & GDK_GL_LEGACY) != 0 ||
-       share != NULL && gdk_gl_context_is_legacy (share))
-    legacy_bit = TRUE;
-
-  if ((_gdk_gl_flags & GDK_GL_GLES) != 0 ||
-      (share != NULL && gdk_gl_context_get_use_es (share)))
-    use_es = TRUE;
-
   gdk_gl_context_get_required_version (context, &major, &minor);
   debug_bit = gdk_gl_context_get_debug_enabled (context);
   compat_bit = gdk_gl_context_get_forward_compatible (context);
 
-  if (win32_display->have_wgl)
-    {
-      if (!_set_pixformat_for_hdc (context_win32->gl_hdc,
-                                   &pixel_format,
-                                   context_win32->need_alpha_bits,
-                                   win32_display))
-        {
-          g_set_error_literal (error, GDK_GL_ERROR,
-                               GDK_GL_ERROR_UNSUPPORTED_FORMAT,
-                               _("No available configurations for the given pixel format"));
+  if (debug_bit)
+    flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
+  if (compat_bit)
+    flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
 
-          return FALSE;
-        }
-
-      /* if there isn't wglCreateContextAttribsARB(), or if GDK_GL_LEGACY is set, we default to a legacy 
context */
-      legacy_bit = !win32_display->hasWglARBCreateContext ||
-                   g_getenv ("GDK_GL_LEGACY") != NULL;
-
-      if (debug_bit)
-        flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
-      if (compat_bit)
-        flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
-
-      GDK_NOTE (OPENGL,
-                g_print ("Creating %s WGL context (version:%d.%d, debug:%s, forward:%s, legacy: %s)\n",
-                          compat_bit ? "core" : "compat",
-                          major,
-                          minor,
-                          debug_bit ? "yes" : "no",
-                          compat_bit ? "yes" : "no",
-                          legacy_bit ? "yes" : "no"));
-
-      hglrc = _create_gl_context (context_win32->gl_hdc,
-                                  share,
-                                  flags,
-                                  major,
-                                  minor,
-                                  &legacy_bit,
-                                  win32_display->hasWglARBCreateContext);
+  GDK_NOTE (OPENGL, g_message ("Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s)",
+                               major, minor,
+                               debug_bit ? "yes" : "no",
+                               compat_bit ? "yes" : "no"));
 
-      if (hglrc == NULL)
-        {
-          g_set_error_literal (error, GDK_GL_ERROR,
-                               GDK_GL_ERROR_NOT_AVAILABLE,
-                               _("Unable to create a GL context"));
-          return FALSE;
-        }
+  ctx = create_egl_context (display_win32->egl_disp,
+                            display_win32->egl_config,
+                            share,
+                            flags,
+                            major,
+                            minor);
 
-      GDK_NOTE (OPENGL,
-                g_print ("Created WGL context[%p], pixel_format=%d\n",
-                         hglrc,
-                         pixel_format));
-
-      context_win32->hglrc = hglrc;
-    }
-
-#ifdef GDK_WIN32_ENABLE_EGL
-  if (win32_display->have_egl)
+  if (ctx == EGL_NO_CONTEXT)
     {
-      EGLContext ctx;
-
-      if (debug_bit)
-        flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
-      if (compat_bit)
-        flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
-
-      GDK_NOTE (OPENGL, g_message ("Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s)",
-                                   major, minor,
-                                   debug_bit ? "yes" : "no",
-                                   compat_bit ? "yes" : "no",
-                                   legacy_bit ? "yes" : "no"));
-
-      ctx = _create_egl_context (win32_display->egl_disp,
-                                 context_win32->egl_config,
-                                 share,
-                                 flags,
-                                 major,
-                                 minor,
-                                &legacy_bit);
-
-      if (ctx == EGL_NO_CONTEXT)
-        {
-          g_set_error_literal (error, GDK_GL_ERROR,
-                               GDK_GL_ERROR_NOT_AVAILABLE,
-                               _("Unable to create a GL context"));
-
-          return FALSE;
-        }
-
-      GDK_NOTE (OPENGL,
-                g_print ("Created EGL context[%p]\n",
-                         ctx));
+      g_set_error_literal (error, GDK_GL_ERROR,
+                           GDK_GL_ERROR_NOT_AVAILABLE,
+                           _("Unable to create a GL context"));
 
-      context_win32->egl_context = ctx;
-      use_es = TRUE;
+      return FALSE;
     }
-#endif
 
+  GDK_NOTE (OPENGL,
+            g_print ("Created EGL context[%p]\n",
+                     ctx));
+
+  context_egl->egl_context = ctx;
+  
   /* set whether we are using GLES */
-  gdk_gl_context_set_use_es(context, use_es);
+  gdk_gl_context_set_use_es (context, TRUE);
 
   /* OpenGL does not work with WS_EX_LAYERED enabled, so we need to
    * disable WS_EX_LAYERED when we acquire a valid HGLRC
@@ -1171,161 +1252,243 @@ _gdk_win32_gl_context_realize (GdkGLContext *context,
   return TRUE;
 }
 
-GdkGLContext *
-_gdk_win32_window_create_gl_context (GdkWindow *window,
-                                     gboolean attached,
-                                     GdkGLContext *share,
-                                     GError **error)
+void
+gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window)
 {
-  GdkDisplay *display = gdk_window_get_display (window);
-  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_window_get_display (window));
-  GdkWin32GLContext *context = NULL;
-  GdkVisual *visual = gdk_window_get_visual (window);
+/* If we are using ANGLE, we need to force redraw of the whole Window and its child windows
+ *  as we need to re-acquire the EGL surfaces that we rendered to upload to Cairo explicitly,
+ *  using gdk_window_invalidate_rect (), when we maximize or restore or use aerosnap
+ */
+  if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
+    {
+      GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 
-  gboolean need_alpha_bits = (visual == gdk_screen_get_rgba_visual (gdk_display_get_default_screen 
(display)));
+      impl->egl_force_redraw_all = TRUE;
+    }
+}
 
-  /* Acquire and store up the Windows-specific HWND and HDC */
-  HDC hdc;
+static gboolean
+gdk_win32_display_make_egl_context_current (GdkDisplay   *display,
+                                            GdkGLContext *context)
+{
+  GdkWin32GLContext *context_win32;
+  GdkWin32GLContextEGL *context_egl;
+  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+  GdkWindow *window;
+  EGLSurface egl_surface;
 
-#ifdef GDK_WIN32_ENABLE_EGL
-  EGLContext egl_context;
-  EGLConfig config;
-#endif
+  if (context == NULL)
+    {
+      eglMakeCurrent (display_win32->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 
-  hdc = GetDC (GDK_WINDOW_HWND (window));
+      return TRUE;
+    }
 
-#ifdef GDK_WIN32_ENABLE_EGL
-  /* display_win32->hdc_egl_temp should *not* be destroyed here!  It is destroyed at dispose()! */
-  display_win32->hdc_egl_temp = hdc;
-#endif
+  context_win32 = GDK_WIN32_GL_CONTEXT (context);
+  context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
+  window = gdk_gl_context_get_window (context);
+
+  if (context_win32->is_attached || !display_win32->hasEglSurfacelessContext)
+    egl_surface = _gdk_win32_window_get_egl_surface (window,
+                                                     display_win32->egl_config,
+                                                    !context_win32->is_attached);
+  else
+    egl_surface = EGL_NO_SURFACE;
 
-  if (!_gdk_win32_display_init_gl (display, need_alpha_bits))
+  if (!eglMakeCurrent (display_win32->egl_disp,
+                       egl_surface,
+                       egl_surface,
+                       context_egl->egl_context))
     {
-      g_set_error_literal (error, GDK_GL_ERROR,
-                           GDK_GL_ERROR_NOT_AVAILABLE,
-                           _("No GL implementation is available"));
-      return NULL;
+      g_warning ("eglMakeCurrent failed");
+      return FALSE;
     }
 
-#ifdef GDK_WIN32_ENABLE_EGL
-  if (display_win32->have_egl && !find_eglconfig_for_window (display_win32, &config,
-                                  &display_win32->egl_min_swap_interval, need_alpha_bits,
-                                  error))
-    return NULL;
-#endif
+  if (display_win32->egl_min_swap_interval == 0)
+    eglSwapInterval (display_win32->egl_disp, 0);
+  else
+    g_debug ("Can't disable GL swap interval");
+
+  return TRUE;
+}
+
+static void
+gdk_win32_gl_context_egl_class_init (GdkWin32GLContextEGLClass *klass)
+{
+  GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
-  context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT,
-                          "display", display,
-                          "window", window,
-                          "shared-context", share,
-                          NULL);
+  context_class->end_frame = gdk_win32_gl_context_end_frame_egl;
+  context_class->realize = gdk_win32_gl_context_realize_egl;
 
-  context->need_alpha_bits = need_alpha_bits;
-  context->gl_hdc = hdc;
+  gobject_class->dispose = gdk_win32_gl_context_dispose_egl;
+}
 
-#ifdef GDK_WIN32_ENABLE_EGL
-  if (display_win32->have_egl)
-    context->egl_config = config;
-#endif
+static void
+gdk_win32_gl_context_egl_init (GdkWin32GLContextEGL *egl_context)
+{
+}
+#else /* GDK_WIN32_ENABLE_EGL */
+/* define EGL stuff as no-op macros or functions if it is not enabled */
 
-  context->is_attached = attached;
+#define gdk_win32_display_init_egl(disp) GDK_WIN32_GL_NONE
+#define gdk_win32_display_make_egl_context_current(disp,ctx) FALSE
 
-  return GDK_GL_CONTEXT (context);
+void
+gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window)
+{
 }
 
-gboolean
-_gdk_win32_display_make_gl_context_current (GdkDisplay *display,
-                                            GdkGLContext *context)
+static gboolean
+find_eglconfig_for_window (GdkWin32Display  *display_win32,
+                           gboolean          need_alpha_bits,
+                           GError          **error)
+{
+  return FALSE;
+}
+#endif /* !GDK_WIN32_ENABLE_EGL */
+
+static void
+gdk_win32_gl_context_class_init (GdkWin32GLContextClass *klass)
+{
+  GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+}
+
+static void
+gdk_win32_gl_context_init (GdkWin32GLContext *self)
 {
+}
+
+void
+gdk_win32_window_invalidate_for_new_frame (GdkWindow      *window,
+                                           cairo_region_t *update_area)
+{
+  cairo_rectangle_int_t window_rect;
+  gboolean invalidate_all = FALSE;
   GdkWin32GLContext *context_win32;
-  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
-  GdkWindow *window;
-  GdkScreen *screen;
+  cairo_rectangle_int_t whole_window = { 0, 0, gdk_window_get_width (window), gdk_window_get_height (window) 
};
 
-#if GDK_WIN32_ENABLE_EGL
-  EGLSurface egl_surface;
-#endif
+  /* Minimal update is ok if we're not drawing with gl */
+  if (window->gl_paint_context == NULL)
+    return;
 
-  gboolean do_frame_sync = FALSE;
+  context_win32 = GDK_WIN32_GL_CONTEXT (window->gl_paint_context);
+  context_win32->do_blit_swap = FALSE;
 
-  if (context == NULL)
+  if (gdk_gl_context_has_framebuffer_blit (window->gl_paint_context) &&
+      cairo_region_contains_rectangle (update_area, &whole_window) != CAIRO_REGION_OVERLAP_IN)
     {
-      if (display_win32->have_wgl)
-        wglMakeCurrent(NULL, NULL);
-
-#ifdef GDK_WIN32_ENABLE_EGL
-      else if (display_win32->have_egl)
-        eglMakeCurrent (display_win32->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-#endif
-      return TRUE;
+      context_win32->do_blit_swap = TRUE;
     }
+  else
+    invalidate_all = TRUE;
 
-  context_win32 = GDK_WIN32_GL_CONTEXT (context);
-  window = gdk_gl_context_get_window (context);
-
-  if (!gdk_gl_context_get_use_es (context))
+  if (invalidate_all)
     {
-      if (!wglMakeCurrent (context_win32->gl_hdc, context_win32->hglrc))
-        {
-          GDK_NOTE (OPENGL,
-                    g_print ("Making WGL context current failed\n"));
-          return FALSE;
-        }
+      window_rect.x = 0;
+      window_rect.y = 0;
+      window_rect.width = gdk_window_get_width (window);
+      window_rect.height = gdk_window_get_height (window);
 
-      if (context_win32->is_attached)
-        {
-          if (display_win32->hasWglEXTSwapControl)
-            {
-              /* If there is compositing there is no particular need to delay
-               * the swap when drawing on the offscreen, rendering to the screen
-               * happens later anyway, and its up to the compositor to sync that
-               * to the vblank. */
-              screen = gdk_window_get_screen (window);
-              do_frame_sync = ! gdk_screen_is_composited (screen);
-
-              if (do_frame_sync != context_win32->do_frame_sync)
-                {
-                  context_win32->do_frame_sync = do_frame_sync;
-
-                  if (do_frame_sync)
-                    wglSwapIntervalEXT (1);
-                  else
-                    wglSwapIntervalEXT (0);
-                }
-            }
-        }
+      /* If nothing else is known, repaint everything so that the back
+         buffer is fully up-to-date for the swapbuffer */
+      cairo_region_union_rectangle (update_area, &window_rect);
     }
+}
 
-#ifdef GDK_WIN32_ENABLE_EGL
+static GdkWin32GLContextType
+gdk_win32_display_init_gl (GdkDisplay     *display,
+                           const gboolean  need_alpha_bits)
+{
+  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+  gint best_idx = 0;
+  gboolean disable_wgl = FALSE;
+
+  if (display_win32->gl_type == GDK_WIN32_GL_WGL ||
+      display_win32->gl_type == GDK_WIN32_GL_EGL)
+    return display_win32->gl_type;
+
+  disable_wgl = ((_gdk_gl_flags & GDK_GL_GLES) != 0) ||
+                 display_win32->running_on_arm64;
+
+  if (!disable_wgl)
+    return gdk_win32_display_init_wgl (display_win32, need_alpha_bits);
   else
-    {
-      if (context_win32->is_attached)
-        egl_surface = _gdk_win32_window_get_egl_surface (window, context_win32->egl_config, FALSE);
-      else
-        {
-          if (display_win32->hasEglSurfacelessContext)
-            egl_surface = EGL_NO_SURFACE;
-          else
-            egl_surface = _gdk_win32_window_get_egl_surface (window, context_win32->egl_config, TRUE);
-        }
+    return gdk_win32_display_init_egl (display_win32);
+}
 
-      if (!eglMakeCurrent (display_win32->egl_disp,
-                           egl_surface,
-                           egl_surface,
-                           context_win32->egl_context))
-        {
-          g_warning ("eglMakeCurrent failed");
-          return FALSE;
-        }
+GdkGLContext *
+gdk_win32_window_create_gl_context (GdkWindow *window,
+                                    gboolean attached,
+                                    GdkGLContext *share,
+                                    GError **error)
+{
+  GdkDisplay *display = gdk_window_get_display (window);
+  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_window_get_display (window));
+  GdkWin32GLContext *context_win32 = NULL;
+  GdkVisual *visual = gdk_window_get_visual (window);
+
+  gboolean need_alpha_bits = (visual == gdk_screen_get_rgba_visual (gdk_display_get_default_screen 
(display)));
+
+  /* Acquire and store up the Windows-specific HWND and HDC */
+  HDC hdc = GetDC (GDK_WINDOW_HWND (window));
+
+  /* display_win32->hdc_egl_temp should *not* be destroyed here!  It is destroyed at dispose()! */
+  display_win32->hdc_egl_temp = hdc;
+  display_win32->gl_type = gdk_win32_display_init_gl (display, need_alpha_bits);
+
+  if (display_win32->gl_type == GDK_WIN32_GL_NONE)
+    {
+      g_set_error_literal (error, GDK_GL_ERROR,
+                           GDK_GL_ERROR_NOT_AVAILABLE,
+                           _("No GL implementation is available"));
+      return NULL;
+    }
 
-      if (display_win32->egl_min_swap_interval == 0)
-        eglSwapInterval (display_win32->egl_disp, 0);
-      else
-        g_debug ("Can't disable GL swap interval");
+  if (display_win32->gl_type == GDK_WIN32_GL_EGL &&
+     !find_eglconfig_for_window (display_win32, need_alpha_bits, error))
+    {
+      display_win32->gl_type = GDK_WIN32_GL_NONE;
+      return NULL;
     }
+
+  if (display_win32->gl_type == GDK_WIN32_GL_WGL)
+    context_win32 = GDK_WIN32_GL_CONTEXT (g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
+                                          "display", display,
+                                          "window", window,
+                                          "shared-context", share,
+                                          NULL));
+#ifdef GDK_WIN32_ENABLE_EGL
+  else if (display_win32->gl_type == GDK_WIN32_GL_EGL)
+    context_win32 = GDK_WIN32_GL_CONTEXT (g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL,
+                                          "display", display,
+                                          "window", window,
+                                          "shared-context", share,
+                                          NULL));
 #endif
 
-  return TRUE;
+  context_win32->need_alpha_bits = need_alpha_bits;
+  context_win32->gl_hdc = hdc;
+  context_win32->is_attached = attached;
+
+  return GDK_GL_CONTEXT (context_win32);
+}
+
+gboolean
+gdk_win32_display_make_gl_context_current (GdkDisplay   *display,
+                                            GdkGLContext *context)
+{
+  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+
+  if (display_win32->gl_type == GDK_WIN32_GL_WGL)
+    return gdk_win32_display_make_wgl_context_current (display, context);
+
+  if (display_win32->gl_type == GDK_WIN32_GL_EGL)
+    return gdk_win32_display_make_egl_context_current (display, context);
+
+  g_assert_not_reached ();
+  return FALSE;
 }
 
 /**
@@ -1353,47 +1516,16 @@ gdk_win32_display_get_wgl_version (GdkDisplay *display,
 
   display_win32 = GDK_WIN32_DISPLAY (display);
 
-  if (!_gdk_win32_display_init_gl (display, FALSE) || !display_win32->have_wgl
-#ifdef GDK_WIN32_ENABLE_EGL
-      || !display_win32->have_egl
-#endif
-     )
-    return FALSE;
+  if (display_win32->gl_type == GDK_WIN32_GL_PENDING)
+    display_win32->gl_type = gdk_win32_display_init_gl (display, FALSE);
 
-  if (display_win32->have_wgl)
-    {
-      if (major != NULL)
-        *major = GDK_WIN32_DISPLAY (display)->gl_version / 10;
-      if (minor != NULL)
-        *minor = GDK_WIN32_DISPLAY (display)->gl_version % 10;
-    }
+  if (display_win32->gl_type == GDK_WIN32_GL_NONE)
+    return FALSE;
 
-#ifdef GDK_WIN32_ENABLE_EGL
-  else if (display_win32->have_egl)
-    {
-      if (major != NULL)
-        *major = GDK_WIN32_DISPLAY (display)->egl_version / 10;
-      if (minor != NULL)
-        *minor = GDK_WIN32_DISPLAY (display)->egl_version % 10;
-    }
-#endif
+  if (major != NULL)
+    *major = GDK_WIN32_DISPLAY (display)->gl_version / 10;
+  if (minor != NULL)
+    *minor = GDK_WIN32_DISPLAY (display)->gl_version % 10;
 
   return TRUE;
 }
-
-void
-_gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window)
-{
-/* If we are using ANGLE, we need to force redraw of the whole Window and its child windows
- *  as we need to re-acquire the EGL surfaces that we rendered to upload to Cairo explicitly,
- *  using gdk_window_invalidate_rect (), when we maximize or restore or use aerosnap
- */
-#ifdef GDK_WIN32_ENABLE_EGL
-  if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
-    {
-      GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
-
-      impl->egl_force_redraw_all = TRUE;
-    }
-#endif
-}
diff --git a/gdk/win32/gdkglcontext-win32.h b/gdk/win32/gdkglcontext-win32.h
index d58760ce63..283e67c969 100644
--- a/gdk/win32/gdkglcontext-win32.h
+++ b/gdk/win32/gdkglcontext-win32.h
@@ -32,62 +32,29 @@
 #include "gdkdisplayprivate.h"
 #include "gdkvisual.h"
 #include "gdkwindow.h"
-#include "gdkinternals.h"
-#include "gdkmain.h"
 
 G_BEGIN_DECLS
 
-struct _GdkWin32GLContext
-{
-  GdkGLContext parent_instance;
+#define GDK_WIN32_GL_CONTEXT_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), 
GDK_TYPE_WIN32_GL_CONTEXT, GdkWin32GLContextClass))
+#define GDK_WIN32_GL_CONTEXT_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GDK_TYPE_WIN32_GL_CONTEXT, GdkWin32GLContextClass))
+#define GDK_WIN32_IS_GL_CONTEXT_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), 
GDK_TYPE_WIN32_GL_CONTEXT)
 
-  /* WGL Context Items */
-  HGLRC hglrc;
-  HDC gl_hdc;
-  guint need_alpha_bits : 1;
-
-  /* other items */
-  guint is_attached : 1;
-  guint do_frame_sync : 1;
-  guint do_blit_swap : 1;
-
-#ifdef GDK_WIN32_ENABLE_EGL
-  /* EGL (Angle) Context Items */
-  EGLContext egl_context;
-  EGLConfig egl_config;
-#endif
-};
-
-struct _GdkWin32GLContextClass
-{
-  GdkGLContextClass parent_class;
-};
+void
+gdk_win32_window_invalidate_egl_framebuffer (GdkWindow      *window);
 
 GdkGLContext *
-_gdk_win32_window_create_gl_context (GdkWindow *window,
-                                     gboolean attached,
-                                     GdkGLContext *share,
-                                     GError **error);
+gdk_win32_window_create_gl_context          (GdkWindow      *window,
+                                             gboolean        attached,
+                                             GdkGLContext   *share,
+                                             GError        **error);
 
 void
-_gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
-                                            cairo_region_t *update_area);
-
-void
-_gdk_win32_gl_context_end_frame (GdkGLContext *context,
-                                 cairo_region_t *painted,
-                                 cairo_region_t *damage);
-
-gboolean
-_gdk_win32_display_make_gl_context_current (GdkDisplay *display,
-                                            GdkGLContext *context);
+gdk_win32_window_invalidate_for_new_frame   (GdkWindow      *window,
+                                             cairo_region_t *update_area);
 
 gboolean
-_gdk_win32_gl_context_realize (GdkGLContext *context,
-                               GError **error);
-
-void
-_gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window);
+gdk_win32_display_make_gl_context_current   (GdkDisplay     *display,
+                                             GdkGLContext   *context);
 
 G_END_DECLS
 
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index 2d0faaca3e..6334e10325 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -1690,7 +1690,7 @@ gdk_win32_window_move_resize (GdkWindow *window,
     }
   else
     {
-      _gdk_win32_window_invalidate_egl_framebuffer (window);
+      gdk_win32_window_invalidate_egl_framebuffer (window);
       if (with_move)
        {
          gdk_win32_window_move_resize_internal (window, x, y, width, height);
@@ -4758,7 +4758,7 @@ gdk_win32_window_end_move_resize_drag (GdkWindow *window)
   GdkW32DragMoveResizeContext *context = &impl->drag_move_resize_context;
 
   if (context->op == GDK_WIN32_DRAGOP_RESIZE)
-    _gdk_win32_window_invalidate_egl_framebuffer (window);
+    gdk_win32_window_invalidate_egl_framebuffer (window);
 
   context->op = GDK_WIN32_DRAGOP_NONE;
 
@@ -5279,7 +5279,7 @@ gdk_win32_window_unmaximize (GdkWindow *window)
                           GDK_WINDOW_HWND (window),
                           _gdk_win32_window_state_to_string (window->state)));
 
-  _gdk_win32_window_invalidate_egl_framebuffer (window);
+  gdk_win32_window_invalidate_egl_framebuffer (window);
 
   if (GDK_WINDOW_IS_MAPPED (window))
     GtkShowWindow (window, SW_RESTORE);
@@ -5376,7 +5376,7 @@ gdk_win32_window_unfullscreen (GdkWindow *window)
 
       impl->hint_flags = fi->hint_flags;
       SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
-      _gdk_win32_window_invalidate_egl_framebuffer (window);
+      gdk_win32_window_invalidate_egl_framebuffer (window);
       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
                               fi->r.left, fi->r.top,
                               fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
@@ -6279,8 +6279,8 @@ gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
   impl_class->get_property = _gdk_win32_window_get_property;
   impl_class->change_property = _gdk_win32_window_change_property;
   impl_class->delete_property = _gdk_win32_window_delete_property;
-  impl_class->create_gl_context = _gdk_win32_window_create_gl_context;
-  impl_class->invalidate_for_new_frame = _gdk_win32_window_invalidate_for_new_frame;
+  impl_class->create_gl_context = gdk_win32_window_create_gl_context;
+  impl_class->invalidate_for_new_frame = gdk_win32_window_invalidate_for_new_frame;
   impl_class->get_scale_factor = _gdk_win32_window_get_scale_factor;
   impl_class->get_unscaled_size = _gdk_win32_window_get_unscaled_size;
 }


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