#include "loader.h"
#include "loader_dri3_helper.h"
+static uint32_t
+dri3_format_for_depth(uint32_t depth)
+{
+ switch (depth) {
+ case 16:
+ return __DRI_IMAGE_FORMAT_RGB565;
+ case 24:
+ return __DRI_IMAGE_FORMAT_XRGB8888;
+ case 30:
+ return __DRI_IMAGE_FORMAT_XRGB2101010;
+ case 32:
+ return __DRI_IMAGE_FORMAT_ARGB8888;
+ default:
+ return __DRI_IMAGE_FORMAT_NONE;
+ }
+}
+
static struct dri3_egl_surface *
loader_drawable_to_egl_surface(struct loader_dri3_drawable *draw) {
size_t offset = offsetof(struct dri3_egl_surface, loader_drawable);
return dri2_ctx->dri_context;
}
+static __DRIscreen *
+egl_dri3_get_dri_screen(void)
+{
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct dri2_egl_context *dri2_ctx;
+ if (!ctx)
+ return NULL;
+ dri2_ctx = dri2_egl_context(ctx);
+ return dri2_egl_display(dri2_ctx->base.Resource.Display)->dri_screen;
+}
+
static void
egl_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags)
{
.set_drawable_size = egl_dri3_set_drawable_size,
.in_current_context = egl_dri3_in_current_context,
.get_dri_context = egl_dri3_get_dri_context,
+ .get_dri_screen = egl_dri3_get_dri_screen,
.flush_drawable = egl_dri3_flush_drawable,
.show_fps = NULL,
};
if (loader_dri3_drawable_init(dri2_dpy->conn, drawable,
dri2_dpy->dri_screen,
- dri2_dpy->is_different_gpu, dri_config,
+ dri2_dpy->is_different_gpu,
+ dri2_dpy->multibuffers_available,
+ dri_config,
&dri2_dpy->loader_dri3_ext,
&egl_dri3_vtable,
&dri3_surf->loader_drawable)) {
return NULL;
}
- switch (bp_reply->depth) {
- case 16:
- format = __DRI_IMAGE_FORMAT_RGB565;
- break;
- case 24:
- format = __DRI_IMAGE_FORMAT_XRGB8888;
- break;
- case 30:
- format = __DRI_IMAGE_FORMAT_XRGB2101010;
- break;
- case 32:
- format = __DRI_IMAGE_FORMAT_ARGB8888;
- break;
- default:
+ format = dri3_format_for_depth(bp_reply->depth);
+ if (format == __DRI_IMAGE_FORMAT_NONE) {
_eglError(EGL_BAD_PARAMETER,
"dri3_create_image_khr: unsupported pixmap depth");
free(bp_reply);
return &dri2_img->base;
}
+static _EGLImage *
+dri3_create_image_khr_pixmap_from_buffers(_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_dri3_buffers_from_pixmap_cookie_t bp_cookie;
+ xcb_dri3_buffers_from_pixmap_reply_t *bp_reply;
+ xcb_drawable_t drawable;
+ unsigned int format;
+
+ drawable = (xcb_drawable_t) (uintptr_t) buffer;
+ bp_cookie = xcb_dri3_buffers_from_pixmap(dri2_dpy->conn, drawable);
+ bp_reply = xcb_dri3_buffers_from_pixmap_reply(dri2_dpy->conn,
+ bp_cookie, NULL);
+
+ if (!bp_reply) {
+ _eglError(EGL_BAD_ATTRIBUTE, "dri3_create_image_khr");
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ format = dri3_format_for_depth(bp_reply->depth);
+ if (format == __DRI_IMAGE_FORMAT_NONE) {
+ _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");
+ free(bp_reply);
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ _eglInitImage(&dri2_img->base, disp);
+
+ dri2_img->dri_image = loader_dri3_create_image_from_buffers(dri2_dpy->conn,
+ bp_reply,
+ format,
+ dri2_dpy->dri_screen,
+ dri2_dpy->image,
+ dri2_img);
+ free(bp_reply);
+
+ if (!dri2_img->dri_image) {
+ _eglError(EGL_BAD_ATTRIBUTE, "dri3_create_image_khr");
+ free(dri2_img);
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ return &dri2_img->base;
+}
+
static _EGLImage *
dri3_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
_EGLContext *ctx, EGLenum target,
EGLClientBuffer buffer, const EGLint *attr_list)
{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
switch (target) {
case EGL_NATIVE_PIXMAP_KHR:
+ if (dri2_dpy->multibuffers_available)
+ return dri3_create_image_khr_pixmap_from_buffers(disp, ctx, buffer,
+ attr_list);
return dri3_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
default:
return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
free(error);
return EGL_FALSE;
}
+
+ dri2_dpy->dri3_major_version = dri3_query->major_version;
+ dri2_dpy->dri3_minor_version = dri3_query->minor_version;
free(dri3_query);
present_query =