summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2021-07-22 17:11:26 -0400
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2021-07-23 13:44:17 -0400
commitf13633797076dab6d42faf2c4078278850089c19 (patch)
treede577c891f314ec981fd43ee4eba358c813def3c
parentefa6d1c2f8f3d8905f021cfaa43c6d1fe7e1f6fe (diff)
downloadgstreamer-plugins-base-f13633797076dab6d42faf2c4078278850089c19.tar.gz
glcontext: egl: Stop comparing native surface pointer
This was noticed with wayland, sometimes the newly create native handle can have the same pointer (even though its new). This lead to unwanted errors or crash. Fixes #927 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1231>
-rw-r--r--gst-libs/gst/gl/egl/gstglcontext_egl.c39
-rw-r--r--gst-libs/gst/gl/egl/gstglcontext_egl.h1
2 files changed, 26 insertions, 14 deletions
diff --git a/gst-libs/gst/gl/egl/gstglcontext_egl.c b/gst-libs/gst/gl/egl/gstglcontext_egl.c
index bd83f88d8..24f2091f6 100644
--- a/gst-libs/gst/gl/egl/gstglcontext_egl.c
+++ b/gst-libs/gst/gl/egl/gstglcontext_egl.c
@@ -832,6 +832,18 @@ _create_context_with_flags (GstGLContextEGL * egl, EGLContext share_context,
attribs);
}
+static void
+gst_gl_context_egl_window_handle_changed_cb (GstGLContextEGL * egl,
+ GstGLWindow * window)
+{
+ if (egl->egl_surface != EGL_NO_SURFACE) {
+ if (!eglDestroySurface (egl->egl_display, egl->egl_surface))
+ GST_WARNING_OBJECT (egl, "Failed to destroy old window surface: %s",
+ gst_egl_get_error_string (eglGetError ()));
+ egl->egl_surface = EGL_NO_SURFACE;
+ }
+}
+
static gboolean
gst_gl_context_egl_create_context (GstGLContext * context,
GstGLAPI gl_api, GstGLContext * other_context, GError ** error)
@@ -1112,8 +1124,6 @@ gst_gl_context_egl_create_context (GstGLContext * context,
egl->egl_surface =
eglCreateWindowSurface (egl->egl_display, egl->egl_config,
(EGLNativeWindowType) window_handle, attrs);
- /* Store window handle for later comparison */
- egl->window_handle = window_handle;
} else if (!gst_gl_check_extension ("EGL_KHR_surfaceless_context",
egl->egl_exts)) {
EGLint surface_attrib[7];
@@ -1152,8 +1162,12 @@ gst_gl_context_egl_create_context (GstGLContext * context,
egl->egl_major = egl_major;
egl->egl_minor = egl_minor;
- if (window)
+ if (window) {
+ egl->window_handle_signal = g_signal_connect_swapped (window,
+ "window-handle-changed",
+ G_CALLBACK (gst_gl_context_egl_window_handle_changed_cb), egl);
gst_object_unref (window);
+ }
return TRUE;
@@ -1168,8 +1182,15 @@ static void
gst_gl_context_egl_destroy_context (GstGLContext * context)
{
GstGLContextEGL *egl;
+ GstGLWindow *window;
egl = GST_GL_CONTEXT_EGL (context);
+ window = gst_gl_context_get_window (context);
+
+ if (window && egl->window_handle_signal) {
+ g_signal_handler_disconnect (window, egl->window_handle_signal);
+ egl->window_handle_signal = 0;
+ }
gst_gl_context_egl_activate (context, FALSE);
@@ -1182,7 +1203,6 @@ gst_gl_context_egl_destroy_context (GstGLContext * context)
eglDestroyContext (egl->egl_display, egl->egl_context);
egl->egl_context = NULL;
}
- egl->window_handle = 0;
eglReleaseThread ();
@@ -1212,7 +1232,7 @@ gst_gl_context_egl_activate (GstGLContext * context, gboolean activate)
handle = gst_gl_window_get_window_handle (window);
gst_object_unref (window);
}
- if (handle && handle != egl->window_handle) {
+ if (handle && (egl->egl_surface == EGL_NO_SURFACE)) {
#if GST_GL_HAVE_WINDOW_WINRT && defined (EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER)
const EGLint attrs[] = {
/* EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER is an optimization that can
@@ -1226,15 +1246,6 @@ gst_gl_context_egl_activate (GstGLContext * context, gboolean activate)
GST_DEBUG_OBJECT (context,
"Handle changed (have:%p, now:%p), switching surface",
(void *) egl->window_handle, (void *) handle);
- if (egl->egl_surface) {
- result = eglDestroySurface (egl->egl_display, egl->egl_surface);
- egl->egl_surface = EGL_NO_SURFACE;
- if (!result) {
- GST_ERROR_OBJECT (context, "Failed to destroy old window surface: %s",
- gst_egl_get_error_string (eglGetError ()));
- goto done;
- }
- }
egl->egl_surface =
eglCreateWindowSurface (egl->egl_display, egl->egl_config,
(EGLNativeWindowType) handle, attrs);
diff --git a/gst-libs/gst/gl/egl/gstglcontext_egl.h b/gst-libs/gst/gl/egl/gstglcontext_egl.h
index 644731f36..4687585ac 100644
--- a/gst-libs/gst/gl/egl/gstglcontext_egl.h
+++ b/gst-libs/gst/gl/egl/gstglcontext_egl.h
@@ -67,6 +67,7 @@ struct _GstGLContextEGL
/* Cached handle */
guintptr window_handle;
+ gulong window_handle_signal;
GstStructure *requested_config;
};