forked from AuroraMiddleware/gtk
Merge branch 'win32-gl-improvements' into 'main'
Windows: Some fixes to GL context realization (EGL/GLES in particular) See merge request GNOME/gtk!4386
This commit is contained in:
commit
68985d42bb
@ -1727,6 +1727,8 @@ gdk_display_init_egl (GdkDisplay *self,
|
|||||||
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
|
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
|
||||||
self->have_egl_pixel_format_float =
|
self->have_egl_pixel_format_float =
|
||||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_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)
|
if (self->have_egl_no_config_context)
|
||||||
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
|
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
|
||||||
|
@ -110,6 +110,7 @@ struct _GdkDisplay
|
|||||||
guint have_egl_swap_buffers_with_damage : 1;
|
guint have_egl_swap_buffers_with_damage : 1;
|
||||||
guint have_egl_no_config_context : 1;
|
guint have_egl_no_config_context : 1;
|
||||||
guint have_egl_pixel_format_float : 1;
|
guint have_egl_pixel_format_float : 1;
|
||||||
|
guint have_egl_win32_libangle : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkDisplayClass
|
struct _GdkDisplayClass
|
||||||
|
@ -278,7 +278,15 @@ gdk_gl_context_real_realize (GdkGLContext *context,
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
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);
|
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
||||||
forward_bit = gdk_gl_context_get_forward_compatible (context);
|
forward_bit = gdk_gl_context_get_forward_compatible (context);
|
||||||
legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ||
|
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);
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||||
gboolean force_gles = FALSE;
|
gboolean force_gles = FALSE;
|
||||||
#ifdef G_ENABLE_DEBUG
|
|
||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
#endif
|
|
||||||
int default_major, default_minor;
|
int default_major, default_minor;
|
||||||
int maj, min;
|
int maj, min;
|
||||||
|
|
||||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
|
||||||
display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||||
|
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
force_gles = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES);
|
force_gles = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES);
|
||||||
#endif
|
#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
|
/* Default fallback values for uninitialised contexts; we
|
||||||
* enforce a context version number of 3.2 for desktop GL,
|
* enforce a context version number of 3.2 for desktop GL,
|
||||||
* and 2.0 for GLES
|
* and 2.0 for GLES
|
||||||
*/
|
*/
|
||||||
if (gdk_gl_context_get_use_es (context) || force_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;
|
default_minor = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1175,16 +1175,18 @@ gdk_win32_display_get_setting (GdkDisplay *display,
|
|||||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static gboolean
|
static GdkGLContext *
|
||||||
gdk_win32_display_init_gl_backend (GdkDisplay *display,
|
gdk_win32_display_init_gl (GdkDisplay *display,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean result = FALSE;
|
|
||||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||||
|
HDC init_gl_hdc = NULL;
|
||||||
|
|
||||||
if (display_win32->dummy_context_wgl.hdc == NULL)
|
if (display_win32->dummy_context_wgl.hdc == NULL)
|
||||||
display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
|
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,
|
* No env vars set, do the regular GL initialization, first WGL and then EGL,
|
||||||
* as WGL is the more tried-and-tested configuration.
|
* as WGL is the more tried-and-tested configuration.
|
||||||
@ -1192,59 +1194,50 @@ gdk_win32_display_init_gl_backend (GdkDisplay *display,
|
|||||||
|
|
||||||
#ifdef HAVE_EGL
|
#ifdef HAVE_EGL
|
||||||
/*
|
/*
|
||||||
* Disable defaulting to EGL for now, since shaders need to be fixed for
|
* Disable defaulting to EGL as EGL is used more as a compatibility layer
|
||||||
* usage against libANGLE EGL. EGL is used more as a compatibility layer
|
|
||||||
* on Windows rather than being a native citizen on Windows
|
* on Windows rather than being a native citizen on Windows
|
||||||
*/
|
*/
|
||||||
if (_gdk_debug_flags & GDK_DEBUG_GL_EGL)
|
if (GDK_DEBUG_CHECK (GL_EGL) || GDK_DEBUG_CHECK (GL_GLES))
|
||||||
result = gdk_display_init_egl (display,
|
|
||||||
EGL_PLATFORM_ANGLE_ANGLE,
|
|
||||||
display_win32->dummy_context_wgl.hdc,
|
|
||||||
FALSE,
|
|
||||||
error);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
{
|
{
|
||||||
g_clear_error (error);
|
if (gdk_display_init_egl (display,
|
||||||
result = gdk_win32_display_init_wgl (display, error);
|
EGL_PLATFORM_ANGLE_ANGLE,
|
||||||
}
|
init_gl_hdc,
|
||||||
|
FALSE,
|
||||||
#ifdef HAVE_EGL
|
error))
|
||||||
if (!result)
|
{
|
||||||
{
|
return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL,
|
||||||
g_clear_error (error);
|
"display", display,
|
||||||
result = gdk_display_init_egl (display,
|
NULL);
|
||||||
EGL_PLATFORM_ANGLE_ANGLE,
|
}
|
||||||
display_win32->dummy_context_wgl.hdc,
|
else
|
||||||
TRUE,
|
g_clear_error (error);
|
||||||
error);
|
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifdef HAVE_EGL
|
||||||
else if (gdk_display_get_egl_display (display))
|
g_clear_error (error);
|
||||||
gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL, "display", display, NULL);
|
|
||||||
|
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
|
#endif
|
||||||
|
|
||||||
g_return_val_if_fail (gl_context != NULL, NULL);
|
return NULL;
|
||||||
|
|
||||||
return gl_context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,7 +125,6 @@ struct _GdkWin32Display
|
|||||||
|
|
||||||
/* WGL/OpenGL Items */
|
/* WGL/OpenGL Items */
|
||||||
GdkWin32GLDummyContextWGL dummy_context_wgl;
|
GdkWin32GLDummyContextWGL dummy_context_wgl;
|
||||||
int wgl_pixel_format;
|
|
||||||
guint gl_version;
|
guint gl_version;
|
||||||
|
|
||||||
GListModel *monitors;
|
GListModel *monitors;
|
||||||
|
@ -258,9 +258,6 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
|||||||
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, error))
|
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (display_win32->wgl_pixel_format != 0)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* acquire and cache dummy Window (HWND & HDC) and
|
/* acquire and cache dummy Window (HWND & HDC) and
|
||||||
* dummy GL Context, it is used to query functions
|
* dummy GL Context, it is used to query functions
|
||||||
* and used for other stuff as well
|
* 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 =
|
display_win32->hasWglARBCreateContext =
|
||||||
epoxy_has_wgl_extension (hdc, "WGL_ARB_create_context");
|
epoxy_has_wgl_extension (hdc, "WGL_ARB_create_context");
|
||||||
display_win32->hasWglEXTSwapControl =
|
display_win32->hasWglEXTSwapControl =
|
||||||
@ -432,33 +427,13 @@ create_wgl_context (HDC hdc,
|
|||||||
goto gl_fail;
|
goto gl_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
hglrc = create_wgl_context_with_attribs (hdc,
|
||||||
* We need a Core GL 4.1 context in order to use the GL support in
|
hglrc_base,
|
||||||
* the GStreamer media widget backend, but wglCreateContextAttribsARB()
|
share,
|
||||||
* may only give us the GL context version that we ask for here, and
|
flags,
|
||||||
* nothing more. So, if we are asking for a pre-GL 4.1 context,
|
major,
|
||||||
* try to ask for a 4.1 context explicitly first. If that is not supported,
|
minor,
|
||||||
* then we fall back to whatever version that we were asking for (or, even a
|
is_legacy);
|
||||||
* 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);
|
|
||||||
|
|
||||||
/* return the legacy context we have if it could be setup properly, in case the 3.0+ context creation failed */
|
/* return the legacy context we have if it could be setup properly, in case the 3.0+ context creation failed */
|
||||||
if (hglrc == NULL)
|
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))
|
if (!gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, error))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
|
||||||
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
||||||
compat_bit = gdk_gl_context_get_forward_compatible (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)
|
if (surface != NULL)
|
||||||
hdc = GDK_WIN32_SURFACE (surface)->hdc;
|
hdc = GDK_WIN32_SURFACE (surface)->hdc;
|
||||||
else
|
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 */
|
/* 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_is_legacy (context, legacy_bit);
|
||||||
|
gdk_gl_context_set_required_version (context, major, minor);
|
||||||
|
|
||||||
return GDK_GL_API_GL;
|
return GDK_GL_API_GL;
|
||||||
}
|
}
|
||||||
@ -728,10 +721,11 @@ gdk_win32_display_get_wgl_version (GdkDisplay *display,
|
|||||||
if (!GDK_IS_WIN32_DISPLAY (display))
|
if (!GDK_IS_WIN32_DISPLAY (display))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
display_win32 = GDK_WIN32_DISPLAY (display);
|
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, NULL))
|
||||||
if (display_win32->wgl_pixel_format == 0)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
display_win32 = GDK_WIN32_DISPLAY (display);
|
||||||
|
|
||||||
if (major != NULL)
|
if (major != NULL)
|
||||||
*major = display_win32->gl_version / 10;
|
*major = display_win32->gl_version / 10;
|
||||||
if (minor != NULL)
|
if (minor != NULL)
|
||||||
|
@ -597,14 +597,7 @@ get_renderer_for_backend (GdkSurface *surface)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef GDK_WINDOWING_WIN32
|
#ifdef GDK_WINDOWING_WIN32
|
||||||
if (GDK_IS_WIN32_SURFACE (surface))
|
if (GDK_IS_WIN32_SURFACE (surface))
|
||||||
/* remove check for OpenGL/ES when OpenGL/ES 2.0 shader is ready */
|
return GSK_TYPE_GL_RENDERER;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return G_TYPE_INVALID;
|
return G_TYPE_INVALID;
|
||||||
|
Loading…
Reference in New Issue
Block a user