src/wayland-egldisplay.c
/* On wayland, when a wl_display backed EGLDisplay is created and then
 * wl_display is destroyed without terminating EGLDisplay first, some
 * driver allocated resources associated with wl_display could not be
 * destroyed properly during EGL teardown.
 * Per EGL spec: Termination of a display that has already been terminated,
 * or has not yet been initialized, is allowed, but the only effect of such
 * a call is to return EGL_TRUE, since there are no EGL resources associated
 * with the display to release.
 * However, in our wayland egl driver, we do allocate some resources
 * which are associated with wl_display even eglInitialize is not called.
 * If the app does not terminate EGLDisplay before closing wl_display,
 * it can hit assertion or hang in pthread_mutex_lock during EGL teardown.
 * To WAR the issue, in case wl_display has been destroyed, we skip
 * destroying some resources during EGL system termination, only when
 * terminateDisplay is called from wlEglDestroyAllDisplays.
 */
On wayland, when a wl_display backed EGLDisplay is created and then
wl_display is destroyed without terminating EGLDisplay first, some
driver allocated resources associated with wl_display could not be
destroyed properly during EGL teardown.
Per EGL spec: Termination of a display that has already been terminated,
or has not yet been initialized, is allowed, but the only effect of such
a call is to return EGL_TRUE, since there are no EGL resources associated
with the display to release.
However, in our wayland egl driver, we do allocate some resources
which are associated with wl_display even eglInitialize is not called.
If the app does not terminate EGLDisplay before closing wl_display,
it can hit assertion or hang in pthread_mutex_lock during EGL teardown.
To WAR the issue, in case wl_display has been destroyed, we skip
destroying some resources during EGL system termination, only when
terminateDisplay is called from wlEglDestroyAllDisplays.
On wayland when a wl_display backed EGLDisplay is created and then wl_display is destroyed without terminating EGLDisplay first some driver allocated resources associated with wl_display could not be destroyed properly during EGL teardown . Per EGL spec : Termination of a display that has already been terminated or has not yet been initialized is allowed but the only effect of such a call is to return EGL_TRUE since there are no EGL resources associated with the display to release . However in our wayland egl driver we do allocate some resources which are associated with wl_display even eglInitialize is not called . If the app does not terminate EGLDisplay before closing wl_display it can hit assertion or hang in pthread_mutex_lock during EGL teardown . To WAR the issue in case wl_display has been destroyed we skip destroying some resources during EGL system termination only when terminateDisplay is called from wlEglDestroyAllDisplays .
static EGLBoolean terminateDisplay(EGLDisplay dpy, EGLBoolean globalTeardown)
{
    WlEglDisplay      *display       = (WlEglDisplay *)dpy;
    if (display->initCount == 0) {
        return EGL_TRUE;
    }
    if (display->initCount > 1 && !globalTeardown) {
        display->initCount--;
        return EGL_TRUE;
    }
    if (!wlInternalTerminate(display->devDpy)) {
        if (!globalTeardown) {
            return EGL_FALSE;
        }
    }
    display->initCount = 0;
    wlEglDestroyAllSurfaces(display);
    if (!globalTeardown || display->ownNativeDpy) {
        if (display->wlRegistry) {
            wl_registry_destroy(display->wlRegistry);
            display->wlRegistry = NULL;
        }
        if (display->wlStreamDpy) {
            wl_eglstream_display_destroy(display->wlStreamDpy);
            display->wlStreamDpy = NULL;
        }
        if (display->wlEventQueue) {
            wl_event_queue_destroy(display->wlEventQueue);
            display->wlEventQueue = NULL;
        }
    }
    return EGL_TRUE;
}
static EGLBoolean terminateDisplay ( EGLDisplay dpy , EGLBoolean globalTeardown ) { WlEglDisplay * display = ( WlEglDisplay * ) dpy ; if ( display -> initCount == 0 ) { return EGL_TRUE ; } if ( display -> initCount > 1 && ! globalTeardown ) { display -> initCount -- ; return EGL_TRUE ; } if ( ! wlInternalTerminate ( display -> devDpy ) ) { if ( ! globalTeardown ) { return EGL_FALSE ; } } display -> initCount = 0 ; wlEglDestroyAllSurfaces ( display ) ; if ( ! globalTeardown || display -> ownNativeDpy ) { if ( display -> wlRegistry ) { wl_registry_destroy ( display -> wlRegistry ) ; display -> wlRegistry = NULL ; } if ( display -> wlStreamDpy ) { wl_eglstream_display_destroy ( display -> wlStreamDpy ) ; display -> wlStreamDpy = NULL ; } if ( display -> wlEventQueue ) { wl_event_queue_destroy ( display -> wlEventQueue ) ; display -> wlEventQueue = NULL ; } } return EGL_TRUE ; }
On wayland, when a wl_display backed EGLDisplay is created and then
 wl_display is destroyed without terminating EGLDisplay first, some
 driver allocated resources associated with wl_display could not be
 destroyed properly during EGL teardown.
On wayland when a wl_display backed EGLDisplay is created and then wl_display is destroyed without terminating EGLDisplay first some driver allocated resources associated with wl_display could not be destroyed properly during EGL teardown .
/* If globalTeardown is true, then ignore the refcount and terminate the
       display. That's used when the library is unloaded. */ /* First, destroy any surface associated to the given display. Then
     * destroy the display connection itself */