summaryrefslogtreecommitdiff
path: root/src/modules/ecore_buffer
diff options
context:
space:
mode:
authorSeunghun Lee <beauty.positive3@gmail.com>2015-06-22 10:23:54 -0400
committerChris Michael <cp.michael@samsung.com>2015-06-22 10:31:42 -0400
commit8b621775619b9959fe952b095b3baaa7aaa99572 (patch)
tree99059a841a79729cac4687ea41f3abf672e6e455 /src/modules/ecore_buffer
parent3671506ad39d2a956e388e151bd20f1b9ffd62a5 (diff)
ecore-buffer: Add ecore_buffer library to EFL.
Summary: Ecore_Buffer is abstraction of graphic buffer. it supports backend of shm, x11_dri2 and x11_dri3 for now, and this library also provides method to share buffers between processes. Ecore_Buffer_Provider and Ecore_Buffer_Consumer is for this, sharing buffer. provider draws something in to Ecore_Buffer, and consumer receives and displays it. the binary, bq_mgr is a connection maker for buffer provider and consumer. it can be included Enlightenment as a deamon later. @feature Test Plan: 1. Configure with --enable-ecore-buffer and --enable-always-build-examples to build examples. 2. Run bq_mgr, it connects consumer and provider. 3. Run ecore_buffer_provider_example and ecore_buffer_consumer_example Reviewers: lsj119, gwanglim, cedric, zmike, jpeg, raster, devilhorns Subscribers: cedric Differential Revision: https://phab.enlightenment.org/D2197
Diffstat (limited to 'src/modules/ecore_buffer')
-rw-r--r--src/modules/ecore_buffer/shm/ecore_buffer_shm.c172
-rw-r--r--src/modules/ecore_buffer/x11_dri2/ecore_buffer_x11_dri2.c538
-rw-r--r--src/modules/ecore_buffer/x11_dri3/ecore_buffer_x11_dri3.c602
3 files changed, 1312 insertions, 0 deletions
diff --git a/src/modules/ecore_buffer/shm/ecore_buffer_shm.c b/src/modules/ecore_buffer/shm/ecore_buffer_shm.c
new file mode 100644
index 0000000000..75900ea094
--- /dev/null
+++ b/src/modules/ecore_buffer/shm/ecore_buffer_shm.c
@@ -0,0 +1,172 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <stdio.h>
6#include <unistd.h>
7#ifdef HAVE_SYS_MMAN_H
8# include <sys/mman.h>
9#endif
10#include <fcntl.h>
11#include <string.h>
12
13#include <Eina.h>
14#include <Ecore.h>
15#include <Ecore_Buffer.h>
16
17typedef struct _Ecore_Buffer_Shm_Data Ecore_Buffer_Shm_Data;
18
19struct _Ecore_Buffer_Shm_Data {
20 const char *file;
21 void *addr;
22 int w, h, stride, size;
23 Eina_Bool am_owner : 1;
24};
25
26static void
27_ecore_buffer_shm_buffer_free(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
28{
29 Ecore_Buffer_Shm_Data* b = bdata;
30
31 if (b->am_owner)
32 if (b->file) unlink(b->file);
33
34 if (b->addr != MAP_FAILED) munmap(b->addr, b->size);
35 eina_stringshare_del(b->file);
36 b->file = NULL;
37 b->addr = MAP_FAILED;
38 b->am_owner = EINA_FALSE;
39 b->w = 0;
40 b->h = 0;
41 b->stride = 0;
42 b->size = 0;
43 free(b);
44}
45
46
47static Ecore_Buffer_Data
48_ecore_buffer_shm_buffer_alloc(Ecore_Buffer_Module_Data bmdata, int width, int height, Ecore_Buffer_Format format EINA_UNUSED, unsigned int flags EINA_UNUSED)
49{
50 Ecore_Buffer_Shm_Data* b;
51 char *name;
52 static const char tmp[] = "/ecore-buffer-shared-XXXXXX";
53 const char *path;
54 int fd, size, page_size;
55
56 path = getenv("XDG_RUNTIME_DIR");
57 if (!path)
58 {
59 path = getenv("TMPDIR");
60 if (!path) path = "/tmp";
61 }
62
63 page_size = eina_cpu_page_size();
64
65 b = calloc(1, sizeof(Ecore_Buffer_Shm_Data));
66 fd = -1;
67 b->addr = MAP_FAILED;
68 b->w = width;
69 b->h = height;
70 b->stride = width * sizeof(int);
71 b->size = page_size * (((b->stride * b->h) + (page_size - 1)) / page_size);
72 b->am_owner = EINA_TRUE;
73
74 size = strlen(path) + sizeof(tmp);
75 name = malloc(size);
76 if (!name) goto err;
77 strcpy(name, path);
78 strcat(name, tmp);
79
80 fd = mkostemp(name, O_CLOEXEC);
81 if (fd < 0) goto err_fd;
82 b->file = eina_stringshare_add(name);
83 free(name);
84
85 if (ftruncate(fd, b->size) < 0) goto err;
86
87 b->addr = mmap(NULL, b->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
88 if (b->addr == MAP_FAILED) goto err;
89 close(fd);
90
91 return b;
92err:
93 close(fd);
94err_fd:
95 _ecore_buffer_shm_buffer_free(bmdata, b);
96 return NULL;
97}
98
99static Ecore_Export_Type
100_ecore_buffer_shm_buffer_export(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata, int *id)
101{
102 Ecore_Buffer_Shm_Data* b = bdata;
103 int fd;
104
105 fd = open(b->file, O_RDWR | O_CLOEXEC);
106 if (id) *id = fd;
107
108 return EXPORT_TYPE_FD;
109}
110
111static void *
112_ecore_buffer_shm_buffer_import(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, int w, int h, Ecore_Buffer_Format format EINA_UNUSED, Ecore_Export_Type type, int export_id, unsigned int flags EINA_UNUSED)
113{
114 Ecore_Buffer_Shm_Data* b;
115 int fd, page_size;
116
117 EINA_SAFETY_ON_FALSE_RETURN_VAL(type == EXPORT_TYPE_FD, NULL);
118
119 b = calloc(1, sizeof(Ecore_Buffer_Shm_Data));
120 if (!b) return NULL;
121
122 page_size = eina_cpu_page_size();
123
124 fd = export_id;
125 b->w = w;
126 b->h = h;
127 b->stride = w * sizeof(int);
128 b->size = page_size * (((b->stride * b->h) + (page_size - 1)) / page_size);
129 b->am_owner = EINA_FALSE;
130
131 b->addr = mmap(NULL, b->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
132 if (b->addr == MAP_FAILED) goto err;
133
134 return b;
135err:
136 _ecore_buffer_shm_buffer_free(bmdata, b);
137 return NULL;
138}
139
140static void *
141_ecore_buffer_shm_data_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
142{
143 Ecore_Buffer_Shm_Data *b = bdata;
144
145 return b->addr;
146}
147
148static Ecore_Buffer_Backend _ecore_buffer_shm_backend = {
149 "shm",
150 NULL,
151 NULL,
152 &_ecore_buffer_shm_buffer_alloc,
153 &_ecore_buffer_shm_buffer_free,
154 &_ecore_buffer_shm_buffer_export,
155 &_ecore_buffer_shm_buffer_import,
156 &_ecore_buffer_shm_data_get,
157 NULL,
158 NULL,
159};
160
161Eina_Bool shm_init(void)
162{
163 return ecore_buffer_register(&_ecore_buffer_shm_backend);
164}
165
166void shm_shutdown(void)
167{
168 ecore_buffer_unregister(&_ecore_buffer_shm_backend);
169}
170
171EINA_MODULE_INIT(shm_init);
172EINA_MODULE_SHUTDOWN(shm_shutdown);
diff --git a/src/modules/ecore_buffer/x11_dri2/ecore_buffer_x11_dri2.c b/src/modules/ecore_buffer/x11_dri2/ecore_buffer_x11_dri2.c
new file mode 100644
index 0000000000..d673facd5a
--- /dev/null
+++ b/src/modules/ecore_buffer/x11_dri2/ecore_buffer_x11_dri2.c
@@ -0,0 +1,538 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <unistd.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <fcntl.h>
9
10#include <Eina.h>
11#include <Ecore.h>
12#include <Ecore_X.h>
13
14#include <tbm_bufmgr.h>
15#include <tbm_surface.h>
16#include <tbm_surface_internal.h>
17
18#include <xf86drm.h>
19#include <X11/Xmd.h>
20#include <dri2/dri2.h>
21
22#include "Ecore_Buffer.h"
23#include "ecore_buffer_private.h"
24
25typedef struct _Ecore_Buffer_Module_X11_Dri2_Data Ecore_Buffer_Module_X11_Dri2_Data;
26typedef struct _Ecore_Buffer_X11_Dri2_Data Ecore_Buffer_X11_Dri2_Data;
27
28struct _Ecore_Buffer_Module_X11_Dri2_Data {
29 tbm_bufmgr tbm_mgr;
30};
31
32struct _Ecore_Buffer_X11_Dri2_Data {
33 Ecore_X_Pixmap pixmap;
34 int w;
35 int h;
36 int stride;
37 Ecore_Buffer_Format format;
38 Eina_Bool is_imported;
39
40 struct
41 {
42 void *surface;
43 Eina_Bool owned;
44 } tbm;
45};
46
47static int
48_buf_get_num_planes(Ecore_Buffer_Format format)
49{
50 int num_planes = 0;
51
52 switch (format)
53 {
54 case ECORE_BUFFER_FORMAT_C8:
55 case ECORE_BUFFER_FORMAT_RGB332:
56 case ECORE_BUFFER_FORMAT_BGR233:
57 case ECORE_BUFFER_FORMAT_XRGB4444:
58 case ECORE_BUFFER_FORMAT_XBGR4444:
59 case ECORE_BUFFER_FORMAT_RGBX4444:
60 case ECORE_BUFFER_FORMAT_BGRX4444:
61 case ECORE_BUFFER_FORMAT_ARGB4444:
62 case ECORE_BUFFER_FORMAT_ABGR4444:
63 case ECORE_BUFFER_FORMAT_RGBA4444:
64 case ECORE_BUFFER_FORMAT_BGRA4444:
65 case ECORE_BUFFER_FORMAT_XRGB1555:
66 case ECORE_BUFFER_FORMAT_XBGR1555:
67 case ECORE_BUFFER_FORMAT_RGBX5551:
68 case ECORE_BUFFER_FORMAT_BGRX5551:
69 case ECORE_BUFFER_FORMAT_ARGB1555:
70 case ECORE_BUFFER_FORMAT_ABGR1555:
71 case ECORE_BUFFER_FORMAT_RGBA5551:
72 case ECORE_BUFFER_FORMAT_BGRA5551:
73 case ECORE_BUFFER_FORMAT_RGB565:
74 case ECORE_BUFFER_FORMAT_BGR565:
75 case ECORE_BUFFER_FORMAT_RGB888:
76 case ECORE_BUFFER_FORMAT_BGR888:
77 case ECORE_BUFFER_FORMAT_XRGB8888:
78 case ECORE_BUFFER_FORMAT_XBGR8888:
79 case ECORE_BUFFER_FORMAT_RGBX8888:
80 case ECORE_BUFFER_FORMAT_BGRX8888:
81 case ECORE_BUFFER_FORMAT_ARGB8888:
82 case ECORE_BUFFER_FORMAT_ABGR8888:
83 case ECORE_BUFFER_FORMAT_RGBA8888:
84 case ECORE_BUFFER_FORMAT_BGRA8888:
85 case ECORE_BUFFER_FORMAT_XRGB2101010:
86 case ECORE_BUFFER_FORMAT_XBGR2101010:
87 case ECORE_BUFFER_FORMAT_RGBX1010102:
88 case ECORE_BUFFER_FORMAT_BGRX1010102:
89 case ECORE_BUFFER_FORMAT_ARGB2101010:
90 case ECORE_BUFFER_FORMAT_ABGR2101010:
91 case ECORE_BUFFER_FORMAT_RGBA1010102:
92 case ECORE_BUFFER_FORMAT_BGRA1010102:
93 case ECORE_BUFFER_FORMAT_YUYV:
94 case ECORE_BUFFER_FORMAT_YVYU:
95 case ECORE_BUFFER_FORMAT_UYVY:
96 case ECORE_BUFFER_FORMAT_VYUY:
97 case ECORE_BUFFER_FORMAT_AYUV:
98 num_planes = 1;
99 break;
100 case ECORE_BUFFER_FORMAT_NV12:
101 case ECORE_BUFFER_FORMAT_NV21:
102 case ECORE_BUFFER_FORMAT_NV16:
103 case ECORE_BUFFER_FORMAT_NV61:
104 num_planes = 2;
105 break;
106 case ECORE_BUFFER_FORMAT_YUV410:
107 case ECORE_BUFFER_FORMAT_YVU410:
108 case ECORE_BUFFER_FORMAT_YUV411:
109 case ECORE_BUFFER_FORMAT_YVU411:
110 case ECORE_BUFFER_FORMAT_YUV420:
111 case ECORE_BUFFER_FORMAT_YVU420:
112 case ECORE_BUFFER_FORMAT_YUV422:
113 case ECORE_BUFFER_FORMAT_YVU422:
114 case ECORE_BUFFER_FORMAT_YUV444:
115 case ECORE_BUFFER_FORMAT_YVU444:
116 num_planes = 3;
117 break;
118
119 default :
120 break;
121 }
122
123 return num_planes;
124}
125
126static int
127_buf_get_bpp(Ecore_Buffer_Format format)
128{
129 int bpp = 0;
130
131 switch (format)
132 {
133 case ECORE_BUFFER_FORMAT_C8:
134 case ECORE_BUFFER_FORMAT_RGB332:
135 case ECORE_BUFFER_FORMAT_BGR233:
136 bpp = 8;
137 break;
138 case ECORE_BUFFER_FORMAT_XRGB4444:
139 case ECORE_BUFFER_FORMAT_XBGR4444:
140 case ECORE_BUFFER_FORMAT_RGBX4444:
141 case ECORE_BUFFER_FORMAT_BGRX4444:
142 case ECORE_BUFFER_FORMAT_ARGB4444:
143 case ECORE_BUFFER_FORMAT_ABGR4444:
144 case ECORE_BUFFER_FORMAT_RGBA4444:
145 case ECORE_BUFFER_FORMAT_BGRA4444:
146 case ECORE_BUFFER_FORMAT_XRGB1555:
147 case ECORE_BUFFER_FORMAT_XBGR1555:
148 case ECORE_BUFFER_FORMAT_RGBX5551:
149 case ECORE_BUFFER_FORMAT_BGRX5551:
150 case ECORE_BUFFER_FORMAT_ARGB1555:
151 case ECORE_BUFFER_FORMAT_ABGR1555:
152 case ECORE_BUFFER_FORMAT_RGBA5551:
153 case ECORE_BUFFER_FORMAT_BGRA5551:
154 case ECORE_BUFFER_FORMAT_RGB565:
155 case ECORE_BUFFER_FORMAT_BGR565:
156 bpp = 16;
157 break;
158 case ECORE_BUFFER_FORMAT_RGB888:
159 case ECORE_BUFFER_FORMAT_BGR888:
160 bpp = 24;
161 break;
162 case ECORE_BUFFER_FORMAT_XRGB8888:
163 case ECORE_BUFFER_FORMAT_XBGR8888:
164 case ECORE_BUFFER_FORMAT_RGBX8888:
165 case ECORE_BUFFER_FORMAT_BGRX8888:
166 case ECORE_BUFFER_FORMAT_ARGB8888:
167 case ECORE_BUFFER_FORMAT_ABGR8888:
168 case ECORE_BUFFER_FORMAT_RGBA8888:
169 case ECORE_BUFFER_FORMAT_BGRA8888:
170 case ECORE_BUFFER_FORMAT_XRGB2101010:
171 case ECORE_BUFFER_FORMAT_XBGR2101010:
172 case ECORE_BUFFER_FORMAT_RGBX1010102:
173 case ECORE_BUFFER_FORMAT_BGRX1010102:
174 case ECORE_BUFFER_FORMAT_ARGB2101010:
175 case ECORE_BUFFER_FORMAT_ABGR2101010:
176 case ECORE_BUFFER_FORMAT_RGBA1010102:
177 case ECORE_BUFFER_FORMAT_BGRA1010102:
178 case ECORE_BUFFER_FORMAT_YUYV:
179 case ECORE_BUFFER_FORMAT_YVYU:
180 case ECORE_BUFFER_FORMAT_UYVY:
181 case ECORE_BUFFER_FORMAT_VYUY:
182 case ECORE_BUFFER_FORMAT_AYUV:
183 bpp = 32;
184 break;
185 case ECORE_BUFFER_FORMAT_NV12:
186 case ECORE_BUFFER_FORMAT_NV21:
187 bpp = 12;
188 break;
189 case ECORE_BUFFER_FORMAT_NV16:
190 case ECORE_BUFFER_FORMAT_NV61:
191 bpp = 16;
192 break;
193 case ECORE_BUFFER_FORMAT_YUV410:
194 case ECORE_BUFFER_FORMAT_YVU410:
195 bpp = 9;
196 break;
197 case ECORE_BUFFER_FORMAT_YUV411:
198 case ECORE_BUFFER_FORMAT_YVU411:
199 case ECORE_BUFFER_FORMAT_YUV420:
200 case ECORE_BUFFER_FORMAT_YVU420:
201 bpp = 12;
202 break;
203 case ECORE_BUFFER_FORMAT_YUV422:
204 case ECORE_BUFFER_FORMAT_YVU422:
205 bpp = 16;
206 break;
207 case ECORE_BUFFER_FORMAT_YUV444:
208 case ECORE_BUFFER_FORMAT_YVU444:
209 bpp = 24;
210 break;
211 default :
212 break;
213 }
214
215 return bpp;
216}
217
218static Ecore_Buffer_Module_Data
219_ecore_buffer_x11_dri2_init(const char *context EINA_UNUSED, const char *options EINA_UNUSED)
220{
221 Ecore_X_Display *xdpy;
222 Ecore_X_Window root;
223 int eb, ee;
224 int major, minor;
225 char *driver_name;
226 char *device_name;
227 int fd = 0;
228 drm_magic_t magic;
229 Ecore_Buffer_Module_X11_Dri2_Data *mdata = NULL;
230
231 if (!ecore_x_init(NULL))
232 return NULL;
233
234 xdpy = ecore_x_display_get();
235 if (!xdpy)
236 goto on_error;
237
238 root = ecore_x_window_root_first_get();
239 if (!root)
240 goto on_error;
241
242 mdata = calloc(1, sizeof(Ecore_Buffer_Module_X11_Dri2_Data));
243 if (!mdata)
244 goto on_error;
245
246 //Init DRI2 and TBM
247 DRI2QueryExtension(xdpy, &eb, &ee);
248 DRI2QueryVersion(xdpy, &major, &minor);
249 DRI2Connect(xdpy, root, &driver_name, &device_name);
250
251 fd = open (device_name, O_RDWR);
252 if (fd < 0)
253 goto on_error;
254
255 if (drmGetMagic(fd, &magic) < 0)
256 goto on_error;
257
258 if (!(DRI2Authenticate(xdpy, root, magic)))
259 goto on_error;
260
261 mdata->tbm_mgr = tbm_bufmgr_init(fd);
262 if (!mdata->tbm_mgr)
263 goto on_error;
264
265 free(driver_name);
266 free(device_name);
267 close(fd);
268
269 return mdata;
270
271on_error:
272 if (fd > 0) close(fd);
273 if (driver_name) free(driver_name);
274 if (device_name) free(device_name);
275 if (mdata) free(mdata);
276 ecore_x_shutdown();
277
278 return NULL;
279}
280
281static void
282_ecore_buffer_x11_dri2_shutdown(Ecore_Buffer_Module_Data bmdata)
283{
284 Ecore_Buffer_Module_X11_Dri2_Data *bm = bmdata;
285
286 if (bm->tbm_mgr)
287 tbm_bufmgr_deinit(bm->tbm_mgr);
288
289 ecore_x_shutdown();
290}
291
292static Ecore_Buffer_Data
293_ecore_buffer_x11_dri2_buffer_alloc(Ecore_Buffer_Module_Data bmdata, int width, int height, Ecore_Buffer_Format format, unsigned int flags EINA_UNUSED)
294{
295 Ecore_X_Display *xdpy;
296 Ecore_X_Pixmap pixmap;
297 Ecore_Buffer_X11_Dri2_Data *buf;
298 Ecore_Buffer_Module_X11_Dri2_Data *bm = bmdata;
299 DRI2Buffer *bufs = NULL;
300 tbm_bo bo = NULL;
301 int bpp;
302 int num_plane;
303 int rw, rh, rcount;
304 unsigned int attachment = DRI2BufferFrontLeft;
305 tbm_surface_info_s info;
306 int i;
307
308 bpp = _buf_get_bpp(format);
309 if (bpp != 32)
310 return NULL;
311
312 num_plane = _buf_get_num_planes(format);
313 if (num_plane != 1)
314 return NULL;
315
316 xdpy = ecore_x_display_get();
317 pixmap = ecore_x_pixmap_new(0, width, height, bpp);
318 if (!pixmap)
319 return NULL;
320
321 buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri2_Data));
322 if (!buf)
323 {
324 ecore_x_pixmap_free(pixmap);
325 return NULL;
326 }
327
328 buf->w = width;
329 buf->h = height;
330 buf->format = format;
331 buf->pixmap = pixmap;
332 buf->is_imported = EINA_FALSE;
333
334 //Get DRI2Buffer
335 DRI2CreateDrawable(xdpy, buf->pixmap);
336 bufs = DRI2GetBuffers(xdpy, buf->pixmap, &rw, &rh, &attachment, 1, &rcount);
337 if (!(bufs) || (buf->w != rw) || (buf->h != rh))
338 goto on_error;
339
340 buf->stride = bufs->pitch;
341
342 //Import tbm_surface
343 bo = tbm_bo_import(bm->tbm_mgr, bufs->name);
344 if (!bo)
345 goto on_error;
346
347 info.width = width;
348 info.height = height;
349 info.format = format;
350 info.bpp = bpp;
351 info.size = width * bufs->pitch;
352 for ( i = 0 ; i < num_plane ; i++)
353 {
354 info.planes[i].size = width * bufs->pitch;
355 info.planes[i].stride = bufs->pitch;
356 info.planes[i].offset = 0;
357 }
358
359 buf->tbm.surface = tbm_surface_internal_create_with_bos(&info, &bo, 1);
360 if (!buf->tbm.surface)
361 goto on_error;
362
363 buf->tbm.owned = EINA_TRUE;
364 tbm_bo_unref(bo);
365 free(bufs);
366
367 return buf;
368
369on_error:
370 if (bo) tbm_bo_unref(bo);
371 if (bufs) free(bufs);
372 ecore_x_pixmap_free(buf->pixmap);
373 DRI2DestroyDrawable(xdpy, buf->pixmap);
374 free(buf);
375
376 return NULL;
377}
378
379static void
380_ecore_buffer_x11_dri2_buffer_free(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
381{
382 Ecore_Buffer_X11_Dri2_Data *buf = bdata;
383
384 if (buf->pixmap)
385 {
386 DRI2DestroyDrawable(ecore_x_display_get(), buf->pixmap);
387
388 if (!buf->is_imported)
389 ecore_x_pixmap_free(buf->pixmap);
390 }
391
392 if (buf->tbm.surface)
393 tbm_surface_destroy(buf->tbm.surface);
394
395 free(buf);
396
397 return;
398}
399
400static Ecore_Export_Type
401_ecore_buffer_x11_dri2_buffer_export(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata, int *id)
402{
403 Ecore_Buffer_X11_Dri2_Data *buf = bdata;
404
405 if (id) *id = buf->pixmap;
406
407 return EXPORT_TYPE_ID;
408}
409
410static void *
411_ecore_buffer_x11_dri2_buffer_import(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, int w, int h, Ecore_Buffer_Format format, Ecore_Export_Type type, int export_id, unsigned int flags EINA_UNUSED)
412{
413 Ecore_Buffer_Module_X11_Dri2_Data *bm = bmdata;
414 Ecore_X_Display *xdpy;
415 Ecore_X_Pixmap pixmap = (Ecore_X_Pixmap)export_id;
416 Ecore_Buffer_X11_Dri2_Data *buf;
417 int rw, rh, rx, ry;
418 DRI2Buffer *bufs = NULL;
419 tbm_bo bo = NULL;
420 int rcount;
421 unsigned int attachment = DRI2BufferFrontLeft;
422 tbm_surface_info_s info;
423 int num_plane,i;
424
425 if (type != EXPORT_TYPE_ID)
426 return NULL;
427
428 xdpy = ecore_x_display_get();
429
430 //Check valid pixmap
431 ecore_x_pixmap_geometry_get(pixmap, &rx, &ry, &rw, &rh);
432 if ((rw != w) || (rh != h))
433 return NULL;
434
435 buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri2_Data));
436 if (!buf)
437 return NULL;
438
439 buf->w = w;
440 buf->h = h;
441 buf->format = format;
442 buf->pixmap = pixmap;
443 buf->is_imported = EINA_TRUE;
444
445 //Get DRI2Buffer
446 DRI2CreateDrawable(xdpy, buf->pixmap);
447 bufs = DRI2GetBuffers(xdpy, buf->pixmap, &rw, &rh, &attachment, 1, &rcount);
448 if ((!bufs) || (buf->w != rw) || (buf->h != rh))
449 goto on_error;
450
451 buf->stride = bufs->pitch;
452
453 //Import tbm_surface
454 bo = tbm_bo_import(bm->tbm_mgr, bufs->name);
455 if (!bo)
456 goto on_error;
457
458 num_plane = _buf_get_num_planes(format);
459 info.width = w;
460 info.height = h;
461 info.format = format;
462 info.bpp = _buf_get_bpp(format);
463 info.size = w * bufs->pitch;
464 for ( i = 0 ; i < num_plane ; i++)
465 {
466 info.planes[i].size = w * bufs->pitch;
467 info.planes[i].stride = bufs->pitch;
468 info.planes[i].offset = 0;
469 }
470
471 buf->tbm.surface = tbm_surface_internal_create_with_bos(&info, &bo, 1);
472 if (!buf->tbm.surface)
473 goto on_error;
474
475 buf->tbm.owned = EINA_TRUE;
476 tbm_bo_unref(bo);
477 free(bufs);
478
479 return buf;
480on_error:
481 if (bo) tbm_bo_unref(bo);
482 if (bufs) free(bufs);
483 DRI2DestroyDrawable(xdpy, buf->pixmap);
484 free(buf);
485
486 return NULL;
487}
488
489static Ecore_Pixmap
490_ecore_buffer_x11_dri2_pixmap_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
491{
492 Ecore_Buffer_X11_Dri2_Data *buf = bdata;
493
494 if (!buf)
495 return 0;
496
497 if (!buf->tbm.owned)
498 return 0;
499
500 return buf->pixmap;
501}
502
503static void *
504_ecore_buffer_x11_dri2_tbm_bo_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
505{
506 Ecore_Buffer_X11_Dri2_Data *buf = bdata;
507
508 if (!buf)
509 return NULL;
510
511 return buf->tbm.surface;
512}
513
514static Ecore_Buffer_Backend _ecore_buffer_x11_dri2_backend = {
515 "x11_dri2",
516 &_ecore_buffer_x11_dri2_init,
517 &_ecore_buffer_x11_dri2_shutdown,
518 &_ecore_buffer_x11_dri2_buffer_alloc,
519 &_ecore_buffer_x11_dri2_buffer_free,
520 &_ecore_buffer_x11_dri2_buffer_export,
521 &_ecore_buffer_x11_dri2_buffer_import,
522 NULL,
523 &_ecore_buffer_x11_dri2_pixmap_get,
524 &_ecore_buffer_x11_dri2_tbm_bo_get,
525};
526
527Eina_Bool x11_dri2_init(void)
528{
529 return ecore_buffer_register(&_ecore_buffer_x11_dri2_backend);
530}
531
532void x11_dri2_shutdown(void)
533{
534 ecore_buffer_unregister(&_ecore_buffer_x11_dri2_backend);
535}
536
537EINA_MODULE_INIT(x11_dri2_init);
538EINA_MODULE_SHUTDOWN(x11_dri2_shutdown);
diff --git a/src/modules/ecore_buffer/x11_dri3/ecore_buffer_x11_dri3.c b/src/modules/ecore_buffer/x11_dri3/ecore_buffer_x11_dri3.c
new file mode 100644
index 0000000000..d3ab7031df
--- /dev/null
+++ b/src/modules/ecore_buffer/x11_dri3/ecore_buffer_x11_dri3.c
@@ -0,0 +1,602 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <unistd.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <fcntl.h>
9
10#include <X11/Xlib.h>
11#include <X11/Xlib-xcb.h>
12#include <X11/xshmfence.h>
13#include <xcb/xcb.h>
14#include <xcb/dri3.h>
15#include <xcb/sync.h>
16
17#include <Eina.h>
18#include <Ecore.h>
19#include <Ecore_X.h>
20#include <Ecore_Buffer.h>
21
22#include <tbm_bufmgr.h>
23#include <tbm_surface.h>
24#include <tbm_surface_internal.h>
25
26#include "ecore_buffer_private.h"
27
28typedef struct _Ecore_Buffer_Module_X11_Dri3_Data Ecore_Buffer_Module_X11_Dri3_Data;
29typedef struct _Ecore_Buffer_X11_Dri3_Data Ecore_Buffer_X11_Dri3_Data;
30
31struct _Ecore_Buffer_Module_X11_Dri3_Data {
32 tbm_bufmgr tbm_mgr;
33};
34
35struct _Ecore_Buffer_X11_Dri3_Data {
36 Ecore_X_Pixmap pixmap;
37 void *tbm_surface;
38 int w;
39 int h;
40 int stride;
41 unsigned int flags;
42 Ecore_Buffer_Format format;
43 Eina_Bool is_imported;
44};
45
46static int
47_buf_get_num_planes(Ecore_Buffer_Format format)
48{
49 int num_planes = 0;
50
51 switch (format)
52 {
53 case ECORE_BUFFER_FORMAT_C8:
54 case ECORE_BUFFER_FORMAT_RGB332:
55 case ECORE_BUFFER_FORMAT_BGR233:
56 case ECORE_BUFFER_FORMAT_XRGB4444:
57 case ECORE_BUFFER_FORMAT_XBGR4444:
58 case ECORE_BUFFER_FORMAT_RGBX4444:
59 case ECORE_BUFFER_FORMAT_BGRX4444:
60 case ECORE_BUFFER_FORMAT_ARGB4444:
61 case ECORE_BUFFER_FORMAT_ABGR4444:
62 case ECORE_BUFFER_FORMAT_RGBA4444:
63 case ECORE_BUFFER_FORMAT_BGRA4444:
64 case ECORE_BUFFER_FORMAT_XRGB1555:
65 case ECORE_BUFFER_FORMAT_XBGR1555:
66 case ECORE_BUFFER_FORMAT_RGBX5551:
67 case ECORE_BUFFER_FORMAT_BGRX5551:
68 case ECORE_BUFFER_FORMAT_ARGB1555:
69 case ECORE_BUFFER_FORMAT_ABGR1555:
70 case ECORE_BUFFER_FORMAT_RGBA5551:
71 case ECORE_BUFFER_FORMAT_BGRA5551:
72 case ECORE_BUFFER_FORMAT_RGB565:
73 case ECORE_BUFFER_FORMAT_BGR565:
74 case ECORE_BUFFER_FORMAT_RGB888:
75 case ECORE_BUFFER_FORMAT_BGR888:
76 case ECORE_BUFFER_FORMAT_XRGB8888:
77 case ECORE_BUFFER_FORMAT_XBGR8888:
78 case ECORE_BUFFER_FORMAT_RGBX8888:
79 case ECORE_BUFFER_FORMAT_BGRX8888:
80 case ECORE_BUFFER_FORMAT_ARGB8888:
81 case ECORE_BUFFER_FORMAT_ABGR8888:
82 case ECORE_BUFFER_FORMAT_RGBA8888:
83 case ECORE_BUFFER_FORMAT_BGRA8888:
84 case ECORE_BUFFER_FORMAT_XRGB2101010:
85 case ECORE_BUFFER_FORMAT_XBGR2101010:
86 case ECORE_BUFFER_FORMAT_RGBX1010102:
87 case ECORE_BUFFER_FORMAT_BGRX1010102:
88 case ECORE_BUFFER_FORMAT_ARGB2101010:
89 case ECORE_BUFFER_FORMAT_ABGR2101010:
90 case ECORE_BUFFER_FORMAT_RGBA1010102:
91 case ECORE_BUFFER_FORMAT_BGRA1010102:
92 case ECORE_BUFFER_FORMAT_YUYV:
93 case ECORE_BUFFER_FORMAT_YVYU:
94 case ECORE_BUFFER_FORMAT_UYVY:
95 case ECORE_BUFFER_FORMAT_VYUY:
96 case ECORE_BUFFER_FORMAT_AYUV:
97 num_planes = 1;
98 break;
99 case ECORE_BUFFER_FORMAT_NV12:
100 case ECORE_BUFFER_FORMAT_NV21:
101 case ECORE_BUFFER_FORMAT_NV16:
102 case ECORE_BUFFER_FORMAT_NV61:
103 num_planes = 2;
104 break;
105 case ECORE_BUFFER_FORMAT_YUV410:
106 case ECORE_BUFFER_FORMAT_YVU410:
107 case ECORE_BUFFER_FORMAT_YUV411:
108 case ECORE_BUFFER_FORMAT_YVU411:
109 case ECORE_BUFFER_FORMAT_YUV420:
110 case ECORE_BUFFER_FORMAT_YVU420:
111 case ECORE_BUFFER_FORMAT_YUV422:
112 case ECORE_BUFFER_FORMAT_YVU422:
113 case ECORE_BUFFER_FORMAT_YUV444:
114 case ECORE_BUFFER_FORMAT_YVU444:
115 num_planes = 3;
116 break;
117
118 default :
119 break;
120 }
121
122 return num_planes;
123}
124
125static int
126_buf_get_bpp(Ecore_Buffer_Format format)
127{
128 int bpp = 0;
129
130 switch (format)
131 {
132 case ECORE_BUFFER_FORMAT_C8:
133 case ECORE_BUFFER_FORMAT_RGB332:
134 case ECORE_BUFFER_FORMAT_BGR233:
135 bpp = 8;
136 break;
137 case ECORE_BUFFER_FORMAT_XRGB4444:
138 case ECORE_BUFFER_FORMAT_XBGR4444:
139 case ECORE_BUFFER_FORMAT_RGBX4444:
140 case ECORE_BUFFER_FORMAT_BGRX4444:
141 case ECORE_BUFFER_FORMAT_ARGB4444:
142 case ECORE_BUFFER_FORMAT_ABGR4444:
143 case ECORE_BUFFER_FORMAT_RGBA4444:
144 case ECORE_BUFFER_FORMAT_BGRA4444:
145 case ECORE_BUFFER_FORMAT_XRGB1555:
146 case ECORE_BUFFER_FORMAT_XBGR1555:
147 case ECORE_BUFFER_FORMAT_RGBX5551:
148 case ECORE_BUFFER_FORMAT_BGRX5551:
149 case ECORE_BUFFER_FORMAT_ARGB1555:
150 case ECORE_BUFFER_FORMAT_ABGR1555:
151 case ECORE_BUFFER_FORMAT_RGBA5551:
152 case ECORE_BUFFER_FORMAT_BGRA5551:
153 case ECORE_BUFFER_FORMAT_RGB565:
154 case ECORE_BUFFER_FORMAT_BGR565:
155 bpp = 16;
156 break;
157 case ECORE_BUFFER_FORMAT_RGB888:
158 case ECORE_BUFFER_FORMAT_BGR888:
159 bpp = 24;
160 break;
161 case ECORE_BUFFER_FORMAT_XRGB8888:
162 case ECORE_BUFFER_FORMAT_XBGR8888:
163 case ECORE_BUFFER_FORMAT_RGBX8888:
164 case ECORE_BUFFER_FORMAT_BGRX8888:
165 case ECORE_BUFFER_FORMAT_ARGB8888:
166 case ECORE_BUFFER_FORMAT_ABGR8888:
167 case ECORE_BUFFER_FORMAT_RGBA8888:
168 case ECORE_BUFFER_FORMAT_BGRA8888:
169 case ECORE_BUFFER_FORMAT_XRGB2101010:
170 case ECORE_BUFFER_FORMAT_XBGR2101010:
171 case ECORE_BUFFER_FORMAT_RGBX1010102:
172 case ECORE_BUFFER_FORMAT_BGRX1010102:
173 case ECORE_BUFFER_FORMAT_ARGB2101010:
174 case ECORE_BUFFER_FORMAT_ABGR2101010:
175 case ECORE_BUFFER_FORMAT_RGBA1010102:
176 case ECORE_BUFFER_FORMAT_BGRA1010102:
177 case ECORE_BUFFER_FORMAT_YUYV:
178 case ECORE_BUFFER_FORMAT_YVYU:
179 case ECORE_BUFFER_FORMAT_UYVY:
180 case ECORE_BUFFER_FORMAT_VYUY:
181 case ECORE_BUFFER_FORMAT_AYUV:
182 bpp = 32;
183 break;
184 case ECORE_BUFFER_FORMAT_NV12:
185 case ECORE_BUFFER_FORMAT_NV21:
186 bpp = 12;
187 break;
188 case ECORE_BUFFER_FORMAT_NV16:
189 case ECORE_BUFFER_FORMAT_NV61:
190 bpp = 16;
191 break;
192 case ECORE_BUFFER_FORMAT_YUV410:
193 case ECORE_BUFFER_FORMAT_YVU410:
194 bpp = 9;
195 break;
196 case ECORE_BUFFER_FORMAT_YUV411:
197 case ECORE_BUFFER_FORMAT_YVU411:
198 case ECORE_BUFFER_FORMAT_YUV420:
199 case ECORE_BUFFER_FORMAT_YVU420:
200 bpp = 12;
201 break;
202 case ECORE_BUFFER_FORMAT_YUV422:
203 case ECORE_BUFFER_FORMAT_YVU422:
204 bpp = 16;
205 break;
206 case ECORE_BUFFER_FORMAT_YUV444:
207 case ECORE_BUFFER_FORMAT_YVU444:
208 bpp = 24;
209 break;
210 default :
211 break;
212 }
213
214 return bpp;
215}
216
217static int
218_buf_get_depth(Ecore_Buffer_Format format)
219{
220 int depth = 0;
221
222 switch (format)
223 {
224 case ECORE_BUFFER_FORMAT_C8:
225 case ECORE_BUFFER_FORMAT_RGB332:
226 case ECORE_BUFFER_FORMAT_BGR233:
227 depth = 8;
228 break;
229 case ECORE_BUFFER_FORMAT_XRGB4444:
230 case ECORE_BUFFER_FORMAT_XBGR4444:
231 case ECORE_BUFFER_FORMAT_RGBX4444:
232 case ECORE_BUFFER_FORMAT_BGRX4444:
233 depth = 12;
234 break;
235 case ECORE_BUFFER_FORMAT_ARGB4444:
236 case ECORE_BUFFER_FORMAT_ABGR4444:
237 case ECORE_BUFFER_FORMAT_RGBA4444:
238 case ECORE_BUFFER_FORMAT_BGRA4444:
239 depth = 16;
240 break;
241 case ECORE_BUFFER_FORMAT_XRGB1555:
242 case ECORE_BUFFER_FORMAT_XBGR1555:
243 case ECORE_BUFFER_FORMAT_RGBX5551:
244 case ECORE_BUFFER_FORMAT_BGRX5551:
245 depth = 15;
246 break;
247 case ECORE_BUFFER_FORMAT_ARGB1555:
248 case ECORE_BUFFER_FORMAT_ABGR1555:
249 case ECORE_BUFFER_FORMAT_RGBA5551:
250 case ECORE_BUFFER_FORMAT_BGRA5551:
251 case ECORE_BUFFER_FORMAT_RGB565:
252 case ECORE_BUFFER_FORMAT_BGR565:
253 depth = 16;
254 break;
255 case ECORE_BUFFER_FORMAT_RGB888:
256 case ECORE_BUFFER_FORMAT_BGR888:
257 depth = 24;
258 break;
259 case ECORE_BUFFER_FORMAT_XRGB8888:
260 case ECORE_BUFFER_FORMAT_XBGR8888:
261 case ECORE_BUFFER_FORMAT_RGBX8888:
262 case ECORE_BUFFER_FORMAT_BGRX8888:
263 depth = 24;
264 break;
265 case ECORE_BUFFER_FORMAT_ARGB8888:
266 case ECORE_BUFFER_FORMAT_ABGR8888:
267 case ECORE_BUFFER_FORMAT_RGBA8888:
268 case ECORE_BUFFER_FORMAT_BGRA8888:
269 depth = 32;
270 break;
271 case ECORE_BUFFER_FORMAT_XRGB2101010:
272 case ECORE_BUFFER_FORMAT_XBGR2101010:
273 case ECORE_BUFFER_FORMAT_RGBX1010102:
274 case ECORE_BUFFER_FORMAT_BGRX1010102:
275 depth = 30;
276 break;
277 case ECORE_BUFFER_FORMAT_ARGB2101010:
278 case ECORE_BUFFER_FORMAT_ABGR2101010:
279 case ECORE_BUFFER_FORMAT_RGBA1010102:
280 case ECORE_BUFFER_FORMAT_BGRA1010102:
281 depth = 32;
282 break;
283 case ECORE_BUFFER_FORMAT_YUYV:
284 case ECORE_BUFFER_FORMAT_YVYU:
285 case ECORE_BUFFER_FORMAT_UYVY:
286 case ECORE_BUFFER_FORMAT_VYUY:
287 case ECORE_BUFFER_FORMAT_AYUV:
288 case ECORE_BUFFER_FORMAT_NV12:
289 case ECORE_BUFFER_FORMAT_NV21:
290 case ECORE_BUFFER_FORMAT_NV16:
291 case ECORE_BUFFER_FORMAT_NV61:
292 case ECORE_BUFFER_FORMAT_YUV410:
293 case ECORE_BUFFER_FORMAT_YVU410:
294 case ECORE_BUFFER_FORMAT_YUV411:
295 case ECORE_BUFFER_FORMAT_YVU411:
296 case ECORE_BUFFER_FORMAT_YUV420:
297 case ECORE_BUFFER_FORMAT_YVU420:
298 case ECORE_BUFFER_FORMAT_YUV422:
299 case ECORE_BUFFER_FORMAT_YVU422:
300 case ECORE_BUFFER_FORMAT_YUV444:
301 case ECORE_BUFFER_FORMAT_YVU444:
302 default :
303 depth = 0; //unknown in X
304 break;
305 }
306
307 return depth;
308}
309
310static int
311_dri3_open(Ecore_X_Display *dpy, Ecore_X_Window root, unsigned provider)
312{
313 xcb_connection_t *c = XGetXCBConnection(dpy);
314 xcb_dri3_open_cookie_t cookie;
315 xcb_dri3_open_reply_t *reply;
316
317 cookie = xcb_dri3_open(c, root, provider);
318 reply = xcb_dri3_open_reply(c, cookie, NULL);
319 if ((!reply) || (reply->nfd != 1))
320 return -1;
321
322 return xcb_dri3_open_reply_fds(c, reply)[0];
323}
324
325static Ecore_X_Pixmap
326_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)
327{
328 xcb_connection_t *c = XGetXCBConnection(dpy);
329 Ecore_X_Pixmap pixmap = xcb_generate_id(c);
330
331 if (!dpy)
332 return 0;
333
334 c = XGetXCBConnection(dpy);
335 if (!c)
336 return 0;
337
338 pixmap = xcb_generate_id(c);
339 if (!pixmap)
340 return 0;
341
342 xcb_dri3_pixmap_from_buffer(c, pixmap, draw, size, width, height, stride, depth, bpp, fd);
343
344 return pixmap;
345}
346
347static Ecore_Buffer_Module_Data
348_ecore_buffer_x11_dri3_init(const char *context EINA_UNUSED, const char *options EINA_UNUSED)
349{
350 Ecore_X_Display *xdpy;
351 Ecore_X_Window root;
352 Ecore_Buffer_Module_X11_Dri3_Data *mdata = NULL;
353 int fd = 0;
354
355 if (!ecore_x_init(NULL))
356 return NULL;
357
358 xdpy = ecore_x_display_get();
359 if (!xdpy)
360 goto on_error;
361
362 root = ecore_x_window_root_first_get();
363 if (!root)
364 goto on_error;
365
366 mdata = calloc(1, sizeof(Ecore_Buffer_Module_X11_Dri3_Data));
367 if (!mdata)
368 goto on_error;
369
370 //Init DRI3 and TBM
371 fd = _dri3_open(xdpy, root, 0);
372 if (fd < 0)
373 goto on_error;
374
375 mdata->tbm_mgr = tbm_bufmgr_init(fd);
376 if (!mdata->tbm_mgr)
377 goto on_error;
378
379 close(fd);
380
381 return mdata;
382
383on_error:
384 if (fd > 0) close(fd);
385 if (mdata) free(mdata);
386 ecore_x_shutdown();
387
388 return NULL;
389}
390
391static void
392_ecore_buffer_x11_dri3_shutdown(Ecore_Buffer_Module_Data bmdata)
393{
394 Ecore_Buffer_Module_X11_Dri3_Data *bm = bmdata;
395
396 if (!bm)
397 return;
398
399 if (bm->tbm_mgr)
400 tbm_bufmgr_deinit(bm->tbm_mgr);
401
402 ecore_x_shutdown();
403}
404
405static Ecore_Buffer_Data
406_ecore_buffer_x11_dri3_buffer_alloc(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, int width, int height, Ecore_Buffer_Format format, unsigned int flags)
407{
408 Ecore_Buffer_X11_Dri3_Data *buf;
409
410 buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri3_Data));
411 if (!buf)
412 return NULL;
413
414 buf->w = width;
415 buf->h = height;
416 buf->format = format;
417 buf->flags = flags;
418 buf->is_imported = EINA_FALSE;
419 buf->tbm_surface = tbm_surface_create(width,height,(tbm_format)format);
420 if (!buf->tbm_surface)
421 {
422 free(buf);
423 return NULL;
424 }
425
426 return buf;
427}
428
429static Ecore_Buffer_Data
430static void
431_ecore_buffer_x11_dri3_buffer_free(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
432{
433 Ecore_Buffer_X11_Dri3_Data *buf = bdata;
434
435 if (!buf)
436 return;
437
438 if (buf->pixmap)
439 ecore_x_pixmap_free(buf->pixmap);
440
441 if (buf->tbm_surface)
442 tbm_surface_destroy(buf->tbm_surface);
443
444 free(buf);
445}
446
447static Ecore_Export_Type
448_ecore_buffer_x11_dri3_buffer_export(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata, int *id)
449{
450 Ecore_Buffer_X11_Dri3_Data *buf = bdata;
451 tbm_bo bo;
452
453 if (_buf_get_num_planes(buf->format) != 1)
454 return EXPORT_TYPE_INVALID;
455
456 bo = tbm_surface_internal_get_bo(buf->tbm_surface, 0);
457 if (!bo)
458 return EXPORT_TYPE_INVALID;
459
460 if (id) *id = tbm_bo_export_fd(bo);
461
462 return EXPORT_TYPE_FD;
463}
464
465static Ecore_Buffer_Data
466_ecore_buffer_x11_dri3_buffer_import(Ecore_Buffer_Module_Data bmdata, int w, int h, Ecore_Buffer_Format format, Ecore_Export_Type type, int export_id, unsigned int flags)
467{
468 Ecore_Buffer_Module_X11_Dri3_Data *bm = bmdata;
469 Ecore_Buffer_X11_Dri3_Data *buf;
470 tbm_bo bo;
471 tbm_surface_info_s info;
472 int i, num_plane;
473
474 if (!bm)
475 return NULL;
476
477 if (type != EXPORT_TYPE_FD)
478 return NULL;
479
480 if (export_id < 1)
481 return NULL;
482
483 buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri3_Data));
484 if (!buf)
485 return NULL;
486
487 buf->w = w;
488 buf->h = h;
489 buf->format = format;
490 buf->flags = flags;
491 buf->is_imported = EINA_TRUE;
492
493 //Import tbm_surface
494 bo = tbm_bo_import_fd(bm->tbm_mgr, export_id);
495 if (!bo)
496 {
497 free(buf);
498 return NULL;
499 }
500
501 num_plane = _buf_get_num_planes(format);
502 info.width = w;
503 info.height = h;
504 info.format = format;
505 info.bpp = _buf_get_bpp(format);
506 info.size = w * h * info.bpp;
507 for ( i = 0 ; i < num_plane ; i++)
508 {
509 info.planes[i].size = w * h * info.bpp;
510 info.planes[i].stride = w * info.bpp;
511 info.planes[i].offset = 0;
512 }
513
514 buf->tbm_surface = tbm_surface_internal_create_with_bos(&info, &bo, 1);
515 if (!buf->tbm_surface)
516 {
517 tbm_bo_unref(bo);
518 free(buf);
519 return NULL;
520 }
521
522 tbm_bo_unref(bo);
523
524 return buf;
525}
526
527static Ecore_Pixmap
528_ecore_buffer_x11_dri3_pixmap_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
529{
530 Ecore_Buffer_X11_Dri3_Data *buf = bdata;
531 Ecore_X_Display *xdpy;
532 Ecore_X_Window root;
533 tbm_surface_info_s info;
534 tbm_bo bo;
535 int ret;
536
537 if (!buf)
538 return 0;
539
540 if (buf->pixmap)
541 return buf->pixmap;
542
543 ret = tbm_surface_get_info(buf->tbm_surface, &info);
544 if (ret != 0)
545 return 0;
546
547 if (info.num_planes != 1)
548 return 0;
549
550 bo = tbm_surface_internal_get_bo(buf->tbm_surface, 0);
551 if (!bo)
552 return 0;
553
554 xdpy = ecore_x_display_get();
555 root = ecore_x_window_root_first_get();
556 buf->pixmap = _dri3_pixmap_from_fd(xdpy, root,
557 buf->w, buf->h,
558 _buf_get_depth(buf->format),
559 tbm_bo_export_fd(bo),
560 _buf_get_bpp(buf->format),
561 info.planes[0].stride,
562 info.planes[0].size);
563
564 return buf->pixmap;
565}
566
567static void *
568_ecore_buffer_x11_dri3_tbm_bo_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
569{
570 Ecore_Buffer_X11_Dri3_Data *buf = bdata;
571
572 if (!buf)
573 return NULL;
574
575 return buf->tbm_surface;
576}
577
578static Ecore_Buffer_Backend _ecore_buffer_x11_dri3_backend = {
579 "x11_dri3",
580 &_ecore_buffer_x11_dri3_init,
581 &_ecore_buffer_x11_dri3_shutdown,
582 &_ecore_buffer_x11_dri3_buffer_alloc,
583 &_ecore_buffer_x11_dri3_buffer_free,
584 &_ecore_buffer_x11_dri3_buffer_export,
585 &_ecore_buffer_x11_dri3_buffer_import,
586 NULL,
587 &_ecore_buffer_x11_dri3_pixmap_get,
588 &_ecore_buffer_x11_dri3_tbm_bo_get,
589};
590
591Eina_Bool x11_dri3_init(void)
592{
593 return ecore_buffer_register(&_ecore_buffer_x11_dri3_backend);
594}
595
596void x11_dri3_shutdown(void)
597{
598 ecore_buffer_unregister(&_ecore_buffer_x11_dri3_backend);
599}
600
601EINA_MODULE_INIT(x11_dri3_init);
602EINA_MODULE_SHUTDOWN(x11_dri3_shutdown);