mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 14:00:09 +00:00
Merge branch 'wip/otte/gl-version' into 'main'
Make sure highest possible version GLContext is created See merge request GNOME/gtk!5870
This commit is contained in:
commit
3b5a2d60c7
@ -32,6 +32,20 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GdkGLAPI:
|
||||
* @GDK_GL_API_GL: The OpenGL API
|
||||
* @GDK_GL_API_GLES: The OpenGL ES API
|
||||
*
|
||||
* The list of the different APIs that GdkGLContext can potentially support.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
typedef enum { /*< underscore_name=GDK_GL_API >*/
|
||||
GDK_GL_API_GL = 1 << 0,
|
||||
GDK_GL_API_GLES = 1 << 1
|
||||
} GdkGLAPI;
|
||||
|
||||
/* Currently, these are the same values numerically as in the
|
||||
* X protocol. If you change that, gdksurface-x11.c/gdk_surface_set_geometry_hints()
|
||||
* will need fixing.
|
||||
|
@ -82,6 +82,7 @@
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
#include "gdkglversionprivate.h"
|
||||
|
||||
#include "gdkprivate.h"
|
||||
|
||||
@ -99,9 +100,8 @@
|
||||
#define DEFAULT_ALLOWED_APIS GDK_GL_API_GL | GDK_GL_API_GLES
|
||||
|
||||
typedef struct {
|
||||
int major;
|
||||
int minor;
|
||||
int gl_version;
|
||||
GdkGLVersion required;
|
||||
GdkGLVersion gl_version;
|
||||
|
||||
guint has_khr_debug : 1;
|
||||
guint use_khr_debug : 1;
|
||||
@ -287,8 +287,11 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
|
||||
EGLConfig egl_config;
|
||||
EGLContext ctx;
|
||||
EGLint context_attribs[N_EGL_ATTRS], i = 0, flags = 0;
|
||||
gsize major_idx, minor_idx;
|
||||
gboolean debug_bit, forward_bit;
|
||||
int min_major, min_minor, major = 0, minor = 0;
|
||||
GdkGLVersion version;
|
||||
const GdkGLVersion* supported_versions;
|
||||
gsize j;
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
if (!gdk_gl_context_is_api_allowed (context, api, NULL))
|
||||
@ -296,11 +299,7 @@ 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 (context, api, legacy, &version);
|
||||
|
||||
if (!eglBindAPI (gdk_api_to_egl_api (api)))
|
||||
return 0;
|
||||
@ -331,9 +330,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;
|
||||
major_idx = i++;
|
||||
context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION;
|
||||
context_attribs[i++] = minor;
|
||||
minor_idx = i++;
|
||||
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
|
||||
context_attribs[i++] = flags;
|
||||
|
||||
@ -342,23 +341,33 @@ 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",
|
||||
api == GDK_GL_API_GLES ? "yes" : "no");
|
||||
|
||||
ctx = eglCreateContext (egl_display,
|
||||
egl_config,
|
||||
share ? share_priv->egl_context : EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
supported_versions = gdk_gl_versions_get_for_api (api);
|
||||
for (j = 0; gdk_gl_version_greater_equal (&supported_versions[j], &version); j++)
|
||||
{
|
||||
context_attribs [major_idx] = gdk_gl_version_get_major (&supported_versions[j]);
|
||||
context_attribs [minor_idx] = gdk_gl_version_get_minor (&supported_versions[j]);
|
||||
|
||||
ctx = eglCreateContext (egl_display,
|
||||
egl_config,
|
||||
share ? share_priv->egl_context : EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
if (ctx != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, OPENGL, "Created EGL context[%p]", ctx);
|
||||
|
||||
priv->egl_context = ctx;
|
||||
gdk_gl_context_set_version (context, &supported_versions[j]);
|
||||
gdk_gl_context_set_is_legacy (context, legacy);
|
||||
|
||||
if (epoxy_has_egl_extension (egl_display, "EGL_KHR_swap_buffers_with_damage"))
|
||||
@ -620,7 +629,7 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
|
||||
glViewport (0, 0, ww, wh);
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (priv->egl_context && gdk_gl_context_check_version (context, 0, 0, 3, 0))
|
||||
if (priv->egl_context && gdk_gl_context_check_version (context, NULL, "3.0"))
|
||||
glDrawBuffers (1, (GLenum[1]) { gdk_gl_context_get_use_es (context) ? GL_BACK : GL_BACK_LEFT });
|
||||
#endif
|
||||
}
|
||||
@ -986,36 +995,33 @@ 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 (GdkGLContext *context,
|
||||
GdkGLAPI api,
|
||||
gboolean legacy,
|
||||
GdkGLVersion *out_version)
|
||||
{
|
||||
int maj, min;
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkGLVersion min_version;
|
||||
|
||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||
|
||||
if (api == GDK_GL_API_GL)
|
||||
{
|
||||
if (legacy)
|
||||
{
|
||||
maj = GDK_GL_MIN_GL_LEGACY_VERSION_MAJOR;
|
||||
min = GDK_GL_MIN_GL_LEGACY_VERSION_MINOR;
|
||||
}
|
||||
min_version = GDK_GL_MIN_GL_LEGACY_VERSION;
|
||||
else
|
||||
{
|
||||
maj = GDK_GL_MIN_GL_VERSION_MAJOR;
|
||||
min = GDK_GL_MIN_GL_VERSION_MINOR;
|
||||
}
|
||||
min_version = GDK_GL_MIN_GL_VERSION;
|
||||
}
|
||||
else
|
||||
{
|
||||
maj = GDK_GL_MIN_GLES_VERSION_MAJOR;
|
||||
min = GDK_GL_MIN_GLES_VERSION_MINOR;
|
||||
min_version = GDK_GL_MIN_GLES_VERSION;
|
||||
}
|
||||
|
||||
if (major != NULL)
|
||||
*major = maj;
|
||||
if (minor != NULL)
|
||||
*minor = min;
|
||||
if (gdk_gl_version_greater_equal (&priv->required, &min_version))
|
||||
*out_version = priv->required;
|
||||
else
|
||||
*out_version = min_version;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1044,22 +1050,17 @@ 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
|
||||
gdk_gl_context_check_version (GdkGLContext *self,
|
||||
int required_gl_major,
|
||||
int required_gl_minor,
|
||||
int required_gles_major,
|
||||
int required_gles_minor)
|
||||
gdk_gl_context_check_gl_version (GdkGLContext *self,
|
||||
const GdkGLVersion *required_gl,
|
||||
const GdkGLVersion *required_gles)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
|
||||
g_return_val_if_fail (required_gl_minor < 10, FALSE);
|
||||
g_return_val_if_fail (required_gles_minor < 10, FALSE);
|
||||
|
||||
if (!gdk_gl_context_is_realized (self))
|
||||
return FALSE;
|
||||
@ -1067,10 +1068,10 @@ gdk_gl_context_check_version (GdkGLContext *self,
|
||||
switch (priv->api)
|
||||
{
|
||||
case GDK_GL_API_GL:
|
||||
return priv->gl_version >= required_gl_major * 10 + required_gl_minor;
|
||||
return required_gl == NULL || gdk_gl_version_greater_equal (&priv->gl_version, required_gl);
|
||||
|
||||
case GDK_GL_API_GLES:
|
||||
return priv->gl_version >= required_gles_major * 10 + required_gles_minor;
|
||||
return required_gles == NULL || gdk_gl_version_greater_equal (&priv->gl_version, required_gles);
|
||||
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
@ -1101,33 +1102,9 @@ 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;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_gl_context_get_clipped_version (GdkGLContext *context,
|
||||
int min_major,
|
||||
int min_minor,
|
||||
int *major,
|
||||
int *minor)
|
||||
{
|
||||
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;
|
||||
*minor = gdk_gl_version_get_minor (&priv->required);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1164,6 +1141,15 @@ gdk_gl_context_is_legacy (GdkGLContext *context)
|
||||
return priv->is_legacy;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_gl_context_set_version (GdkGLContext *context,
|
||||
const GdkGLVersion *version)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
|
||||
priv->gl_version = *version;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
||||
gboolean is_legacy)
|
||||
@ -1499,11 +1485,23 @@ gdk_gl_context_realize (GdkGLContext *context,
|
||||
priv->api = GDK_GL_CONTEXT_GET_CLASS (context)->realize (context, error);
|
||||
|
||||
if (priv->api)
|
||||
g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_API]);
|
||||
{
|
||||
g_assert (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (0, 0)));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_API]);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -1517,8 +1515,6 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
if (priv->extensions_checked)
|
||||
return;
|
||||
|
||||
priv->gl_version = epoxy_gl_version ();
|
||||
|
||||
priv->has_debug_output = epoxy_has_gl_extension ("GL_ARB_debug_output") ||
|
||||
epoxy_has_gl_extension ("GL_KHR_debug");
|
||||
|
||||
@ -1544,7 +1540,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
|
||||
|
||||
/* We asked for a core profile, but we didn't get one, so we're in legacy mode */
|
||||
if (priv->gl_version < 32)
|
||||
if (!gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
|
||||
priv->is_legacy = TRUE;
|
||||
}
|
||||
|
||||
@ -1554,7 +1550,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
glGetIntegerv (GL_MAX_LABEL_LENGTH, &priv->max_debug_label_length);
|
||||
}
|
||||
|
||||
priv->has_half_float = gdk_gl_context_check_version (context, 3, 0, 3, 0) ||
|
||||
priv->has_half_float = gdk_gl_context_check_version (context, "3.0", "3.0") ||
|
||||
epoxy_has_gl_extension ("OES_vertex_half_float");
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
@ -1570,7 +1566,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
" - GL_EXT_unpack_subimage: %s\n"
|
||||
" - OES_vertex_half_float: %s",
|
||||
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
|
||||
priv->gl_version / 10, priv->gl_version % 10,
|
||||
gdk_gl_version_get_major (&priv->gl_version), gdk_gl_version_get_minor (&priv->gl_version),
|
||||
priv->is_legacy ? "legacy" : "core",
|
||||
glGetString (GL_SHADING_LANGUAGE_VERSION),
|
||||
max_texture_size,
|
||||
@ -1698,10 +1694,6 @@ gdk_gl_context_get_shared_context (GdkGLContext *context)
|
||||
* Retrieves the OpenGL version of the @context.
|
||||
*
|
||||
* The @context must be realized prior to calling this function.
|
||||
*
|
||||
* If the @context has never been made current, the version cannot
|
||||
* be known and it will return 0 for both @major and @minor.
|
||||
*
|
||||
*/
|
||||
void
|
||||
gdk_gl_context_get_version (GdkGLContext *context,
|
||||
@ -1714,9 +1706,9 @@ gdk_gl_context_get_version (GdkGLContext *context,
|
||||
g_return_if_fail (gdk_gl_context_is_realized (context));
|
||||
|
||||
if (major != NULL)
|
||||
*major = priv->gl_version / 10;
|
||||
*major = gdk_gl_version_get_major (&priv->gl_version);
|
||||
if (minor != NULL)
|
||||
*minor = priv->gl_version % 10;
|
||||
*minor = gdk_gl_version_get_minor (&priv->gl_version);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,25 +24,12 @@
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#include <gdk/gdkenums.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GdkGLAPI:
|
||||
* @GDK_GL_API_GL: The OpenGL API
|
||||
* @GDK_GL_API_GLES: The OpenGL ES API
|
||||
*
|
||||
* The list of the different APIs that GdkGLContext can potentially support.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
typedef enum { /*< underscore_name=GDK_GL_API >*/
|
||||
GDK_GL_API_GL = 1 << 0,
|
||||
GDK_GL_API_GLES = 1 << 1
|
||||
} GdkGLAPI;
|
||||
|
||||
#define GDK_TYPE_GL_CONTEXT (gdk_gl_context_get_type ())
|
||||
#define GDK_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_GL_CONTEXT, GdkGLContext))
|
||||
#define GDK_IS_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_GL_CONTEXT))
|
||||
|
@ -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,
|
||||
@ -118,26 +99,31 @@ void gdk_gl_context_clear_current_if_surface (GdkSurface
|
||||
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
|
||||
GdkSurface *surface);
|
||||
|
||||
gboolean gdk_gl_context_is_api_allowed (GdkGLContext *self,
|
||||
GdkGLAPI api,
|
||||
GError **error);
|
||||
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
||||
gboolean is_legacy);
|
||||
gboolean gdk_gl_context_is_api_allowed (GdkGLContext *self,
|
||||
GdkGLAPI api,
|
||||
GError **error);
|
||||
void gdk_gl_context_set_version (GdkGLContext *context,
|
||||
const GdkGLVersion *version);
|
||||
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
||||
gboolean is_legacy);
|
||||
gboolean gdk_gl_context_check_gl_version (GdkGLContext *context,
|
||||
const GdkGLVersion *gl_version,
|
||||
const GdkGLVersion *gles_version);
|
||||
|
||||
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);
|
||||
static inline gboolean
|
||||
gdk_gl_context_check_version (GdkGLContext *context,
|
||||
const char *gl_version,
|
||||
const char *gles_version)
|
||||
{
|
||||
return gdk_gl_context_check_gl_version (context,
|
||||
gl_version ? &GDK_GL_VERSION_STRING (gl_version) : NULL,
|
||||
gles_version ? &GDK_GL_VERSION_STRING (gles_version) : NULL);
|
||||
}
|
||||
|
||||
void gdk_gl_context_get_matching_version (GdkGLContext *context,
|
||||
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,
|
||||
|
@ -189,7 +189,7 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
|
||||
glGenFramebuffers (1, &fbo);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
|
||||
if (gdk_gl_context_check_version (context, 4, 3, 3, 1))
|
||||
if (gdk_gl_context_check_version (context, "4.3", "3.1"))
|
||||
{
|
||||
gdk_gl_context_get_version (context, &major, &minor);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
|
||||
@ -335,7 +335,7 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
if (context == NULL ||
|
||||
!gdk_gl_context_is_shared (self->context, context) ||
|
||||
/* ... or glGetTexLevelParameter() isn't supported */
|
||||
!gdk_gl_context_check_version (context, 0, 0, 3, 1))
|
||||
!gdk_gl_context_check_version (context, NULL, "3.1"))
|
||||
{
|
||||
texture->format = GDK_MEMORY_DEFAULT;
|
||||
self->has_mipmap = FALSE;
|
||||
|
138
gdk/gdkglversionprivate.h
Normal file
138
gdk/gdkglversionprivate.h
Normal file
@ -0,0 +1,138 @@
|
||||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gdkenums.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 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) { maj, min }
|
||||
|
||||
static const GdkGLVersion supported_gl_versions[] = {
|
||||
GDK_GL_VERSION_INIT (4, 6),
|
||||
GDK_GL_VERSION_INIT (4, 5),
|
||||
GDK_GL_VERSION_INIT (4, 4),
|
||||
GDK_GL_VERSION_INIT (4, 3),
|
||||
GDK_GL_VERSION_INIT (4, 2),
|
||||
GDK_GL_VERSION_INIT (4, 1),
|
||||
GDK_GL_VERSION_INIT (4, 0),
|
||||
GDK_GL_VERSION_INIT (3, 3),
|
||||
GDK_GL_VERSION_INIT (3, 2),
|
||||
GDK_GL_VERSION_INIT (3, 1),
|
||||
GDK_GL_VERSION_INIT (3, 0),
|
||||
|
||||
GDK_GL_VERSION_INIT (0, 0)
|
||||
};
|
||||
|
||||
static const GdkGLVersion supported_gles_versions[] = {
|
||||
GDK_GL_VERSION_INIT (3, 2),
|
||||
GDK_GL_VERSION_INIT (3, 1),
|
||||
GDK_GL_VERSION_INIT (3, 0),
|
||||
GDK_GL_VERSION_INIT (2, 0),
|
||||
|
||||
GDK_GL_VERSION_INIT (0, 0)
|
||||
};
|
||||
|
||||
#undef GDK_GL_VERSION_INIT
|
||||
#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 const GdkGLVersion *
|
||||
gdk_gl_versions_get_for_api (GdkGLAPI api)
|
||||
{
|
||||
switch (api)
|
||||
{
|
||||
case GDK_GL_API_GL:
|
||||
return supported_gl_versions;
|
||||
case GDK_GL_API_GLES:
|
||||
return supported_gles_versions;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -323,12 +323,12 @@ gdk_macos_gl_context_release (GdkMacosGLContext *self)
|
||||
}
|
||||
|
||||
static CGLPixelFormatObj
|
||||
create_pixel_format (int major,
|
||||
int minor,
|
||||
GError **error)
|
||||
create_pixel_format (GdkGLVersion *version,
|
||||
gboolean *out_legacy,
|
||||
GError **error)
|
||||
{
|
||||
CGLPixelFormatAttribute attrs[] = {
|
||||
kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_Legacy,
|
||||
kCGLPFAOpenGLProfile, 0,
|
||||
kCGLPFAAllowOfflineRenderers, /* allow sharing across GPUs */
|
||||
kCGLPFADepthSize, 0,
|
||||
kCGLPFAStencilSize, 0,
|
||||
@ -339,14 +339,28 @@ create_pixel_format (int major,
|
||||
CGLPixelFormatObj format = NULL;
|
||||
GLint n_format = 1;
|
||||
|
||||
if (major == 3 && minor == 2)
|
||||
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL3_Core;
|
||||
else if (major == 4 && minor == 1)
|
||||
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL4_Core;
|
||||
*out_legacy = FALSE;
|
||||
|
||||
if (gdk_gl_version_get_major (version) >= 4)
|
||||
{
|
||||
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL4_Core;
|
||||
if (CGLChoosePixelFormat (attrs, &format, &n_format))
|
||||
return g_steal_pointer (&format);
|
||||
}
|
||||
|
||||
if (gdk_gl_version_greater_equal (version, &GDK_GL_MIN_GL_VERSION))
|
||||
{
|
||||
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL3_Core;
|
||||
if (CGLChoosePixelFormat (attrs, &format, &n_format))
|
||||
return g_steal_pointer (&format);
|
||||
}
|
||||
|
||||
attrs[1] = (CGLPixelFormatAttribute) kCGLOGLPVersion_Legacy;
|
||||
if (!CHECK (error, CGLChoosePixelFormat (attrs, &format, &n_format)))
|
||||
return NULL;
|
||||
|
||||
*out_legacy = TRUE;
|
||||
|
||||
return g_steal_pointer (&format);
|
||||
}
|
||||
|
||||
@ -366,7 +380,8 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
||||
GLint validate = 0;
|
||||
GLint renderer_id = 0;
|
||||
GLint swapRect[4];
|
||||
int major, minor;
|
||||
GdkGLVersion min_version, version;
|
||||
gboolean legacy;
|
||||
|
||||
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
|
||||
|
||||
@ -378,10 +393,10 @@ 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_context_get_matching_version (context,
|
||||
GDK_GL_API_GL,
|
||||
FALSE,
|
||||
&version);
|
||||
|
||||
display = gdk_gl_context_get_display (context);
|
||||
shared = gdk_display_get_gl_context (display);
|
||||
@ -400,9 +415,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 (&min_version), gdk_gl_version_get_minor (&min_version));
|
||||
|
||||
if (!(pixelFormat = create_pixel_format (major, minor, error)))
|
||||
if (!(pixelFormat = create_pixel_format (&min_version, &legacy, error)))
|
||||
return 0;
|
||||
|
||||
if (!CHECK (error, CGLCreateContext (pixelFormat, shared_gl_context, &cgl_context)))
|
||||
@ -414,6 +429,13 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
||||
CGLSetCurrentContext (cgl_context);
|
||||
CGLReleasePixelFormat (pixelFormat);
|
||||
|
||||
gdk_gl_version_init_epoxy (&version);
|
||||
if (!gdk_gl_version_greater_equal (&version, &min_version))
|
||||
{
|
||||
CGLReleaseContext (cgl_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (validate)
|
||||
CHECK (NULL, CGLEnable (cgl_context, kCGLCEStateValidation));
|
||||
|
||||
@ -445,6 +467,9 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
||||
cgl_context,
|
||||
get_renderer_name (renderer_id));
|
||||
|
||||
gdk_gl_context_set_version (context, &version);
|
||||
gdk_gl_context_set_is_legacy (context, legacy);
|
||||
|
||||
self->cgl_context = g_steal_pointer (&cgl_context);
|
||||
|
||||
if (existing != NULL)
|
||||
|
@ -1182,6 +1182,7 @@ gdk_win32_display_init_gl (GdkDisplay *display,
|
||||
{
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
HDC init_gl_hdc = NULL;
|
||||
GdkGLContext *context;
|
||||
|
||||
if (display_win32->dummy_context_wgl.hdc == NULL)
|
||||
display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
|
||||
@ -1216,12 +1217,9 @@ gdk_win32_display_init_gl (GdkDisplay *display,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gdk_win32_display_init_wgl (display, error))
|
||||
{
|
||||
return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
context = gdk_win32_display_init_wgl (display, error);
|
||||
if (context)
|
||||
return context;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
g_clear_error (error);
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "gdkwin32screen.h"
|
||||
#include "gdkwin32cursor.h"
|
||||
|
||||
#include "gdkglversionprivate.h"
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
# include <epoxy/egl.h>
|
||||
#endif
|
||||
@ -124,7 +126,6 @@ struct _GdkWin32Display
|
||||
|
||||
/* WGL/OpenGL Items */
|
||||
GdkWin32GLDummyContextWGL dummy_context_wgl;
|
||||
guint gl_version;
|
||||
|
||||
GListModel *monitors;
|
||||
|
||||
|
@ -247,16 +247,17 @@ gdk_init_dummy_wgl_context (GdkWin32Display *display_win32)
|
||||
return best_idx;
|
||||
}
|
||||
|
||||
gboolean
|
||||
GdkGLContext *
|
||||
gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
int best_idx = 0;
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkGLContext *context;
|
||||
HDC hdc;
|
||||
|
||||
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, error))
|
||||
return FALSE;
|
||||
return NULL;
|
||||
|
||||
/* acquire and cache dummy Window (HWND & HDC) and
|
||||
* dummy GL Context, it is used to query functions
|
||||
@ -275,25 +276,7 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("No GL implementation is available"));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
display_win32->gl_version = epoxy_gl_version ();
|
||||
|
||||
/* We must have OpenGL/WGL 2.0 or later, or have the GL_ARB_shader_objects extension */
|
||||
if (display_win32->gl_version < 20)
|
||||
{
|
||||
if (!epoxy_has_gl_extension ("GL_ARB_shader_objects"))
|
||||
{
|
||||
wglMakeCurrent (NULL, NULL);
|
||||
wglDeleteContext (display_win32->dummy_context_wgl.hglrc);
|
||||
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("No GL implementation is available"));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
display_win32->hasWglARBCreateContext =
|
||||
@ -307,45 +290,92 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
display_win32->hasWglARBmultisample =
|
||||
epoxy_has_wgl_extension (hdc, "WGL_ARB_multisample");
|
||||
|
||||
GDK_NOTE (OPENGL,
|
||||
g_print ("WGL API version %d.%d found\n"
|
||||
" - Vendor: %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->hasWglARBPixelFormat ? "yes" : "no",
|
||||
display_win32->hasWglARBCreateContext ? "yes" : "no",
|
||||
display_win32->hasWglEXTSwapControl ? "yes" : "no",
|
||||
display_win32->hasWglOMLSyncControl ? "yes" : "no",
|
||||
display_win32->hasWglARBmultisample ? "yes" : "no"));
|
||||
context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
|
||||
"display", display,
|
||||
NULL);
|
||||
if (!gdk_gl_context_realize (context, error))
|
||||
{
|
||||
g_object_unref (context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if G_ENABLE_DEBUG
|
||||
{
|
||||
int major, minor;
|
||||
gdk_gl_context_get_version (context, &major, &minor);
|
||||
GDK_NOTE (OPENGL, g_print ("WGL API version %d.%d found\n"
|
||||
" - Vendor: %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",
|
||||
major, minor,
|
||||
glGetString (GL_VENDOR),
|
||||
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"));
|
||||
}
|
||||
#endif
|
||||
|
||||
wglMakeCurrent (NULL, NULL);
|
||||
|
||||
return TRUE;
|
||||
return context;
|
||||
}
|
||||
|
||||
/* Setup the legacy context after creating it */
|
||||
static gboolean
|
||||
ensure_legacy_wgl_context (HDC hdc,
|
||||
HGLRC hglrc_legacy,
|
||||
GdkGLContext *share)
|
||||
ensure_legacy_wgl_context (HDC hdc,
|
||||
HGLRC hglrc_legacy,
|
||||
GdkGLContext *share,
|
||||
GdkGLVersion *version,
|
||||
GError **error)
|
||||
{
|
||||
GdkWin32GLContextWGL *context_wgl;
|
||||
GdkGLVersion legacy_version;
|
||||
|
||||
GDK_NOTE (OPENGL,
|
||||
g_print ("Creating legacy WGL context (version:%d.%d)\n",
|
||||
gdk_gl_version_get_major (version),
|
||||
gdk_gl_version_get_minor (version)));
|
||||
|
||||
if (!wglMakeCurrent (hdc, hglrc_legacy))
|
||||
return FALSE;
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Unable to create a GL context"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdk_gl_version_init_epoxy (&legacy_version);
|
||||
if (!gdk_gl_version_greater_equal (&legacy_version, version))
|
||||
{
|
||||
g_set_error (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("WGL version %d.%d is too low, need at least %d.%d"),
|
||||
gdk_gl_version_get_major (&legacy_version),
|
||||
gdk_gl_version_get_minor (&legacy_version),
|
||||
gdk_gl_version_get_major (version),
|
||||
gdk_gl_version_get_minor (version));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*version = legacy_version;
|
||||
|
||||
if (share != NULL)
|
||||
{
|
||||
context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
|
||||
|
||||
return wglShareLists (hglrc_legacy, context_wgl->wgl_context);
|
||||
if (!wglShareLists (hglrc_legacy, context_wgl->wgl_context))
|
||||
{
|
||||
g_set_error (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_PROFILE,
|
||||
_("GL implementation cannot share GL contexts"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -356,130 +386,138 @@ create_wgl_context_with_attribs (HDC hdc,
|
||||
HGLRC hglrc_base,
|
||||
GdkGLContext *share,
|
||||
int flags,
|
||||
int major,
|
||||
int minor,
|
||||
gboolean *is_legacy)
|
||||
gboolean is_legacy,
|
||||
GdkGLVersion *version)
|
||||
{
|
||||
HGLRC hglrc;
|
||||
GdkWin32GLContextWGL *context_wgl;
|
||||
const GdkGLVersion *supported_versions = gdk_gl_versions_get_for_api (GDK_GL_API_GL);
|
||||
guint i;
|
||||
|
||||
/* if we have wglCreateContextAttribsARB(), create a
|
||||
* context with the compatibility profile if a legacy
|
||||
* context is requested, or when we go into fallback mode
|
||||
*/
|
||||
int profile = *is_legacy ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :
|
||||
WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
GDK_NOTE (OPENGL,
|
||||
g_print ("Creating %s WGL context (version:%d.%d, debug:%s, forward:%s)\n",
|
||||
is_legacy ? "core" : "compat",
|
||||
gdk_gl_version_get_major (version),
|
||||
gdk_gl_version_get_minor (version),
|
||||
(flags & WGL_CONTEXT_DEBUG_BIT_ARB) ? "yes" : "no",
|
||||
(flags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) ? "yes" : "no"));
|
||||
|
||||
int attribs[] = {
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, profile,
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, *is_legacy ? 3 : major,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, *is_legacy ? 0 : minor,
|
||||
WGL_CONTEXT_FLAGS_ARB, flags,
|
||||
0
|
||||
};
|
||||
for (i = 0; gdk_gl_version_greater_equal (&supported_versions[i], version); i++)
|
||||
{
|
||||
/* if we have wglCreateContextAttribsARB(), create a
|
||||
* context with the compatibility profile if a legacy
|
||||
* context is requested, or when we go into fallback mode
|
||||
*/
|
||||
int profile = is_legacy ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :
|
||||
WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
|
||||
if (share != NULL)
|
||||
context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
|
||||
int attribs[] = {
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, profile,
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, gdk_gl_version_get_major (&supported_versions[i]),
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, gdk_gl_version_get_minor (&supported_versions[i]),
|
||||
WGL_CONTEXT_FLAGS_ARB, flags,
|
||||
0
|
||||
};
|
||||
|
||||
hglrc = wglCreateContextAttribsARB (hdc,
|
||||
share != NULL ? context_wgl->wgl_context : NULL,
|
||||
attribs);
|
||||
if (share != NULL)
|
||||
context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
|
||||
|
||||
return hglrc;
|
||||
hglrc = wglCreateContextAttribsARB (hdc,
|
||||
share != NULL ? context_wgl->wgl_context : NULL,
|
||||
attribs);
|
||||
|
||||
if (hglrc)
|
||||
{
|
||||
*version = supported_versions[i];
|
||||
return hglrc;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HGLRC
|
||||
create_wgl_context (HDC hdc,
|
||||
GdkGLContext *share,
|
||||
int flags,
|
||||
int major,
|
||||
int minor,
|
||||
gboolean *is_legacy,
|
||||
gboolean hasWglARBCreateContext)
|
||||
create_wgl_context (GdkGLContext *context,
|
||||
HDC hdc,
|
||||
gboolean hasWglARBCreateContext,
|
||||
GdkGLContext *share,
|
||||
int flags,
|
||||
gboolean legacy,
|
||||
GError **error)
|
||||
{
|
||||
/* We need a legacy context for *all* cases */
|
||||
HGLRC hglrc_base = wglCreateContext (hdc);
|
||||
gboolean success = TRUE;
|
||||
|
||||
HGLRC hglrc_base, hglrc;
|
||||
GdkGLVersion version;
|
||||
/* Save up the HDC and HGLRC that we are currently using, to restore back to it when we are done here */
|
||||
HDC hdc_current = wglGetCurrentDC ();
|
||||
HGLRC hglrc_current = wglGetCurrentContext ();
|
||||
|
||||
/* if we have no wglCreateContextAttribsARB(), return the legacy context when all is set */
|
||||
if (*is_legacy && !hasWglARBCreateContext)
|
||||
hglrc_base = wglCreateContext (hdc);
|
||||
if (hglrc_base == NULL ||
|
||||
!wglMakeCurrent (hdc, hglrc_base))
|
||||
{
|
||||
if (ensure_legacy_wgl_context (hdc, hglrc_base, share))
|
||||
{
|
||||
wglMakeCurrent (hdc_current, hglrc_current);
|
||||
return hglrc_base;
|
||||
}
|
||||
|
||||
success = FALSE;
|
||||
goto gl_fail;
|
||||
g_clear_pointer (&hglrc_base, wglDeleteContext);
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Unable to create a GL context"));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
||||
hglrc = NULL;
|
||||
|
||||
if (hasWglARBCreateContext)
|
||||
{
|
||||
HGLRC hglrc = NULL;
|
||||
|
||||
if (!wglMakeCurrent (hdc, hglrc_base))
|
||||
if (!legacy)
|
||||
{
|
||||
success = FALSE;
|
||||
goto gl_fail;
|
||||
gdk_gl_context_get_matching_version (context,
|
||||
GDK_GL_API_GL,
|
||||
FALSE,
|
||||
&version);
|
||||
hglrc = create_wgl_context_with_attribs (hdc,
|
||||
hglrc_base,
|
||||
share,
|
||||
flags,
|
||||
FALSE,
|
||||
&version);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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_wgl_context_with_attribs (hdc,
|
||||
hglrc_base,
|
||||
share,
|
||||
flags,
|
||||
0, 0,
|
||||
is_legacy);
|
||||
|
||||
*is_legacy = TRUE;
|
||||
}
|
||||
|
||||
if (hglrc == NULL)
|
||||
{
|
||||
if (!ensure_legacy_wgl_context (hdc, hglrc_base, share))
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
if (success)
|
||||
GDK_NOTE (OPENGL, g_print ("Using legacy context as fallback\n"));
|
||||
legacy = TRUE;
|
||||
gdk_gl_context_get_matching_version (context,
|
||||
GDK_GL_API_GL,
|
||||
TRUE,
|
||||
&version);
|
||||
hglrc = create_wgl_context_with_attribs (hdc,
|
||||
hglrc_base,
|
||||
share,
|
||||
flags,
|
||||
TRUE,
|
||||
&version);
|
||||
}
|
||||
}
|
||||
|
||||
gl_fail:
|
||||
if (hglrc == NULL)
|
||||
{
|
||||
legacy = TRUE;
|
||||
gdk_gl_context_get_matching_version (context,
|
||||
GDK_GL_API_GL,
|
||||
TRUE,
|
||||
&version);
|
||||
if (ensure_legacy_wgl_context (hdc, hglrc_base, share, &version, error))
|
||||
hglrc = g_steal_pointer (&hglrc_base);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
wglMakeCurrent (NULL, NULL);
|
||||
wglDeleteContext (hglrc_base);
|
||||
return NULL;
|
||||
}
|
||||
if (hglrc)
|
||||
{
|
||||
gdk_gl_context_set_version (context, &version);
|
||||
gdk_gl_context_set_is_legacy (context, legacy);
|
||||
}
|
||||
|
||||
wglMakeCurrent (hdc_current, hglrc_current);
|
||||
g_clear_pointer (&hglrc_base, wglDeleteContext);
|
||||
|
||||
if (hglrc != NULL)
|
||||
{
|
||||
wglDeleteContext (hglrc_base);
|
||||
return hglrc;
|
||||
}
|
||||
wglMakeCurrent (hdc_current, hglrc_current);
|
||||
|
||||
return hglrc_base;
|
||||
}
|
||||
return hglrc;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -525,8 +563,6 @@ 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;
|
||||
HGLRC hglrc;
|
||||
int pixel_format;
|
||||
HDC hdc;
|
||||
@ -542,24 +578,6 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
|
||||
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.
|
||||
*/
|
||||
gdk_gl_context_get_clipped_version (context,
|
||||
display_win32->gl_version / 10,
|
||||
display_win32->gl_version % 10,
|
||||
&major, &minor);
|
||||
|
||||
if (surface != NULL)
|
||||
hdc = GDK_WIN32_SURFACE (surface)->hdc;
|
||||
else
|
||||
hdc = display_win32->dummy_context_wgl.hdc;
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -568,6 +586,11 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
|
||||
? TRUE
|
||||
: share != NULL && gdk_gl_context_is_legacy (share);
|
||||
|
||||
if (surface != NULL)
|
||||
hdc = GDK_WIN32_SURFACE (surface)->hdc;
|
||||
else
|
||||
hdc = display_win32->dummy_context_wgl.hdc;
|
||||
|
||||
if (!set_wgl_pixformat_for_hdc (hdc,
|
||||
&pixel_format,
|
||||
display_win32))
|
||||
@ -587,30 +610,15 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
|
||||
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 (hdc,
|
||||
hglrc = create_wgl_context (context,
|
||||
hdc,
|
||||
display_win32->hasWglARBCreateContext,
|
||||
share,
|
||||
flags,
|
||||
major,
|
||||
minor,
|
||||
&legacy_bit,
|
||||
display_win32->hasWglARBCreateContext);
|
||||
|
||||
legacy_bit,
|
||||
error);
|
||||
if (hglrc == NULL)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Unable to create a GL context"));
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
GDK_NOTE (OPENGL,
|
||||
g_print ("Created WGL context[%p], pixel_format=%d\n",
|
||||
@ -619,9 +627,6 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
|
||||
|
||||
context_wgl->wgl_context = hglrc;
|
||||
|
||||
/* Ensure that any other context is created with a legacy bit set */
|
||||
gdk_gl_context_set_is_legacy (context, legacy_bit);
|
||||
|
||||
return GDK_GL_API_GL;
|
||||
}
|
||||
|
||||
@ -715,10 +720,11 @@ gdk_win32_gl_context_wgl_init (GdkWin32GLContextWGL *wgl_context)
|
||||
*/
|
||||
gboolean
|
||||
gdk_win32_display_get_wgl_version (GdkDisplay *display,
|
||||
int *major,
|
||||
int *minor)
|
||||
int *major,
|
||||
int *minor)
|
||||
{
|
||||
GdkWin32Display *display_win32;
|
||||
GdkGLContext *context;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||
|
||||
if (!GDK_IS_WIN32_DISPLAY (display))
|
||||
@ -727,12 +733,11 @@ gdk_win32_display_get_wgl_version (GdkDisplay *display,
|
||||
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, NULL))
|
||||
return FALSE;
|
||||
|
||||
display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
context = gdk_display_get_gl_context (display);
|
||||
if (context == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (major != NULL)
|
||||
*major = display_win32->gl_version / 10;
|
||||
if (minor != NULL)
|
||||
*minor = display_win32->gl_version % 10;
|
||||
gdk_gl_context_get_version (context, major, minor);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -64,10 +64,10 @@ struct _GdkWin32GLContextClass
|
||||
|
||||
typedef struct _GdkWin32GLContextWGL GdkWin32GLContextWGL;
|
||||
|
||||
gboolean gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
GError **error);
|
||||
void gdk_win32_gl_context_wgl_bind_surface (GdkWin32GLContextWGL *ctx,
|
||||
GdkWin32Surface *win32_surface);
|
||||
GdkGLContext * gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
GError **error);
|
||||
void gdk_win32_gl_context_wgl_bind_surface (GdkWin32GLContextWGL *ctx,
|
||||
GdkWin32Surface *win32_surface);
|
||||
|
||||
GType gdk_win32_gl_context_wgl_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
@ -477,8 +477,11 @@ 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;
|
||||
gsize major_idx, minor_idx;
|
||||
GdkGLVersion version;
|
||||
const GdkGLVersion* supported_versions;
|
||||
gboolean debug_bit, compat_bit;
|
||||
gsize j;
|
||||
|
||||
if (!gdk_gl_context_is_api_allowed (context, api, NULL))
|
||||
return 0;
|
||||
@ -488,10 +491,7 @@ 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 (context, api, legacy, &version);
|
||||
|
||||
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
||||
compat_bit = gdk_gl_context_get_forward_compatible (context);
|
||||
@ -511,9 +511,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;
|
||||
major_idx = i++;
|
||||
context_attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB;
|
||||
context_attribs[i++] = minor;
|
||||
minor_idx = i++;
|
||||
context_attribs[i++] = GLX_CONTEXT_FLAGS_ARB;
|
||||
context_attribs[i++] = flags;
|
||||
|
||||
@ -522,7 +522,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",
|
||||
@ -533,25 +533,44 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
|
||||
|
||||
gdk_x11_display_error_trap_push (display);
|
||||
|
||||
/* If we don't have access to GLX_ARB_create_context_profile, then
|
||||
* we have to fall back to the old GLX 1.3 API.
|
||||
*/
|
||||
if (legacy && !display_x11->has_glx_create_context)
|
||||
ctx = glXCreateNewContext (gdk_x11_display_get_xdisplay (display),
|
||||
display_x11->glx_config,
|
||||
GLX_RGBA_TYPE,
|
||||
share_glx != NULL ? share_glx->glx_context : NULL,
|
||||
TRUE);
|
||||
supported_versions = gdk_gl_versions_get_for_api (api);
|
||||
for (j = 0; gdk_gl_version_greater_equal (&supported_versions[j], &version); j++)
|
||||
{
|
||||
context_attribs [major_idx] = gdk_gl_version_get_major (&supported_versions[j]);
|
||||
context_attribs [minor_idx] = gdk_gl_version_get_minor (&supported_versions[j]);
|
||||
|
||||
else
|
||||
ctx = glXCreateContextAttribsARB (gdk_x11_display_get_xdisplay (display),
|
||||
display_x11->glx_config,
|
||||
share_glx != NULL ? share_glx->glx_context : NULL,
|
||||
True,
|
||||
context_attribs);
|
||||
/* If we don't have access to GLX_ARB_create_context_profile, then
|
||||
* we have to fall back to the old GLX 1.3 API.
|
||||
*/
|
||||
if (legacy && !display_x11->has_glx_create_context)
|
||||
ctx = glXCreateNewContext (gdk_x11_display_get_xdisplay (display),
|
||||
display_x11->glx_config,
|
||||
GLX_RGBA_TYPE,
|
||||
share_glx != NULL ? share_glx->glx_context : NULL,
|
||||
TRUE);
|
||||
|
||||
if (gdk_x11_display_error_trap_pop (display) || ctx == NULL)
|
||||
return 0;
|
||||
else
|
||||
ctx = glXCreateContextAttribsARB (gdk_x11_display_get_xdisplay (display),
|
||||
display_x11->glx_config,
|
||||
share_glx != NULL ? share_glx->glx_context : NULL,
|
||||
True,
|
||||
context_attribs);
|
||||
|
||||
if (ctx)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctx == NULL)
|
||||
{
|
||||
gdk_x11_display_error_trap_pop_ignored (display);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gdk_x11_display_error_trap_pop (display))
|
||||
{
|
||||
glXDestroyContext (dpy, ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, OPENGL,
|
||||
"Realized GLX context[%p], %s, version: %d.%d",
|
||||
@ -561,6 +580,7 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
|
||||
display_x11->glx_version % 10);
|
||||
|
||||
context_glx->glx_context = ctx;
|
||||
gdk_gl_context_set_version (context, &supported_versions[j]);
|
||||
gdk_gl_context_set_is_legacy (context, legacy);
|
||||
|
||||
#ifdef HAVE_XDAMAGE
|
||||
|
@ -491,7 +491,7 @@ gsk_gl_command_queue_new (GdkGLContext *context,
|
||||
}
|
||||
}
|
||||
|
||||
self->has_samplers = gdk_gl_context_check_version (context, 3, 3, 3, 0);
|
||||
self->has_samplers = gdk_gl_context_check_version (context, "3.3", "3.0");
|
||||
|
||||
/* create the samplers */
|
||||
if (self->has_samplers)
|
||||
@ -1522,7 +1522,7 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, x, y, width, height, gl_format, gl_type, data);
|
||||
}
|
||||
else if (stride % bpp == 0 &&
|
||||
(gdk_gl_context_check_version (self->context, 0, 0, 3, 0) || gdk_gl_context_has_unpack_subimage (self->context)))
|
||||
(gdk_gl_context_check_version (self->context, NULL, "3.0") || gdk_gl_context_has_unpack_subimage (self->context)))
|
||||
{
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
|
||||
|
||||
|
@ -373,7 +373,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
}
|
||||
|
||||
if (gsk_render_node_prefers_high_depth (root) &&
|
||||
gdk_gl_context_check_version (self->context, 3, 0, 3, 0))
|
||||
gdk_gl_context_check_version (self->context, "3.0", "3.0"))
|
||||
format = GL_RGBA32F;
|
||||
else
|
||||
format = GL_RGBA8;
|
||||
|
@ -4408,7 +4408,7 @@ get_framebuffer_format (GdkGLContext *context,
|
||||
{
|
||||
int size;
|
||||
|
||||
if (!gdk_gl_context_check_version (context, 0, 0, 3, 0))
|
||||
if (!gdk_gl_context_check_version (context, NULL, "3.0"))
|
||||
return GL_RGBA8;
|
||||
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
|
||||
|
Loading…
Reference in New Issue
Block a user