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_dri3(_EGLDriver *drv, _EGLDisplay *disp) { _EGLDevice *dev; struct dri2_egl_display *dri2_dpy; dri2_dpy = calloc(1, sizeof *dri2_dpy); if (!dri2_dpy) return _eglError(EGL_BAD_ALLOC, "eglInitialize"); dri2_dpy->fd = -1; if (!dri2_get_xcb_connection(drv, disp, dri2_dpy)) goto cleanup; if (!dri3_x11_connect(dri2_dpy)) goto cleanup; dev = _eglAddDevice(dri2_dpy->fd, false); if (!dev) { _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice"); goto cleanup; } disp->Device = dev; if (!dri2_load_driver_dri3(disp)) goto cleanup; dri2_dpy->loader_extensions = dri3_image_loader_extensions; dri2_dpy->swap_available = true; dri2_dpy->invalidate_available = true; if (!dri2_create_screen(disp)) goto cleanup; if (!dri2_setup_extensions(disp)) goto cleanup; dri2_setup_screen(disp); dri2_x11_setup_swap_interval(disp); 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; dri2_set_WL_bind_wayland_display(drv, disp); if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, false)) goto cleanup; 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: dri2_display_destroy(disp); return EGL_FALSE; }