Beispiel #1
0
EGLBoolean
drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
	struct drm_device *dev = lookup_drm_device(dpy);
	struct drm_screen *screen;
	int i = 0;

	_eglReleaseDisplayResources(drv, dpy);
	_eglCleanupDisplay(dpy);

	drmFreeVersion(dev->version);

	for (i = 0; i < dev->count_screens; i++) {
		screen = dev->screens[i];

		if (screen->shown)
			drm_takedown_shown_screen(dpy, screen);

		drmModeFreeProperty(screen->dpms);
		drmModeFreeConnector(screen->connector);
		_eglDestroyScreen(&screen->base);
		dev->screens[i] = NULL;
	}

	dev->screen->destroy(dev->screen);
	dev->winsys = NULL;

	drmClose(dev->drmFD);

	dev->api->destroy(dev->api);
	free(dev);
	dpy->DriverData = NULL;

	return EGL_TRUE;
}
static EGLBoolean
egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);

   _eglReleaseDisplayResources(drv, dpy);

   if (dpy->Configs) {
      _eglDestroyArray(dpy->Configs, egl_g3d_free_config);
      dpy->Configs = NULL;
   }
   if (dpy->Screens) {
      _eglDestroyArray(dpy->Screens, egl_g3d_free_screen);
      dpy->Screens = NULL;
   }

   _eglCleanupDisplay(dpy);

   if (gdpy->smapi)
      egl_g3d_destroy_st_manager(gdpy->smapi);

   if (gdpy->native)
      gdpy->native->destroy(gdpy->native);

   FREE(gdpy);
   dpy->DriverData = NULL;

   return EGL_TRUE;
}
Beispiel #3
0
/**
 * Called via eglTerminate(), drv->API.Terminate().
 */
static EGLBoolean
xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
   struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
   __GLXscreenConfigs *psc;

   _eglReleaseDisplayResources(drv, dpy);
   _eglCleanupDisplay(dpy);

   psc = xdri_dpy->psc;
   if (psc->driver_configs) {
      unsigned int i;
      for (i = 0; psc->driver_configs[i]; i++)
         free((__DRIconfig *) psc->driver_configs[i]);
      free(psc->driver_configs);
      psc->driver_configs = NULL;
   }
   if (psc->driScreen) {
      psc->driScreen->destroyScreen(psc);
      free(psc->driScreen);
      psc->driScreen = NULL;
   }

   xdri_dpy->driDisplay->destroyDisplay(xdri_dpy->driDisplay);
   __glXRelease(xdri_dpy->dpyPriv);

   free(xdri_dpy);
   dpy->DriverData = NULL;

   return EGL_TRUE;
}
static EGLBoolean
fbTerminate(_EGLDriver *drv, EGLDisplay dpy)
{
   fbDisplay *display = Lookup_fbDisplay(dpy);
   _eglCleanupDisplay(&display->Base);
   free(display);
   free(drv);
   return EGL_TRUE;
}
Beispiel #5
0
/**
 * Called via eglTerminate(), drv->API.Terminate().
 */
static EGLBoolean
dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);

   _eglReleaseDisplayResources(drv, disp);
   _eglCleanupDisplay(disp);

   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
   close(dri2_dpy->fd);
   dlclose(dri2_dpy->driver);
   free(dri2_dpy->driver_name);
   free(dri2_dpy->device_name);
   wl_drm_destroy(dri2_dpy->wl_drm);
   if (dri2_dpy->own_device)
      wl_display_destroy(dri2_dpy->wl_dpy);
   free(dri2_dpy);
   disp->DriverData = NULL;

   return EGL_TRUE;
}
Beispiel #6
0
static EGLBoolean
dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp)
{
   struct dri2_egl_display *dri2_dpy;

   drv->API.CreateWindowSurface = dri2_create_window_surface;
   drv->API.CreatePixmapSurface = dri2_create_pixmap_surface;
   drv->API.CreatePbufferSurface = dri2_create_pbuffer_surface;
   drv->API.DestroySurface = dri2_destroy_surface;
   drv->API.SwapBuffers = dri2_swap_buffers;
   drv->API.CopyBuffers = dri2_copy_buffers;

   drv->API.SwapBuffersRegionNOK = NULL;
   drv->API.CreateImageKHR  = NULL;
   drv->API.DestroyImageKHR = NULL;
   drv->API.CreateDRMImageMESA = NULL;
   drv->API.ExportDRMImageMESA = NULL;

   dri2_dpy = calloc(1, sizeof *dri2_dpy);
   if (!dri2_dpy)
      return _eglError(EGL_BAD_ALLOC, "eglInitialize");

   disp->DriverData = (void *) dri2_dpy;
   if (disp->PlatformDisplay == NULL) {
      dri2_dpy->conn = xcb_connect(0, 0);
   } else {
      dri2_dpy->conn = XGetXCBConnection((Display *) disp->PlatformDisplay);
   }

   if (xcb_connection_has_error(dri2_dpy->conn)) {
      _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
      goto cleanup_dpy;
   }

   if (!dri2_load_driver_swrast(disp))
      goto cleanup_conn;

   dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER;
   dri2_dpy->swrast_loader_extension.base.version = __DRI_SWRAST_LOADER_VERSION;
   dri2_dpy->swrast_loader_extension.getDrawableInfo = swrastGetDrawableInfo;
   dri2_dpy->swrast_loader_extension.putImage = swrastPutImage;
   dri2_dpy->swrast_loader_extension.getImage = swrastGetImage;

   dri2_dpy->extensions[0] = &dri2_dpy->swrast_loader_extension.base;
   dri2_dpy->extensions[1] = NULL;
   dri2_dpy->extensions[2] = NULL;

   if (!dri2_create_screen(disp))
      goto cleanup_driver;

   if (dri2_dpy->conn) {
      if (!dri2_add_configs_for_visuals(dri2_dpy, disp))
         goto cleanup_configs;
   }

   /* we're supporting EGL 1.4 */
   disp->VersionMajor = 1;
   disp->VersionMinor = 4;

   return EGL_TRUE;

 cleanup_configs:
   _eglCleanupDisplay(disp);
   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
 cleanup_driver:
   dlclose(dri2_dpy->driver);
 cleanup_conn:
   if (disp->PlatformDisplay == NULL)
      xcb_disconnect(dri2_dpy->conn);
 cleanup_dpy:
   free(dri2_dpy);

   return EGL_FALSE;
}
Beispiel #7
0
static EGLBoolean
dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
{
   struct dri2_egl_display *dri2_dpy;

   drv->API.CreateWindowSurface = dri2_create_window_surface;
   drv->API.CreatePixmapSurface = dri2_create_pixmap_surface;
   drv->API.CreatePbufferSurface = dri2_create_pbuffer_surface;
   drv->API.DestroySurface = dri2_destroy_surface;
   drv->API.SwapBuffers = dri2_swap_buffers;
   drv->API.CopyBuffers = dri2_copy_buffers;
   drv->API.CreateImageKHR = dri2_x11_create_image_khr;
   drv->API.SwapBuffersRegionNOK = dri2_swap_buffers_region;
   drv->API.PostSubBufferNV = dri2_post_sub_buffer;
   drv->API.SwapInterval = dri2_swap_interval;

   dri2_dpy = calloc(1, sizeof *dri2_dpy);
   if (!dri2_dpy)
      return _eglError(EGL_BAD_ALLOC, "eglInitialize");

   disp->DriverData = (void *) dri2_dpy;
   if (disp->PlatformDisplay == NULL) {
      dri2_dpy->conn = xcb_connect(0, 0);
   } else {
      dri2_dpy->conn = XGetXCBConnection((Display *) disp->PlatformDisplay);
   }

   if (xcb_connection_has_error(dri2_dpy->conn)) {
      _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
      goto cleanup_dpy;
   }

   if (dri2_dpy->conn) {
      if (!dri2_connect(dri2_dpy))
	 goto cleanup_conn;
   }

   if (!dri2_load_driver(disp))
      goto cleanup_conn;

#ifdef O_CLOEXEC
   dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC);
   if (dri2_dpy->fd == -1 && errno == EINVAL)
#endif
   {
      dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
      if (dri2_dpy->fd != -1)
         fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) |
            FD_CLOEXEC);
   }
   if (dri2_dpy->fd == -1) {
      _eglLog(_EGL_WARNING,
	      "DRI2: could not open %s (%s)", dri2_dpy->device_name,
              strerror(errno));
      goto cleanup_driver;
   }

   if (dri2_dpy->conn) {
      if (!dri2_authenticate(disp))
	 goto cleanup_fd;
   }

   if (dri2_dpy->dri2_minor >= 1) {
      dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
      dri2_dpy->dri2_loader_extension.base.version = 3;
      dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers;
      dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
      dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
	 dri2_get_buffers_with_format;
   } else {
      dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
      dri2_dpy->dri2_loader_extension.base.version = 2;
      dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers;
      dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
      dri2_dpy->dri2_loader_extension.getBuffersWithFormat = NULL;
   }
      
   dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
   dri2_dpy->extensions[1] = &image_lookup_extension.base;
   dri2_dpy->extensions[2] = NULL;

   dri2_dpy->swap_available = (dri2_dpy->dri2_minor >= 2);
   dri2_dpy->invalidate_available = (dri2_dpy->dri2_minor >= 3);

   if (!dri2_create_screen(disp))
      goto cleanup_fd;

   dri2_setup_swap_interval(dri2_dpy);

   disp->Extensions.KHR_image_pixmap = EGL_TRUE;
   disp->Extensions.NOK_swap_region = EGL_TRUE;
   disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
   disp->Extensions.NV_post_sub_buffer = EGL_TRUE;

#ifdef HAVE_WAYLAND_PLATFORM
   disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
#endif

   if (dri2_dpy->conn) {
      if (!dri2_add_configs_for_visuals(dri2_dpy, disp))
	 goto cleanup_configs;
   }

   dri2_dpy->authenticate = dri2_x11_authenticate;

   /* we're supporting EGL 1.4 */
   disp->VersionMajor = 1;
   disp->VersionMinor = 4;

   return EGL_TRUE;

 cleanup_configs:
   _eglCleanupDisplay(disp);
   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
 cleanup_fd:
   close(dri2_dpy->fd);
 cleanup_driver:
   dlclose(dri2_dpy->driver);
 cleanup_conn:
   if (disp->PlatformDisplay == NULL)
      xcb_disconnect(dri2_dpy->conn);
 cleanup_dpy:
   free(dri2_dpy);

   return EGL_FALSE;
}
Beispiel #8
0
static EGLBoolean
dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
{
   struct dri2_egl_display *dri2_dpy;

   dri2_dpy = calloc(1, sizeof *dri2_dpy);
   if (!dri2_dpy)
      return _eglError(EGL_BAD_ALLOC, "eglInitialize");

   disp->DriverData = (void *) dri2_dpy;
   if (disp->PlatformDisplay == NULL) {
      dri2_dpy->conn = xcb_connect(0, &dri2_dpy->screen);
      dri2_dpy->own_device = true;
   } else {
      Display *dpy = disp->PlatformDisplay;

      dri2_dpy->conn = XGetXCBConnection(dpy);
      dri2_dpy->screen = DefaultScreen(dpy);
   }

   if (!dri2_dpy->conn || xcb_connection_has_error(dri2_dpy->conn)) {
      _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
      goto cleanup_dpy;
   }

   if (!dri2_x11_connect(dri2_dpy))
      goto cleanup_conn;

   if (!dri2_load_driver(disp))
      goto cleanup_fd;

   if (dri2_dpy->dri2_minor >= 1) {
      dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
      dri2_dpy->dri2_loader_extension.base.version = 3;
      dri2_dpy->dri2_loader_extension.getBuffers = dri2_x11_get_buffers;
      dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_x11_flush_front_buffer;
      dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
	 dri2_x11_get_buffers_with_format;
   } else {
      dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
      dri2_dpy->dri2_loader_extension.base.version = 2;
      dri2_dpy->dri2_loader_extension.getBuffers = dri2_x11_get_buffers;
      dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_x11_flush_front_buffer;
      dri2_dpy->dri2_loader_extension.getBuffersWithFormat = NULL;
   }
      
   dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
   dri2_dpy->extensions[1] = &image_lookup_extension.base;
   dri2_dpy->extensions[2] = NULL;

   dri2_dpy->swap_available = (dri2_dpy->dri2_minor >= 2);
   dri2_dpy->invalidate_available = (dri2_dpy->dri2_minor >= 3);

   if (!dri2_create_screen(disp))
      goto cleanup_driver;

   dri2_x11_setup_swap_interval(dri2_dpy);

   disp->Extensions.KHR_image_pixmap = EGL_TRUE;
   disp->Extensions.NOK_swap_region = EGL_TRUE;
   disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
   disp->Extensions.NV_post_sub_buffer = EGL_TRUE;
   disp->Extensions.CHROMIUM_sync_control = EGL_TRUE;

#ifdef HAVE_WAYLAND_PLATFORM
   disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
#endif

   if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, true))
      goto cleanup_configs;

   /* Fill vtbl last to prevent accidentally calling virtual function during
    * initialization.
    */
   dri2_dpy->vtbl = &dri2_x11_display_vtbl;

   _eglLog(_EGL_INFO, "Using DRI2");

   return EGL_TRUE;

 cleanup_configs:
   _eglCleanupDisplay(disp);
   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
 cleanup_driver:
   dlclose(dri2_dpy->driver);
 cleanup_fd:
   close(dri2_dpy->fd);
 cleanup_conn:
   if (disp->PlatformDisplay == NULL)
      xcb_disconnect(dri2_dpy->conn);
 cleanup_dpy:
   free(dri2_dpy);

   return EGL_FALSE;
}
Beispiel #9
0
static EGLBoolean
dri2_initialize_x11_dri3(_EGLDriver *drv, _EGLDisplay *disp)
{
   struct dri2_egl_display *dri2_dpy;

   dri2_dpy = calloc(1, sizeof *dri2_dpy);
   if (!dri2_dpy)
      return _eglError(EGL_BAD_ALLOC, "eglInitialize");

   disp->DriverData = (void *) dri2_dpy;
   if (disp->PlatformDisplay == NULL) {
      dri2_dpy->conn = xcb_connect(0, &dri2_dpy->screen);
      dri2_dpy->own_device = true;
   } else {
      Display *dpy = disp->PlatformDisplay;

      dri2_dpy->conn = XGetXCBConnection(dpy);
      dri2_dpy->screen = DefaultScreen(dpy);
   }

   if (xcb_connection_has_error(dri2_dpy->conn)) {
      _eglLog(_EGL_WARNING, "DRI3: xcb_connect failed");
      goto cleanup_dpy;
   }

   if (dri2_dpy->conn) {
      if (!dri3_x11_connect(dri2_dpy))
         goto cleanup_conn;
   }

   if (!dri2_load_driver_dri3(disp))
      goto cleanup_conn;

   dri2_dpy->extensions[0] = &dri3_image_loader_extension.base;
   dri2_dpy->extensions[1] = &use_invalidate.base;
   dri2_dpy->extensions[2] = &image_lookup_extension.base;
   dri2_dpy->extensions[3] = NULL;

   dri2_dpy->swap_available = true;
   dri2_dpy->invalidate_available = true;

   if (!dri2_create_screen(disp))
      goto cleanup_fd;

   dri2_x11_setup_swap_interval(dri2_dpy);

   if (!dri2_dpy->is_different_gpu)
      disp->Extensions.KHR_image_pixmap = EGL_TRUE;
   disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
   disp->Extensions.CHROMIUM_sync_control = EGL_TRUE;
   disp->Extensions.EXT_buffer_age = EGL_TRUE;

#ifdef HAVE_WAYLAND_PLATFORM
   disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
#endif

   if (dri2_dpy->conn) {
      if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, false))
         goto cleanup_configs;
   }

   dri2_dpy->loader_dri3_ext.core = dri2_dpy->core;
   dri2_dpy->loader_dri3_ext.image_driver = dri2_dpy->image_driver;
   dri2_dpy->loader_dri3_ext.flush = dri2_dpy->flush;
   dri2_dpy->loader_dri3_ext.tex_buffer = dri2_dpy->tex_buffer;
   dri2_dpy->loader_dri3_ext.image = dri2_dpy->image;
   dri2_dpy->loader_dri3_ext.config = dri2_dpy->config;

   /* Fill vtbl last to prevent accidentally calling virtual function during
    * initialization.
    */
   dri2_dpy->vtbl = &dri3_x11_display_vtbl;

   _eglLog(_EGL_INFO, "Using DRI3");

   return EGL_TRUE;

 cleanup_configs:
   _eglCleanupDisplay(disp);
   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
   dlclose(dri2_dpy->driver);
 cleanup_fd:
   close(dri2_dpy->fd);
 cleanup_conn:
   if (disp->PlatformDisplay == NULL)
      xcb_disconnect(dri2_dpy->conn);
 cleanup_dpy:
   free(dri2_dpy);

   return EGL_FALSE;
}
Beispiel #10
0
static EGLBoolean
dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp)
{
   struct dri2_egl_display *dri2_dpy;

   dri2_dpy = calloc(1, sizeof *dri2_dpy);
   if (!dri2_dpy)
      return _eglError(EGL_BAD_ALLOC, "eglInitialize");

   disp->DriverData = (void *) dri2_dpy;
   if (disp->PlatformDisplay == NULL) {
      dri2_dpy->conn = xcb_connect(0, &dri2_dpy->screen);
      dri2_dpy->own_device = true;
   } else {
      Display *dpy = disp->PlatformDisplay;

      dri2_dpy->conn = XGetXCBConnection(dpy);
      dri2_dpy->screen = DefaultScreen(dpy);
   }

   if (!dri2_dpy->conn || xcb_connection_has_error(dri2_dpy->conn)) {
      _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
      goto cleanup_dpy;
   }

   /*
    * Every hardware driver_name is set using strdup. Doing the same in
    * here will allow is to simply free the memory at dri2_terminate().
    */
   dri2_dpy->fd = -1;
   dri2_dpy->driver_name = strdup("swrast");
   if (!dri2_load_driver_swrast(disp))
      goto cleanup_conn;

   dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER;
   dri2_dpy->swrast_loader_extension.base.version = 2;
   dri2_dpy->swrast_loader_extension.getDrawableInfo = swrastGetDrawableInfo;
   dri2_dpy->swrast_loader_extension.putImage = swrastPutImage;
   dri2_dpy->swrast_loader_extension.getImage = swrastGetImage;

   dri2_dpy->extensions[0] = &dri2_dpy->swrast_loader_extension.base;
   dri2_dpy->extensions[1] = NULL;
   dri2_dpy->extensions[2] = NULL;

   if (!dri2_create_screen(disp))
      goto cleanup_driver;

   if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, true))
      goto cleanup_configs;

   /* Fill vtbl last to prevent accidentally calling virtual function during
    * initialization.
    */
   dri2_dpy->vtbl = &dri2_x11_swrast_display_vtbl;

   return EGL_TRUE;

 cleanup_configs:
   _eglCleanupDisplay(disp);
   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
 cleanup_driver:
   dlclose(dri2_dpy->driver);
 cleanup_conn:
   free(dri2_dpy->driver_name);
   if (disp->PlatformDisplay == NULL)
      xcb_disconnect(dri2_dpy->conn);
 cleanup_dpy:
   free(dri2_dpy);

   return EGL_FALSE;
}
Beispiel #11
0
static EGLBoolean
dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp)
{
   struct dri2_egl_display *dri2_dpy;

   dri2_dpy = calloc(1, sizeof *dri2_dpy);
   if (!dri2_dpy)
      return _eglError(EGL_BAD_ALLOC, "eglInitialize");

   disp->DriverData = (void *) dri2_dpy;
   if (disp->PlatformDisplay == NULL) {
      dri2_dpy->conn = xcb_connect(0, 0);
      dri2_dpy->own_device = true;
   } else {
      dri2_dpy->conn = XGetXCBConnection((Display *) disp->PlatformDisplay);
   }

   if (xcb_connection_has_error(dri2_dpy->conn)) {
      _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
      goto cleanup_dpy;
   }

   if (!dri2_load_driver_swrast(disp))
      goto cleanup_conn;

   dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER;
   dri2_dpy->swrast_loader_extension.base.version = __DRI_SWRAST_LOADER_VERSION;
   dri2_dpy->swrast_loader_extension.getDrawableInfo = swrastGetDrawableInfo;
   dri2_dpy->swrast_loader_extension.putImage = swrastPutImage;
   dri2_dpy->swrast_loader_extension.getImage = swrastGetImage;

   dri2_dpy->extensions[0] = &dri2_dpy->swrast_loader_extension.base;
   dri2_dpy->extensions[1] = NULL;
   dri2_dpy->extensions[2] = NULL;

   if (!dri2_create_screen(disp))
      goto cleanup_driver;

   if (dri2_dpy->conn) {
      if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp))
         goto cleanup_configs;
   }

   /* we're supporting EGL 1.4 */
   disp->VersionMajor = 1;
   disp->VersionMinor = 4;

   /* Fill vtbl last to prevent accidentally calling virtual function during
    * initialization.
    */
   dri2_dpy->vtbl = &dri2_x11_swrast_display_vtbl;

   return EGL_TRUE;

 cleanup_configs:
   _eglCleanupDisplay(disp);
   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
 cleanup_driver:
   dlclose(dri2_dpy->driver);
 cleanup_conn:
   if (disp->PlatformDisplay == NULL)
      xcb_disconnect(dri2_dpy->conn);
 cleanup_dpy:
   free(dri2_dpy);

   return EGL_FALSE;
}