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
@ -89,6 +89,7 @@ struct _GdkWaylandDisplay
|
||||
guint have_egl_khr_create_context : 1;
|
||||
guint have_egl_buffer_age : 1;
|
||||
guint have_egl_swap_buffers_with_damage : 1;
|
||||
guint have_egl_surfaceless_context : 1;
|
||||
};
|
||||
|
||||
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,
|
||||
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,
|
||||
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 =
|
||||
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,
|
||||
g_print ("EGL API version %d.%d found\n"
|
||||
" - Vendor: %s\n"
|
||||
@ -297,6 +301,7 @@ find_eglconfig_for_window (GdkWindow *window,
|
||||
|
||||
GdkGLContext *
|
||||
gdk_wayland_window_create_gl_context (GdkWindow *window,
|
||||
gboolean attached,
|
||||
GdkGLProfile profile,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
@ -359,6 +364,7 @@ gdk_wayland_window_create_gl_context (GdkWindow *window,
|
||||
|
||||
context->egl_config = config;
|
||||
context->egl_context = ctx;
|
||||
context->is_attached = attached;
|
||||
|
||||
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);
|
||||
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,
|
||||
egl_surface, context_wayland->egl_context))
|
||||
|
||||
@ -39,6 +39,7 @@ struct _GdkWaylandGLContext
|
||||
|
||||
EGLContext egl_context;
|
||||
EGLConfig egl_config;
|
||||
gboolean is_attached;
|
||||
};
|
||||
|
||||
struct _GdkWaylandGLContextClass
|
||||
@ -48,6 +49,7 @@ struct _GdkWaylandGLContextClass
|
||||
|
||||
gboolean gdk_wayland_display_init_gl (GdkDisplay *display);
|
||||
GdkGLContext * gdk_wayland_window_create_gl_context (GdkWindow *window,
|
||||
gboolean attach,
|
||||
GdkGLProfile profile,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
|
||||
@ -239,5 +239,7 @@ void gdk_wayland_selection_unset_data_source (GdkAtom selection);
|
||||
|
||||
EGLSurface gdk_wayland_window_get_egl_surface (GdkWindow *window,
|
||||
EGLConfig config);
|
||||
EGLSurface gdk_wayland_window_get_dummy_egl_surface (GdkWindow *window,
|
||||
EGLConfig config);
|
||||
|
||||
#endif /* __GDK_PRIVATE_WAYLAND_H__ */
|
||||
|
||||
@ -101,6 +101,9 @@ struct _GdkWindowImplWayland
|
||||
struct wl_egl_window *egl_window;
|
||||
EGLSurface egl_surface;
|
||||
|
||||
struct wl_egl_window *dummy_egl_window;
|
||||
EGLSurface dummy_egl_surface;
|
||||
|
||||
unsigned int mapped : 1;
|
||||
unsigned int use_custom_surface : 1;
|
||||
unsigned int pending_commit : 1;
|
||||
@ -1171,6 +1174,18 @@ gdk_wayland_window_hide_surface (GdkWindow *window)
|
||||
|
||||
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)
|
||||
{
|
||||
eglDestroySurface(display_wayland->egl_display, impl->egl_surface);
|
||||
@ -2238,6 +2253,32 @@ gdk_wayland_window_get_egl_surface (GdkWindow *window,
|
||||
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:
|
||||
* @window: (type GdkWaylandWindow): a #GdkWindow
|
||||
|
||||
Reference in New Issue
Block a user