gl: Add context options

Users of the GdkGLContext API should be allowed to set properties on the
shim GdkGLContext instance prior to realization, so that the
backend-specific implementation can use the value of those properties
when creating the windowing system specific resources.

The main three options are:

 • a major/minor version tuple, to request a specific GL version
 • a debug bit, to request a "debug context", which provides additional
   validation and run time checking
 • a forward compatibility bit, to request a context that does not
   have deprecated functionality

See also:
 - https://www.opengl.org/registry/specs/ARB/glx_create_context.txt

https://bugzilla.gnome.org/show_bug.cgi?id=741946
This commit is contained in:
Emmanuele Bassi 2015-01-28 09:34:16 +00:00
parent 22e6f37c9c
commit fa90052299
3 changed files with 208 additions and 7 deletions

View File

@ -85,11 +85,16 @@ typedef struct {
GdkGLContext *shared_context;
GdkGLProfile profile;
int major;
int minor;
guint realized : 1;
guint use_texture_rectangle : 1;
guint has_gl_framebuffer_blit : 1;
guint has_frame_terminator : 1;
guint extensions_checked : 1;
guint debug_enabled : 1;
guint forward_compatible : 1;
GdkGLContextPaintData *paint_data;
} GdkGLContextPrivate;
@ -390,6 +395,186 @@ gdk_gl_context_has_frame_terminator (GdkGLContext *context)
return priv->has_frame_terminator;
}
/**
* gdk_gl_context_set_debug_enabled:
* @context: a #GdkGLContext
* @enabled: whether to enable debugging in the context
*
* Sets whether the #GdkGLContext should perform extra validations and
* run time checking. This is useful during development, but has
* additional overhead.
*
* The #GdkGLContext must not be realized.
*
* This function has effect only on #GdkGLContexts created using
* the %GDK_GL_PROFILE_3_2_CORE profile.
*
* Since: 3.16
*/
void
gdk_gl_context_set_debug_enabled (GdkGLContext *context,
gboolean enabled)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
g_return_if_fail (!priv->realized);
g_return_if_fail (priv->profile == GDK_GL_PROFILE_3_2_CORE);
enabled = !!enabled;
priv->debug_enabled = enabled;
}
/*< private >
* gdk_gl_context_get_debug_enabled:
* @context: a #GdkGLContext
*
* Retrieves the value set using gdk_gl_context_set_debug_enabled().
*
* Returns: %TRUE if debugging is enabled
*/
gboolean
gdk_gl_context_get_debug_enabled (GdkGLContext *context)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
return priv->debug_enabled;
}
/**
* gdk_gl_context_set_forward_compatible:
* @context: a #GdkGLContext
* @compatible: whether the context should be forward compatible
*
* Sets whether the #GdkGLContext should be forward compatible.
*
* Forward compatibile contexts must not support OpenGL functionality that
* has been marked as deprecated in the requested version; non-forward
* compatible contexts, on the other hand, must support both deprecated and
* non deprecated functionality.
*
* The #GdkGLContext must not be realized.
*
* This function has effect only on #GdkGLContexts created using
* the %GDK_GL_PROFILE_3_2_CORE profile.
*
* Since: 3.16
*/
void
gdk_gl_context_set_forward_compatible (GdkGLContext *context,
gboolean compatible)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
compatible = !!compatible;
priv->forward_compatible = compatible;
}
/*< private >
* gdk_gl_context_get_forward_compatible:
* @context: a #GdkGLContext
*
* Retrieves the value set using gdk_gl_context_set_forward_compatible().
*
* Returns: %TRUE if the context should be forward compatible
*/
gboolean
gdk_gl_context_get_forward_compatible (GdkGLContext *context)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
return priv->forward_compatible;
}
/**
* gdk_gl_context_set_required_version:
* @context: a #GdkGLContext
* @major: the major version to request
* @minor: the minor version to request
*
* Sets the major and minor version of OpenGL to request.
*
* Setting @major and @minor to zero will use the default values.
*
* The #GdkGLContext must not be realized.
*
* This function has effect only on #GdkGLContexts created using
* the %GDK_GL_PROFILE_3_2_CORE profile.
*
* Since: 3.16
*/
void
gdk_gl_context_set_required_version (GdkGLContext *context,
int major,
int minor)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
g_return_if_fail (!priv->realized);
g_return_if_fail (priv->profile == GDK_GL_PROFILE_3_2_CORE);
priv->major = major;
priv->minor = minor;
}
/*< private >
* gdk_gl_context_get_required_version:
* @context: a #GdkGLContext
* @major: (out) (nullable): return location for the major version to request
* @minor: (out) (nullable): return location for the minor version to request
*
* Retrieves the major and minor version requested by calling
* gdk_gl_context_set_required_version().
*/
void
gdk_gl_context_get_required_version (GdkGLContext *context,
int *major,
int *minor)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
if (major != NULL && priv->major > 0)
*major = priv->major;
else
{
switch (priv->profile)
{
case GDK_GL_PROFILE_DEFAULT:
case GDK_GL_PROFILE_LEGACY:
if (major != NULL)
*major = 1;
break;
case GDK_GL_PROFILE_3_2_CORE:
if (major != NULL)
*major = 3;
break;
}
}
if (minor != NULL && priv->minor > 0)
*minor = priv->minor;
else
{
switch (priv->profile)
{
case GDK_GL_PROFILE_DEFAULT:
case GDK_GL_PROFILE_LEGACY:
if (minor != NULL)
*minor = 0;
break;
case GDK_GL_PROFILE_3_2_CORE:
if (minor != NULL)
*minor = 2;
break;
}
}
}
/**
* gdk_gl_context_realize:
* @context: a #GdkGLContext

View File

@ -51,6 +51,17 @@ GdkGLProfile gdk_gl_context_get_profile (GdkGLContext *
GDK_AVAILABLE_IN_3_16
GdkGLContext * gdk_gl_context_get_shared_context (GdkGLContext *context);
GDK_AVAILABLE_IN_3_16
void gdk_gl_context_set_required_version (GdkGLContext *context,
int major,
int minor);
GDK_AVAILABLE_IN_3_16
void gdk_gl_context_set_debug_enabled (GdkGLContext *context,
gboolean enabled);
GDK_AVAILABLE_IN_3_16
void gdk_gl_context_set_forward_compatible (GdkGLContext *context,
gboolean compatible);
GDK_AVAILABLE_IN_3_16
gboolean gdk_gl_context_realize (GdkGLContext *context,
GError **error);

View File

@ -74,13 +74,18 @@ typedef struct {
GdkGLContextProgram *current_program;
} GdkGLContextPaintData;
GdkGLContextPaintData *gdk_gl_context_get_paint_data (GdkGLContext *context);
gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext *context);
gboolean gdk_gl_context_has_framebuffer_blit (GdkGLContext *context);
gboolean gdk_gl_context_has_frame_terminator (GdkGLContext *context);
void gdk_gl_context_end_frame (GdkGLContext *context,
cairo_region_t *painted,
cairo_region_t *damage);
void gdk_gl_context_get_required_version (GdkGLContext *context,
int *major,
int *minor);
gboolean gdk_gl_context_get_debug_enabled (GdkGLContext *context);
gboolean gdk_gl_context_get_forward_compatible (GdkGLContext *context);
GdkGLContextPaintData * gdk_gl_context_get_paint_data (GdkGLContext *context);
gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext *context);
gboolean gdk_gl_context_has_framebuffer_blit (GdkGLContext *context);
gboolean gdk_gl_context_has_frame_terminator (GdkGLContext *context);
void gdk_gl_context_end_frame (GdkGLContext *context,
cairo_region_t *painted,
cairo_region_t *damage);
G_END_DECLS