mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
Merge branch 'win32-egl-cleanup' into 'master'
GDK-Win32: Port EGL code to newer common GDK code See merge request GNOME/gtk!4040
This commit is contained in:
commit
48b83d3e97
@ -1438,31 +1438,6 @@ describe_egl_config (EGLDisplay egl_display,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*<private>
|
|
||||||
* gdk_display_get_egl_display:
|
|
||||||
* @self: a display
|
|
||||||
*
|
|
||||||
* Retrieves the EGL display connection object for the given GDK display.
|
|
||||||
*
|
|
||||||
* This function returns `NULL` if GL is not supported or GDK is using
|
|
||||||
* a different OpenGL framework than EGL.
|
|
||||||
*
|
|
||||||
* Returns: (nullable): the EGL display object
|
|
||||||
*/
|
|
||||||
gpointer
|
|
||||||
gdk_display_get_egl_display (GdkDisplay *self)
|
|
||||||
{
|
|
||||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
|
||||||
|
|
||||||
g_return_val_if_fail (GDK_IS_DISPLAY (self), NULL);
|
|
||||||
|
|
||||||
if (!priv->egl_display &&
|
|
||||||
!gdk_display_prepare_gl (self, NULL))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return priv->egl_display;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpointer
|
gpointer
|
||||||
gdk_display_get_egl_config (GdkDisplay *self)
|
gdk_display_get_egl_config (GdkDisplay *self)
|
||||||
{
|
{
|
||||||
@ -1789,6 +1764,35 @@ gdk_display_init_egl (GdkDisplay *self,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*<private>
|
||||||
|
* gdk_display_get_egl_display:
|
||||||
|
* @self: a display
|
||||||
|
*
|
||||||
|
* Retrieves the EGL display connection object for the given GDK display.
|
||||||
|
*
|
||||||
|
* This function returns `NULL` if GL is not supported or GDK is using
|
||||||
|
* a different OpenGL framework than EGL.
|
||||||
|
*
|
||||||
|
* Returns: (nullable): the EGL display object
|
||||||
|
*/
|
||||||
|
gpointer
|
||||||
|
gdk_display_get_egl_display (GdkDisplay *self)
|
||||||
|
{
|
||||||
|
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDK_IS_DISPLAY (self), NULL);
|
||||||
|
|
||||||
|
#ifdef HAVE_EGL
|
||||||
|
if (!priv->egl_display &&
|
||||||
|
!gdk_display_prepare_gl (self, NULL))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return priv->egl_display;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
GdkDebugFlags
|
GdkDebugFlags
|
||||||
gdk_display_get_debug_flags (GdkDisplay *display)
|
gdk_display_get_debug_flags (GdkDisplay *display)
|
||||||
{
|
{
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
#include <dwmapi.h>
|
#include <dwmapi.h>
|
||||||
|
|
||||||
#include "gdkwin32langnotification.h"
|
#include "gdkwin32langnotification.h"
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef HAVE_EGL
|
||||||
# include <epoxy/egl.h>
|
# include <epoxy/egl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -645,14 +645,6 @@ gdk_win32_display_dispose (GObject *object)
|
|||||||
{
|
{
|
||||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (object);
|
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (object);
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
|
||||||
if (display_win32->egl_disp != EGL_NO_DISPLAY)
|
|
||||||
{
|
|
||||||
eglTerminate (display_win32->egl_disp);
|
|
||||||
display_win32->egl_disp = EGL_NO_DISPLAY;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (display_win32->hwnd != NULL)
|
if (display_win32->hwnd != NULL)
|
||||||
{
|
{
|
||||||
if (display_win32->dummy_context_wgl.hglrc != NULL)
|
if (display_win32->dummy_context_wgl.hglrc != NULL)
|
||||||
@ -1146,23 +1138,54 @@ gdk_win32_display_get_setting (GdkDisplay *display,
|
|||||||
return _gdk_win32_get_setting (name, value);
|
return _gdk_win32_get_setting (name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef EGL_PLATFORM_ANGLE_ANGLE
|
||||||
|
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||||
|
#endif
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gdk_win32_display_init_gl_backend (GdkDisplay *display,
|
gdk_win32_display_init_gl_backend (GdkDisplay *display,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
|
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||||
|
|
||||||
/* No env vars set, do the regular GL initialization, first WGL and then EGL,
|
if (display_win32->dummy_context_wgl.hdc == NULL)
|
||||||
|
display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
result = gdk_win32_display_init_wgl (display, error);
|
#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
|
||||||
|
* 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
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
g_clear_error (error);
|
g_clear_error (error);
|
||||||
result = gdk_win32_display_init_egl (display, 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);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1179,13 +1202,12 @@ gdk_win32_display_init_gl (GdkDisplay *display,
|
|||||||
if (!gdk_win32_display_init_gl_backend (display, error))
|
if (!gdk_win32_display_init_gl_backend (display, error))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
|
||||||
if (display_win32->egl_disp)
|
|
||||||
gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL, "display", display, NULL);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if (display_win32->wgl_pixel_format != 0)
|
if (display_win32->wgl_pixel_format != 0)
|
||||||
gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL, "display", display, NULL);
|
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);
|
||||||
|
#endif
|
||||||
|
|
||||||
g_return_val_if_fail (gl_context != NULL, NULL);
|
g_return_val_if_fail (gl_context != NULL, NULL);
|
||||||
|
|
||||||
@ -1203,23 +1225,9 @@ gdk_win32_display_init_gl (GdkDisplay *display,
|
|||||||
gpointer
|
gpointer
|
||||||
gdk_win32_display_get_egl_display (GdkDisplay *display)
|
gdk_win32_display_get_egl_display (GdkDisplay *display)
|
||||||
{
|
{
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
|
||||||
GdkWin32Display *display_win32;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_return_val_if_fail (GDK_IS_WIN32_DISPLAY (display), NULL);
|
g_return_val_if_fail (GDK_IS_WIN32_DISPLAY (display), NULL);
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
return gdk_display_get_egl_display (display);
|
||||||
display_win32 = GDK_WIN32_DISPLAY (display);
|
|
||||||
|
|
||||||
if (display_win32->wgl_pixel_format != 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return display_win32->egl_disp;
|
|
||||||
#else
|
|
||||||
/* no EGL support */
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "gdkwin32screen.h"
|
#include "gdkwin32screen.h"
|
||||||
#include "gdkwin32cursor.h"
|
#include "gdkwin32cursor.h"
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef HAVE_EGL
|
||||||
# include <epoxy/egl.h>
|
# include <epoxy/egl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -135,14 +135,6 @@ struct _GdkWin32Display
|
|||||||
int wgl_pixel_format;
|
int wgl_pixel_format;
|
||||||
guint gl_version;
|
guint gl_version;
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
|
||||||
/* EGL (Angle) Items */
|
|
||||||
guint egl_version;
|
|
||||||
EGLDisplay egl_disp;
|
|
||||||
EGLConfig egl_config;
|
|
||||||
HDC hdc_egl_temp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GListModel *monitors;
|
GListModel *monitors;
|
||||||
|
|
||||||
guint hasWglARBCreateContext : 1;
|
guint hasWglARBCreateContext : 1;
|
||||||
@ -151,7 +143,7 @@ struct _GdkWin32Display
|
|||||||
guint hasWglARBPixelFormat : 1;
|
guint hasWglARBPixelFormat : 1;
|
||||||
guint hasWglARBmultisample : 1;
|
guint hasWglARBmultisample : 1;
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef HAVE_EGL
|
||||||
guint hasEglKHRCreateContext : 1;
|
guint hasEglKHRCreateContext : 1;
|
||||||
guint hasEglSurfacelessContext : 1;
|
guint hasEglSurfacelessContext : 1;
|
||||||
EGLint egl_min_swap_interval;
|
EGLint egl_min_swap_interval;
|
||||||
|
@ -53,30 +53,6 @@ typedef struct _GdkWin32GLContextClass GdkWin32GLContextEGLClass;
|
|||||||
|
|
||||||
G_DEFINE_TYPE (GdkWin32GLContextEGL, gdk_win32_gl_context_egl, GDK_TYPE_WIN32_GL_CONTEXT)
|
G_DEFINE_TYPE (GdkWin32GLContextEGL, gdk_win32_gl_context_egl, GDK_TYPE_WIN32_GL_CONTEXT)
|
||||||
|
|
||||||
static void
|
|
||||||
gdk_win32_gl_context_egl_dispose (GObject *gobject)
|
|
||||||
{
|
|
||||||
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
|
||||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (gobject);
|
|
||||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context));
|
|
||||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
|
||||||
|
|
||||||
if (display_win32 != NULL)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (gdk_win32_gl_context_egl_parent_class)->dispose (gobject);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_egl_force_redraw (GdkSurface *surface)
|
is_egl_force_redraw (GdkSurface *surface)
|
||||||
{
|
{
|
||||||
@ -109,7 +85,7 @@ gdk_win32_gl_context_egl_end_frame (GdkDrawContext *draw_context,
|
|||||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
|
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
|
||||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||||
GdkWin32Display *display_win32 = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
|
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||||
cairo_rectangle_int_t whole_window;
|
cairo_rectangle_int_t whole_window;
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
|
|
||||||
@ -122,7 +98,7 @@ gdk_win32_gl_context_egl_end_frame (GdkDrawContext *draw_context,
|
|||||||
gdk_surface_get_height (surface)
|
gdk_surface_get_height (surface)
|
||||||
};
|
};
|
||||||
|
|
||||||
egl_surface = gdk_win32_surface_get_egl_surface (surface, display_win32->egl_config, FALSE);
|
egl_surface = gdk_surface_get_egl_surface (surface);
|
||||||
|
|
||||||
if (is_egl_force_redraw (surface))
|
if (is_egl_force_redraw (surface))
|
||||||
{
|
{
|
||||||
@ -135,338 +111,7 @@ gdk_win32_gl_context_egl_end_frame (GdkDrawContext *draw_context,
|
|||||||
reset_egl_force_redraw (surface);
|
reset_egl_force_redraw (surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
eglSwapBuffers (display_win32->egl_disp, egl_surface);
|
eglSwapBuffers (gdk_display_get_egl_display (display), egl_surface);
|
||||||
}
|
|
||||||
|
|
||||||
#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)
|
|
||||||
{
|
|
||||||
EGLDisplay disp;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_EGL_ATTRS 30
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
find_eglconfig_for_window (GdkWin32Display *display,
|
|
||||||
EGLConfig *egl_config_out,
|
|
||||||
EGLint *min_swap_interval_out,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
EGLint attrs[MAX_EGL_ATTRS];
|
|
||||||
EGLint count;
|
|
||||||
EGLConfig *configs, chosen_config;
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
EGLDisplay egl_disp = display->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;
|
|
||||||
attrs[i++] = EGL_ALPHA_SIZE;
|
|
||||||
attrs[i++] = 1;
|
|
||||||
|
|
||||||
attrs[i++] = EGL_NONE;
|
|
||||||
g_assert (i < MAX_EGL_ATTRS);
|
|
||||||
|
|
||||||
if (!eglChooseConfig (display->egl_disp, attrs, NULL, 0, &count) || count < 1)
|
|
||||||
{
|
|
||||||
g_set_error_literal (error, GDK_GL_ERROR,
|
|
||||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
|
||||||
_("No available configurations for the given pixel format"));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
configs = g_new (EGLConfig, count);
|
|
||||||
|
|
||||||
if (!eglChooseConfig (display->egl_disp, attrs, configs, count, &count) || count < 1)
|
|
||||||
{
|
|
||||||
g_set_error_literal (error, GDK_GL_ERROR,
|
|
||||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
|
||||||
_("No available configurations for the given pixel format"));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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))
|
|
||||||
{
|
|
||||||
g_set_error_literal (error, GDK_GL_ERROR,
|
|
||||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
|
||||||
"Could not retrieve the minimum swap interval");
|
|
||||||
g_free (configs);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (egl_config_out != NULL)
|
|
||||||
*egl_config_out = chosen_config;
|
|
||||||
|
|
||||||
g_free (configs);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
gdk_win32_display_init_egl (GdkDisplay *display,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
|
||||||
int best_idx = 0;
|
|
||||||
EGLDisplay egl_disp;
|
|
||||||
|
|
||||||
if (!gdk_gl_backend_can_be_used (GDK_GL_EGL, error))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (display_win32->egl_disp != EGL_NO_DISPLAY)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
egl_disp = gdk_win32_get_egl_display (display_win32);
|
|
||||||
|
|
||||||
if (egl_disp == EGL_NO_DISPLAY)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (!eglInitialize (egl_disp, NULL, NULL))
|
|
||||||
{
|
|
||||||
eglTerminate (egl_disp);
|
|
||||||
egl_disp = EGL_NO_DISPLAY;
|
|
||||||
g_set_error_literal (error, GDK_GL_ERROR,
|
|
||||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
|
||||||
_("No GL implementation is available"));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
display_win32->egl_disp = egl_disp;
|
|
||||||
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");
|
|
||||||
|
|
||||||
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"));
|
|
||||||
|
|
||||||
return find_eglconfig_for_window (display_win32, &display_win32->egl_config,
|
|
||||||
&display_win32->egl_min_swap_interval, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
#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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* Specify the flags */
|
|
||||||
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
|
|
||||||
context_attribs[i++] = flags;
|
|
||||||
|
|
||||||
context_attribs[i++] = EGL_NONE;
|
|
||||||
g_assert (i < N_EGL_ATTRS);
|
|
||||||
|
|
||||||
ctx = eglCreateContext (display,
|
|
||||||
config,
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gdk_win32_gl_context_egl_realize (GdkGLContext *context,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
|
|
||||||
|
|
||||||
gboolean debug_bit, compat_bit, legacy_bit;
|
|
||||||
gboolean use_es = FALSE;
|
|
||||||
EGLContext egl_context;
|
|
||||||
EGLContext ctx;
|
|
||||||
|
|
||||||
/* request flags and specific versions for core (3.2+) WGL context */
|
|
||||||
int flags = 0;
|
|
||||||
int major = 0;
|
|
||||||
int minor = 0;
|
|
||||||
|
|
||||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
|
||||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
|
||||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
|
||||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
|
||||||
GdkGLContext *share = gdk_display_get_gl_context (display);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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_LEGACY is set, we default to a legacy context */
|
|
||||||
legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ?
|
|
||||||
TRUE :
|
|
||||||
share != NULL && gdk_gl_context_is_legacy (share);
|
|
||||||
|
|
||||||
use_es = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
|
|
||||||
(share != NULL && gdk_gl_context_get_use_es (share));
|
|
||||||
|
|
||||||
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 (display_win32->egl_disp,
|
|
||||||
display_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));
|
|
||||||
|
|
||||||
context_egl->egl_context = ctx;
|
|
||||||
|
|
||||||
/* We are using GLES here */
|
|
||||||
gdk_gl_context_set_use_es (context, TRUE);
|
|
||||||
|
|
||||||
/* 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_gl_context_egl_clear_current (GdkGLContext *context)
|
|
||||||
{
|
|
||||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
|
||||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
|
||||||
|
|
||||||
if (display_win32->egl_disp != EGL_NO_DISPLAY)
|
|
||||||
return eglMakeCurrent (display_win32->egl_disp,
|
|
||||||
EGL_NO_SURFACE,
|
|
||||||
EGL_NO_SURFACE,
|
|
||||||
EGL_NO_CONTEXT);
|
|
||||||
else
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gdk_win32_gl_context_egl_make_current (GdkGLContext *context,
|
|
||||||
gboolean surfaceless)
|
|
||||||
{
|
|
||||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
|
|
||||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
|
||||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
|
||||||
GdkSurface *surface;
|
|
||||||
|
|
||||||
gboolean do_frame_sync = FALSE;
|
|
||||||
|
|
||||||
EGLSurface egl_surface;
|
|
||||||
|
|
||||||
surface = gdk_gl_context_get_surface (context);
|
|
||||||
|
|
||||||
if (!surfaceless)
|
|
||||||
egl_surface = gdk_win32_surface_get_egl_surface (surface, display_win32->egl_config, FALSE);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (display_win32->hasEglSurfacelessContext)
|
|
||||||
egl_surface = EGL_NO_SURFACE;
|
|
||||||
else
|
|
||||||
egl_surface = gdk_win32_surface_get_egl_surface (surface, display_win32->egl_config, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!eglMakeCurrent (display_win32->egl_disp,
|
|
||||||
egl_surface,
|
|
||||||
egl_surface,
|
|
||||||
context_egl->egl_context))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
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
|
static void
|
||||||
@ -484,18 +129,11 @@ gdk_win32_gl_context_egl_class_init (GdkWin32GLContextClass *klass)
|
|||||||
{
|
{
|
||||||
GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS(klass);
|
GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS(klass);
|
||||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS(klass);
|
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS(klass);
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
||||||
|
|
||||||
context_class->backend_type = GDK_GL_EGL;
|
context_class->backend_type = GDK_GL_EGL;
|
||||||
|
|
||||||
context_class->realize = gdk_win32_gl_context_egl_realize;
|
|
||||||
context_class->make_current = gdk_win32_gl_context_egl_make_current;
|
|
||||||
context_class->clear_current = gdk_win32_gl_context_egl_clear_current;
|
|
||||||
|
|
||||||
draw_context_class->begin_frame = gdk_win32_gl_context_egl_begin_frame;
|
draw_context_class->begin_frame = gdk_win32_gl_context_egl_begin_frame;
|
||||||
draw_context_class->end_frame = gdk_win32_gl_context_egl_end_frame;
|
draw_context_class->end_frame = gdk_win32_gl_context_egl_end_frame;
|
||||||
|
|
||||||
gobject_class->dispose = gdk_win32_gl_context_egl_dispose;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -226,9 +226,6 @@ gdk_init_dummy_wgl_context (GdkWin32Display *display_win32)
|
|||||||
gboolean set_pixel_format_result = FALSE;
|
gboolean set_pixel_format_result = FALSE;
|
||||||
int best_idx = 0;
|
int best_idx = 0;
|
||||||
|
|
||||||
if (display_win32->dummy_context_wgl.hdc == NULL)
|
|
||||||
display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
|
|
||||||
|
|
||||||
memset (&pfd, 0, sizeof (PIXELFORMATDESCRIPTOR));
|
memset (&pfd, 0, sizeof (PIXELFORMATDESCRIPTOR));
|
||||||
|
|
||||||
best_idx = get_wgl_pfd (display_win32->dummy_context_wgl.hdc, &pfd, NULL);
|
best_idx = get_wgl_pfd (display_win32->dummy_context_wgl.hdc, &pfd, NULL);
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <epoxy/wgl.h>
|
#include <epoxy/wgl.h>
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef HAVE_EGL
|
||||||
# include <epoxy/egl.h>
|
# include <epoxy/egl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <epoxy/gl.h>
|
#include <epoxy/gl.h>
|
||||||
#include <epoxy/wgl.h>
|
#include <epoxy/wgl.h>
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef HAVE_EGL
|
||||||
# include <epoxy/egl.h>
|
# include <epoxy/egl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -685,22 +685,6 @@ gdk_win32_surface_destroy (GdkSurface *window,
|
|||||||
gdk_win32_surface_set_transient_for (child, NULL);
|
gdk_win32_surface_set_transient_for (child, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
|
||||||
GdkWin32Display *display = GDK_WIN32_DISPLAY (gdk_surface_get_display (window));
|
|
||||||
|
|
||||||
/* Get rid of any EGLSurfaces that we might have created */
|
|
||||||
if (surface->egl_surface != EGL_NO_SURFACE)
|
|
||||||
{
|
|
||||||
eglDestroySurface (display->egl_disp, surface->egl_surface);
|
|
||||||
surface->egl_surface = EGL_NO_SURFACE;
|
|
||||||
}
|
|
||||||
if (surface->egl_dummy_surface != EGL_NO_SURFACE)
|
|
||||||
{
|
|
||||||
eglDestroySurface (display->egl_disp, surface->egl_dummy_surface);
|
|
||||||
surface->egl_dummy_surface = EGL_NO_SURFACE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Remove ourself from our transient owner */
|
/* Remove ourself from our transient owner */
|
||||||
if (surface->transient_owner != NULL)
|
if (surface->transient_owner != NULL)
|
||||||
{
|
{
|
||||||
@ -5026,39 +5010,6 @@ gdk_win32_drag_surface_iface_init (GdkDragSurfaceInterface *iface)
|
|||||||
iface->present = gdk_win32_drag_surface_present;
|
iface->present = gdk_win32_drag_surface_present;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
|
||||||
EGLSurface
|
|
||||||
gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
|
||||||
EGLConfig config,
|
|
||||||
gboolean is_dummy)
|
|
||||||
{
|
|
||||||
GdkWin32Display *display = GDK_WIN32_DISPLAY (gdk_surface_get_display (surface));
|
|
||||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
|
||||||
|
|
||||||
if (is_dummy)
|
|
||||||
{
|
|
||||||
if (impl->egl_dummy_surface == EGL_NO_SURFACE)
|
|
||||||
{
|
|
||||||
EGLint attribs[] = {EGL_WIDTH, 1, EGL_WIDTH, 1, EGL_NONE};
|
|
||||||
impl->egl_dummy_surface = eglCreatePbufferSurface (display->egl_disp,
|
|
||||||
config,
|
|
||||||
attribs);
|
|
||||||
}
|
|
||||||
return impl->egl_dummy_surface;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (impl->egl_surface == EGL_NO_SURFACE)
|
|
||||||
impl->egl_surface = eglCreateWindowSurface (display->egl_disp,
|
|
||||||
config,
|
|
||||||
GDK_SURFACE_HWND (surface),
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
return impl->egl_surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
|
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
|
||||||
@ -5137,7 +5088,7 @@ _gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface)
|
|||||||
* as we need to re-acquire the EGL surfaces that we rendered to upload to Cairo explicitly,
|
* 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
|
* using gdk_window_invalidate_rect (), when we maximize or restore or use aerosnap
|
||||||
*/
|
*/
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef HAVE_EGL
|
||||||
if (surface->gl_paint_context != NULL && gdk_gl_context_get_use_es (surface->gl_paint_context))
|
if (surface->gl_paint_context != NULL && gdk_gl_context_get_use_es (surface->gl_paint_context))
|
||||||
{
|
{
|
||||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef HAVE_EGL
|
||||||
# include <epoxy/egl.h>
|
# include <epoxy/egl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -338,9 +338,7 @@ struct _GdkWin32Surface
|
|||||||
RECT configured_rect;
|
RECT configured_rect;
|
||||||
} next_layout;
|
} next_layout;
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef HAVE_EGL
|
||||||
EGLSurface egl_surface;
|
|
||||||
EGLSurface egl_dummy_surface;
|
|
||||||
guint egl_force_redraw_all : 1;
|
guint egl_force_redraw_all : 1;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -373,7 +371,7 @@ void gdk_win32_surface_move_resize (GdkSurface *window,
|
|||||||
RECT
|
RECT
|
||||||
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context);
|
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context);
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef HAVE_EGL
|
||||||
EGLSurface gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
EGLSurface gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
||||||
EGLConfig config,
|
EGLConfig config,
|
||||||
gboolean is_dummy);
|
gboolean is_dummy);
|
||||||
|
@ -46,10 +46,7 @@ gdk_win32_public_headers = files([
|
|||||||
|
|
||||||
install_headers(gdk_win32_public_headers, 'gdkwin32.h', subdir: 'gtk-4.0/gdk/win32/')
|
install_headers(gdk_win32_public_headers, 'gdkwin32.h', subdir: 'gtk-4.0/gdk/win32/')
|
||||||
|
|
||||||
GDK_WIN32_EGL_CFLAGS = []
|
|
||||||
|
|
||||||
if have_egl
|
if have_egl
|
||||||
GDK_WIN32_EGL_CFLAGS = ['-DGDK_WIN32_ENABLE_EGL']
|
|
||||||
gdk_win32_sources += ['gdkglcontext-win32-egl.c']
|
gdk_win32_sources += ['gdkglcontext-win32-egl.c']
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -67,6 +64,6 @@ libgdk_win32 = static_library('gdk-win32',
|
|||||||
'-DINSIDE_GDK_WIN32',
|
'-DINSIDE_GDK_WIN32',
|
||||||
'-D_WIN32_WINNT=0x0601',
|
'-D_WIN32_WINNT=0x0601',
|
||||||
'-DWINVER=0x0601',
|
'-DWINVER=0x0601',
|
||||||
] + GDK_WIN32_EGL_CFLAGS,
|
],
|
||||||
dependencies: [ gdk_deps, gdk_win32_deps ],
|
dependencies: [ gdk_deps, gdk_win32_deps ],
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user