[Cogl] [PATCH] Bind the dummy surface or drawable when current onscreen is destroyed
Robert Bragg
robert at sixbynine.org
Fri Jan 25 09:16:42 PST 2013
This looks good to land to me:
Reviewed-by: Robert Bragg <robert at linux.intel.com>
thanks,
- Robert
On Thu, Jan 24, 2013 at 4:32 PM, Neil Roberts <neil at linux.intel.com> wrote:
> Similar to commit 2c0cfdefbb9d1 for the SDL2 winsys, the GLX and EGL
> window systems need to bind the dummy surface or drawable when the
> currently bound onscreen is destroyed so that there will always be a
> valid context bound.
>
> Previously I got the idea that this would not be necessary on GLX
> because the documentation for glXDestroyDrawable states that the
> drawable won't actually be destroyed if it is currently bound until it
> becomes unbound. However it doesn't say what happens if the underlying
> X window is also destroyed and after testing it seems this causes a
> segfault in Mesa in GLX and an XError for EGLX.
> ---
> cogl/winsys/cogl-winsys-egl.c | 17 ++++++++++++++++-
> cogl/winsys/cogl-winsys-glx.c | 27 ++++++++++++++++++++++++++-
> 2 files changed, 42 insertions(+), 2 deletions(-)
>
> diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c
> index cd6ae3a..223aa84 100644
> --- a/cogl/winsys/cogl-winsys-egl.c
> +++ b/cogl/winsys/cogl-winsys-egl.c
> @@ -3,7 +3,7 @@
> *
> * An object oriented GL/GLES Abstraction/Utility Layer
> *
> - * Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation.
> + * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation.
> *
> * This library is free software; you can redistribute it and/or
> * modify it under the terms of the GNU Lesser General Public
> @@ -625,6 +625,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
> {
> CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
> CoglContext *context = framebuffer->context;
> + CoglDisplayEGL *egl_display = context->display->winsys;
> CoglRenderer *renderer = context->display->renderer;
> CoglRendererEGL *egl_renderer = renderer->winsys;
> CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
> @@ -632,8 +633,22 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
> /* If we never successfully allocated then there's nothing to do */
> if (egl_onscreen == NULL)
> return;
> +
> if (egl_onscreen->egl_surface != EGL_NO_SURFACE)
> {
> + /* Cogl always needs a valid context bound to something so if we
> + * are destroying the onscreen that is currently bound we'll
> + * switch back to the dummy drawable. */
> + if (egl_display->dummy_surface != EGL_NO_SURFACE &&
> + (egl_display->current_draw_surface == egl_onscreen->egl_surface ||
> + egl_display->current_read_surface == egl_onscreen->egl_surface))
> + {
> + _cogl_winsys_egl_make_current (context->display,
> + egl_display->dummy_surface,
> + egl_display->dummy_surface,
> + egl_display->current_context);
> + }
> +
> if (eglDestroySurface (egl_renderer->edpy, egl_onscreen->egl_surface)
> == EGL_FALSE)
> g_warning ("Failed to destroy EGL surface");
> diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c
> index 3a0abba..6301c38 100644
> --- a/cogl/winsys/cogl-winsys-glx.c
> +++ b/cogl/winsys/cogl-winsys-glx.c
> @@ -3,7 +3,7 @@
> *
> * An object oriented GL/GLES Abstraction/Utility Layer
> *
> - * Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation.
> + * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation.
> *
> * This library is free software; you can redistribute it and/or
> * modify it under the terms of the GNU Lesser General Public
> @@ -1036,12 +1036,15 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
> {
> CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
> CoglContext *context = framebuffer->context;
> + CoglContextGLX *glx_context = context->winsys;
> + CoglGLXDisplay *glx_display = context->display->winsys;
> CoglXlibRenderer *xlib_renderer =
> _cogl_xlib_renderer_get_data (context->display->renderer);
> CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
> CoglXlibTrapState old_state;
> CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
> CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
> + GLXDrawable drawable;
>
> /* If we never successfully allocated then there's nothing to do */
> if (glx_onscreen == NULL)
> @@ -1049,6 +1052,28 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
>
> _cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state);
>
> + drawable =
> + glx_onscreen->glxwin == None ? xlib_onscreen->xwin : glx_onscreen->glxwin;
> +
> + /* Cogl always needs a valid context bound to something so if we are
> + * destroying the onscreen that is currently bound we'll switch back
> + * to the dummy drawable. Although the documentation for
> + * glXDestroyWindow states that a currently bound window won't
> + * actually be destroyed until it is unbound, it looks like this
> + * doesn't work if the X window itself is destroyed */
> + if (drawable == glx_context->current_drawable)
> + {
> + GLXDrawable dummy_drawable = (glx_display->dummy_glxwin == None ?
> + glx_display->dummy_xwin :
> + glx_display->dummy_glxwin);
> +
> + glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
> + dummy_drawable,
> + dummy_drawable,
> + glx_display->glx_context);
> + glx_context->current_drawable = dummy_drawable;
> + }
> +
> if (glx_onscreen->glxwin != None)
> {
> glx_renderer->glXDestroyWindow (xlib_renderer->xdpy,
> --
> 1.7.11.3.g3c3efa5
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl
More information about the Cogl
mailing list