11 #include <X11/Xlib-xcb.h>
12 #include <X11/xshmfence.h>
20 #include <Ecore_Buffer.h>
22 #include <tbm_bufmgr.h>
23 #include <tbm_surface.h>
24 #include <tbm_surface_internal.h>
26 #include "ecore_buffer_private.h"
28 typedef struct _Ecore_Buffer_Module_X11_Dri3_Data Ecore_Buffer_Module_X11_Dri3_Data;
29 typedef struct _Ecore_Buffer_X11_Dri3_Data Ecore_Buffer_X11_Dri3_Data;
31 struct _Ecore_Buffer_Module_X11_Dri3_Data {
35 struct _Ecore_Buffer_X11_Dri3_Data {
36 Ecore_X_Pixmap pixmap;
42 Ecore_Buffer_Format format;
43 Eina_Bool is_imported;
46 static Ecore_Pixmap _ecore_buffer_x11_dri3_pixmap_get(Ecore_Buffer_Module_Data bmdata, Ecore_Buffer_Data bdata);
49 _buf_get_num_planes(Ecore_Buffer_Format format)
55 case ECORE_BUFFER_FORMAT_C8:
56 case ECORE_BUFFER_FORMAT_RGB332:
57 case ECORE_BUFFER_FORMAT_BGR233:
58 case ECORE_BUFFER_FORMAT_XRGB4444:
59 case ECORE_BUFFER_FORMAT_XBGR4444:
60 case ECORE_BUFFER_FORMAT_RGBX4444:
61 case ECORE_BUFFER_FORMAT_BGRX4444:
62 case ECORE_BUFFER_FORMAT_ARGB4444:
63 case ECORE_BUFFER_FORMAT_ABGR4444:
64 case ECORE_BUFFER_FORMAT_RGBA4444:
65 case ECORE_BUFFER_FORMAT_BGRA4444:
66 case ECORE_BUFFER_FORMAT_XRGB1555:
67 case ECORE_BUFFER_FORMAT_XBGR1555:
68 case ECORE_BUFFER_FORMAT_RGBX5551:
69 case ECORE_BUFFER_FORMAT_BGRX5551:
70 case ECORE_BUFFER_FORMAT_ARGB1555:
71 case ECORE_BUFFER_FORMAT_ABGR1555:
72 case ECORE_BUFFER_FORMAT_RGBA5551:
73 case ECORE_BUFFER_FORMAT_BGRA5551:
74 case ECORE_BUFFER_FORMAT_RGB565:
75 case ECORE_BUFFER_FORMAT_BGR565:
76 case ECORE_BUFFER_FORMAT_RGB888:
77 case ECORE_BUFFER_FORMAT_BGR888:
78 case ECORE_BUFFER_FORMAT_XRGB8888:
79 case ECORE_BUFFER_FORMAT_XBGR8888:
80 case ECORE_BUFFER_FORMAT_RGBX8888:
81 case ECORE_BUFFER_FORMAT_BGRX8888:
82 case ECORE_BUFFER_FORMAT_ARGB8888:
83 case ECORE_BUFFER_FORMAT_ABGR8888:
84 case ECORE_BUFFER_FORMAT_RGBA8888:
85 case ECORE_BUFFER_FORMAT_BGRA8888:
86 case ECORE_BUFFER_FORMAT_XRGB2101010:
87 case ECORE_BUFFER_FORMAT_XBGR2101010:
88 case ECORE_BUFFER_FORMAT_RGBX1010102:
89 case ECORE_BUFFER_FORMAT_BGRX1010102:
90 case ECORE_BUFFER_FORMAT_ARGB2101010:
91 case ECORE_BUFFER_FORMAT_ABGR2101010:
92 case ECORE_BUFFER_FORMAT_RGBA1010102:
93 case ECORE_BUFFER_FORMAT_BGRA1010102:
94 case ECORE_BUFFER_FORMAT_YUYV:
95 case ECORE_BUFFER_FORMAT_YVYU:
96 case ECORE_BUFFER_FORMAT_UYVY:
97 case ECORE_BUFFER_FORMAT_VYUY:
98 case ECORE_BUFFER_FORMAT_AYUV:
101 case ECORE_BUFFER_FORMAT_NV12:
102 case ECORE_BUFFER_FORMAT_NV21:
103 case ECORE_BUFFER_FORMAT_NV16:
104 case ECORE_BUFFER_FORMAT_NV61:
107 case ECORE_BUFFER_FORMAT_YUV410:
108 case ECORE_BUFFER_FORMAT_YVU410:
109 case ECORE_BUFFER_FORMAT_YUV411:
110 case ECORE_BUFFER_FORMAT_YVU411:
111 case ECORE_BUFFER_FORMAT_YUV420:
112 case ECORE_BUFFER_FORMAT_YVU420:
113 case ECORE_BUFFER_FORMAT_YUV422:
114 case ECORE_BUFFER_FORMAT_YVU422:
115 case ECORE_BUFFER_FORMAT_YUV444:
116 case ECORE_BUFFER_FORMAT_YVU444:
128 _buf_get_bpp(Ecore_Buffer_Format format)
134 case ECORE_BUFFER_FORMAT_C8:
135 case ECORE_BUFFER_FORMAT_RGB332:
136 case ECORE_BUFFER_FORMAT_BGR233:
139 case ECORE_BUFFER_FORMAT_XRGB4444:
140 case ECORE_BUFFER_FORMAT_XBGR4444:
141 case ECORE_BUFFER_FORMAT_RGBX4444:
142 case ECORE_BUFFER_FORMAT_BGRX4444:
143 case ECORE_BUFFER_FORMAT_ARGB4444:
144 case ECORE_BUFFER_FORMAT_ABGR4444:
145 case ECORE_BUFFER_FORMAT_RGBA4444:
146 case ECORE_BUFFER_FORMAT_BGRA4444:
147 case ECORE_BUFFER_FORMAT_XRGB1555:
148 case ECORE_BUFFER_FORMAT_XBGR1555:
149 case ECORE_BUFFER_FORMAT_RGBX5551:
150 case ECORE_BUFFER_FORMAT_BGRX5551:
151 case ECORE_BUFFER_FORMAT_ARGB1555:
152 case ECORE_BUFFER_FORMAT_ABGR1555:
153 case ECORE_BUFFER_FORMAT_RGBA5551:
154 case ECORE_BUFFER_FORMAT_BGRA5551:
155 case ECORE_BUFFER_FORMAT_RGB565:
156 case ECORE_BUFFER_FORMAT_BGR565:
159 case ECORE_BUFFER_FORMAT_RGB888:
160 case ECORE_BUFFER_FORMAT_BGR888:
163 case ECORE_BUFFER_FORMAT_XRGB8888:
164 case ECORE_BUFFER_FORMAT_XBGR8888:
165 case ECORE_BUFFER_FORMAT_RGBX8888:
166 case ECORE_BUFFER_FORMAT_BGRX8888:
167 case ECORE_BUFFER_FORMAT_ARGB8888:
168 case ECORE_BUFFER_FORMAT_ABGR8888:
169 case ECORE_BUFFER_FORMAT_RGBA8888:
170 case ECORE_BUFFER_FORMAT_BGRA8888:
171 case ECORE_BUFFER_FORMAT_XRGB2101010:
172 case ECORE_BUFFER_FORMAT_XBGR2101010:
173 case ECORE_BUFFER_FORMAT_RGBX1010102:
174 case ECORE_BUFFER_FORMAT_BGRX1010102:
175 case ECORE_BUFFER_FORMAT_ARGB2101010:
176 case ECORE_BUFFER_FORMAT_ABGR2101010:
177 case ECORE_BUFFER_FORMAT_RGBA1010102:
178 case ECORE_BUFFER_FORMAT_BGRA1010102:
179 case ECORE_BUFFER_FORMAT_YUYV:
180 case ECORE_BUFFER_FORMAT_YVYU:
181 case ECORE_BUFFER_FORMAT_UYVY:
182 case ECORE_BUFFER_FORMAT_VYUY:
183 case ECORE_BUFFER_FORMAT_AYUV:
186 case ECORE_BUFFER_FORMAT_NV12:
187 case ECORE_BUFFER_FORMAT_NV21:
190 case ECORE_BUFFER_FORMAT_NV16:
191 case ECORE_BUFFER_FORMAT_NV61:
194 case ECORE_BUFFER_FORMAT_YUV410:
195 case ECORE_BUFFER_FORMAT_YVU410:
198 case ECORE_BUFFER_FORMAT_YUV411:
199 case ECORE_BUFFER_FORMAT_YVU411:
200 case ECORE_BUFFER_FORMAT_YUV420:
201 case ECORE_BUFFER_FORMAT_YVU420:
204 case ECORE_BUFFER_FORMAT_YUV422:
205 case ECORE_BUFFER_FORMAT_YVU422:
208 case ECORE_BUFFER_FORMAT_YUV444:
209 case ECORE_BUFFER_FORMAT_YVU444:
220 _buf_get_depth(Ecore_Buffer_Format format)
226 case ECORE_BUFFER_FORMAT_C8:
227 case ECORE_BUFFER_FORMAT_RGB332:
228 case ECORE_BUFFER_FORMAT_BGR233:
231 case ECORE_BUFFER_FORMAT_XRGB4444:
232 case ECORE_BUFFER_FORMAT_XBGR4444:
233 case ECORE_BUFFER_FORMAT_RGBX4444:
234 case ECORE_BUFFER_FORMAT_BGRX4444:
237 case ECORE_BUFFER_FORMAT_ARGB4444:
238 case ECORE_BUFFER_FORMAT_ABGR4444:
239 case ECORE_BUFFER_FORMAT_RGBA4444:
240 case ECORE_BUFFER_FORMAT_BGRA4444:
243 case ECORE_BUFFER_FORMAT_XRGB1555:
244 case ECORE_BUFFER_FORMAT_XBGR1555:
245 case ECORE_BUFFER_FORMAT_RGBX5551:
246 case ECORE_BUFFER_FORMAT_BGRX5551:
249 case ECORE_BUFFER_FORMAT_ARGB1555:
250 case ECORE_BUFFER_FORMAT_ABGR1555:
251 case ECORE_BUFFER_FORMAT_RGBA5551:
252 case ECORE_BUFFER_FORMAT_BGRA5551:
253 case ECORE_BUFFER_FORMAT_RGB565:
254 case ECORE_BUFFER_FORMAT_BGR565:
257 case ECORE_BUFFER_FORMAT_RGB888:
258 case ECORE_BUFFER_FORMAT_BGR888:
261 case ECORE_BUFFER_FORMAT_XRGB8888:
262 case ECORE_BUFFER_FORMAT_XBGR8888:
263 case ECORE_BUFFER_FORMAT_RGBX8888:
264 case ECORE_BUFFER_FORMAT_BGRX8888:
267 case ECORE_BUFFER_FORMAT_ARGB8888:
268 case ECORE_BUFFER_FORMAT_ABGR8888:
269 case ECORE_BUFFER_FORMAT_RGBA8888:
270 case ECORE_BUFFER_FORMAT_BGRA8888:
273 case ECORE_BUFFER_FORMAT_XRGB2101010:
274 case ECORE_BUFFER_FORMAT_XBGR2101010:
275 case ECORE_BUFFER_FORMAT_RGBX1010102:
276 case ECORE_BUFFER_FORMAT_BGRX1010102:
279 case ECORE_BUFFER_FORMAT_ARGB2101010:
280 case ECORE_BUFFER_FORMAT_ABGR2101010:
281 case ECORE_BUFFER_FORMAT_RGBA1010102:
282 case ECORE_BUFFER_FORMAT_BGRA1010102:
285 case ECORE_BUFFER_FORMAT_YUYV:
286 case ECORE_BUFFER_FORMAT_YVYU:
287 case ECORE_BUFFER_FORMAT_UYVY:
288 case ECORE_BUFFER_FORMAT_VYUY:
289 case ECORE_BUFFER_FORMAT_AYUV:
290 case ECORE_BUFFER_FORMAT_NV12:
291 case ECORE_BUFFER_FORMAT_NV21:
292 case ECORE_BUFFER_FORMAT_NV16:
293 case ECORE_BUFFER_FORMAT_NV61:
294 case ECORE_BUFFER_FORMAT_YUV410:
295 case ECORE_BUFFER_FORMAT_YVU410:
296 case ECORE_BUFFER_FORMAT_YUV411:
297 case ECORE_BUFFER_FORMAT_YVU411:
298 case ECORE_BUFFER_FORMAT_YUV420:
299 case ECORE_BUFFER_FORMAT_YVU420:
300 case ECORE_BUFFER_FORMAT_YUV422:
301 case ECORE_BUFFER_FORMAT_YVU422:
302 case ECORE_BUFFER_FORMAT_YUV444:
303 case ECORE_BUFFER_FORMAT_YVU444:
305 depth = 0; //unknown in X
313 _dri3_open(Ecore_X_Display *dpy, Ecore_X_Window root, unsigned provider)
315 xcb_connection_t *c = XGetXCBConnection(dpy);
316 xcb_dri3_open_cookie_t cookie;
317 xcb_dri3_open_reply_t *reply;
319 cookie = xcb_dri3_open(c, root, provider);
320 reply = xcb_dri3_open_reply(c, cookie, NULL);
321 if ((!reply) || (reply->nfd != 1))
324 return xcb_dri3_open_reply_fds(c, reply)[0];
327 static Ecore_X_Pixmap
328 _dri3_pixmap_from_fd(Ecore_X_Display *dpy, Ecore_X_Drawable draw, int width, int height, int depth, int fd, int bpp, int stride, int size)
331 Ecore_X_Pixmap pixmap;
336 c = XGetXCBConnection(dpy);
340 pixmap = xcb_generate_id(c);
344 xcb_dri3_pixmap_from_buffer(c, pixmap, draw, size, width, height, stride, depth, bpp, fd);
349 static Ecore_Buffer_Module_Data
350 _ecore_buffer_x11_dri3_init(const char *context EINA_UNUSED, const char *options EINA_UNUSED)
352 Ecore_X_Display *xdpy;
354 Ecore_Buffer_Module_X11_Dri3_Data *mdata = NULL;
357 if (!ecore_x_init(NULL))
360 xdpy = ecore_x_display_get();
364 root = ecore_x_window_root_first_get();
368 mdata = calloc(1, sizeof(Ecore_Buffer_Module_X11_Dri3_Data));
373 fd = _dri3_open(xdpy, root, 0);
377 mdata->tbm_mgr = tbm_bufmgr_init(fd);
386 if (fd > 0) close(fd);
387 if (mdata) free(mdata);
394 _ecore_buffer_x11_dri3_shutdown(Ecore_Buffer_Module_Data bmdata)
396 Ecore_Buffer_Module_X11_Dri3_Data *bm = bmdata;
402 tbm_bufmgr_deinit(bm->tbm_mgr);
407 static Ecore_Buffer_Data
408 _ecore_buffer_x11_dri3_buffer_alloc(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, int width, int height, Ecore_Buffer_Format format, unsigned int flags)
410 Ecore_Buffer_X11_Dri3_Data *buf;
412 buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri3_Data));
418 buf->format = format;
420 buf->is_imported = EINA_FALSE;
421 buf->tbm_surface = tbm_surface_create(width,height,(tbm_format)format);
422 if (!buf->tbm_surface)
431 static Ecore_Buffer_Data
432 _ecore_buffer_x11_dri3_buffer_alloc_with_tbm_surface(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, void *tbm_surface, int *ret_w, int *ret_h, Ecore_Buffer_Format *ret_format, unsigned int flags)
434 Ecore_Buffer_X11_Dri3_Data *buf;
436 EINA_SAFETY_ON_NULL_RETURN_VAL(tbm_surface, NULL);
438 buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri3_Data));
442 buf->w = tbm_surface_get_width(tbm_surface);
443 buf->h = tbm_surface_get_height(tbm_surface);
444 buf->format = tbm_surface_get_format(tbm_surface);
446 buf->is_imported = EINA_FALSE;
447 buf->tbm_surface = tbm_surface;
449 if (ret_w) *ret_w = buf->w;
450 if (ret_h) *ret_h = buf->h;
451 if (ret_format) *ret_format = buf->format;
457 _ecore_buffer_x11_dri3_buffer_info_get(Ecore_Buffer_Module_Data bmdata, Ecore_Buffer_Data bdata, Ecore_Buffer_Info *info)
459 Ecore_Buffer_X11_Dri3_Data *buf = bdata;
460 tbm_surface_info_s tinfo;
463 if (!buf->tbm_surface)
466 res = tbm_surface_get_info(buf->tbm_surface, &tinfo);
467 if (res != TBM_SURFACE_ERROR_NONE)
472 info->width = tinfo.width;
473 info->height = tinfo.height;
474 info->format = tinfo.format;
475 info->bpp = tinfo.bpp;
476 info->size = tinfo.size;
477 info->num_planes = tinfo.num_planes;
478 info->pixmap = _ecore_buffer_x11_dri3_pixmap_get(bmdata, bdata);
480 for (i = 0; i < tinfo.num_planes; i++)
482 info->planes[i].size = tinfo.planes[i].size;
483 info->planes[i].offset = tinfo.planes[i].offset;
484 info->planes[i].stride = tinfo.planes[i].stride;
492 _ecore_buffer_x11_dri3_buffer_free(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
494 Ecore_Buffer_X11_Dri3_Data *buf = bdata;
500 ecore_x_pixmap_free(buf->pixmap);
502 if (buf->tbm_surface)
503 tbm_surface_destroy(buf->tbm_surface);
508 static Ecore_Export_Type
509 _ecore_buffer_x11_dri3_buffer_export(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata, int *id)
511 Ecore_Buffer_X11_Dri3_Data *buf = bdata;
514 if (_buf_get_num_planes(buf->format) != 1)
515 return EXPORT_TYPE_INVALID;
517 bo = tbm_surface_internal_get_bo(buf->tbm_surface, 0);
519 return EXPORT_TYPE_INVALID;
521 if (id) *id = tbm_bo_export_fd(bo);
523 return EXPORT_TYPE_FD;
526 static Ecore_Buffer_Data
527 _ecore_buffer_x11_dri3_buffer_import(Ecore_Buffer_Module_Data bmdata, Ecore_Buffer_Info *einfo, Ecore_Export_Type type, int export_id, unsigned int flags)
529 Ecore_Buffer_Module_X11_Dri3_Data *bm = bmdata;
530 Ecore_Buffer_X11_Dri3_Data *buf;
532 tbm_surface_info_s tinfo;
538 if (type != EXPORT_TYPE_FD)
544 buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri3_Data));
548 buf->w = einfo->width;
549 buf->h = einfo->height;
550 buf->format = einfo->format;
552 buf->is_imported = EINA_TRUE;
555 bo = tbm_bo_import_fd(bm->tbm_mgr, export_id);
562 tinfo.width = buf->w = einfo->width;
563 tinfo.height = buf->h = einfo->height;
564 tinfo.format = buf->format = einfo->format;
565 tinfo.bpp = _buf_get_bpp(einfo->format);
566 tinfo.size = einfo->height * einfo->planes[0].stride;
567 tinfo.num_planes = _buf_get_num_planes(einfo->format);
568 for (i = 0; i < tinfo.num_planes; i++)
570 tinfo.planes[i].size = einfo->height * einfo->planes[i].stride;
571 tinfo.planes[i].stride = einfo->planes[i].stride;
572 tinfo.planes[i].offset = einfo->planes[i].offset;
575 buf->tbm_surface = tbm_surface_internal_create_with_bos(&tinfo, &bo, 1);
576 if (!buf->tbm_surface)
589 _ecore_buffer_x11_dri3_pixmap_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
591 Ecore_Buffer_X11_Dri3_Data *buf = bdata;
592 Ecore_X_Display *xdpy;
594 tbm_surface_info_s info;
604 ret = tbm_surface_get_info(buf->tbm_surface, &info);
608 if (info.num_planes != 1)
611 bo = tbm_surface_internal_get_bo(buf->tbm_surface, 0);
615 xdpy = ecore_x_display_get();
616 root = ecore_x_window_root_first_get();
617 buf->pixmap = _dri3_pixmap_from_fd(xdpy, root,
619 _buf_get_depth(buf->format),
620 tbm_bo_export_fd(bo),
621 _buf_get_bpp(buf->format),
622 info.planes[0].stride,
623 info.planes[0].size);
629 _ecore_buffer_x11_dri3_tbm_bo_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
631 Ecore_Buffer_X11_Dri3_Data *buf = bdata;
636 return buf->tbm_surface;
639 static Ecore_Buffer_Backend _ecore_buffer_x11_dri3_backend = {
641 &_ecore_buffer_x11_dri3_init,
642 &_ecore_buffer_x11_dri3_shutdown,
643 &_ecore_buffer_x11_dri3_buffer_alloc,
644 &_ecore_buffer_x11_dri3_buffer_alloc_with_tbm_surface,
645 &_ecore_buffer_x11_dri3_buffer_info_get,
646 &_ecore_buffer_x11_dri3_buffer_free,
647 &_ecore_buffer_x11_dri3_buffer_export,
648 &_ecore_buffer_x11_dri3_buffer_import,
649 &_ecore_buffer_x11_dri3_pixmap_get,
650 &_ecore_buffer_x11_dri3_tbm_bo_get,
653 Eina_Bool x11_dri3_init(void)
655 return ecore_buffer_register(&_ecore_buffer_x11_dri3_backend);
658 void x11_dri3_shutdown(void)
660 ecore_buffer_unregister(&_ecore_buffer_x11_dri3_backend);
663 EINA_MODULE_INIT(x11_dri3_init);
664 EINA_MODULE_SHUTDOWN(x11_dri3_shutdown);