2014-10-09 08:45:44 +00:00
|
|
|
/* GDK - The GIMP Drawing Kit
|
|
|
|
*
|
|
|
|
* gdkglcontext.c: 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/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SECTION:gdkglcontext
|
|
|
|
* @Title: GdkGLContext
|
|
|
|
* @Short_description: OpenGL context
|
|
|
|
*
|
|
|
|
* #GdkGLContext is an object representing the platform-specific
|
|
|
|
* OpenGL drawing context.
|
|
|
|
*
|
2014-10-12 03:17:34 +00:00
|
|
|
* #GdkGLContexts are created for a #GdkWindow using
|
|
|
|
* gdk_window_create_gl_context(), and the context will match
|
|
|
|
* the #GdkVisual of the window.
|
2014-10-09 14:09:05 +00:00
|
|
|
*
|
2014-10-12 03:35:52 +00:00
|
|
|
* A #GdkGLContext is not tied to any particular normal framebuffer.
|
|
|
|
* For instance, it cannot draw to the #GdkWindow back buffer. The GDK
|
|
|
|
* repaint system is in full control of the painting to that. Instead,
|
|
|
|
* you can create render buffers or textures and use gdk_cairo_draw_from_gl()
|
|
|
|
* in the draw function of your widget to draw them. Then GDK will handle
|
|
|
|
* the integration of your rendering with that of other widgets.
|
2014-10-09 08:45:44 +00:00
|
|
|
*
|
2014-10-12 03:17:34 +00:00
|
|
|
* Support for #GdkGLContext is platform-specific, context creation
|
|
|
|
* can fail, returning %NULL context.
|
2014-10-09 08:45:44 +00:00
|
|
|
*
|
|
|
|
* A #GdkGLContext has to be made "current" in order to start using
|
|
|
|
* it, otherwise any OpenGL call will be ignored.
|
|
|
|
*
|
|
|
|
* ## Creating a new OpenGL context ##
|
|
|
|
*
|
|
|
|
* In order to create a new #GdkGLContext instance you need a
|
2014-10-12 03:17:34 +00:00
|
|
|
* #GdkWindow, which you typically get during the realize call
|
|
|
|
* of a widget.
|
2014-10-09 08:45:44 +00:00
|
|
|
*
|
2015-02-09 16:09:25 +00:00
|
|
|
* A #GdkGLContext is not realized until either gdk_gl_context_make_current(),
|
|
|
|
* or until it is realized using gdk_gl_context_realize(). It is possible to
|
|
|
|
* specify details of the GL context like the OpenGL version to be used, or
|
|
|
|
* whether the GL context should have extra state validation enabled after
|
|
|
|
* calling gdk_window_create_gl_context() by calling gdk_gl_context_realize().
|
|
|
|
* If the realization fails you have the option to change the settings of the
|
|
|
|
* #GdkGLContext and try again.
|
|
|
|
*
|
2014-10-09 08:45:44 +00:00
|
|
|
* ## Using a GdkGLContext ##
|
|
|
|
*
|
|
|
|
* You will need to make the #GdkGLContext the current context
|
|
|
|
* before issuing OpenGL calls; the system sends OpenGL commands to
|
|
|
|
* whichever context is current. It is possible to have multiple
|
|
|
|
* contexts, so you always need to ensure that the one which you
|
|
|
|
* want to draw with is the current one before issuing commands:
|
|
|
|
*
|
|
|
|
* |[<!-- language="C" -->
|
|
|
|
* gdk_gl_context_make_current (context);
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* You can now perform your drawing using OpenGL commands.
|
|
|
|
*
|
|
|
|
* You can check which #GdkGLContext is the current one by using
|
|
|
|
* gdk_gl_context_get_current(); you can also unset any #GdkGLContext
|
|
|
|
* that is currently set by calling gdk_gl_context_clear_current().
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "gdkglcontextprivate.h"
|
|
|
|
#include "gdkdisplayprivate.h"
|
|
|
|
#include "gdkinternals.h"
|
|
|
|
|
|
|
|
#include "gdkintl.h"
|
2014-11-07 14:27:56 +00:00
|
|
|
#include "gdk-private.h"
|
2014-10-09 08:45:44 +00:00
|
|
|
|
2014-10-27 20:12:40 +00:00
|
|
|
#include <epoxy/gl.h>
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
typedef struct {
|
2014-11-03 12:20:55 +00:00
|
|
|
GdkDisplay *display;
|
2014-10-09 08:45:44 +00:00
|
|
|
GdkWindow *window;
|
2014-10-30 11:04:23 +00:00
|
|
|
GdkGLContext *shared_context;
|
2014-10-27 20:12:40 +00:00
|
|
|
|
2015-01-28 09:34:16 +00:00
|
|
|
int major;
|
|
|
|
int minor;
|
2015-02-12 14:28:22 +00:00
|
|
|
int gl_version;
|
2015-01-28 09:34:16 +00:00
|
|
|
|
2014-10-27 20:12:40 +00:00
|
|
|
guint realized : 1;
|
|
|
|
guint use_texture_rectangle : 1;
|
2014-11-06 11:13:08 +00:00
|
|
|
guint has_gl_framebuffer_blit : 1;
|
2014-11-06 11:21:28 +00:00
|
|
|
guint has_frame_terminator : 1;
|
2016-04-22 16:27:04 +00:00
|
|
|
guint has_unpack_subimage : 1;
|
GL: Split GL context creation in two phases
One of the major requests by OpenGL users has been the ability to
specify settings when creating a GL context, like the version to use
or whether the debug support should be enabled.
We have a couple of requirements in terms of API:
• avoid, if at all possible, the "C arrays of integers with
attribute, value pairs", which are hard to write and hard
to bind in non-C languages.
• allow failing in a recoverable way.
• do not make the GL context creation API a mess of arguments.
Looking at prior art, it seems that a common pattern is to split the
construction phase in two:
• a first phase that creates a GL context wrapper object and
does preliminary checks on the environment.
• a second phase that creates the backend-specific GL object.
We adopted a similar pattern:
• gdk_window_create_gl_context() creates a GdkGLContext
• gdk_gl_context_realize() creates the underlying resources
Calling gdk_gl_context_make_current() also realizes the context, so
simple GL users do not need to care. Advanced users will want to
call gdk_window_create_gl_context(), set up the optional requirements,
and then call gdk_gl_context_realize(). If either of these two steps
fails, it's possible to recover by changing the requirements, or simply
creating a new GdkGLContext instance.
https://bugzilla.gnome.org/show_bug.cgi?id=741946
2015-01-27 21:23:23 +00:00
|
|
|
guint extensions_checked : 1;
|
2015-01-28 09:34:16 +00:00
|
|
|
guint debug_enabled : 1;
|
|
|
|
guint forward_compatible : 1;
|
2015-10-06 17:54:58 +00:00
|
|
|
guint is_legacy : 1;
|
2016-10-19 12:43:17 +00:00
|
|
|
|
|
|
|
int use_es;
|
2014-10-27 20:12:40 +00:00
|
|
|
|
2014-11-05 14:19:00 +00:00
|
|
|
GdkGLContextPaintData *paint_data;
|
2014-10-09 08:45:44 +00:00
|
|
|
} GdkGLContextPrivate;
|
|
|
|
|
|
|
|
enum {
|
|
|
|
PROP_0,
|
|
|
|
|
2014-11-03 12:20:55 +00:00
|
|
|
PROP_DISPLAY,
|
2014-10-09 08:45:44 +00:00
|
|
|
PROP_WINDOW,
|
2014-10-30 11:04:23 +00:00
|
|
|
PROP_SHARED_CONTEXT,
|
2014-10-09 08:45:44 +00:00
|
|
|
|
|
|
|
LAST_PROP
|
|
|
|
};
|
|
|
|
|
|
|
|
static GParamSpec *obj_pspecs[LAST_PROP] = { NULL, };
|
|
|
|
|
|
|
|
G_DEFINE_QUARK (gdk-gl-error-quark, gdk_gl_error)
|
|
|
|
|
|
|
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkGLContext, gdk_gl_context, G_TYPE_OBJECT)
|
|
|
|
|
2014-10-30 10:46:09 +00:00
|
|
|
static GPrivate thread_current_context = G_PRIVATE_INIT (g_object_unref);
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
static void
|
|
|
|
gdk_gl_context_dispose (GObject *gobject)
|
|
|
|
{
|
|
|
|
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
2014-10-30 10:46:09 +00:00
|
|
|
GdkGLContext *current;
|
2014-10-09 08:45:44 +00:00
|
|
|
|
2014-10-30 10:46:09 +00:00
|
|
|
current = g_private_get (&thread_current_context);
|
|
|
|
if (current == context)
|
|
|
|
g_private_replace (&thread_current_context, NULL);
|
2014-10-09 08:45:44 +00:00
|
|
|
|
2014-11-03 12:20:55 +00:00
|
|
|
g_clear_object (&priv->display);
|
2014-10-09 08:45:44 +00:00
|
|
|
g_clear_object (&priv->window);
|
2014-10-30 11:04:23 +00:00
|
|
|
g_clear_object (&priv->shared_context);
|
2014-10-09 08:45:44 +00:00
|
|
|
|
|
|
|
G_OBJECT_CLASS (gdk_gl_context_parent_class)->dispose (gobject);
|
|
|
|
}
|
|
|
|
|
2014-11-05 14:19:00 +00:00
|
|
|
static void
|
|
|
|
gdk_gl_context_finalize (GObject *gobject)
|
|
|
|
{
|
|
|
|
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
|
|
|
g_clear_pointer (&priv->paint_data, g_free);
|
2016-11-05 13:21:22 +00:00
|
|
|
G_OBJECT_CLASS (gdk_gl_context_parent_class)->finalize (gobject);
|
2014-11-05 14:19:00 +00:00
|
|
|
}
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
static void
|
|
|
|
gdk_gl_context_set_property (GObject *gobject,
|
|
|
|
guint prop_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private ((GdkGLContext *) gobject);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
2014-11-03 12:20:55 +00:00
|
|
|
case PROP_DISPLAY:
|
|
|
|
{
|
|
|
|
GdkDisplay *display = g_value_get_object (value);
|
|
|
|
|
|
|
|
if (display)
|
|
|
|
g_object_ref (display);
|
|
|
|
|
|
|
|
if (priv->display)
|
|
|
|
g_object_unref (priv->display);
|
|
|
|
|
|
|
|
priv->display = display;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
case PROP_WINDOW:
|
|
|
|
{
|
|
|
|
GdkWindow *window = g_value_get_object (value);
|
|
|
|
|
|
|
|
if (window)
|
|
|
|
g_object_ref (window);
|
|
|
|
|
|
|
|
if (priv->window)
|
|
|
|
g_object_unref (priv->window);
|
|
|
|
|
|
|
|
priv->window = window;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2014-10-30 11:04:23 +00:00
|
|
|
case PROP_SHARED_CONTEXT:
|
|
|
|
{
|
|
|
|
GdkGLContext *context = g_value_get_object (value);
|
|
|
|
|
|
|
|
if (context != NULL)
|
|
|
|
priv->shared_context = g_object_ref (context);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_gl_context_get_property (GObject *gobject,
|
|
|
|
guint prop_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private ((GdkGLContext *) gobject);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
2014-11-03 12:20:55 +00:00
|
|
|
case PROP_DISPLAY:
|
|
|
|
g_value_set_object (value, priv->display);
|
|
|
|
break;
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
case PROP_WINDOW:
|
|
|
|
g_value_set_object (value, priv->window);
|
|
|
|
break;
|
|
|
|
|
2014-10-30 11:04:23 +00:00
|
|
|
case PROP_SHARED_CONTEXT:
|
|
|
|
g_value_set_object (value, priv->shared_context);
|
|
|
|
break;
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-09 19:09:31 +00:00
|
|
|
void
|
2014-12-17 08:06:25 +00:00
|
|
|
gdk_gl_context_upload_texture (GdkGLContext *context,
|
|
|
|
cairo_surface_t *image_surface,
|
|
|
|
int width,
|
|
|
|
int height,
|
|
|
|
guint texture_target)
|
|
|
|
{
|
2016-04-22 16:27:04 +00:00
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
2014-12-17 08:06:25 +00:00
|
|
|
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
|
|
|
|
2016-04-22 16:27:04 +00:00
|
|
|
/* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
|
|
|
|
* the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
|
|
|
|
*/
|
2016-04-25 09:31:51 +00:00
|
|
|
if (!priv->use_es ||
|
|
|
|
(priv->use_es && (priv->gl_version >= 30 || priv->has_unpack_subimage)))
|
2016-04-22 16:27:04 +00:00
|
|
|
{
|
|
|
|
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
|
|
|
|
glPixelStorei (GL_UNPACK_ROW_LENGTH, cairo_image_surface_get_stride (image_surface) / 4);
|
2016-04-23 09:21:13 +00:00
|
|
|
|
2016-04-25 09:31:51 +00:00
|
|
|
if (priv->use_es)
|
2016-04-23 09:21:13 +00:00
|
|
|
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
|
|
|
cairo_image_surface_get_data (image_surface));
|
|
|
|
else
|
|
|
|
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
|
|
|
cairo_image_surface_get_data (image_surface));
|
|
|
|
|
2016-04-22 16:27:04 +00:00
|
|
|
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
|
|
|
}
|
|
|
|
else
|
2016-04-25 09:31:51 +00:00
|
|
|
{
|
|
|
|
GLvoid *data = cairo_image_surface_get_data (image_surface);
|
|
|
|
int stride = cairo_image_surface_get_stride (image_surface);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (priv->use_es)
|
|
|
|
{
|
|
|
|
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
|
|
|
|
|
|
|
for (i = 0; i < height; i++)
|
2016-04-26 12:29:23 +00:00
|
|
|
glTexSubImage2D (texture_target, 0, 0, i, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*) data + (i * stride));
|
2016-04-25 09:31:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
|
|
|
|
|
|
|
for (i = 0; i < height; i++)
|
2016-04-26 12:29:23 +00:00
|
|
|
glTexSubImage2D (texture_target, 0, 0, i, width, 1, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, (unsigned char*) data + (i * stride));
|
2016-04-25 09:31:51 +00:00
|
|
|
}
|
|
|
|
}
|
2014-12-17 08:06:25 +00:00
|
|
|
}
|
|
|
|
|
2016-05-23 07:31:47 +00:00
|
|
|
static gboolean
|
|
|
|
gdk_gl_context_real_realize (GdkGLContext *self,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
|
|
|
"The current backend does not support OpenGL");
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
static void
|
|
|
|
gdk_gl_context_class_init (GdkGLContextClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
2016-05-23 07:31:47 +00:00
|
|
|
klass->realize = gdk_gl_context_real_realize;
|
|
|
|
|
2014-11-03 12:20:55 +00:00
|
|
|
/**
|
|
|
|
* GdkGLContext:display:
|
|
|
|
*
|
2015-07-16 16:22:07 +00:00
|
|
|
* The #GdkDisplay used to create the #GdkGLContext.
|
2014-11-03 12:20:55 +00:00
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
obj_pspecs[PROP_DISPLAY] =
|
|
|
|
g_param_spec_object ("display",
|
|
|
|
P_("Display"),
|
2015-07-16 16:22:07 +00:00
|
|
|
P_("The GDK display used to create the GL context"),
|
2014-11-03 12:20:55 +00:00
|
|
|
GDK_TYPE_DISPLAY,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
/**
|
|
|
|
* GdkGLContext:window:
|
|
|
|
*
|
|
|
|
* The #GdkWindow the gl context is bound to.
|
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
obj_pspecs[PROP_WINDOW] =
|
|
|
|
g_param_spec_object ("window",
|
|
|
|
P_("Window"),
|
|
|
|
P_("The GDK window bound to the GL context"),
|
|
|
|
GDK_TYPE_WINDOW,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
2014-10-30 11:04:23 +00:00
|
|
|
/**
|
|
|
|
* GdkGLContext:shared-context:
|
|
|
|
*
|
2017-11-22 19:19:36 +00:00
|
|
|
* The #GdkGLContext that this context is sharing data with, or %NULL
|
2014-10-30 11:04:23 +00:00
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
obj_pspecs[PROP_SHARED_CONTEXT] =
|
|
|
|
g_param_spec_object ("shared-context",
|
|
|
|
P_("Shared context"),
|
2015-07-16 16:22:07 +00:00
|
|
|
P_("The GL context this context shares data with"),
|
2014-10-30 11:04:23 +00:00
|
|
|
GDK_TYPE_GL_CONTEXT,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
gobject_class->set_property = gdk_gl_context_set_property;
|
|
|
|
gobject_class->get_property = gdk_gl_context_get_property;
|
|
|
|
gobject_class->dispose = gdk_gl_context_dispose;
|
2014-11-05 14:19:00 +00:00
|
|
|
gobject_class->finalize = gdk_gl_context_finalize;
|
2014-10-09 08:45:44 +00:00
|
|
|
|
|
|
|
g_object_class_install_properties (gobject_class, LAST_PROP, obj_pspecs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_gl_context_init (GdkGLContext *self)
|
|
|
|
{
|
2016-10-19 12:43:17 +00:00
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
|
|
|
|
|
|
|
priv->use_es = -1;
|
2014-10-09 08:45:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*< private >
|
2014-10-27 15:33:37 +00:00
|
|
|
* gdk_gl_context_end_frame:
|
2014-10-09 08:45:44 +00:00
|
|
|
* @context: a #GdkGLContext
|
|
|
|
* @painted: The area that has been redrawn this frame
|
|
|
|
* @damage: The area that we know is actually different from the last frame
|
|
|
|
*
|
|
|
|
* Copies the back buffer to the front buffer.
|
|
|
|
*
|
|
|
|
* This function may call `glFlush()` implicitly before returning; it
|
|
|
|
* is not recommended to call `glFlush()` explicitly before calling
|
|
|
|
* this function.
|
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
void
|
2014-10-27 15:33:37 +00:00
|
|
|
gdk_gl_context_end_frame (GdkGLContext *context,
|
|
|
|
cairo_region_t *painted,
|
|
|
|
cairo_region_t *damage)
|
2014-10-09 08:45:44 +00:00
|
|
|
{
|
|
|
|
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
|
|
|
|
2014-10-27 15:33:37 +00:00
|
|
|
GDK_GL_CONTEXT_GET_CLASS (context)->end_frame (context, painted, damage);
|
2014-10-09 08:45:44 +00:00
|
|
|
}
|
|
|
|
|
2014-11-05 14:19:00 +00:00
|
|
|
GdkGLContextPaintData *
|
|
|
|
gdk_gl_context_get_paint_data (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
|
|
|
if (priv->paint_data == NULL)
|
2015-10-06 18:55:07 +00:00
|
|
|
{
|
|
|
|
priv->paint_data = g_new0 (GdkGLContextPaintData, 1);
|
|
|
|
priv->paint_data->is_legacy = priv->is_legacy;
|
2016-04-18 09:21:36 +00:00
|
|
|
priv->paint_data->use_es = priv->use_es;
|
2015-10-06 18:55:07 +00:00
|
|
|
}
|
2014-11-05 14:19:00 +00:00
|
|
|
|
|
|
|
return priv->paint_data;
|
|
|
|
}
|
|
|
|
|
2014-10-27 20:12:40 +00:00
|
|
|
gboolean
|
|
|
|
gdk_gl_context_use_texture_rectangle (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
|
|
|
return priv->use_texture_rectangle;
|
|
|
|
}
|
|
|
|
|
2014-11-06 11:13:08 +00:00
|
|
|
gboolean
|
|
|
|
gdk_gl_context_has_framebuffer_blit (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
|
|
|
return priv->has_gl_framebuffer_blit;
|
|
|
|
}
|
|
|
|
|
2014-11-06 11:21:28 +00:00
|
|
|
gboolean
|
|
|
|
gdk_gl_context_has_frame_terminator (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
|
|
|
return priv->has_frame_terminator;
|
|
|
|
}
|
|
|
|
|
2016-04-22 16:27:04 +00:00
|
|
|
gboolean
|
|
|
|
gdk_gl_context_has_unpack_subimage (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
|
|
|
return priv->has_unpack_subimage;
|
|
|
|
}
|
|
|
|
|
2015-01-28 09:34:16 +00:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*
|
2015-02-09 16:09:25 +00:00
|
|
|
* The #GdkGLContext must not be realized or made current prior to
|
|
|
|
* calling this function.
|
2015-01-28 09:34:16 +00:00
|
|
|
*
|
|
|
|
* 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);
|
|
|
|
|
|
|
|
enabled = !!enabled;
|
|
|
|
|
|
|
|
priv->debug_enabled = enabled;
|
|
|
|
}
|
|
|
|
|
2015-01-28 14:37:26 +00:00
|
|
|
/**
|
2015-01-28 09:34:16 +00:00
|
|
|
* 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
|
2015-01-28 14:37:26 +00:00
|
|
|
*
|
|
|
|
* Since: 3.16
|
2015-01-28 09:34:16 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gdk_gl_context_get_debug_enabled (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
2015-01-28 14:37:26 +00:00
|
|
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
|
|
|
|
|
2015-01-28 09:34:16 +00:00
|
|
|
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.
|
|
|
|
*
|
2015-02-09 16:09:25 +00:00
|
|
|
* The #GdkGLContext must not be realized or made current prior to calling
|
|
|
|
* this function.
|
2015-01-28 09:34:16 +00:00
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
gdk_gl_context_set_forward_compatible (GdkGLContext *context,
|
|
|
|
gboolean compatible)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
2015-02-09 16:08:43 +00:00
|
|
|
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
|
|
|
g_return_if_fail (!priv->realized);
|
|
|
|
|
2015-01-28 09:34:16 +00:00
|
|
|
compatible = !!compatible;
|
|
|
|
|
|
|
|
priv->forward_compatible = compatible;
|
|
|
|
}
|
|
|
|
|
2015-01-28 14:37:26 +00:00
|
|
|
/**
|
2015-01-28 09:34:16 +00:00
|
|
|
* 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
|
2015-01-28 14:37:26 +00:00
|
|
|
*
|
|
|
|
* Since: 3.16
|
2015-01-28 09:34:16 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gdk_gl_context_get_forward_compatible (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
2015-01-28 14:37:26 +00:00
|
|
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
|
|
|
|
|
2015-01-28 09:34:16 +00:00
|
|
|
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.
|
|
|
|
*
|
2015-02-09 16:09:25 +00:00
|
|
|
* The #GdkGLContext must not be realized or made current prior to calling
|
|
|
|
* this function.
|
2015-01-28 09:34:16 +00:00
|
|
|
*
|
|
|
|
* 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);
|
2016-04-18 09:10:30 +00:00
|
|
|
int version, min_ver;
|
2015-01-28 09:34:16 +00:00
|
|
|
|
|
|
|
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
|
|
|
g_return_if_fail (!priv->realized);
|
|
|
|
|
2015-02-10 10:16:53 +00:00
|
|
|
/* this will take care of the default */
|
|
|
|
if (major == 0 && minor == 0)
|
|
|
|
{
|
|
|
|
priv->major = 0;
|
|
|
|
priv->minor = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-02-11 04:35:01 +00:00
|
|
|
/* Enforce a minimum context version number of 3.2 */
|
|
|
|
version = (major * 100) + minor;
|
2016-04-18 09:10:30 +00:00
|
|
|
|
2016-10-22 01:37:53 +00:00
|
|
|
if (priv->use_es > 0 || (_gdk_gl_flags & GDK_GL_GLES) != 0)
|
2016-04-18 09:10:30 +00:00
|
|
|
min_ver = 200;
|
2016-04-22 16:27:04 +00:00
|
|
|
else
|
|
|
|
min_ver = 302;
|
2016-04-18 09:10:30 +00:00
|
|
|
|
|
|
|
if (version < min_ver)
|
2015-02-11 04:35:01 +00:00
|
|
|
{
|
|
|
|
g_warning ("gdk_gl_context_set_required_version - GL context versions less than 3.2 are not supported.");
|
2016-04-18 09:10:30 +00:00
|
|
|
version = min_ver;
|
2015-02-11 04:35:01 +00:00
|
|
|
}
|
|
|
|
priv->major = version / 100;
|
|
|
|
priv->minor = version % 100;
|
2015-01-28 09:34:16 +00:00
|
|
|
}
|
|
|
|
|
2015-01-28 14:37:26 +00:00
|
|
|
/**
|
2015-01-28 09:34:16 +00:00
|
|
|
* 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().
|
2015-01-28 14:37:26 +00:00
|
|
|
*
|
|
|
|
* Since: 3.16
|
2015-01-28 09:34:16 +00:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
gdk_gl_context_get_required_version (GdkGLContext *context,
|
|
|
|
int *major,
|
|
|
|
int *minor)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
2016-04-18 09:10:30 +00:00
|
|
|
int default_major, default_minor;
|
2015-02-09 16:10:22 +00:00
|
|
|
int maj, min;
|
2015-01-28 09:34:16 +00:00
|
|
|
|
2015-02-09 16:10:22 +00:00
|
|
|
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
|
|
|
|
2016-10-22 01:37:53 +00:00
|
|
|
if (priv->use_es > 0 || (_gdk_gl_flags & GDK_GL_GLES) != 0)
|
2016-04-18 09:10:30 +00:00
|
|
|
{
|
2016-04-22 16:27:04 +00:00
|
|
|
default_major = 2;
|
|
|
|
default_minor = 0;
|
2016-04-18 09:10:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-04-22 16:27:04 +00:00
|
|
|
default_major = 3;
|
|
|
|
default_minor = 2;
|
2016-04-18 09:10:30 +00:00
|
|
|
}
|
|
|
|
|
2015-02-09 16:10:22 +00:00
|
|
|
if (priv->major > 0)
|
|
|
|
maj = priv->major;
|
2015-01-28 09:34:16 +00:00
|
|
|
else
|
2016-04-18 09:10:30 +00:00
|
|
|
maj = default_major;
|
2015-01-28 09:34:16 +00:00
|
|
|
|
2015-02-09 16:10:22 +00:00
|
|
|
if (priv->minor > 0)
|
|
|
|
min = priv->minor;
|
2015-01-28 09:34:16 +00:00
|
|
|
else
|
2016-04-18 09:10:30 +00:00
|
|
|
min = default_minor;
|
2015-02-09 16:10:22 +00:00
|
|
|
|
|
|
|
if (major != NULL)
|
|
|
|
*major = maj;
|
|
|
|
if (minor != NULL)
|
|
|
|
*minor = min;
|
2015-01-28 09:34:16 +00:00
|
|
|
}
|
|
|
|
|
2015-10-06 17:54:58 +00:00
|
|
|
/**
|
|
|
|
* gdk_gl_context_is_legacy:
|
|
|
|
* @context: a #GdkGLContext
|
|
|
|
*
|
|
|
|
* Whether the #GdkGLContext is in legacy mode or not.
|
|
|
|
*
|
2015-10-07 07:50:23 +00:00
|
|
|
* The #GdkGLContext must be realized before calling this function.
|
|
|
|
*
|
|
|
|
* When realizing a GL context, GDK will try to use the OpenGL 3.2 core
|
|
|
|
* profile; this profile removes all the OpenGL API that was deprecated
|
|
|
|
* prior to the 3.2 version of the specification. If the realization is
|
|
|
|
* successful, this function will return %FALSE.
|
|
|
|
*
|
|
|
|
* If the underlying OpenGL implementation does not support core profiles,
|
|
|
|
* GDK will fall back to a pre-3.2 compatibility profile, and this function
|
|
|
|
* will return %TRUE.
|
|
|
|
*
|
|
|
|
* You can use the value returned by this function to decide which kind
|
|
|
|
* of OpenGL API to use, or whether to do extension discovery, or what
|
|
|
|
* kind of shader programs to load.
|
2015-10-06 17:54:58 +00:00
|
|
|
*
|
|
|
|
* Returns: %TRUE if the GL context is in legacy mode
|
|
|
|
*
|
|
|
|
* Since: 3.20
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gdk_gl_context_is_legacy (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
|
|
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
|
|
|
|
g_return_val_if_fail (priv->realized, FALSE);
|
|
|
|
|
|
|
|
return priv->is_legacy;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
|
|
|
gboolean is_legacy)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
|
|
|
priv->is_legacy = !!is_legacy;
|
|
|
|
}
|
|
|
|
|
2016-04-22 16:27:04 +00:00
|
|
|
/**
|
|
|
|
* gdk_gl_context_set_use_es:
|
|
|
|
* @context: a #GdkGLContext:
|
2016-10-19 12:43:17 +00:00
|
|
|
* @use_es: whether the context should use OpenGL ES instead of OpenGL,
|
|
|
|
* or -1 to allow auto-detection
|
2016-04-22 16:27:04 +00:00
|
|
|
*
|
2016-04-23 09:33:08 +00:00
|
|
|
* Requests that GDK create a OpenGL ES context instead of an OpenGL one,
|
|
|
|
* if the platform and windowing system allows it.
|
2016-04-22 16:27:04 +00:00
|
|
|
*
|
|
|
|
* The @context must not have been realized.
|
|
|
|
*
|
2016-10-19 12:43:17 +00:00
|
|
|
* By default, GDK will attempt to automatically detect whether the
|
|
|
|
* underlying GL implementation is OpenGL or OpenGL ES once the @context
|
|
|
|
* is realized.
|
|
|
|
*
|
2016-04-23 09:33:08 +00:00
|
|
|
* You should check the return value of gdk_gl_context_get_use_es() after
|
|
|
|
* calling gdk_gl_context_realize() to decide whether to use the OpenGL or
|
|
|
|
* OpenGL ES API, extensions, or shaders.
|
2016-04-22 16:27:04 +00:00
|
|
|
*
|
|
|
|
* Since: 3.22
|
|
|
|
*/
|
2016-04-18 09:10:30 +00:00
|
|
|
void
|
|
|
|
gdk_gl_context_set_use_es (GdkGLContext *context,
|
2016-10-19 12:43:17 +00:00
|
|
|
int use_es)
|
2016-04-18 09:10:30 +00:00
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
2016-04-22 16:27:04 +00:00
|
|
|
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
|
|
|
g_return_if_fail (!priv->realized);
|
|
|
|
|
2016-10-19 12:43:17 +00:00
|
|
|
if (priv->use_es != use_es)
|
|
|
|
priv->use_es = use_es;
|
2016-04-18 09:10:30 +00:00
|
|
|
}
|
|
|
|
|
2016-04-22 16:27:04 +00:00
|
|
|
/**
|
|
|
|
* gdk_gl_context_get_use_es:
|
|
|
|
* @context: a #GdkGLContext
|
|
|
|
*
|
|
|
|
* Checks whether the @context is using an OpenGL or OpenGL ES profile.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if the #GdkGLContext is using an OpenGL ES profile
|
|
|
|
*
|
|
|
|
* Since: 3.22
|
|
|
|
*/
|
2016-04-18 09:10:30 +00:00
|
|
|
gboolean
|
|
|
|
gdk_gl_context_get_use_es (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
2016-04-22 16:27:04 +00:00
|
|
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
|
|
|
|
|
2016-10-19 12:43:17 +00:00
|
|
|
if (!priv->realized)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return priv->use_es > 0;
|
2016-04-18 09:10:30 +00:00
|
|
|
}
|
|
|
|
|
GL: Split GL context creation in two phases
One of the major requests by OpenGL users has been the ability to
specify settings when creating a GL context, like the version to use
or whether the debug support should be enabled.
We have a couple of requirements in terms of API:
• avoid, if at all possible, the "C arrays of integers with
attribute, value pairs", which are hard to write and hard
to bind in non-C languages.
• allow failing in a recoverable way.
• do not make the GL context creation API a mess of arguments.
Looking at prior art, it seems that a common pattern is to split the
construction phase in two:
• a first phase that creates a GL context wrapper object and
does preliminary checks on the environment.
• a second phase that creates the backend-specific GL object.
We adopted a similar pattern:
• gdk_window_create_gl_context() creates a GdkGLContext
• gdk_gl_context_realize() creates the underlying resources
Calling gdk_gl_context_make_current() also realizes the context, so
simple GL users do not need to care. Advanced users will want to
call gdk_window_create_gl_context(), set up the optional requirements,
and then call gdk_gl_context_realize(). If either of these two steps
fails, it's possible to recover by changing the requirements, or simply
creating a new GdkGLContext instance.
https://bugzilla.gnome.org/show_bug.cgi?id=741946
2015-01-27 21:23:23 +00:00
|
|
|
/**
|
|
|
|
* gdk_gl_context_realize:
|
|
|
|
* @context: a #GdkGLContext
|
|
|
|
* @error: return location for a #GError
|
|
|
|
*
|
|
|
|
* Realizes the given #GdkGLContext.
|
|
|
|
*
|
|
|
|
* It is safe to call this function on a realized #GdkGLContext.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if the context is realized
|
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gdk_gl_context_realize (GdkGLContext *context,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
|
|
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
|
|
|
|
|
|
|
|
if (priv->realized)
|
2015-02-09 16:10:22 +00:00
|
|
|
return TRUE;
|
GL: Split GL context creation in two phases
One of the major requests by OpenGL users has been the ability to
specify settings when creating a GL context, like the version to use
or whether the debug support should be enabled.
We have a couple of requirements in terms of API:
• avoid, if at all possible, the "C arrays of integers with
attribute, value pairs", which are hard to write and hard
to bind in non-C languages.
• allow failing in a recoverable way.
• do not make the GL context creation API a mess of arguments.
Looking at prior art, it seems that a common pattern is to split the
construction phase in two:
• a first phase that creates a GL context wrapper object and
does preliminary checks on the environment.
• a second phase that creates the backend-specific GL object.
We adopted a similar pattern:
• gdk_window_create_gl_context() creates a GdkGLContext
• gdk_gl_context_realize() creates the underlying resources
Calling gdk_gl_context_make_current() also realizes the context, so
simple GL users do not need to care. Advanced users will want to
call gdk_window_create_gl_context(), set up the optional requirements,
and then call gdk_gl_context_realize(). If either of these two steps
fails, it's possible to recover by changing the requirements, or simply
creating a new GdkGLContext instance.
https://bugzilla.gnome.org/show_bug.cgi?id=741946
2015-01-27 21:23:23 +00:00
|
|
|
|
|
|
|
priv->realized = GDK_GL_CONTEXT_GET_CLASS (context)->realize (context, error);
|
|
|
|
|
|
|
|
return priv->realized;
|
|
|
|
}
|
|
|
|
|
2014-10-27 20:12:40 +00:00
|
|
|
static void
|
GL: Split GL context creation in two phases
One of the major requests by OpenGL users has been the ability to
specify settings when creating a GL context, like the version to use
or whether the debug support should be enabled.
We have a couple of requirements in terms of API:
• avoid, if at all possible, the "C arrays of integers with
attribute, value pairs", which are hard to write and hard
to bind in non-C languages.
• allow failing in a recoverable way.
• do not make the GL context creation API a mess of arguments.
Looking at prior art, it seems that a common pattern is to split the
construction phase in two:
• a first phase that creates a GL context wrapper object and
does preliminary checks on the environment.
• a second phase that creates the backend-specific GL object.
We adopted a similar pattern:
• gdk_window_create_gl_context() creates a GdkGLContext
• gdk_gl_context_realize() creates the underlying resources
Calling gdk_gl_context_make_current() also realizes the context, so
simple GL users do not need to care. Advanced users will want to
call gdk_window_create_gl_context(), set up the optional requirements,
and then call gdk_gl_context_realize(). If either of these two steps
fails, it's possible to recover by changing the requirements, or simply
creating a new GdkGLContext instance.
https://bugzilla.gnome.org/show_bug.cgi?id=741946
2015-01-27 21:23:23 +00:00
|
|
|
gdk_gl_context_check_extensions (GdkGLContext *context)
|
2014-10-27 20:12:40 +00:00
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
gboolean has_npot, has_texture_rectangle;
|
|
|
|
|
GL: Split GL context creation in two phases
One of the major requests by OpenGL users has been the ability to
specify settings when creating a GL context, like the version to use
or whether the debug support should be enabled.
We have a couple of requirements in terms of API:
• avoid, if at all possible, the "C arrays of integers with
attribute, value pairs", which are hard to write and hard
to bind in non-C languages.
• allow failing in a recoverable way.
• do not make the GL context creation API a mess of arguments.
Looking at prior art, it seems that a common pattern is to split the
construction phase in two:
• a first phase that creates a GL context wrapper object and
does preliminary checks on the environment.
• a second phase that creates the backend-specific GL object.
We adopted a similar pattern:
• gdk_window_create_gl_context() creates a GdkGLContext
• gdk_gl_context_realize() creates the underlying resources
Calling gdk_gl_context_make_current() also realizes the context, so
simple GL users do not need to care. Advanced users will want to
call gdk_window_create_gl_context(), set up the optional requirements,
and then call gdk_gl_context_realize(). If either of these two steps
fails, it's possible to recover by changing the requirements, or simply
creating a new GdkGLContext instance.
https://bugzilla.gnome.org/show_bug.cgi?id=741946
2015-01-27 21:23:23 +00:00
|
|
|
if (!priv->realized)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (priv->extensions_checked)
|
|
|
|
return;
|
|
|
|
|
2015-02-12 14:28:22 +00:00
|
|
|
priv->gl_version = epoxy_gl_version ();
|
|
|
|
|
2016-10-19 12:43:17 +00:00
|
|
|
if (priv->use_es < 0)
|
|
|
|
priv->use_es = !epoxy_is_desktop_gl ();
|
|
|
|
|
2016-04-22 16:27:04 +00:00
|
|
|
if (priv->use_es)
|
|
|
|
{
|
|
|
|
has_npot = priv->gl_version >= 20;
|
|
|
|
has_texture_rectangle = FALSE;
|
|
|
|
|
Add a EGL renderer (via ANGLE) for Windows
This is for adding a EGL-based renderer which is done via the ANGLE
project, which translate EGL calls to Direct3D 9/11. This is done as a
possible solution to issue #105, especially for cases where the needed
full GL extensions to map OpenGL to Direc3D is unavailable or
unreliable, or when the OpenGL implementation from the graphics drivers
are problematic.
To enable this, do the following:
-Build ANGLE and ensure the ANGLE libEGL.dll and libGLESv2.dll are
available. A sufficiently-recent ANGLE is needed for things to
work correctly--note that the copy of ANGLE that is included in
qtbase-5.10.1 is sufficient. ANGLE is licensed under a BSD 3-clause
license. Note also that Visual Studio 2013 or later is required to
build ANGLE from QT-5.10.1, but the 2013-built ANGLE DLLs can work
without without problems for GTK+ that is built with Visual Studio
2008 or later.
-Build libepoxy on Windows with EGL support enabled.
-Define GDK_WIN32_ENABLE_EGL when building gdk-win32.lib when building
with Visual Studio, or pass in --enable-win32-gles during configure
when building with MinGW/mingw-w64.
-Prior to running GTK+ programs, the GDK_GL envvar needs to contain
gles.
Known issues:
-Only OpenGL ES 3 is supported, ANGLE's ES 2 does not support the needed
extensions, notably GL_OES_vertex_array_object, but its ES 3 support is
sufficient.
-There is no autodetection or fallback mechanism to enable using
EGL/Angle automatically yet. There is no plans to do this in this
commit.
Thanks to LRN for pointing out that we should #include
"win32/gdkwin32.h" instead of #include "gdkwin32.h" for gdkgl.c. LRN
also did the autotools portion of this patch.
Further notes about the autotools --enable-win32-gles option, fom LRN:
This adds --enable-win32-gles option, which enables the
code for GLES renderer. This commit also adds tests for WGL and
EGL in epoxy. The absence of WGL is highly unlikely (it's enabled
by default), but checking for EGL when GLES is enabled is necessary,
as EGL is disabled in Windows builds of epoxy by default.
2018-04-27 15:30:32 +00:00
|
|
|
/* This should check for GL_NV_framebuffer_blit as well - see extension at:
|
2016-04-22 16:27:04 +00:00
|
|
|
*
|
|
|
|
* https://www.khronos.org/registry/gles/extensions/NV/NV_framebuffer_blit.txt
|
Add a EGL renderer (via ANGLE) for Windows
This is for adding a EGL-based renderer which is done via the ANGLE
project, which translate EGL calls to Direct3D 9/11. This is done as a
possible solution to issue #105, especially for cases where the needed
full GL extensions to map OpenGL to Direc3D is unavailable or
unreliable, or when the OpenGL implementation from the graphics drivers
are problematic.
To enable this, do the following:
-Build ANGLE and ensure the ANGLE libEGL.dll and libGLESv2.dll are
available. A sufficiently-recent ANGLE is needed for things to
work correctly--note that the copy of ANGLE that is included in
qtbase-5.10.1 is sufficient. ANGLE is licensed under a BSD 3-clause
license. Note also that Visual Studio 2013 or later is required to
build ANGLE from QT-5.10.1, but the 2013-built ANGLE DLLs can work
without without problems for GTK+ that is built with Visual Studio
2008 or later.
-Build libepoxy on Windows with EGL support enabled.
-Define GDK_WIN32_ENABLE_EGL when building gdk-win32.lib when building
with Visual Studio, or pass in --enable-win32-gles during configure
when building with MinGW/mingw-w64.
-Prior to running GTK+ programs, the GDK_GL envvar needs to contain
gles.
Known issues:
-Only OpenGL ES 3 is supported, ANGLE's ES 2 does not support the needed
extensions, notably GL_OES_vertex_array_object, but its ES 3 support is
sufficient.
-There is no autodetection or fallback mechanism to enable using
EGL/Angle automatically yet. There is no plans to do this in this
commit.
Thanks to LRN for pointing out that we should #include
"win32/gdkwin32.h" instead of #include "gdkwin32.h" for gdkgl.c. LRN
also did the autotools portion of this patch.
Further notes about the autotools --enable-win32-gles option, fom LRN:
This adds --enable-win32-gles option, which enables the
code for GLES renderer. This commit also adds tests for WGL and
EGL in epoxy. The absence of WGL is highly unlikely (it's enabled
by default), but checking for EGL when GLES is enabled is necessary,
as EGL is disabled in Windows builds of epoxy by default.
2018-04-27 15:30:32 +00:00
|
|
|
*
|
|
|
|
* for ANGLE, we can enable bit blitting if we have the
|
|
|
|
* GL_ANGLE_framebuffer_blit extension
|
2016-04-22 16:27:04 +00:00
|
|
|
*/
|
Add a EGL renderer (via ANGLE) for Windows
This is for adding a EGL-based renderer which is done via the ANGLE
project, which translate EGL calls to Direct3D 9/11. This is done as a
possible solution to issue #105, especially for cases where the needed
full GL extensions to map OpenGL to Direc3D is unavailable or
unreliable, or when the OpenGL implementation from the graphics drivers
are problematic.
To enable this, do the following:
-Build ANGLE and ensure the ANGLE libEGL.dll and libGLESv2.dll are
available. A sufficiently-recent ANGLE is needed for things to
work correctly--note that the copy of ANGLE that is included in
qtbase-5.10.1 is sufficient. ANGLE is licensed under a BSD 3-clause
license. Note also that Visual Studio 2013 or later is required to
build ANGLE from QT-5.10.1, but the 2013-built ANGLE DLLs can work
without without problems for GTK+ that is built with Visual Studio
2008 or later.
-Build libepoxy on Windows with EGL support enabled.
-Define GDK_WIN32_ENABLE_EGL when building gdk-win32.lib when building
with Visual Studio, or pass in --enable-win32-gles during configure
when building with MinGW/mingw-w64.
-Prior to running GTK+ programs, the GDK_GL envvar needs to contain
gles.
Known issues:
-Only OpenGL ES 3 is supported, ANGLE's ES 2 does not support the needed
extensions, notably GL_OES_vertex_array_object, but its ES 3 support is
sufficient.
-There is no autodetection or fallback mechanism to enable using
EGL/Angle automatically yet. There is no plans to do this in this
commit.
Thanks to LRN for pointing out that we should #include
"win32/gdkwin32.h" instead of #include "gdkwin32.h" for gdkgl.c. LRN
also did the autotools portion of this patch.
Further notes about the autotools --enable-win32-gles option, fom LRN:
This adds --enable-win32-gles option, which enables the
code for GLES renderer. This commit also adds tests for WGL and
EGL in epoxy. The absence of WGL is highly unlikely (it's enabled
by default), but checking for EGL when GLES is enabled is necessary,
as EGL is disabled in Windows builds of epoxy by default.
2018-04-27 15:30:32 +00:00
|
|
|
if (epoxy_has_gl_extension ("GL_ANGLE_framebuffer_blit"))
|
|
|
|
priv->has_gl_framebuffer_blit = TRUE;
|
|
|
|
else
|
|
|
|
priv->has_gl_framebuffer_blit = FALSE;
|
2014-10-27 20:12:40 +00:00
|
|
|
|
2016-04-22 16:27:04 +00:00
|
|
|
/* No OES version */
|
|
|
|
priv->has_frame_terminator = FALSE;
|
|
|
|
|
|
|
|
priv->has_unpack_subimage = epoxy_has_gl_extension ("GL_EXT_unpack_subimage");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-02-12 19:52:24 +00:00
|
|
|
has_npot = priv->gl_version >= 20 || epoxy_has_gl_extension ("GL_ARB_texture_non_power_of_two");
|
|
|
|
has_texture_rectangle = priv->gl_version >= 31 || epoxy_has_gl_extension ("GL_ARB_texture_rectangle");
|
2016-04-22 16:27:04 +00:00
|
|
|
|
2020-02-12 19:52:24 +00:00
|
|
|
priv->has_gl_framebuffer_blit = priv->gl_version >= 30 || epoxy_has_gl_extension ("GL_EXT_framebuffer_blit");
|
2016-04-22 16:27:04 +00:00
|
|
|
priv->has_frame_terminator = epoxy_has_gl_extension ("GL_GREMEDY_frame_terminator");
|
|
|
|
priv->has_unpack_subimage = TRUE;
|
2016-10-21 20:21:39 +00:00
|
|
|
|
|
|
|
/* We asked for a core profile, but we didn't get one, so we're in legacy mode */
|
|
|
|
if (priv->gl_version < 32)
|
|
|
|
priv->is_legacy = TRUE;
|
2016-04-22 16:27:04 +00:00
|
|
|
}
|
2014-11-06 11:13:08 +00:00
|
|
|
|
2016-04-22 16:27:04 +00:00
|
|
|
if (!priv->use_es && G_UNLIKELY (_gdk_gl_flags & GDK_GL_TEXTURE_RECTANGLE))
|
2014-11-06 10:29:51 +00:00
|
|
|
priv->use_texture_rectangle = TRUE;
|
|
|
|
else if (has_npot)
|
2014-10-27 20:12:40 +00:00
|
|
|
priv->use_texture_rectangle = FALSE;
|
|
|
|
else if (has_texture_rectangle)
|
|
|
|
priv->use_texture_rectangle = TRUE;
|
|
|
|
else
|
2014-11-07 04:29:16 +00:00
|
|
|
g_warning ("GL implementation doesn't support any form of non-power-of-two textures");
|
2014-10-27 20:12:40 +00:00
|
|
|
|
2015-02-05 16:23:04 +00:00
|
|
|
GDK_NOTE (OPENGL,
|
2016-10-21 20:21:39 +00:00
|
|
|
g_message ("%s version: %d.%d (%s)\n"
|
|
|
|
"* GLSL version: %s\n"
|
2016-04-22 16:27:04 +00:00
|
|
|
"* Extensions checked:\n"
|
2016-02-28 20:39:05 +00:00
|
|
|
" - GL_ARB_texture_non_power_of_two: %s\n"
|
|
|
|
" - GL_ARB_texture_rectangle: %s\n"
|
|
|
|
" - GL_EXT_framebuffer_blit: %s\n"
|
|
|
|
" - GL_GREMEDY_frame_terminator: %s\n"
|
2016-04-22 16:27:04 +00:00
|
|
|
"* Using texture rectangle: %s",
|
|
|
|
priv->use_es ? "OpenGL ES" : "OpenGL",
|
2016-02-28 20:39:05 +00:00
|
|
|
priv->gl_version / 10, priv->gl_version % 10,
|
2016-10-21 20:21:39 +00:00
|
|
|
priv->is_legacy ? "legacy" : "core",
|
|
|
|
glGetString (GL_SHADING_LANGUAGE_VERSION),
|
2016-02-28 20:39:05 +00:00
|
|
|
has_npot ? "yes" : "no",
|
|
|
|
has_texture_rectangle ? "yes" : "no",
|
|
|
|
priv->has_gl_framebuffer_blit ? "yes" : "no",
|
|
|
|
priv->has_frame_terminator ? "yes" : "no",
|
|
|
|
priv->use_texture_rectangle ? "yes" : "no"));
|
2015-02-05 16:23:04 +00:00
|
|
|
|
GL: Split GL context creation in two phases
One of the major requests by OpenGL users has been the ability to
specify settings when creating a GL context, like the version to use
or whether the debug support should be enabled.
We have a couple of requirements in terms of API:
• avoid, if at all possible, the "C arrays of integers with
attribute, value pairs", which are hard to write and hard
to bind in non-C languages.
• allow failing in a recoverable way.
• do not make the GL context creation API a mess of arguments.
Looking at prior art, it seems that a common pattern is to split the
construction phase in two:
• a first phase that creates a GL context wrapper object and
does preliminary checks on the environment.
• a second phase that creates the backend-specific GL object.
We adopted a similar pattern:
• gdk_window_create_gl_context() creates a GdkGLContext
• gdk_gl_context_realize() creates the underlying resources
Calling gdk_gl_context_make_current() also realizes the context, so
simple GL users do not need to care. Advanced users will want to
call gdk_window_create_gl_context(), set up the optional requirements,
and then call gdk_gl_context_realize(). If either of these two steps
fails, it's possible to recover by changing the requirements, or simply
creating a new GdkGLContext instance.
https://bugzilla.gnome.org/show_bug.cgi?id=741946
2015-01-27 21:23:23 +00:00
|
|
|
priv->extensions_checked = TRUE;
|
2014-10-27 20:12:40 +00:00
|
|
|
}
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
/**
|
|
|
|
* gdk_gl_context_make_current:
|
|
|
|
* @context: a #GdkGLContext
|
|
|
|
*
|
|
|
|
* Makes the @context the current one.
|
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
2014-10-09 15:24:21 +00:00
|
|
|
void
|
2014-10-09 08:45:44 +00:00
|
|
|
gdk_gl_context_make_current (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
2014-10-30 10:46:09 +00:00
|
|
|
GdkGLContext *current;
|
2014-10-09 08:45:44 +00:00
|
|
|
|
2014-10-09 15:24:21 +00:00
|
|
|
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
2014-10-09 08:45:44 +00:00
|
|
|
|
2014-10-30 10:46:09 +00:00
|
|
|
current = g_private_get (&thread_current_context);
|
|
|
|
if (current == context)
|
|
|
|
return;
|
2014-10-27 20:12:40 +00:00
|
|
|
|
GL: Split GL context creation in two phases
One of the major requests by OpenGL users has been the ability to
specify settings when creating a GL context, like the version to use
or whether the debug support should be enabled.
We have a couple of requirements in terms of API:
• avoid, if at all possible, the "C arrays of integers with
attribute, value pairs", which are hard to write and hard
to bind in non-C languages.
• allow failing in a recoverable way.
• do not make the GL context creation API a mess of arguments.
Looking at prior art, it seems that a common pattern is to split the
construction phase in two:
• a first phase that creates a GL context wrapper object and
does preliminary checks on the environment.
• a second phase that creates the backend-specific GL object.
We adopted a similar pattern:
• gdk_window_create_gl_context() creates a GdkGLContext
• gdk_gl_context_realize() creates the underlying resources
Calling gdk_gl_context_make_current() also realizes the context, so
simple GL users do not need to care. Advanced users will want to
call gdk_window_create_gl_context(), set up the optional requirements,
and then call gdk_gl_context_realize(). If either of these two steps
fails, it's possible to recover by changing the requirements, or simply
creating a new GdkGLContext instance.
https://bugzilla.gnome.org/show_bug.cgi?id=741946
2015-01-27 21:23:23 +00:00
|
|
|
/* we need to realize the GdkGLContext if it wasn't explicitly realized */
|
|
|
|
if (!priv->realized)
|
|
|
|
{
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
gdk_gl_context_realize (context, &error);
|
|
|
|
if (error != NULL)
|
|
|
|
{
|
|
|
|
g_critical ("Could not realize the GL context: %s", error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-03 12:20:55 +00:00
|
|
|
if (gdk_display_make_gl_context_current (priv->display, context))
|
2014-10-30 10:46:09 +00:00
|
|
|
{
|
|
|
|
g_private_replace (&thread_current_context, g_object_ref (context));
|
GL: Split GL context creation in two phases
One of the major requests by OpenGL users has been the ability to
specify settings when creating a GL context, like the version to use
or whether the debug support should be enabled.
We have a couple of requirements in terms of API:
• avoid, if at all possible, the "C arrays of integers with
attribute, value pairs", which are hard to write and hard
to bind in non-C languages.
• allow failing in a recoverable way.
• do not make the GL context creation API a mess of arguments.
Looking at prior art, it seems that a common pattern is to split the
construction phase in two:
• a first phase that creates a GL context wrapper object and
does preliminary checks on the environment.
• a second phase that creates the backend-specific GL object.
We adopted a similar pattern:
• gdk_window_create_gl_context() creates a GdkGLContext
• gdk_gl_context_realize() creates the underlying resources
Calling gdk_gl_context_make_current() also realizes the context, so
simple GL users do not need to care. Advanced users will want to
call gdk_window_create_gl_context(), set up the optional requirements,
and then call gdk_gl_context_realize(). If either of these two steps
fails, it's possible to recover by changing the requirements, or simply
creating a new GdkGLContext instance.
https://bugzilla.gnome.org/show_bug.cgi?id=741946
2015-01-27 21:23:23 +00:00
|
|
|
gdk_gl_context_check_extensions (context);
|
2014-10-30 10:46:09 +00:00
|
|
|
}
|
2014-10-09 08:45:44 +00:00
|
|
|
}
|
|
|
|
|
2014-11-03 12:20:55 +00:00
|
|
|
/**
|
|
|
|
* gdk_gl_context_get_display:
|
|
|
|
* @context: a #GdkGLContext
|
|
|
|
*
|
|
|
|
* Retrieves the #GdkDisplay the @context is created for
|
|
|
|
*
|
2016-09-22 11:56:47 +00:00
|
|
|
* Returns: (nullable) (transfer none): a #GdkDisplay or %NULL
|
2014-11-03 12:20:55 +00:00
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
GdkDisplay *
|
|
|
|
gdk_gl_context_get_display (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
|
|
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
|
|
|
|
|
|
|
|
return priv->display;
|
|
|
|
}
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
/**
|
|
|
|
* gdk_gl_context_get_window:
|
|
|
|
* @context: a #GdkGLContext
|
|
|
|
*
|
|
|
|
* Retrieves the #GdkWindow used by the @context.
|
|
|
|
*
|
2016-09-22 11:56:47 +00:00
|
|
|
* Returns: (nullable) (transfer none): a #GdkWindow or %NULL
|
2014-10-09 08:45:44 +00:00
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
GdkWindow *
|
|
|
|
gdk_gl_context_get_window (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
|
|
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
|
|
|
|
|
|
|
|
return priv->window;
|
|
|
|
}
|
|
|
|
|
2014-10-30 11:04:23 +00:00
|
|
|
/**
|
|
|
|
* gdk_gl_context_get_shared_context:
|
|
|
|
* @context: a #GdkGLContext
|
|
|
|
*
|
|
|
|
* Retrieves the #GdkGLContext that this @context share data with.
|
|
|
|
*
|
2016-09-22 11:56:47 +00:00
|
|
|
* Returns: (nullable) (transfer none): a #GdkGLContext or %NULL
|
2014-10-30 11:04:23 +00:00
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
GdkGLContext *
|
|
|
|
gdk_gl_context_get_shared_context (GdkGLContext *context)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
|
|
|
|
|
|
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
|
|
|
|
|
|
|
|
return priv->shared_context;
|
|
|
|
}
|
|
|
|
|
2015-02-12 14:28:22 +00:00
|
|
|
/**
|
|
|
|
* gdk_gl_context_get_version:
|
|
|
|
* @context: a #GdkGLContext
|
|
|
|
* @major: (out): return location for the major version
|
|
|
|
* @minor: (out): return location for the minor version
|
|
|
|
*
|
|
|
|
* Retrieves the OpenGL version of the @context.
|
|
|
|
*
|
|
|
|
* The @context must be realized prior to calling this function.
|
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
gdk_gl_context_get_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);
|
|
|
|
|
|
|
|
if (major != NULL)
|
|
|
|
*major = priv->gl_version / 10;
|
|
|
|
if (minor != NULL)
|
|
|
|
*minor = priv->gl_version % 10;
|
|
|
|
}
|
|
|
|
|
2014-10-09 08:45:44 +00:00
|
|
|
/**
|
|
|
|
* gdk_gl_context_clear_current:
|
|
|
|
*
|
|
|
|
* Clears the current #GdkGLContext.
|
|
|
|
*
|
|
|
|
* Any OpenGL call after this function returns will be ignored
|
|
|
|
* until gdk_gl_context_make_current() is called.
|
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
gdk_gl_context_clear_current (void)
|
|
|
|
{
|
2014-10-30 10:46:09 +00:00
|
|
|
GdkGLContext *current;
|
2014-10-09 08:45:44 +00:00
|
|
|
|
2014-10-30 10:46:09 +00:00
|
|
|
current = g_private_get (&thread_current_context);
|
|
|
|
if (current != NULL)
|
|
|
|
{
|
|
|
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (current);
|
|
|
|
|
2014-11-03 12:20:55 +00:00
|
|
|
if (gdk_display_make_gl_context_current (priv->display, NULL))
|
2014-10-30 10:46:09 +00:00
|
|
|
g_private_replace (&thread_current_context, NULL);
|
|
|
|
}
|
2014-10-09 08:45:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gdk_gl_context_get_current:
|
|
|
|
*
|
|
|
|
* Retrieves the current #GdkGLContext.
|
|
|
|
*
|
2016-09-22 11:56:47 +00:00
|
|
|
* Returns: (nullable) (transfer none): the current #GdkGLContext, or %NULL
|
2014-10-09 08:45:44 +00:00
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
GdkGLContext *
|
|
|
|
gdk_gl_context_get_current (void)
|
|
|
|
{
|
2014-10-30 10:46:09 +00:00
|
|
|
GdkGLContext *current;
|
|
|
|
|
|
|
|
current = g_private_get (&thread_current_context);
|
2014-10-09 08:45:44 +00:00
|
|
|
|
2014-10-30 10:46:09 +00:00
|
|
|
return current;
|
2014-10-09 08:45:44 +00:00
|
|
|
}
|
2014-11-07 04:29:16 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* gdk_gl_get_flags:
|
|
|
|
*
|
|
|
|
* Returns the currently active GL flags.
|
|
|
|
*
|
|
|
|
* Returns: the GL flags
|
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
GdkGLFlags
|
|
|
|
gdk_gl_get_flags (void)
|
|
|
|
{
|
|
|
|
return _gdk_gl_flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gdk_gl_set_flags:
|
|
|
|
* @flags: #GdkGLFlags to set
|
|
|
|
*
|
|
|
|
* Sets GL flags.
|
|
|
|
*
|
|
|
|
* Since: 3.16
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
gdk_gl_set_flags (GdkGLFlags flags)
|
|
|
|
{
|
|
|
|
_gdk_gl_flags = flags;
|
|
|
|
}
|