diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index dddc8b2060..0e935d8176 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -1727,6 +1727,8 @@ gdk_display_init_egl (GdkDisplay *self, epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context"); self->have_egl_pixel_format_float = epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float"); + self->have_egl_win32_libangle = + epoxy_has_egl_extension (priv->egl_display, "EGL_ANGLE_d3d_share_handle_client_buffer"); if (self->have_egl_no_config_context) priv->egl_config_high_depth = gdk_display_create_egl_config (self, diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h index cb80ad3f88..4eb3625d88 100644 --- a/gdk/gdkdisplayprivate.h +++ b/gdk/gdkdisplayprivate.h @@ -110,6 +110,7 @@ struct _GdkDisplay guint have_egl_swap_buffers_with_damage : 1; guint have_egl_no_config_context : 1; guint have_egl_pixel_format_float : 1; + guint have_egl_win32_libangle : 1; }; struct _GdkDisplayClass diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c index 3c5e4ffdb1..d1bc7c57c2 100644 --- a/gdk/gdkglcontext.c +++ b/gdk/gdkglcontext.c @@ -278,7 +278,15 @@ gdk_gl_context_real_realize (GdkGLContext *context, int i = 0; G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME; - gdk_gl_context_get_required_version (context, &major, &minor); + if (share != NULL) + { + gdk_gl_context_get_required_version (share, &major, &minor); + gdk_gl_context_set_allowed_apis (context, + gdk_gl_context_get_allowed_apis (share)); + } + else + gdk_gl_context_get_required_version (context, &major, &minor); + debug_bit = gdk_gl_context_get_debug_enabled (context); forward_bit = gdk_gl_context_get_forward_compatible (context); legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) || @@ -1048,26 +1056,29 @@ gdk_gl_context_get_required_version (GdkGLContext *context, { GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context); gboolean force_gles = FALSE; -#ifdef G_ENABLE_DEBUG GdkDisplay *display; -#endif int default_major, default_minor; int maj, min; g_return_if_fail (GDK_IS_GL_CONTEXT (context)); -#ifdef G_ENABLE_DEBUG display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)); + +#ifdef G_ENABLE_DEBUG force_gles = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES); #endif + /* libANGLE on Windows at least requires GLES 3.0+ */ + if (display->have_egl_win32_libangle) + force_gles = TRUE; + /* Default fallback values for uninitialised contexts; we * enforce a context version number of 3.2 for desktop GL, * and 2.0 for GLES */ if (gdk_gl_context_get_use_es (context) || force_gles) { - default_major = 2; + default_major = display->have_egl_win32_libangle ? 3 : 2; default_minor = 0; } else diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c index 675e1af5e2..a544bf3827 100644 --- a/gdk/win32/gdkdisplay-win32.c +++ b/gdk/win32/gdkdisplay-win32.c @@ -1175,16 +1175,18 @@ gdk_win32_display_get_setting (GdkDisplay *display, #define EGL_PLATFORM_ANGLE_ANGLE 0x3202 #endif -static gboolean -gdk_win32_display_init_gl_backend (GdkDisplay *display, - GError **error) +static GdkGLContext * +gdk_win32_display_init_gl (GdkDisplay *display, + GError **error) { - gboolean result = FALSE; GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display); + HDC init_gl_hdc = NULL; if (display_win32->dummy_context_wgl.hdc == NULL) display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd); + init_gl_hdc = display_win32->dummy_context_wgl.hdc; + /* * No env vars set, do the regular GL initialization, first WGL and then EGL, * as WGL is the more tried-and-tested configuration. @@ -1192,59 +1194,50 @@ gdk_win32_display_init_gl_backend (GdkDisplay *display, #ifdef HAVE_EGL /* - * Disable defaulting to EGL for now, since shaders need to be fixed for - * usage against libANGLE EGL. EGL is used more as a compatibility layer + * Disable defaulting to EGL as EGL is used more as a compatibility layer * on Windows rather than being a native citizen on Windows */ - if (_gdk_debug_flags & GDK_DEBUG_GL_EGL) - result = gdk_display_init_egl (display, - EGL_PLATFORM_ANGLE_ANGLE, - display_win32->dummy_context_wgl.hdc, - FALSE, - error); -#endif - - if (!result) + if (GDK_DEBUG_CHECK (GL_EGL) || GDK_DEBUG_CHECK (GL_GLES)) { - g_clear_error (error); - result = gdk_win32_display_init_wgl (display, error); - } - -#ifdef HAVE_EGL - if (!result) - { - g_clear_error (error); - result = gdk_display_init_egl (display, - EGL_PLATFORM_ANGLE_ANGLE, - display_win32->dummy_context_wgl.hdc, - TRUE, - error); + if (gdk_display_init_egl (display, + EGL_PLATFORM_ANGLE_ANGLE, + init_gl_hdc, + FALSE, + error)) + { + return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL, + "display", display, + NULL); + } + else + g_clear_error (error); } #endif - return result; -} + if (gdk_win32_display_init_wgl (display, error)) + { + return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL, + "display", display, + NULL); + } -static GdkGLContext * -gdk_win32_display_init_gl (GdkDisplay *display, - GError **error) -{ - GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display); - GdkGLContext *gl_context = NULL; - - if (!gdk_win32_display_init_gl_backend (display, error)) - return NULL; - - if (display_win32->wgl_pixel_format != 0) - gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL, "display", display, NULL); #ifdef HAVE_EGL - else if (gdk_display_get_egl_display (display)) - gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL, "display", display, NULL); + g_clear_error (error); + + if (gdk_display_init_egl (display, + EGL_PLATFORM_ANGLE_ANGLE, + init_gl_hdc, + TRUE, + error)) + { + return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL, + "display", display, + NULL); + + } #endif - g_return_val_if_fail (gl_context != NULL, NULL); - - return gl_context; + return NULL; } /** diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h index 3b746bbe1b..19f11e5f9f 100644 --- a/gdk/win32/gdkdisplay-win32.h +++ b/gdk/win32/gdkdisplay-win32.h @@ -125,7 +125,6 @@ struct _GdkWin32Display /* WGL/OpenGL Items */ GdkWin32GLDummyContextWGL dummy_context_wgl; - int wgl_pixel_format; guint gl_version; GListModel *monitors; diff --git a/gdk/win32/gdkglcontext-win32-wgl.c b/gdk/win32/gdkglcontext-win32-wgl.c index d443a2c7ff..231f2a6a01 100644 --- a/gdk/win32/gdkglcontext-win32-wgl.c +++ b/gdk/win32/gdkglcontext-win32-wgl.c @@ -258,9 +258,6 @@ gdk_win32_display_init_wgl (GdkDisplay *display, if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, error)) return FALSE; - if (display_win32->wgl_pixel_format != 0) - return TRUE; - /* acquire and cache dummy Window (HWND & HDC) and * dummy GL Context, it is used to query functions * and used for other stuff as well @@ -299,8 +296,6 @@ gdk_win32_display_init_wgl (GdkDisplay *display, } } - display_win32->wgl_pixel_format = best_idx; - display_win32->hasWglARBCreateContext = epoxy_has_wgl_extension (hdc, "WGL_ARB_create_context"); display_win32->hasWglEXTSwapControl = @@ -432,33 +427,13 @@ create_wgl_context (HDC hdc, goto gl_fail; } - /* - * We need a Core GL 4.1 context in order to use the GL support in - * the GStreamer media widget backend, but wglCreateContextAttribsARB() - * may only give us the GL context version that we ask for here, and - * nothing more. So, if we are asking for a pre-GL 4.1 context, - * try to ask for a 4.1 context explicitly first. If that is not supported, - * then we fall back to whatever version that we were asking for (or, even a - * legacy context if that fails), at a price of not able to have GL support - * for the media GStreamer backend. - */ - if (major < 4 || (major == 4 && minor < 1)) - hglrc = create_wgl_context_with_attribs (hdc, - hglrc_base, - share, - flags, - 4, - 1, - is_legacy); - - if (hglrc == NULL) - hglrc = create_wgl_context_with_attribs (hdc, - hglrc_base, - share, - flags, - major, - minor, - is_legacy); + hglrc = create_wgl_context_with_attribs (hdc, + hglrc_base, + share, + flags, + major, + minor, + is_legacy); /* return the legacy context we have if it could be setup properly, in case the 3.0+ context creation failed */ if (hglrc == NULL) @@ -564,10 +539,27 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context, if (!gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, error)) return 0; - 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); + /* + * We may need a Core GL 4.1+ context in order to use the GL support in + * the GStreamer media widget backend (such as on Intel drivers), but + * wglCreateContextAttribsARB() may only give us the GL context version + * that we ask for here, and nothing more. So, improve things here by + * asking for the GL version that is reported to us via epoxy_gl_version(), + * rather than the default GL core 3.2 context. Save this up in our + * GdkGLContext so that subsequent contexts that are shared with this + * context are created likewise too. + */ + if (share != NULL) + gdk_gl_context_get_required_version (share, &major, &minor); + else + { + major = display_win32->gl_version / 10; + minor = display_win32->gl_version % 10; + } + if (surface != NULL) hdc = GDK_WIN32_SURFACE (surface)->hdc; else @@ -634,6 +626,7 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context, /* Ensure that any other context is created with a legacy bit set */ gdk_gl_context_set_is_legacy (context, legacy_bit); + gdk_gl_context_set_required_version (context, major, minor); return GDK_GL_API_GL; } @@ -728,10 +721,11 @@ gdk_win32_display_get_wgl_version (GdkDisplay *display, if (!GDK_IS_WIN32_DISPLAY (display)) return FALSE; - display_win32 = GDK_WIN32_DISPLAY (display); - if (display_win32->wgl_pixel_format == 0) + if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, NULL)) return FALSE; + display_win32 = GDK_WIN32_DISPLAY (display); + if (major != NULL) *major = display_win32->gl_version / 10; if (minor != NULL) diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index b782cfd493..03aa87f512 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -597,14 +597,7 @@ get_renderer_for_backend (GdkSurface *surface) #endif #ifdef GDK_WINDOWING_WIN32 if (GDK_IS_WIN32_SURFACE (surface)) - /* remove check for OpenGL/ES when OpenGL/ES 2.0 shader is ready */ - { - GdkDisplay *display = gdk_surface_get_display (surface); - - if (!(GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) || - GDK_WIN32_DISPLAY (display)->running_on_arm64)) - return GSK_TYPE_GL_RENDERER; - } + return GSK_TYPE_GL_RENDERER; #endif return G_TYPE_INVALID;