Bind the dummy surface or drawable when current onscreen is destroyed
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. Reviewed-by: Robert Bragg <robert@linux.intel.com> (cherry picked from commit 4a464eec8c5b5832b9fd6b69746ab4ab36229182)
This commit is contained in:
parent
da7971f6be
commit
1e00ff268e
@ -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");
|
||||
|
@ -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
|
||||
@ -1046,12 +1046,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)
|
||||
@ -1059,6 +1062,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,
|
||||
|
Loading…
Reference in New Issue
Block a user