diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index 9f3608d3cd..398e191a12 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -1675,6 +1675,7 @@ gdk_display_init_egl (GdkDisplay *self, if (!gdk_display_check_egl_extensions (priv->egl_display, (const char *[]) { + "EGL_KHR_create_context", "EGL_KHR_surfaceless_context", NULL }, diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c index 82cb6ecf2f..c64c2a6a47 100644 --- a/gdk/gdksurface.c +++ b/gdk/gdksurface.c @@ -46,6 +46,10 @@ #include +#ifdef HAVE_EGL +#include +#endif + /** * GdkSurface: * @@ -64,6 +68,11 @@ typedef struct _GdkSurfacePrivate GdkSurfacePrivate; struct _GdkSurfacePrivate { + gpointer egl_native_window; +#ifdef HAVE_EGL + EGLSurface egl_surface; +#endif + gpointer widget; }; @@ -920,8 +929,10 @@ surface_remove_from_pointer_info (GdkSurface *surface, */ static void _gdk_surface_destroy_hierarchy (GdkSurface *surface, - gboolean foreign_destroy) + gboolean foreign_destroy) { + G_GNUC_UNUSED GdkSurfacePrivate *priv = gdk_surface_get_instance_private (surface); + g_return_if_fail (GDK_IS_SURFACE (surface)); if (GDK_SURFACE_DESTROYED (surface)) @@ -929,6 +940,9 @@ _gdk_surface_destroy_hierarchy (GdkSurface *surface, GDK_SURFACE_GET_CLASS (surface)->destroy (surface, foreign_destroy); + /* backend must have unset this */ + g_assert (priv->egl_native_window == NULL); + if (surface->gl_paint_context) { /* Make sure to destroy if current */ @@ -1063,6 +1077,48 @@ gdk_surface_get_mapped (GdkSurface *surface) return GDK_SURFACE_IS_MAPPED (surface); } +void +gdk_surface_set_egl_native_window (GdkSurface *self, + gpointer native_window) +{ +#ifdef HAVE_EGL + GdkSurfacePrivate *priv = gdk_surface_get_instance_private (self); + + /* This checks that all EGL platforms we support conform to the same struct sizes. + * When this ever fails, there will be some fun times happening for whoever tries + * this weird EGL backend... */ + G_STATIC_ASSERT (sizeof (gpointer) == sizeof (EGLNativeWindowType)); + + if (priv->egl_surface != NULL) + { + eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface); + priv->egl_surface = NULL; + } + + priv->egl_native_window = native_window; +} + +gpointer /* EGLSurface */ +gdk_surface_get_egl_surface (GdkSurface *self) +{ + GdkSurfacePrivate *priv = gdk_surface_get_instance_private (self); + + g_return_val_if_fail (priv->egl_native_window != NULL, NULL); + + if (priv->egl_surface == NULL) + { + GdkDisplay *display = gdk_surface_get_display (self); + + priv->egl_surface = eglCreateWindowSurface (gdk_display_get_egl_display (display), + gdk_display_get_egl_config (display), + (EGLNativeWindowType) priv->egl_native_window, + NULL); + } + + return priv->egl_surface; +#endif +} + GdkGLContext * gdk_surface_get_paint_gl_context (GdkSurface *surface, GError **error) diff --git a/gdk/gdksurfaceprivate.h b/gdk/gdksurfaceprivate.h index 16a6bf8bea..ec9f177e5e 100644 --- a/gdk/gdksurfaceprivate.h +++ b/gdk/gdksurfaceprivate.h @@ -292,6 +292,10 @@ void gdk_surface_get_geometry (GdkSurface *surface, int *width, int *height); +void gdk_surface_set_egl_native_window (GdkSurface *self, + gpointer native_window); +gpointer /*EGLSurface*/ gdk_surface_get_egl_surface (GdkSurface *self); + void gdk_surface_set_widget (GdkSurface *self, gpointer widget); gpointer gdk_surface_get_widget (GdkSurface *self); diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c index 29d2761ddd..c60d4cfc48 100644 --- a/gdk/wayland/gdkglcontext-wayland.c +++ b/gdk/wayland/gdkglcontext-wayland.c @@ -215,7 +215,7 @@ gdk_wayland_gl_context_get_damage (GdkGLContext *context) if (display_wayland->have_egl_buffer_age) { - egl_surface = gdk_wayland_surface_get_egl_surface (surface); + egl_surface = gdk_surface_get_egl_surface (surface); gdk_gl_context_make_current (context); eglQuerySurface (gdk_display_get_egl_display (display), egl_surface, EGL_BUFFER_AGE_EXT, &buffer_age); @@ -269,7 +269,7 @@ gdk_wayland_gl_context_make_current (GdkGLContext *context, EGLSurface egl_surface; if (!surfaceless) - egl_surface = gdk_wayland_surface_get_egl_surface (gdk_gl_context_get_surface (context)); + egl_surface = gdk_surface_get_egl_surface (gdk_gl_context_get_surface (context)); else egl_surface = EGL_NO_SURFACE; @@ -283,6 +283,8 @@ static void gdk_wayland_gl_context_begin_frame (GdkDrawContext *draw_context, cairo_region_t *region) { + gdk_wayland_surface_ensure_wl_egl_window (gdk_draw_context_get_surface (draw_context)); + GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->begin_frame (draw_context, region); glDrawBuffers (1, (GLenum[1]) { GL_BACK }); @@ -302,7 +304,7 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context, gdk_gl_context_make_current (context); - egl_surface = gdk_wayland_surface_get_egl_surface (surface); + egl_surface = gdk_surface_get_egl_surface (surface); gdk_wayland_surface_sync (surface); gdk_wayland_surface_request_frame (surface); diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index c1f1357165..0a02cede91 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -110,8 +110,6 @@ struct _GdkWaylandSurface struct wl_event_queue *event_queue; - EGLSurface egl_surface; - uint32_t reposition_token; uint32_t received_reposition_token; @@ -2901,14 +2899,9 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) if (impl->display_server.wl_surface) { - if (impl->egl_surface) - { - eglDestroySurface (gdk_display_get_egl_display (display), impl->egl_surface); - impl->egl_surface = NULL; - } - if (impl->display_server.egl_window) { + gdk_surface_set_egl_native_window (surface, NULL); wl_egl_window_destroy (impl->display_server.egl_window); impl->display_server.egl_window = NULL; } @@ -4332,8 +4325,8 @@ gdk_wayland_surface_get_wl_output (GdkSurface *surface) return NULL; } -static struct wl_egl_window * -gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface) +void +gdk_wayland_surface_ensure_wl_egl_window (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); @@ -4344,33 +4337,9 @@ gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface) surface->width * impl->scale, surface->height * impl->scale); wl_surface_set_buffer_scale (impl->display_server.wl_surface, impl->scale); + + gdk_surface_set_egl_native_window (surface, impl->display_server.egl_window); } - - return impl->display_server.egl_window; -} - -EGLSurface -gdk_wayland_surface_get_egl_surface (GdkSurface *surface) -{ - GdkDisplay *display = gdk_surface_get_display (surface); - GdkWaylandSurface *impl; - struct wl_egl_window *egl_window; - - g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); - - impl = GDK_WAYLAND_SURFACE (surface); - - if (impl->egl_surface == NULL) - { - egl_window = gdk_wayland_surface_get_wl_egl_window (surface); - - impl->egl_surface = eglCreateWindowSurface (gdk_display_get_egl_display (display), - gdk_display_get_egl_config (display), - egl_window, - NULL); - } - - return impl->egl_surface; } struct gtk_surface1 * diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index cd2b1f3e9a..d6d90d6908 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -22,9 +22,6 @@ #include "gdkwaylandsurface.h" -#include -#include - G_BEGIN_DECLS void gdk_wayland_toplevel_set_dbus_properties (GdkToplevel *toplevel, @@ -41,6 +38,6 @@ void gdk_wayland_toplevel_announce_ssd (GdkTopl gboolean gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel); void gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel); -EGLSurface gdk_wayland_surface_get_egl_surface (GdkSurface *surface); +void gdk_wayland_surface_ensure_wl_egl_window (GdkSurface *surface); G_END_DECLS diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index 269fd9cd2f..499bbd86f3 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -2995,8 +2995,6 @@ gdk_x11_display_init_gl_backend (GdkX11Display *self, self->egl_version = epoxy_egl_version (egl_display); - self->has_egl_khr_create_context = - epoxy_has_egl_extension (egl_display, "EGL_KHR_create_context"); self->has_egl_buffer_age = epoxy_has_egl_extension (egl_display, "EGL_EXT_buffer_age"); self->has_egl_swap_buffers_with_damage = diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h index 5be6c8e5e0..6ebca4bd29 100644 --- a/gdk/x11/gdkdisplay-x11.h +++ b/gdk/x11/gdkdisplay-x11.h @@ -157,7 +157,6 @@ struct _GdkX11Display guint has_async_glx_swap_buffers : 1; /* EGL extensions we check */ - guint has_egl_khr_create_context : 1; guint has_egl_buffer_age : 1; guint has_egl_swap_buffers_with_damage : 1; }; diff --git a/gdk/x11/gdkglcontext-egl.c b/gdk/x11/gdkglcontext-egl.c index f385ec0c60..83662a4c4d 100644 --- a/gdk/x11/gdkglcontext-egl.c +++ b/gdk/x11/gdkglcontext-egl.c @@ -18,7 +18,6 @@ #include "gdkx11display.h" #include "gdkx11glcontext.h" #include "gdkx11screen.h" -#include "gdkx11surface.h" #include "gdkx11property.h" #include @@ -62,38 +61,6 @@ gdk_x11_display_get_egl_display (GdkDisplay *display) return gdk_display_get_egl_display (display); } -static EGLSurface -gdk_x11_surface_get_egl_surface (GdkSurface *surface) -{ - GdkX11Surface *self = GDK_X11_SURFACE (surface); - GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (self)); - - if (self->egl_surface) - return self->egl_surface; - - self->egl_surface = - eglCreateWindowSurface (gdk_display_get_egl_display (display), - gdk_display_get_egl_config (display), - (EGLNativeWindowType) gdk_x11_surface_get_xid (surface), - NULL); - - return self->egl_surface; -} - -void -gdk_x11_surface_destroy_egl_surface (GdkX11Surface *self) -{ - GdkDisplay *display; - - if (self->egl_surface == NULL) - return; - - display = gdk_surface_get_display (GDK_SURFACE (self)); - - eglDestroySurface (gdk_display_get_egl_display (display), self->egl_surface); - self->egl_surface = NULL; -} - static void gdk_x11_gl_context_egl_begin_frame (GdkDrawContext *draw_context, cairo_region_t *region) @@ -117,7 +84,7 @@ gdk_x11_gl_context_egl_end_frame (GdkDrawContext *draw_context, gdk_gl_context_make_current (context); - egl_surface = gdk_x11_surface_get_egl_surface (surface); + egl_surface = gdk_surface_get_egl_surface (surface); gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "x11", "swap buffers"); if (display_x11->has_egl_swap_buffers_with_damage) @@ -184,7 +151,7 @@ gdk_x11_gl_context_egl_make_current (GdkGLContext *context, } surface = gdk_gl_context_get_surface (context); - egl_surface = gdk_x11_surface_get_egl_surface (surface); + egl_surface = gdk_surface_get_egl_surface (surface); GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Making EGL context %p current to surface %p", @@ -227,7 +194,7 @@ gdk_x11_gl_context_egl_get_damage (GdkGLContext *context) EGLSurface egl_surface; int buffer_age = 0; - egl_surface = gdk_x11_surface_get_egl_surface (surface); + egl_surface = gdk_surface_get_egl_surface (surface); gdk_gl_context_make_current (context); eglQuerySurface (gdk_display_get_egl_display (display), @@ -268,20 +235,18 @@ static gboolean gdk_x11_gl_context_egl_realize (GdkGLContext *context, GError **error) { - GdkX11Display *display_x11; GdkDisplay *display; GdkX11GLContextEGL *context_egl; GdkGLContext *share; EGLDisplay egl_display; EGLConfig egl_config; gboolean debug_bit, forward_bit, legacy_bit, use_es; - int major, minor, i = 0; + int major, minor, flags, i = 0; EGLint context_attrs[N_EGL_ATTRS]; display = gdk_gl_context_get_display (context); context_egl = GDK_X11_GL_CONTEXT_EGL (context); - display_x11 = GDK_X11_DISPLAY (display); share = gdk_display_get_gl_context (display); egl_display = gdk_display_get_egl_display (display), egl_config = gdk_display_get_egl_config (display), @@ -294,35 +259,28 @@ gdk_x11_gl_context_egl_realize (GdkGLContext *context, use_es = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) || (share != NULL && gdk_gl_context_get_use_es (share)); + flags = 0; + if (debug_bit) + flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; + if (forward_bit) + flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; + if (!use_es) { eglBindAPI (EGL_OPENGL_API); - if (display_x11->has_egl_khr_create_context) - { - int flags = 0; + /* We want a core profile, unless in legacy mode */ + context_attrs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; + context_attrs[i++] = legacy_bit + ? EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR + : EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; - if (debug_bit) - flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; - if (forward_bit) - flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; - - context_attrs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; - context_attrs[i++] = legacy_bit - ? EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR - : EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; - context_attrs[i++] = EGL_CONTEXT_MAJOR_VERSION_KHR; - context_attrs[i++] = legacy_bit ? 3 : major; - context_attrs[i++] = EGL_CONTEXT_MINOR_VERSION_KHR; - context_attrs[i++] = legacy_bit ? 0 : minor; - context_attrs[i++] = EGL_CONTEXT_FLAGS_KHR; - context_attrs[i++] = flags; - context_attrs[i++] = EGL_NONE; - } - else - { - context_attrs[i++] = EGL_NONE; - } + /* Specify the version */ + context_attrs[i++] = EGL_CONTEXT_MAJOR_VERSION_KHR; + context_attrs[i++] = legacy_bit ? 3 : major; + context_attrs[i++] = EGL_CONTEXT_MINOR_VERSION_KHR; + context_attrs[i++] = legacy_bit ? 0 : minor; + context_attrs[i++] = EGL_CONTEXT_FLAGS_KHR; } else { @@ -335,6 +293,9 @@ gdk_x11_gl_context_egl_realize (GdkGLContext *context, context_attrs[i++] = 2; } + context_attrs[i++] = EGL_CONTEXT_FLAGS_KHR; + context_attrs[i++] = flags; + context_attrs[i++] = EGL_NONE; g_assert (i < N_EGL_ATTRS); diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c index 8c78e3c07e..567ae89002 100644 --- a/gdk/x11/gdkglcontext-x11.c +++ b/gdk/x11/gdkglcontext-x11.c @@ -28,7 +28,6 @@ #include "gdkx11display.h" #include "gdkx11glcontext.h" #include "gdkx11screen.h" -#include "gdkx11surface.h" #include "gdkx11property.h" #include diff --git a/gdk/x11/gdkglcontext-x11.h b/gdk/x11/gdkglcontext-x11.h index cf268d9f15..10b94ca54b 100644 --- a/gdk/x11/gdkglcontext-x11.h +++ b/gdk/x11/gdkglcontext-x11.h @@ -76,8 +76,6 @@ GType gdk_x11_gl_context_glx_get_type (void) G_GNUC_CO typedef struct _GdkX11GLContextEGL GdkX11GLContextEGL; -void gdk_x11_surface_destroy_egl_surface (GdkX11Surface *self); - GType gdk_x11_gl_context_egl_get_type (void) G_GNUC_CONST; G_END_DECLS diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c index 06bc9cf00e..16e1a3678d 100644 --- a/gdk/x11/gdksurface-x11.c +++ b/gdk/x11/gdksurface-x11.c @@ -1275,6 +1275,8 @@ _gdk_x11_display_create_surface (GdkDisplay *display, g_object_ref (surface); _gdk_x11_display_add_window (x11_screen->display, &impl->xid, surface); + gdk_surface_set_egl_native_window (surface, (void *) impl->xid); + gdk_x11_surface_set_title (surface, get_default_title ()); if (surface_type == GDK_SURFACE_TOPLEVEL) gdk_x11_surface_set_type_hint (surface, GDK_SURFACE_TYPE_HINT_NORMAL); @@ -1364,7 +1366,7 @@ gdk_x11_surface_destroy (GdkSurface *surface, if (!foreign_destroy) { - gdk_x11_surface_destroy_egl_surface (impl); + gdk_surface_set_egl_native_window (surface, NULL); gdk_x11_surface_destroy_glx_drawable (impl); XDestroyWindow (GDK_SURFACE_XDISPLAY (surface), GDK_SURFACE_XID (surface)); diff --git a/gdk/x11/gdksurface-x11.h b/gdk/x11/gdksurface-x11.h index 8a50b5b5d4..f338ccfc21 100644 --- a/gdk/x11/gdksurface-x11.h +++ b/gdk/x11/gdksurface-x11.h @@ -86,7 +86,6 @@ struct _GdkX11Surface guint compute_size_source_id; cairo_surface_t *cairo_surface; - /* EGLSurface */ gpointer egl_surface; /* GLXDrawable */ XID glx_drawable; guint32 glx_frame_counter;