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; }
/** * 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; }
/** * 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; }
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; }
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; }
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; }
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; }
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; }
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; }