gl: Make all user GdkGLContexts not attached to any window
We make user facing gl contexts not attached to a surface if possible, or attached to dummy surfaces. This means nothing can accidentally read/write to the toplevel back buffer.
This commit is contained in:

committed by
Matthias Clasen

parent
62a26eb3c8
commit
236d08c3c5
@ -27,15 +27,15 @@
|
|||||||
* OpenGL drawing context.
|
* OpenGL drawing context.
|
||||||
*
|
*
|
||||||
* #GdkGLContexts are created for a #GdkWindow using gdk_window_create_gl_context(), and
|
* #GdkGLContexts are created for a #GdkWindow using gdk_window_create_gl_context(), and
|
||||||
* the context will be tied to the native window backing that window, matching the
|
* the context will match the GdkVisual of the window.
|
||||||
* GdkVisual of the window.
|
|
||||||
*
|
*
|
||||||
* A #GdkGLContexts normal framebuffer draws directly on to the back buffer of the native
|
* A #GdkGLContexts is not tied to any particulare normal
|
||||||
* window backing the #GdkWindow, so its not allowed to draw directly to that, as the
|
* framebuffer. For instance, it cannot draw to the #GdkWindow back
|
||||||
* gdk repaint system is in full control of that. Instead you can create render buffers
|
* buffer. The gdk repaint system is in full control of the painting
|
||||||
* or textures and use gdk_cairo_draw_from_gl() in the draw function of your widget
|
* to that. Instead you can create render buffers or textures and use
|
||||||
* to draw them. Then Gdk will handle the integration of your rendering with that of
|
* gdk_cairo_draw_from_gl() in the draw function of your widget to
|
||||||
* other widgets.
|
* draw them. Then Gdk will handle the integration of your rendering
|
||||||
|
* with that of other widgets.
|
||||||
*
|
*
|
||||||
* Support for #GdkGLContext is platform specific, context creation can fail, returning
|
* Support for #GdkGLContext is platform specific, context creation can fail, returning
|
||||||
* a %NULL context.
|
* a %NULL context.
|
||||||
|
@ -2725,6 +2725,7 @@ gdk_window_get_paint_gl_context (GdkWindow *window, GError **error)
|
|||||||
if (window->impl_window->gl_paint_context == NULL)
|
if (window->impl_window->gl_paint_context == NULL)
|
||||||
window->impl_window->gl_paint_context =
|
window->impl_window->gl_paint_context =
|
||||||
GDK_WINDOW_IMPL_GET_CLASS (window->impl)->create_gl_context (window,
|
GDK_WINDOW_IMPL_GET_CLASS (window->impl)->create_gl_context (window,
|
||||||
|
TRUE,
|
||||||
GDK_GL_PROFILE_DEFAULT,
|
GDK_GL_PROFILE_DEFAULT,
|
||||||
NULL,
|
NULL,
|
||||||
error);
|
error);
|
||||||
@ -2738,8 +2739,9 @@ gdk_window_get_paint_gl_context (GdkWindow *window, GError **error)
|
|||||||
* @profile: the GL profile the context should target
|
* @profile: the GL profile the context should target
|
||||||
* @error: return location for an error
|
* @error: return location for an error
|
||||||
*
|
*
|
||||||
* Creates a new #GdkGLContext for the given window, matching the
|
* Creates a new #GdkGLContext matching the
|
||||||
* framebuffer format to the visual of the #GdkWindow.
|
* framebuffer format to the visual of the #GdkWindow. The context
|
||||||
|
* is disconnected from any particular window or surface.
|
||||||
*
|
*
|
||||||
* If the creation of the #GdkGLContext failed, @error will be set.
|
* If the creation of the #GdkGLContext failed, @error will be set.
|
||||||
*
|
*
|
||||||
@ -2763,6 +2765,7 @@ gdk_window_create_gl_context (GdkWindow *window,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->create_gl_context (window,
|
return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->create_gl_context (window,
|
||||||
|
FALSE,
|
||||||
profile,
|
profile,
|
||||||
paint_context,
|
paint_context,
|
||||||
error);
|
error);
|
||||||
|
@ -290,6 +290,7 @@ struct _GdkWindowImplClass
|
|||||||
gboolean (* show_window_menu) (GdkWindow *window,
|
gboolean (* show_window_menu) (GdkWindow *window,
|
||||||
GdkEvent *event);
|
GdkEvent *event);
|
||||||
GdkGLContext *(*create_gl_context) (GdkWindow *window,
|
GdkGLContext *(*create_gl_context) (GdkWindow *window,
|
||||||
|
gboolean attached,
|
||||||
GdkGLProfile profile,
|
GdkGLProfile profile,
|
||||||
GdkGLContext *share,
|
GdkGLContext *share,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
@ -89,6 +89,7 @@ struct _GdkWaylandDisplay
|
|||||||
guint have_egl_khr_create_context : 1;
|
guint have_egl_khr_create_context : 1;
|
||||||
guint have_egl_buffer_age : 1;
|
guint have_egl_buffer_age : 1;
|
||||||
guint have_egl_swap_buffers_with_damage : 1;
|
guint have_egl_swap_buffers_with_damage : 1;
|
||||||
|
guint have_egl_surfaceless_context : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkWaylandDisplayClass
|
struct _GdkWaylandDisplayClass
|
||||||
|
@ -76,7 +76,8 @@ gdk_wayland_window_invalidate_for_new_frame (GdkWindow *window,
|
|||||||
egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window,
|
egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window,
|
||||||
context_wayland->egl_config);
|
context_wayland->egl_config);
|
||||||
|
|
||||||
if (display_wayland->have_egl_buffer_age)
|
if (display_wayland->have_egl_buffer_age &&
|
||||||
|
gdk_gl_context_make_current (window->gl_paint_context))
|
||||||
eglQuerySurface (display_wayland->egl_display, egl_surface,
|
eglQuerySurface (display_wayland->egl_display, egl_surface,
|
||||||
EGL_BUFFER_AGE_EXT, &buffer_age);
|
EGL_BUFFER_AGE_EXT, &buffer_age);
|
||||||
|
|
||||||
@ -203,6 +204,9 @@ gdk_wayland_display_init_gl (GdkDisplay *display)
|
|||||||
display_wayland->have_egl_swap_buffers_with_damage =
|
display_wayland->have_egl_swap_buffers_with_damage =
|
||||||
epoxy_has_egl_extension (dpy, "EGL_EXT_swap_buffers_with_damage");
|
epoxy_has_egl_extension (dpy, "EGL_EXT_swap_buffers_with_damage");
|
||||||
|
|
||||||
|
display_wayland->have_egl_surfaceless_context =
|
||||||
|
epoxy_has_egl_extension (dpy, "EGL_KHR_surfaceless_context");
|
||||||
|
|
||||||
GDK_NOTE (OPENGL,
|
GDK_NOTE (OPENGL,
|
||||||
g_print ("EGL API version %d.%d found\n"
|
g_print ("EGL API version %d.%d found\n"
|
||||||
" - Vendor: %s\n"
|
" - Vendor: %s\n"
|
||||||
@ -297,6 +301,7 @@ find_eglconfig_for_window (GdkWindow *window,
|
|||||||
|
|
||||||
GdkGLContext *
|
GdkGLContext *
|
||||||
gdk_wayland_window_create_gl_context (GdkWindow *window,
|
gdk_wayland_window_create_gl_context (GdkWindow *window,
|
||||||
|
gboolean attached,
|
||||||
GdkGLProfile profile,
|
GdkGLProfile profile,
|
||||||
GdkGLContext *share,
|
GdkGLContext *share,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -359,6 +364,7 @@ gdk_wayland_window_create_gl_context (GdkWindow *window,
|
|||||||
|
|
||||||
context->egl_config = config;
|
context->egl_config = config;
|
||||||
context->egl_context = ctx;
|
context->egl_context = ctx;
|
||||||
|
context->is_attached = attached;
|
||||||
|
|
||||||
return GDK_GL_CONTEXT (context);
|
return GDK_GL_CONTEXT (context);
|
||||||
}
|
}
|
||||||
@ -404,7 +410,16 @@ gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
|
|||||||
context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
|
context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
|
||||||
window = gdk_gl_context_get_window (context);
|
window = gdk_gl_context_get_window (context);
|
||||||
|
|
||||||
egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window, context_wayland->egl_config);
|
if (context_wayland->is_attached)
|
||||||
|
egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window, context_wayland->egl_config);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (display_wayland->have_egl_surfaceless_context)
|
||||||
|
egl_surface = EGL_NO_SURFACE;
|
||||||
|
else
|
||||||
|
egl_surface = gdk_wayland_window_get_dummy_egl_surface (window->impl_window,
|
||||||
|
context_wayland->egl_config);
|
||||||
|
}
|
||||||
|
|
||||||
if (!eglMakeCurrent(display_wayland->egl_display, egl_surface,
|
if (!eglMakeCurrent(display_wayland->egl_display, egl_surface,
|
||||||
egl_surface, context_wayland->egl_context))
|
egl_surface, context_wayland->egl_context))
|
||||||
|
@ -39,6 +39,7 @@ struct _GdkWaylandGLContext
|
|||||||
|
|
||||||
EGLContext egl_context;
|
EGLContext egl_context;
|
||||||
EGLConfig egl_config;
|
EGLConfig egl_config;
|
||||||
|
gboolean is_attached;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkWaylandGLContextClass
|
struct _GdkWaylandGLContextClass
|
||||||
@ -48,6 +49,7 @@ struct _GdkWaylandGLContextClass
|
|||||||
|
|
||||||
gboolean gdk_wayland_display_init_gl (GdkDisplay *display);
|
gboolean gdk_wayland_display_init_gl (GdkDisplay *display);
|
||||||
GdkGLContext * gdk_wayland_window_create_gl_context (GdkWindow *window,
|
GdkGLContext * gdk_wayland_window_create_gl_context (GdkWindow *window,
|
||||||
|
gboolean attach,
|
||||||
GdkGLProfile profile,
|
GdkGLProfile profile,
|
||||||
GdkGLContext *share,
|
GdkGLContext *share,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
@ -239,5 +239,7 @@ void gdk_wayland_selection_unset_data_source (GdkAtom selection);
|
|||||||
|
|
||||||
EGLSurface gdk_wayland_window_get_egl_surface (GdkWindow *window,
|
EGLSurface gdk_wayland_window_get_egl_surface (GdkWindow *window,
|
||||||
EGLConfig config);
|
EGLConfig config);
|
||||||
|
EGLSurface gdk_wayland_window_get_dummy_egl_surface (GdkWindow *window,
|
||||||
|
EGLConfig config);
|
||||||
|
|
||||||
#endif /* __GDK_PRIVATE_WAYLAND_H__ */
|
#endif /* __GDK_PRIVATE_WAYLAND_H__ */
|
||||||
|
@ -101,6 +101,9 @@ struct _GdkWindowImplWayland
|
|||||||
struct wl_egl_window *egl_window;
|
struct wl_egl_window *egl_window;
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
|
|
||||||
|
struct wl_egl_window *dummy_egl_window;
|
||||||
|
EGLSurface dummy_egl_surface;
|
||||||
|
|
||||||
unsigned int mapped : 1;
|
unsigned int mapped : 1;
|
||||||
unsigned int use_custom_surface : 1;
|
unsigned int use_custom_surface : 1;
|
||||||
unsigned int pending_commit : 1;
|
unsigned int pending_commit : 1;
|
||||||
@ -1171,6 +1174,18 @@ gdk_wayland_window_hide_surface (GdkWindow *window)
|
|||||||
|
|
||||||
if (impl->surface)
|
if (impl->surface)
|
||||||
{
|
{
|
||||||
|
if (impl->dummy_egl_surface)
|
||||||
|
{
|
||||||
|
eglDestroySurface(display_wayland->egl_display, impl->dummy_egl_surface);
|
||||||
|
impl->dummy_egl_surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (impl->dummy_egl_window)
|
||||||
|
{
|
||||||
|
wl_egl_window_destroy (impl->dummy_egl_window);
|
||||||
|
impl->dummy_egl_window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (impl->egl_surface)
|
if (impl->egl_surface)
|
||||||
{
|
{
|
||||||
eglDestroySurface(display_wayland->egl_display, impl->egl_surface);
|
eglDestroySurface(display_wayland->egl_display, impl->egl_surface);
|
||||||
@ -2238,6 +2253,32 @@ gdk_wayland_window_get_egl_surface (GdkWindow *window,
|
|||||||
return impl->egl_surface;
|
return impl->egl_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EGLSurface
|
||||||
|
gdk_wayland_window_get_dummy_egl_surface (GdkWindow *window,
|
||||||
|
EGLConfig config)
|
||||||
|
{
|
||||||
|
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
||||||
|
GdkWindowImplWayland *impl;
|
||||||
|
struct wl_egl_window *egl_window;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDK_IS_WAYLAND_WINDOW (window), NULL);
|
||||||
|
|
||||||
|
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||||
|
|
||||||
|
if (impl->dummy_egl_surface == NULL)
|
||||||
|
{
|
||||||
|
impl->dummy_egl_window =
|
||||||
|
wl_egl_window_create (impl->surface, 1, 1);
|
||||||
|
|
||||||
|
impl->dummy_egl_surface =
|
||||||
|
eglCreateWindowSurface (display_wayland->egl_display,
|
||||||
|
config, impl->dummy_egl_window, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return impl->dummy_egl_surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_wayland_window_set_use_custom_surface:
|
* gdk_wayland_window_set_use_custom_surface:
|
||||||
* @window: (type GdkWaylandWindow): a #GdkWindow
|
* @window: (type GdkWaylandWindow): a #GdkWindow
|
||||||
|
@ -41,10 +41,12 @@
|
|||||||
G_DEFINE_TYPE (GdkX11GLContext, gdk_x11_gl_context, GDK_TYPE_GL_CONTEXT)
|
G_DEFINE_TYPE (GdkX11GLContext, gdk_x11_gl_context, GDK_TYPE_GL_CONTEXT)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GLXDrawable drawable;
|
|
||||||
|
|
||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
GdkWindow *window;
|
|
||||||
|
GLXDrawable glx_drawable;
|
||||||
|
|
||||||
|
Window dummy_xwin;
|
||||||
|
GLXWindow dummy_glx;
|
||||||
|
|
||||||
guint32 last_frame_counter;
|
guint32 last_frame_counter;
|
||||||
} DrawableInfo;
|
} DrawableInfo;
|
||||||
@ -53,11 +55,20 @@ static void
|
|||||||
drawable_info_free (gpointer data_)
|
drawable_info_free (gpointer data_)
|
||||||
{
|
{
|
||||||
DrawableInfo *data = data_;
|
DrawableInfo *data = data_;
|
||||||
|
Display *dpy;
|
||||||
|
|
||||||
gdk_x11_display_error_trap_push (data->display);
|
gdk_x11_display_error_trap_push (data->display);
|
||||||
|
|
||||||
if (data->drawable)
|
dpy = gdk_x11_display_get_xdisplay (data->display);
|
||||||
glXDestroyWindow (gdk_x11_display_get_xdisplay (data->display), data->drawable);
|
|
||||||
|
if (data->glx_drawable)
|
||||||
|
glXDestroyWindow (dpy, data->glx_drawable);
|
||||||
|
|
||||||
|
if (data->dummy_glx)
|
||||||
|
glXDestroyWindow (dpy, data->dummy_glx);
|
||||||
|
|
||||||
|
if (data->dummy_xwin)
|
||||||
|
XDestroyWindow (dpy, data->dummy_xwin);
|
||||||
|
|
||||||
gdk_x11_display_error_trap_pop_ignored (data->display);
|
gdk_x11_display_error_trap_pop_ignored (data->display);
|
||||||
|
|
||||||
@ -144,9 +155,10 @@ gdk_x11_window_invalidate_for_new_frame (GdkWindow *window,
|
|||||||
|
|
||||||
buffer_age = 0;
|
buffer_age = 0;
|
||||||
|
|
||||||
if (display_x11->has_glx_buffer_age)
|
if (display_x11->has_glx_buffer_age &&
|
||||||
|
gdk_gl_context_make_current (window->gl_paint_context))
|
||||||
glXQueryDrawable(dpy, context_x11->drawable,
|
glXQueryDrawable(dpy, context_x11->drawable,
|
||||||
GLX_BACK_BUFFER_AGE_EXT, &buffer_age);
|
GLX_BACK_BUFFER_AGE_EXT, &buffer_age);
|
||||||
|
|
||||||
invalidate_all = FALSE;
|
invalidate_all = FALSE;
|
||||||
if (buffer_age == 0 || buffer_age >= 4)
|
if (buffer_age == 0 || buffer_age >= 4)
|
||||||
@ -500,14 +512,13 @@ gdk_x11_display_init_gl (GdkDisplay *display)
|
|||||||
#define MAX_GLX_ATTRS 30
|
#define MAX_GLX_ATTRS 30
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
find_fbconfig_for_window (GdkWindow *window,
|
find_fbconfig_for_visual (GdkDisplay *display,
|
||||||
|
GdkVisual *visual,
|
||||||
GLXFBConfig *fb_config_out,
|
GLXFBConfig *fb_config_out,
|
||||||
XVisualInfo **visinfo_out,
|
XVisualInfo **visinfo_out,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
static int attrs[MAX_GLX_ATTRS];
|
static int attrs[MAX_GLX_ATTRS];
|
||||||
GdkVisual *visual = gdk_window_get_visual (window);
|
|
||||||
GdkDisplay *display = gdk_window_get_display (window);
|
|
||||||
Display *dpy = gdk_x11_display_get_xdisplay (display);
|
Display *dpy = gdk_x11_display_get_xdisplay (display);
|
||||||
GLXFBConfig *configs;
|
GLXFBConfig *configs;
|
||||||
int n_configs, i;
|
int n_configs, i;
|
||||||
@ -650,12 +661,14 @@ create_gl_context (GdkDisplay *display,
|
|||||||
|
|
||||||
GdkGLContext *
|
GdkGLContext *
|
||||||
gdk_x11_window_create_gl_context (GdkWindow *window,
|
gdk_x11_window_create_gl_context (GdkWindow *window,
|
||||||
GdkGLProfile profile,
|
gboolean attached,
|
||||||
GdkGLContext *share,
|
GdkGLProfile profile,
|
||||||
GError **error)
|
GdkGLContext *share,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
GdkDisplay *display = gdk_window_get_display (window);
|
GdkDisplay *display;
|
||||||
GdkX11GLContext *context;
|
GdkX11GLContext *context;
|
||||||
|
GdkVisual *visual;
|
||||||
GdkVisual *gdk_visual;
|
GdkVisual *gdk_visual;
|
||||||
GLXFBConfig config;
|
GLXFBConfig config;
|
||||||
GLXContext glx_context;
|
GLXContext glx_context;
|
||||||
@ -665,6 +678,8 @@ gdk_x11_window_create_gl_context (GdkWindow *window,
|
|||||||
Display *dpy;
|
Display *dpy;
|
||||||
DrawableInfo *info;
|
DrawableInfo *info;
|
||||||
|
|
||||||
|
display = gdk_window_get_display (window);
|
||||||
|
|
||||||
if (!gdk_x11_display_init_gl (display))
|
if (!gdk_x11_display_init_gl (display))
|
||||||
{
|
{
|
||||||
g_set_error_literal (error, GDK_GL_ERROR,
|
g_set_error_literal (error, GDK_GL_ERROR,
|
||||||
@ -684,7 +699,9 @@ gdk_x11_window_create_gl_context (GdkWindow *window,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!find_fbconfig_for_window (window, &config, &xvisinfo, error))
|
visual = gdk_window_get_visual (window);
|
||||||
|
|
||||||
|
if (!find_fbconfig_for_visual (display, visual, &config, &xvisinfo, error))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dpy = gdk_x11_display_get_xdisplay (display);
|
dpy = gdk_x11_display_get_xdisplay (display);
|
||||||
@ -712,31 +729,53 @@ gdk_x11_window_create_gl_context (GdkWindow *window,
|
|||||||
|
|
||||||
is_direct = glXIsDirect (dpy, glx_context);
|
is_direct = glXIsDirect (dpy, glx_context);
|
||||||
|
|
||||||
gdk_x11_display_error_trap_push (display);
|
info = get_glx_drawable_info (window->impl_window);
|
||||||
|
if (info == NULL)
|
||||||
if (GDK_X11_DISPLAY (display)->glx_version >= 13)
|
|
||||||
{
|
{
|
||||||
info = get_glx_drawable_info (window->impl_window);
|
XSetWindowAttributes attrs;
|
||||||
|
unsigned long mask;
|
||||||
|
|
||||||
if (info == NULL)
|
gdk_x11_display_error_trap_push (display);
|
||||||
{
|
|
||||||
info = g_slice_new (DrawableInfo);
|
|
||||||
info->window = window->impl_window;
|
|
||||||
info->display = display;
|
|
||||||
info->drawable = glXCreateWindow (dpy,
|
|
||||||
config,
|
|
||||||
gdk_x11_window_get_xid (window->impl_window),
|
|
||||||
NULL);
|
|
||||||
info->last_frame_counter = 0;
|
|
||||||
|
|
||||||
set_glx_drawable_info (window->impl_window, info);
|
info = g_slice_new0 (DrawableInfo);
|
||||||
}
|
info->display = display;
|
||||||
|
info->last_frame_counter = 0;
|
||||||
|
|
||||||
drawable = info->drawable;
|
attrs.override_redirect = True;
|
||||||
}
|
attrs.colormap = XCreateColormap (dpy, DefaultRootWindow (dpy), xvisinfo->visual, AllocNone);
|
||||||
else
|
attrs.border_pixel = 0;
|
||||||
{
|
mask = CWOverrideRedirect | CWColormap | CWBorderPixel;
|
||||||
drawable = gdk_x11_window_get_xid (window);
|
info->dummy_xwin = XCreateWindow (dpy, DefaultRootWindow (dpy),
|
||||||
|
-100, -100, 1, 1,
|
||||||
|
0,
|
||||||
|
xvisinfo->depth,
|
||||||
|
CopyFromParent,
|
||||||
|
xvisinfo->visual,
|
||||||
|
mask,
|
||||||
|
&attrs);
|
||||||
|
XMapWindow(dpy, info->dummy_xwin);
|
||||||
|
|
||||||
|
if (GDK_X11_DISPLAY (display)->glx_version >= 13)
|
||||||
|
{
|
||||||
|
info->glx_drawable = glXCreateWindow (dpy, config,
|
||||||
|
gdk_x11_window_get_xid (window->impl_window),
|
||||||
|
NULL);
|
||||||
|
info->dummy_glx = glXCreateWindow (dpy, config, info->dummy_xwin, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gdk_x11_display_error_trap_pop (display))
|
||||||
|
{
|
||||||
|
g_set_error_literal (error, GDK_GL_ERROR,
|
||||||
|
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||||
|
_("Unable to create a GL context"));
|
||||||
|
|
||||||
|
drawable_info_free (info);
|
||||||
|
glXDestroyContext (dpy, glx_context);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_glx_drawable_info (window->impl_window, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
gdk_visual = gdk_x11_screen_lookup_visual (gdk_display_get_default_screen (display),
|
gdk_visual = gdk_x11_screen_lookup_visual (gdk_display_get_default_screen (display),
|
||||||
@ -744,16 +783,10 @@ gdk_x11_window_create_gl_context (GdkWindow *window,
|
|||||||
|
|
||||||
XFree (xvisinfo);
|
XFree (xvisinfo);
|
||||||
|
|
||||||
if (gdk_x11_display_error_trap_pop (display))
|
if (attached)
|
||||||
{
|
drawable = info->glx_drawable ? info->glx_drawable : gdk_x11_window_get_xid (window->impl_window);
|
||||||
g_set_error_literal (error, GDK_GL_ERROR,
|
else
|
||||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
drawable = info->dummy_glx ? info->dummy_glx : info->dummy_xwin;
|
||||||
_("Unable to create a GL context"));
|
|
||||||
|
|
||||||
glXDestroyContext (dpy, glx_context);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
GDK_NOTE (OPENGL,
|
GDK_NOTE (OPENGL,
|
||||||
g_print ("Created GLX context[%p], %s\n",
|
g_print ("Created GLX context[%p], %s\n",
|
||||||
@ -765,9 +798,11 @@ gdk_x11_window_create_gl_context (GdkWindow *window,
|
|||||||
"visual", gdk_visual,
|
"visual", gdk_visual,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
context->profile = profile;
|
||||||
context->glx_config = config;
|
context->glx_config = config;
|
||||||
context->glx_context = glx_context;
|
context->glx_context = glx_context;
|
||||||
context->drawable = drawable;
|
context->drawable = drawable;
|
||||||
|
context->is_attached = attached;
|
||||||
context->is_direct = is_direct;
|
context->is_direct = is_direct;
|
||||||
|
|
||||||
return GDK_GL_CONTEXT (context);
|
return GDK_GL_CONTEXT (context);
|
||||||
@ -832,7 +867,7 @@ gdk_x11_display_make_gl_context_current (GdkDisplay *display,
|
|||||||
glXMakeContextCurrent (dpy, context_x11->drawable, context_x11->drawable,
|
glXMakeContextCurrent (dpy, context_x11->drawable, context_x11->drawable,
|
||||||
context_x11->glx_context);
|
context_x11->glx_context);
|
||||||
|
|
||||||
if (GDK_X11_DISPLAY (display)->has_glx_swap_interval)
|
if (context_x11->is_attached && GDK_X11_DISPLAY (display)->has_glx_swap_interval)
|
||||||
{
|
{
|
||||||
if (context_x11->do_frame_sync)
|
if (context_x11->do_frame_sync)
|
||||||
glXSwapIntervalSGI (1);
|
glXSwapIntervalSGI (1);
|
||||||
|
@ -40,10 +40,12 @@ struct _GdkX11GLContext
|
|||||||
{
|
{
|
||||||
GdkGLContext parent_instance;
|
GdkGLContext parent_instance;
|
||||||
|
|
||||||
|
GdkGLProfile profile;
|
||||||
GLXContext glx_context;
|
GLXContext glx_context;
|
||||||
GLXFBConfig glx_config;
|
GLXFBConfig glx_config;
|
||||||
GLXDrawable drawable;
|
GLXDrawable drawable;
|
||||||
|
|
||||||
|
guint is_attached : 1;
|
||||||
guint is_direct : 1;
|
guint is_direct : 1;
|
||||||
guint do_frame_sync : 1;
|
guint do_frame_sync : 1;
|
||||||
|
|
||||||
@ -56,6 +58,7 @@ struct _GdkX11GLContextClass
|
|||||||
|
|
||||||
gboolean gdk_x11_display_init_gl (GdkDisplay *display);
|
gboolean gdk_x11_display_init_gl (GdkDisplay *display);
|
||||||
GdkGLContext * gdk_x11_window_create_gl_context (GdkWindow *window,
|
GdkGLContext * gdk_x11_window_create_gl_context (GdkWindow *window,
|
||||||
|
gboolean attached,
|
||||||
GdkGLProfile profile,
|
GdkGLProfile profile,
|
||||||
GdkGLContext *share,
|
GdkGLContext *share,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
Reference in New Issue
Block a user