From fcdc798515a74d12e4f1f848ac8b8bacce928855 Mon Sep 17 00:00:00 2001 From: Boyan Ding Date: Tue, 21 Jul 2015 23:44:02 +0800 Subject: [PATCH] egl/x11_dri3: Implement EGL_KHR_image_pixmap MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit v2: from Martin Peres - Replace a tab with spaces v3: from Martin Peres - disable EGL_KHR_image_pixmap when is_different_gpu is set (Axel Davy) Signed-off-by: Boyan Ding Reviewed-by: Martin Peres Reviewed-by: Kristian Høgsberg Reviewed-by: Emil Velikov --- src/egl/drivers/dri2/platform_x11.c | 2 + src/egl/drivers/dri2/platform_x11_dri3.c | 77 +++++++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c index d291b478a25..9dd5defd6a6 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -1305,6 +1305,8 @@ dri2_initialize_x11_dri3(_EGLDriver *drv, _EGLDisplay *disp) 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; diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c index 0b95e4d42de..aaafd1d6708 100644 --- a/src/egl/drivers/dri2/platform_x11_dri3.c +++ b/src/egl/drivers/dri2/platform_x11_dri3.c @@ -272,6 +272,81 @@ dri3_get_sync_values(_EGLDisplay *display, _EGLSurface *surface, (int64_t *) sbc) ? EGL_TRUE : EGL_FALSE; } +static _EGLImage * +dri3_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, + EGLClientBuffer buffer, const EGLint *attr_list) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_image *dri2_img; + xcb_drawable_t drawable; + xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie; + xcb_dri3_buffer_from_pixmap_reply_t *bp_reply; + unsigned int format; + + drawable = (xcb_drawable_t) (uintptr_t) buffer; + bp_cookie = xcb_dri3_buffer_from_pixmap(dri2_dpy->conn, drawable); + bp_reply = xcb_dri3_buffer_from_pixmap_reply(dri2_dpy->conn, + bp_cookie, NULL); + if (!bp_reply) { + _eglError(EGL_BAD_ALLOC, "xcb_dri3_buffer_from_pixmap"); + return NULL; + } + + switch (bp_reply->depth) { + case 16: + format = __DRI_IMAGE_FORMAT_RGB565; + break; + case 24: + format = __DRI_IMAGE_FORMAT_XRGB8888; + break; + case 32: + format = __DRI_IMAGE_FORMAT_ARGB8888; + break; + default: + _eglError(EGL_BAD_PARAMETER, + "dri3_create_image_khr: unsupported pixmap depth"); + free(bp_reply); + return EGL_NO_IMAGE_KHR; + } + + dri2_img = malloc(sizeof *dri2_img); + if (!dri2_img) { + _eglError(EGL_BAD_ALLOC, "dri3_create_image_khr"); + return EGL_NO_IMAGE_KHR; + } + + if (!_eglInitImage(&dri2_img->base, disp)) { + free(dri2_img); + return EGL_NO_IMAGE_KHR; + } + + dri2_img->dri_image = loader_dri3_create_image(dri2_dpy->conn, + bp_reply, + format, + dri2_dpy->dri_screen, + dri2_dpy->image, + dri2_img); + + free(bp_reply); + + return &dri2_img->base; +} + +static _EGLImage * +dri3_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, + _EGLContext *ctx, EGLenum target, + EGLClientBuffer buffer, const EGLint *attr_list) +{ + (void) drv; + + switch (target) { + case EGL_NATIVE_PIXMAP_KHR: + return dri3_create_image_khr_pixmap(disp, ctx, buffer, attr_list); + default: + return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list); + } +} + /** * Called by the driver when it needs to update the real front buffer with the * contents of its fake front buffer. @@ -347,7 +422,7 @@ struct dri2_egl_display_vtbl dri3_x11_display_vtbl = { .create_pixmap_surface = dri3_create_pixmap_surface, .create_pbuffer_surface = dri3_create_pbuffer_surface, .destroy_surface = dri3_destroy_surface, - .create_image = dri2_create_image_khr, + .create_image = dri3_create_image_khr, .swap_interval = dri3_set_swap_interval, .swap_buffers = dri3_swap_buffers, .swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage, -- 2.30.2