egl/dri2: only take a dri2_dpy reference when binding a new context/surfaces
authorFrank Binns <>
Tue, 28 Jul 2020 14:50:30 +0000 (15:50 +0100)
committerMarge Bot <>
Wed, 29 Jul 2020 20:01:14 +0000 (20:01 +0000)
This effectively reverts part of 2907faee, which changed dri2_make_current() to
always take a dri2_dpy reference regardless of whether or not a new context or
surface(s) were being bound. This led to a reference count imbalance as there
was no corresponding code added to drop a reference on the dri2_dpy. As a
consequence, any application that called eglInitialize() on a default/native
display after having called eglTerminate() would always get back the old
dri2_dpy, inheriting its previous state.

As the reference count is there to prevent the dri2_dpy from being destroyed
between eglTerminate() and eglInitialize() calls when a context is still bound,
a reference should only be taken when a successful call to
dri2_dpy->core->bindContext() has been made. Fix the issue by restoring the old
reference counting behaviour.

Fixes: 4e8f95f64d004 ("egl_dri2: Always unbind old contexts")
Fixes: 2907faee7a397 ("egl/dri2: try to bind old context if bindContext failed")
Signed-off-by: Frank Binns <>
Reviewed-by: Luigi Santivetti <>
Reviewed-by: Emil Velikov <>
Tested-by: Nicolas Cortes <>
Part-of: <>


index 299508b679cb274768d59dd4f69b71ea4c365bee..ba0d78cf64d00521618a19a72c4ed031560a2d79 100644 (file)
@@ -1852,6 +1852,13 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
                 tmp_rsurf == old_rsurf);
          _eglLog(_EGL_WARNING, "DRI2: failed to rebind the previous context");
+      } else {
+         /* dri2_dpy->core->bindContext succeeded, so take a reference on the
+          * dri2_dpy. This prevents dri2_dpy from being reinitialized when a
+          * EGLDisplay is terminated and then initialized again while a
+          * context is still bound. See dri2_intitialize() for a more in depth
+          * explanation. */
+         dri2_dpy->ref_count++;
@@ -1866,8 +1873,6 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
    if (egl_error != EGL_SUCCESS)
       return _eglError(egl_error, "eglMakeCurrent");
-   dri2_dpy->ref_count++;
    if (dsurf && _eglSurfaceHasMutableRenderBuffer(dsurf) &&
        dri2_dpy->vtbl->set_shared_buffer_mode) {
       /* Always update the shared buffer mode. This is obviously needed when