diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c index 8d38a0c50f..f084944487 100644 --- a/gdk/gdkglcontext.c +++ b/gdk/gdkglcontext.c @@ -82,6 +82,7 @@ #include "gdkmemoryformatprivate.h" #include "gdkmemorytextureprivate.h" #include "gdkprofilerprivate.h" +#include "gdkglversionprivate.h" #include "gdkprivate.h" @@ -99,8 +100,7 @@ #define DEFAULT_ALLOWED_APIS GDK_GL_API_GL | GDK_GL_API_GLES typedef struct { - int major; - int minor; + GdkGLVersion required; int gl_version; guint has_khr_debug : 1; @@ -288,7 +288,7 @@ gdk_gl_context_create_egl_context (GdkGLContext *context, EGLContext ctx; EGLint context_attribs[N_EGL_ATTRS], i = 0, flags = 0; gboolean debug_bit, forward_bit; - int min_major, min_minor, major = 0, minor = 0; + GdkGLVersion min, version; G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME; if (!gdk_gl_context_is_api_allowed (context, api, NULL)) @@ -296,11 +296,8 @@ gdk_gl_context_create_egl_context (GdkGLContext *context, /* We will use the default version matching the context status * unless the user requested a version which makes sense */ - gdk_gl_context_get_matching_version (api, legacy, - &min_major, &min_minor); - gdk_gl_context_get_clipped_version (context, - min_major, min_minor, - &major, &minor); + gdk_gl_context_get_matching_version (api, legacy, &min); + gdk_gl_context_get_clipped_version (context, &min, &version); if (!eglBindAPI (gdk_api_to_egl_api (api))) return 0; @@ -331,9 +328,9 @@ gdk_gl_context_create_egl_context (GdkGLContext *context, flags &= ~EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION; - context_attribs[i++] = major; + context_attribs[i++] = gdk_gl_version_get_major (&version); context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION; - context_attribs[i++] = minor; + context_attribs[i++] = gdk_gl_version_get_minor (&version); context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR; context_attribs[i++] = flags; @@ -342,7 +339,7 @@ gdk_gl_context_create_egl_context (GdkGLContext *context, GDK_DISPLAY_DEBUG (display, OPENGL, "Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s, es:%s)", - major, minor, + gdk_gl_version_get_major (&version), gdk_gl_version_get_minor (&version), debug_bit ? "yes" : "no", forward_bit ? "yes" : "no", legacy ? "yes" : "no", @@ -986,36 +983,21 @@ gdk_gl_context_get_forward_compatible (GdkGLContext *context) } void -gdk_gl_context_get_matching_version (GdkGLAPI api, - gboolean legacy, - int *major, - int *minor) +gdk_gl_context_get_matching_version (GdkGLAPI api, + gboolean legacy, + GdkGLVersion *out_version) { - int maj, min; - if (api == GDK_GL_API_GL) { if (legacy) - { - maj = GDK_GL_MIN_GL_LEGACY_VERSION_MAJOR; - min = GDK_GL_MIN_GL_LEGACY_VERSION_MINOR; - } + *out_version = GDK_GL_MIN_GL_LEGACY_VERSION; else - { - maj = GDK_GL_MIN_GL_VERSION_MAJOR; - min = GDK_GL_MIN_GL_VERSION_MINOR; - } + *out_version = GDK_GL_MIN_GL_VERSION; } else { - maj = GDK_GL_MIN_GLES_VERSION_MAJOR; - min = GDK_GL_MIN_GLES_VERSION_MINOR; + *out_version = GDK_GL_MIN_GLES_VERSION; } - - if (major != NULL) - *major = maj; - if (minor != NULL) - *minor = min; } /** @@ -1044,8 +1026,7 @@ gdk_gl_context_set_required_version (GdkGLContext *context, g_return_if_fail (GDK_IS_GL_CONTEXT (context)); g_return_if_fail (!gdk_gl_context_is_realized (context)); - priv->major = major; - priv->minor = minor; + priv->required = GDK_GL_VERSION_INIT (major, minor); } gboolean @@ -1101,33 +1082,24 @@ gdk_gl_context_get_required_version (GdkGLContext *context, g_return_if_fail (GDK_IS_GL_CONTEXT (context)); if (major != NULL) - *major = priv->major; + *major = gdk_gl_version_get_major (&priv->required); if (minor != NULL) - *minor = priv->minor; + *minor = gdk_gl_version_get_minor (&priv->required); } void -gdk_gl_context_get_clipped_version (GdkGLContext *context, - int min_major, - int min_minor, - int *major, - int *minor) +gdk_gl_context_get_clipped_version (GdkGLContext *context, + const GdkGLVersion *min_version, + GdkGLVersion *out_clipped) { GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context); - int maj = min_major, min = min_minor; g_return_if_fail (GDK_IS_GL_CONTEXT (context)); - if (priv->major > maj || (priv->major == maj && priv->minor > min)) - { - maj = priv->major; - min = priv->minor; - } - - if (major != NULL) - *major = maj; - if (minor != NULL) - *minor = min; + if (gdk_gl_version_greater_equal (&priv->required, min_version)) + *out_clipped = priv->required; + else + *out_clipped = *min_version; } /** @@ -1504,6 +1476,14 @@ gdk_gl_context_realize (GdkGLContext *context, return priv->api; } +void +gdk_gl_version_init_epoxy (GdkGLVersion *version) +{ + int epoxy_version = epoxy_gl_version (); + + *version = GDK_GL_VERSION_INIT (epoxy_version / 10, epoxy_version % 10); +} + static void gdk_gl_context_check_extensions (GdkGLContext *context) { diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h index ac20742ea9..ee91350aef 100644 --- a/gdk/gdkglcontextprivate.h +++ b/gdk/gdkglcontextprivate.h @@ -22,29 +22,10 @@ #include "gdkglcontext.h" #include "gdkdrawcontextprivate.h" +#include "gdkglversionprivate.h" G_BEGIN_DECLS -/* Version requirements for EGL contexts. - * - * If you add support for EGL to your backend, please require this. - */ -#define GDK_EGL_MIN_VERSION_MAJOR (1) -#define GDK_EGL_MIN_VERSION_MINOR (4) - -/* Minimum OpenGL versions supported by GTK. - * Backends should make sure to never create a context of a previous version. - * - * The macros refer to OpenGL; OpenGL with OPENGL_COMPATIBILITY_PROFILE_BIT as - * OPENGL_PROFILE_MASK; and OpenGL ES respectively - */ -#define GDK_GL_MIN_GL_VERSION_MAJOR (3) -#define GDK_GL_MIN_GL_VERSION_MINOR (2) -#define GDK_GL_MIN_GL_LEGACY_VERSION_MAJOR (3) -#define GDK_GL_MIN_GL_LEGACY_VERSION_MINOR (0) -#define GDK_GL_MIN_GLES_VERSION_MAJOR (2) -#define GDK_GL_MIN_GLES_VERSION_MINOR (0) - typedef enum { GDK_GL_NONE = 0, GDK_GL_EGL, @@ -124,20 +105,17 @@ gboolean gdk_gl_context_is_api_allowed (GdkGLContext void gdk_gl_context_set_is_legacy (GdkGLContext *context, gboolean is_legacy); -gboolean gdk_gl_context_check_version (GdkGLContext *context, - int required_gl_major, - int required_gl_minor, - int required_gles_major, - int required_gles_minor); -void gdk_gl_context_get_clipped_version (GdkGLContext *context, - int min_major, - int min_minor, - int *major, - int *minor); -void gdk_gl_context_get_matching_version (GdkGLAPI api, - gboolean legacy, - int *major, - int *minor); +gboolean gdk_gl_context_check_version (GdkGLContext *context, + int required_gl_major, + int required_gl_minor, + int required_gles_major, + int required_gles_minor); +void gdk_gl_context_get_clipped_version (GdkGLContext *context, + const GdkGLVersion *min_version, + GdkGLVersion *out_clipped); +void gdk_gl_context_get_matching_version (GdkGLAPI api, + gboolean legacy, + GdkGLVersion *out_version); gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context); void gdk_gl_context_push_debug_group (GdkGLContext *context, diff --git a/gdk/gdkglversionprivate.h b/gdk/gdkglversionprivate.h new file mode 100644 index 0000000000..4ea97bceb6 --- /dev/null +++ b/gdk/gdkglversionprivate.h @@ -0,0 +1,95 @@ +/* GDK - The GIMP Drawing Kit + * + * gdkglcontextprivate.h: GL context abstraction + * + * Copyright © 2014 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +/* Version requirements for EGL contexts. + * + * If you add support for EGL to your backend, please require this. + */ +#define GDK_EGL_MIN_VERSION_MAJOR (1) +#define GDK_EGL_MIN_VERSION_MINOR (4) + +/* Minimum OpenGL versions supported by GTK. + * Backends should make sure to never create a context of a previous version. + * + * The macros refer to OpenGL; OpenGL with OPENGL_COMPATIBILITY_PROFILE_BIT as + * OPENGL_PROFILE_MASK; and OpenGL ES respectively + */ +#define GDK_GL_MIN_GL_VERSION GDK_GL_VERSION_INIT (3, 2) +#define GDK_GL_MIN_GL_LEGACY_VERSION GDK_GL_VERSION_INIT (3, 0) +#define GDK_GL_MIN_GLES_VERSION GDK_GL_VERSION_INIT (2, 0) + +typedef struct _GdkGLVersion GdkGLVersion; + +struct _GdkGLVersion +{ + int major; + int minor; +}; + +#define GDK_GL_VERSION_INIT(maj,min) (GdkGLVersion) { maj, min } +#define GDK_GL_VERSION_STRING(str) GDK_GL_VERSION_INIT(str[0] - '0', str[2] - '0') + +static inline int +gdk_gl_version_get_major (const GdkGLVersion *self) +{ + return self->major; +} + +static inline int +gdk_gl_version_get_minor (const GdkGLVersion *self) +{ + return self->minor; +} + +static inline int +gdk_gl_version_compare (const GdkGLVersion *a, + const GdkGLVersion *b) +{ + if (a->major > b->major) + return 1; + if (a->major < b->major) + return -1; + + if (a->minor > b->minor) + return 1; + if (a->minor < b->minor) + return -1; + + return 0; +} + +static inline gboolean +gdk_gl_version_greater_equal (const GdkGLVersion *a, + const GdkGLVersion *b) +{ + return gdk_gl_version_compare (a, b) >= 0; +} + +/* in gdkglcontext.c */ +void gdk_gl_version_init_epoxy (GdkGLVersion *version); + +G_END_DECLS + diff --git a/gdk/macos/gdkmacosglcontext.c b/gdk/macos/gdkmacosglcontext.c index 5dc7c202ef..a74917d872 100644 --- a/gdk/macos/gdkmacosglcontext.c +++ b/gdk/macos/gdkmacosglcontext.c @@ -323,9 +323,8 @@ gdk_macos_gl_context_release (GdkMacosGLContext *self) } static CGLPixelFormatObj -create_pixel_format (int major, - int minor, - GError **error) +create_pixel_format (GdkGLVersion *version, + GError **error) { CGLPixelFormatAttribute attrs[] = { kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_Legacy, @@ -339,9 +338,9 @@ create_pixel_format (int major, CGLPixelFormatObj format = NULL; GLint n_format = 1; - if (major == 3 && minor == 2) + if (gdk_gl_version_get_major (version) == 3) attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL3_Core; - else if (major == 4 && minor == 1) + else attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL4_Core; if (!CHECK (error, CGLChoosePixelFormat (attrs, &format, &n_format))) @@ -366,7 +365,7 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context, GLint validate = 0; GLint renderer_id = 0; GLint swapRect[4]; - int major, minor; + GdkGLVersion version; g_assert (GDK_IS_MACOS_GL_CONTEXT (self)); @@ -379,9 +378,8 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context, existing = CGLGetCurrentContext (); gdk_gl_context_get_clipped_version (context, - GDK_GL_MIN_GL_VERSION_MAJOR, - GDK_GL_MIN_GL_VERSION_MINOR, - &major, &minor); + GDK_GL_MIN_GL_VERSION, + &version); display = gdk_gl_context_get_display (context); shared = gdk_display_get_gl_context (display); @@ -400,9 +398,9 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context, GDK_DISPLAY_DEBUG (display, OPENGL, "Creating CGLContextObj (version %d.%d)", - major, minor); + gdk_gl_version_get_major (&version), gdk_gl_version_get_minor (&version)); - if (!(pixelFormat = create_pixel_format (major, minor, error))) + if (!(pixelFormat = create_pixel_format (&version, error))) return 0; if (!CHECK (error, CGLCreateContext (pixelFormat, shared_gl_context, &cgl_context))) diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h index c197395422..3f53115ff8 100644 --- a/gdk/win32/gdkdisplay-win32.h +++ b/gdk/win32/gdkdisplay-win32.h @@ -24,6 +24,8 @@ #include "gdkwin32screen.h" #include "gdkwin32cursor.h" +#include "gdkglversionprivate.h" + #ifdef HAVE_EGL # include #endif @@ -124,7 +126,7 @@ struct _GdkWin32Display /* WGL/OpenGL Items */ GdkWin32GLDummyContextWGL dummy_context_wgl; - guint gl_version; + GdkGLVersion gl_version; GListModel *monitors; diff --git a/gdk/win32/gdkglcontext-win32-wgl.c b/gdk/win32/gdkglcontext-win32-wgl.c index 1ae9fc2161..80995fdcce 100644 --- a/gdk/win32/gdkglcontext-win32-wgl.c +++ b/gdk/win32/gdkglcontext-win32-wgl.c @@ -278,7 +278,7 @@ gdk_win32_display_init_wgl (GdkDisplay *display, return FALSE; } - display_win32->gl_version = epoxy_gl_version (); + gdk_gl_version_init_epoxy (&display_win32->gl_version); display_win32->hasWglARBCreateContext = epoxy_has_wgl_extension (hdc, "WGL_ARB_create_context"); @@ -300,8 +300,8 @@ gdk_win32_display_init_wgl (GdkDisplay *display, "\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, + gdk_gl_version_get_major (&display_win32->gl_version), + gdk_gl_version_get_minor (&display_win32->gl_version), glGetString (GL_VENDOR), display_win32->hasWglARBPixelFormat ? "yes" : "no", display_win32->hasWglARBCreateContext ? "yes" : "no", @@ -509,8 +509,7 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context, /* request flags and specific versions for core (3.2+) WGL context */ int flags = 0; - int major = 0; - int minor = 0; + GdkGLVersion version; HGLRC hglrc; int pixel_format; HDC hdc; @@ -535,9 +534,8 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context, * rather than the default GL core 3.2 context. */ gdk_gl_context_get_clipped_version (context, - display_win32->gl_version / 10, - display_win32->gl_version % 10, - &major, &minor); + &display_win32->gl_version, + &version); if (surface != NULL) hdc = GDK_WIN32_SURFACE (surface)->hdc; @@ -574,8 +572,8 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context, 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, + gdk_gl_version_get_major (&version), + gdk_gl_version_get_minor (&version), debug_bit ? "yes" : "no", compat_bit ? "yes" : "no", legacy_bit ? "yes" : "no")); @@ -583,9 +581,9 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context, hglrc = create_wgl_context (hdc, share, flags, - major, - minor, - &legacy_bit, + gdk_gl_version_get_major (&version), + gdk_gl_version_get_minor (&version), + &legacy_bit, display_win32->hasWglARBCreateContext); if (hglrc == NULL) @@ -714,9 +712,9 @@ gdk_win32_display_get_wgl_version (GdkDisplay *display, display_win32 = GDK_WIN32_DISPLAY (display); if (major != NULL) - *major = display_win32->gl_version / 10; + *major = gdk_gl_version_get_major (&display_win32->gl_version); if (minor != NULL) - *minor = display_win32->gl_version % 10; + *major = gdk_gl_version_get_major (&display_win32->gl_version); return TRUE; } diff --git a/gdk/x11/gdkglcontext-glx.c b/gdk/x11/gdkglcontext-glx.c index bdcd3042cc..7ee885b831 100644 --- a/gdk/x11/gdkglcontext-glx.c +++ b/gdk/x11/gdkglcontext-glx.c @@ -477,7 +477,7 @@ gdk_x11_context_create_glx_context (GdkGLContext *context, GdkSurface *surface = gdk_gl_context_get_surface (context); GLXContext ctx; int context_attribs[N_GLX_ATTRS], i = 0, flags = 0; - int min_major, min_minor, major, minor; + GdkGLVersion min, version; gboolean debug_bit, compat_bit; if (!gdk_gl_context_is_api_allowed (context, api, NULL)) @@ -488,10 +488,8 @@ gdk_x11_context_create_glx_context (GdkGLContext *context, /* We will use the default version matching the context status * unless the user requested a version which makes sense */ - gdk_gl_context_get_matching_version (api, legacy, - &min_major, &min_minor); - gdk_gl_context_get_clipped_version (context, min_major, min_minor, - &major, &minor); + gdk_gl_context_get_matching_version (api, legacy, &min); + gdk_gl_context_get_clipped_version (context, &min, &version); debug_bit = gdk_gl_context_get_debug_enabled (context); compat_bit = gdk_gl_context_get_forward_compatible (context); @@ -511,9 +509,9 @@ gdk_x11_context_create_glx_context (GdkGLContext *context, context_attribs[i++] = GLX_CONTEXT_ES2_PROFILE_BIT_EXT; context_attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; - context_attribs[i++] = major; + context_attribs[i++] = gdk_gl_version_get_major (&version); context_attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; - context_attribs[i++] = minor; + context_attribs[i++] = gdk_gl_version_get_minor (&version); context_attribs[i++] = GLX_CONTEXT_FLAGS_ARB; context_attribs[i++] = flags; @@ -522,7 +520,7 @@ gdk_x11_context_create_glx_context (GdkGLContext *context, GDK_DISPLAY_DEBUG (display, OPENGL, "Creating GLX context version %d.%d (debug:%s, forward:%s, legacy:%s, es:%s)", - major, minor, + gdk_gl_version_get_major (&version), gdk_gl_version_get_minor (&version), debug_bit ? "yes" : "no", compat_bit ? "yes" : "no", legacy ? "yes" : "no",