From e4bb5be7b27cd3a5c8b6d98a1e1b5f9a55815103 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Nicolai=20H=C3=A4hnle?= Date: Thu, 2 Feb 2017 18:06:27 +0100 Subject: [PATCH] glx: guard swap-interval functions against destroyed drawables MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The GLX specification says about glXDestroyPixmap: "The storage for the GLX pixmap will be freed when it is not current to any client." So arguably, functions like glXSwapIntervalMESA can be called after glXDestroyPixmap has been called for the currently bound GLXPixmap. In that case, the GLXDRIDrawable no longer exists, and so we just skip those calls. Cc: 17.0 Reviewed-by: Marek Olšák Reviewed-by: Emil Velikov (cherry picked from commit f446f3fb33528eebe9b120340fca3ac5c5ba518d) --- src/glx/dri3_glx.c | 4 ++++ src/glx/glxcmds.c | 18 +++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c index 2d40f0ad458..42a94f9f242 100644 --- a/src/glx/dri3_glx.c +++ b/src/glx/dri3_glx.c @@ -564,6 +564,8 @@ dri3_destroy_screen(struct glx_screen *base) static int dri3_set_swap_interval(__GLXDRIdrawable *pdraw, int interval) { + assert(pdraw != NULL); + struct dri3_drawable *priv = (struct dri3_drawable *) pdraw; GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1; struct dri3_screen *psc = (struct dri3_screen *) priv->base.psc; @@ -597,6 +599,8 @@ dri3_set_swap_interval(__GLXDRIdrawable *pdraw, int interval) static int dri3_get_swap_interval(__GLXDRIdrawable *pdraw) { + assert(pdraw != NULL); + struct dri3_drawable *priv = (struct dri3_drawable *) pdraw; return priv->swap_interval; diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index 6c7bbfd5d1c..53c9f9ce2af 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -1761,7 +1761,11 @@ __glXSwapIntervalSGI(int interval) psc->driScreen->setSwapInterval) { __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable); - psc->driScreen->setSwapInterval(pdraw, interval); + /* Simply ignore the command if the GLX drawable has been destroyed but + * the context is still bound. + */ + if (pdraw) + psc->driScreen->setSwapInterval(pdraw, interval); return 0; } #endif @@ -1807,7 +1811,14 @@ __glXSwapIntervalMESA(unsigned int interval) if (psc && psc->driScreen && psc->driScreen->setSwapInterval) { __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable); - return psc->driScreen->setSwapInterval(pdraw, interval); + + /* Simply ignore the command if the GLX drawable has been destroyed but + * the context is still bound. + */ + if (!pdraw) + return 0; + + return psc->driScreen->setSwapInterval(pdraw, interval); } } #endif @@ -1829,7 +1840,8 @@ __glXGetSwapIntervalMESA(void) if (psc && psc->driScreen && psc->driScreen->getSwapInterval) { __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable); - return psc->driScreen->getSwapInterval(pdraw); + if (pdraw) + return psc->driScreen->getSwapInterval(pdraw); } } #endif -- 2.11.0