/** * Initialize DRI2 and pipe screen. */ static boolean dri2_display_init_screen(struct native_display *ndpy) { struct dri2_display *dri2dpy = dri2_display(ndpy); int fd; if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) || !x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_GLX)) { _eglLog(_EGL_WARNING, "GLX/DRI2 is not supported"); return FALSE; } dri2dpy->dri_driver = x11_screen_probe_dri2(dri2dpy->xscr, &dri2dpy->dri_major, &dri2dpy->dri_minor); fd = x11_screen_enable_dri2(dri2dpy->xscr, dri2_display_invalidate_buffers, &dri2dpy->base); if (fd < 0) return FALSE; dri2dpy->base.screen = dri2dpy->event_handler->new_drm_screen(&dri2dpy->base, dri2dpy->dri_driver, fd); if (!dri2dpy->base.screen) { _eglLog(_EGL_DEBUG, "failed to create DRM screen"); return FALSE; } return TRUE; }
static boolean dri2_display_get_pixmap_format(struct native_display *ndpy, EGLNativePixmapType pix, enum pipe_format *format) { struct dri2_display *dri2dpy = dri2_display(ndpy); boolean ret = EGL_TRUE; uint depth; depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix); switch (depth) { case 32: case 24: *format = PIPE_FORMAT_B8G8R8A8_UNORM; break; case 16: *format = PIPE_FORMAT_B5G6R5_UNORM; break; default: *format = PIPE_FORMAT_NONE; ret = EGL_FALSE; break; } return ret; }
static struct native_surface * dri2_display_create_pixmap_surface(struct native_display *ndpy, EGLNativePixmapType pix, const struct native_config *nconf) { struct dri2_surface *dri2surf; if (!nconf) { struct dri2_display *dri2dpy = dri2_display(ndpy); uint depth, nconf_depth; int i; depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix); for (i = 0; i < dri2dpy->num_configs; i++) { nconf_depth = util_format_get_blocksizebits( dri2dpy->configs[i].base.color_format); /* simple depth match for now */ if (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth)) { nconf = &dri2dpy->configs[i].base; break; } } if (!nconf) return NULL; } dri2surf = dri2_display_create_surface(ndpy, (Drawable) pix, nconf->color_format); return (dri2surf) ? &dri2surf->base : NULL; }
static struct dri2_surface * dri2_display_create_surface(struct native_display *ndpy, Drawable drawable, enum pipe_format color_format) { struct dri2_display *dri2dpy = dri2_display(ndpy); struct dri2_surface *dri2surf; dri2surf = CALLOC_STRUCT(dri2_surface); if (!dri2surf) return NULL; dri2surf->dri2dpy = dri2dpy; dri2surf->drawable = drawable; dri2surf->color_format = color_format; dri2surf->base.destroy = dri2_surface_destroy; dri2surf->base.present = dri2_surface_present; dri2surf->base.validate = dri2_surface_validate; dri2surf->base.wait = dri2_surface_wait; if (drawable) { x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE); /* initialize the geometry */ dri2_surface_update_buffers(&dri2surf->base, 0x0); util_hash_table_set(dri2surf->dri2dpy->surfaces, (void *) dri2surf->drawable, (void *) &dri2surf->base); } return dri2surf; }
static int dri2_display_authenticate(void *user_data, uint32_t magic) { struct native_display *ndpy = user_data; struct dri2_display *dri2dpy = dri2_display(ndpy); return x11_screen_authenticate(dri2dpy->xscr, magic); }
static boolean dri2_display_unbind_wayland_display(struct native_display *ndpy, struct wl_display *wl_dpy) { struct dri2_display *dri2dpy = dri2_display(ndpy); if (!dri2dpy->wl_server_drm) return FALSE; wayland_drm_uninit(dri2dpy->wl_server_drm); dri2dpy->wl_server_drm = NULL; return TRUE; }
static boolean dri2_display_bind_wayland_display(struct native_display *ndpy, struct wl_display *wl_dpy) { struct dri2_display *dri2dpy = dri2_display(ndpy); if (dri2dpy->wl_server_drm) return FALSE; dri2dpy->wl_server_drm = wayland_drm_init(wl_dpy, x11_screen_get_device_name(dri2dpy->xscr), &wl_drm_callbacks, ndpy, 0); if (!dri2dpy->wl_server_drm) return FALSE; return TRUE; }
static void dri2_display_destroy(struct native_display *ndpy) { struct dri2_display *dri2dpy = dri2_display(ndpy); FREE(dri2dpy->configs); if (dri2dpy->base.screen) dri2dpy->base.screen->destroy(dri2dpy->base.screen); if (dri2dpy->surfaces) util_hash_table_destroy(dri2dpy->surfaces); if (dri2dpy->xscr) x11_screen_destroy(dri2dpy->xscr); if (dri2dpy->own_dpy) XCloseDisplay(dri2dpy->dpy); FREE(dri2dpy); }
static void dri2_display_invalidate_buffers(struct x11_screen *xscr, Drawable drawable, void *user_data) { struct native_display *ndpy = (struct native_display* ) user_data; struct dri2_display *dri2dpy = dri2_display(ndpy); struct native_surface *nsurf; struct dri2_surface *dri2surf; nsurf = (struct native_surface *) util_hash_table_get(dri2dpy->surfaces, (void *) drawable); if (!nsurf) return; dri2surf = dri2_surface(nsurf); dri2surf->server_stamp++; dri2dpy->event_handler->invalid_surface(&dri2dpy->base, &dri2surf->base, dri2surf->server_stamp); }
static void dri2_display_destroy(struct native_display *ndpy) { struct dri2_display *dri2dpy = dri2_display(ndpy); FREE(dri2dpy->configs); if (dri2dpy->base.screen) dri2dpy->base.screen->destroy(dri2dpy->base.screen); if (dri2dpy->surfaces) util_hash_table_destroy(dri2dpy->surfaces); #ifdef HAVE_WAYLAND_BACKEND wayland_drm_bufmgr_destroy(ndpy->wayland_bufmgr); #endif if (dri2dpy->xscr) x11_screen_destroy(dri2dpy->xscr); if (dri2dpy->own_dpy) XCloseDisplay(dri2dpy->dpy); FREE(dri2dpy); }
/** * Initialize DRI2 and pipe screen. */ static boolean dri2_display_init_screen(struct native_display *ndpy) { struct dri2_display *dri2dpy = dri2_display(ndpy); int fd; if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) || !x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_GLX)) { _eglLog(_EGL_WARNING, "GLX/DRI2 is not supported"); return FALSE; } dri2dpy->dri_driver = x11_screen_probe_dri2(dri2dpy->xscr, &dri2dpy->dri_major, &dri2dpy->dri_minor); fd = x11_screen_enable_dri2(dri2dpy->xscr, dri2_display_invalidate_buffers, &dri2dpy->base); if (fd < 0) return FALSE; dri2dpy->base.screen = dri2dpy->event_handler->new_drm_screen(&dri2dpy->base, dri2dpy->dri_driver, fd); if (!dri2dpy->base.screen) { _eglLog(_EGL_DEBUG, "failed to create DRM screen"); return FALSE; } #ifdef HAVE_WAYLAND_BACKEND dri2dpy->base.wayland_bufmgr = wayland_drm_bufmgr_create( dri2_display_authenticate, dri2dpy, x11_screen_get_device_name(dri2dpy->xscr)); #endif return TRUE; }