mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-11 06:11:27 +00:00
gl/egl: Detect window handle changes
When (re)activating the context, the backing window handle might have changed. If that happened, destroy the previous surface and create a new one https://bugzilla.gnome.org/show_bug.cgi?id=745090
This commit is contained in:
parent
6a515ab278
commit
4fa2ddda96
2 changed files with 38 additions and 4 deletions
gst-libs/gst/gl/egl
|
@ -399,13 +399,18 @@ gst_gl_context_egl_create_context (GstGLContext * context,
|
||||||
(EGLNativeWindowType) gst_gl_window_get_window_handle (window);
|
(EGLNativeWindowType) gst_gl_window_get_window_handle (window);
|
||||||
|
|
||||||
if (window_handle) {
|
if (window_handle) {
|
||||||
|
GST_DEBUG ("Creating EGLSurface from window_handle %p",
|
||||||
|
(void *) window_handle);
|
||||||
egl->egl_surface =
|
egl->egl_surface =
|
||||||
eglCreateWindowSurface (egl->egl_display, egl->egl_config,
|
eglCreateWindowSurface (egl->egl_display, egl->egl_config,
|
||||||
window_handle, NULL);
|
window_handle, NULL);
|
||||||
|
/* Store window handle for later comparision */
|
||||||
|
egl->window_handle = window_handle;
|
||||||
} else if (!gst_gl_check_extension ("EGL_KHR_surfaceless_context", egl_exts)) {
|
} else if (!gst_gl_check_extension ("EGL_KHR_surfaceless_context", egl_exts)) {
|
||||||
EGLint surface_attrib[7];
|
EGLint surface_attrib[7];
|
||||||
gint j = 0;
|
gint j = 0;
|
||||||
|
|
||||||
|
GST_DEBUG ("Surfaceless context, creating PBufferSurface");
|
||||||
/* FIXME: Width/height doesn't seem to matter but we can't leave them
|
/* FIXME: Width/height doesn't seem to matter but we can't leave them
|
||||||
* at 0, otherwise X11 complains about BadValue */
|
* at 0, otherwise X11 complains about BadValue */
|
||||||
surface_attrib[j++] = EGL_WIDTH;
|
surface_attrib[j++] = EGL_WIDTH;
|
||||||
|
@ -420,6 +425,7 @@ gst_gl_context_egl_create_context (GstGLContext * context,
|
||||||
eglCreatePbufferSurface (egl->egl_display, egl->egl_config,
|
eglCreatePbufferSurface (egl->egl_display, egl->egl_config,
|
||||||
surface_attrib);
|
surface_attrib);
|
||||||
} else {
|
} else {
|
||||||
|
GST_DEBUG ("No surface/handle !");
|
||||||
egl->egl_surface = EGL_NO_SURFACE;
|
egl->egl_surface = EGL_NO_SURFACE;
|
||||||
need_surface = FALSE;
|
need_surface = FALSE;
|
||||||
}
|
}
|
||||||
|
@ -473,11 +479,16 @@ gst_gl_context_egl_destroy_context (GstGLContext * context)
|
||||||
|
|
||||||
gst_gl_context_egl_activate (context, FALSE);
|
gst_gl_context_egl_activate (context, FALSE);
|
||||||
|
|
||||||
if (egl->egl_surface)
|
if (egl->egl_surface) {
|
||||||
eglDestroySurface (egl->egl_display, egl->egl_surface);
|
eglDestroySurface (egl->egl_display, egl->egl_surface);
|
||||||
|
egl->egl_surface = EGL_NO_SURFACE;
|
||||||
|
}
|
||||||
|
|
||||||
if (egl->egl_context)
|
if (egl->egl_context) {
|
||||||
eglDestroyContext (egl->egl_display, egl->egl_context);
|
eglDestroyContext (egl->egl_display, egl->egl_context);
|
||||||
|
egl->egl_context = NULL;
|
||||||
|
}
|
||||||
|
egl->window_handle = 0;
|
||||||
|
|
||||||
eglReleaseThread ();
|
eglReleaseThread ();
|
||||||
}
|
}
|
||||||
|
@ -490,10 +501,30 @@ gst_gl_context_egl_activate (GstGLContext * context, gboolean activate)
|
||||||
|
|
||||||
egl = GST_GL_CONTEXT_EGL (context);
|
egl = GST_GL_CONTEXT_EGL (context);
|
||||||
|
|
||||||
if (activate)
|
if (activate) {
|
||||||
|
GstGLWindow *window = gst_gl_context_get_window (context);
|
||||||
|
EGLNativeWindowType handle = 0;
|
||||||
|
/* Check if the backing handle changed */
|
||||||
|
if (window) {
|
||||||
|
handle = (EGLNativeWindowType) gst_gl_window_get_window_handle (window);
|
||||||
|
gst_object_unref (window);
|
||||||
|
}
|
||||||
|
if (handle && handle != egl->window_handle) {
|
||||||
|
GST_DEBUG_OBJECT (context,
|
||||||
|
"Handle changed (have:%p, now:%p), switching surface",
|
||||||
|
(void *) egl->window_handle, (void *) handle);
|
||||||
|
if (egl->egl_surface) {
|
||||||
|
eglDestroySurface (egl->egl_display, egl->egl_surface);
|
||||||
|
egl->egl_surface = EGL_NO_SURFACE;
|
||||||
|
}
|
||||||
|
egl->egl_surface =
|
||||||
|
eglCreateWindowSurface (egl->egl_display, egl->egl_config, handle,
|
||||||
|
NULL);
|
||||||
|
egl->window_handle = handle;
|
||||||
|
}
|
||||||
result = eglMakeCurrent (egl->egl_display, egl->egl_surface,
|
result = eglMakeCurrent (egl->egl_display, egl->egl_surface,
|
||||||
egl->egl_surface, egl->egl_context);
|
egl->egl_surface, egl->egl_context);
|
||||||
else
|
} else
|
||||||
result = eglMakeCurrent (egl->egl_display, EGL_NO_SURFACE,
|
result = eglMakeCurrent (egl->egl_display, EGL_NO_SURFACE,
|
||||||
EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,9 @@ struct _GstGLContextEGL {
|
||||||
EGLImageKHR (*eglCreateImage) (EGLDisplay dpy, EGLContext ctx, EGLenum target,
|
EGLImageKHR (*eglCreateImage) (EGLDisplay dpy, EGLContext ctx, EGLenum target,
|
||||||
EGLClientBuffer buffer, const EGLint *attrib_list);
|
EGLClientBuffer buffer, const EGLint *attrib_list);
|
||||||
EGLBoolean (*eglDestroyImage) (EGLDisplay dpy, EGLImageKHR image);
|
EGLBoolean (*eglDestroyImage) (EGLDisplay dpy, EGLImageKHR image);
|
||||||
|
|
||||||
|
/* Cached handle */
|
||||||
|
EGLNativeWindowType window_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGLContextEGLClass {
|
struct _GstGLContextEGLClass {
|
||||||
|
|
Loading…
Reference in a new issue