Tizen 2.4 SDK Rev6 Release
[framework/uifw/efl.git] / src / modules / ecore_buffer / x11_dri2 / ecore_buffer_x11_dri2.c
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
25 typedef struct _Ecore_Buffer_Module_X11_Dri2_Data Ecore_Buffer_Module_X11_Dri2_Data;
26 typedef struct _Ecore_Buffer_X11_Dri2_Data Ecore_Buffer_X11_Dri2_Data;
27
28 struct _Ecore_Buffer_Module_X11_Dri2_Data {
29      tbm_bufmgr tbm_mgr;
30 };
31
32 struct _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
47 static 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
126 static 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
218 static 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 = NULL;
226    char *device_name = NULL;
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_fd_error;
257
258    if (!(DRI2Authenticate(xdpy, root, magic)))
259      goto on_fd_error;
260
261    mdata->tbm_mgr = tbm_bufmgr_init(fd);
262    if (!mdata->tbm_mgr)
263      goto on_fd_error;
264
265    free(driver_name);
266    free(device_name);
267    close(fd);
268
269    return mdata;
270
271 on_fd_error:
272    close(fd);
273
274 on_error:
275    if (driver_name) free(driver_name);
276    if (device_name) free(device_name);
277    if (mdata) free(mdata);
278    ecore_x_shutdown();
279
280    return NULL;
281 }
282
283 static void
284 _ecore_buffer_x11_dri2_shutdown(Ecore_Buffer_Module_Data bmdata)
285 {
286    Ecore_Buffer_Module_X11_Dri2_Data *bm = bmdata;
287
288    if (bm->tbm_mgr)
289      tbm_bufmgr_deinit(bm->tbm_mgr);
290
291    ecore_x_shutdown();
292 }
293
294 static Ecore_Buffer_Data
295 _ecore_buffer_x11_dri2_buffer_alloc(Ecore_Buffer_Module_Data bmdata, int width, int height, Ecore_Buffer_Format format, unsigned int flags EINA_UNUSED)
296 {
297    Ecore_X_Display *xdpy;
298    Ecore_X_Pixmap pixmap;
299    Ecore_Buffer_X11_Dri2_Data *buf;
300    Ecore_Buffer_Module_X11_Dri2_Data *bm = bmdata;
301    DRI2Buffer *bufs = NULL;
302    tbm_bo bo = NULL;
303    int bpp;
304    int num_plane;
305    int rw, rh, rcount;
306    unsigned int attachment = DRI2BufferFrontLeft;
307    tbm_surface_info_s info;
308    int i;
309
310    bpp = _buf_get_bpp(format);
311    if (bpp != 32)
312      return NULL;
313
314    num_plane = _buf_get_num_planes(format);
315    if (num_plane != 1)
316      return NULL;
317
318    xdpy = ecore_x_display_get();
319    pixmap = ecore_x_pixmap_new(0, width, height, bpp);
320    if (!pixmap)
321      return NULL;
322
323    buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri2_Data));
324    if (!buf)
325      {
326         ecore_x_pixmap_free(pixmap);
327         return NULL;
328      }
329
330    buf->w = width;
331    buf->h = height;
332    buf->format = format;
333    buf->pixmap = pixmap;
334    buf->is_imported = EINA_FALSE;
335
336    //Get DRI2Buffer
337    DRI2CreateDrawable(xdpy, buf->pixmap);
338    bufs = DRI2GetBuffers(xdpy, buf->pixmap, &rw, &rh, &attachment, 1, &rcount);
339    if (!(bufs) || (buf->w != rw) || (buf->h != rh))
340      goto on_error;
341
342    buf->stride = bufs->pitch;
343
344    //Import tbm_surface
345    bo = tbm_bo_import(bm->tbm_mgr, bufs->name);
346    if (!bo)
347      goto on_error;
348
349    info.width = width;
350    info.height =  height;
351    info.format = format;
352    info.bpp = bpp;
353    info.size = height * bufs->pitch;
354    info.num_planes = num_plane;
355    for ( i = 0 ; i < num_plane ; i++)
356    {
357       info.planes[i].size = height * bufs->pitch;
358       info.planes[i].stride = bufs->pitch;
359       info.planes[i].offset = 0;
360    }
361
362    buf->tbm.surface = tbm_surface_internal_create_with_bos(&info, &bo, 1);
363    if (!buf->tbm.surface)
364      goto on_error;
365
366    buf->tbm.owned = EINA_TRUE;
367    tbm_bo_unref(bo);
368    free(bufs);
369
370    return buf;
371
372 on_error:
373    if (bo) tbm_bo_unref(bo);
374    if (bufs) free(bufs);
375    ecore_x_pixmap_free(buf->pixmap);
376    DRI2DestroyDrawable(xdpy, buf->pixmap);
377    free(buf);
378
379    return NULL;
380 }
381
382 static Ecore_Buffer_Data
383 _ecore_buffer_x11_dri2_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 EINA_UNUSED)
384 {
385    Ecore_Buffer_X11_Dri2_Data *buf;
386
387    EINA_SAFETY_ON_NULL_RETURN_VAL(tbm_surface, NULL);
388
389    buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri2_Data));
390    if (!buf)
391      return NULL;
392
393    buf->w = tbm_surface_get_width(tbm_surface);
394    buf->h = tbm_surface_get_height(tbm_surface);
395    buf->format = tbm_surface_get_format(tbm_surface);
396    buf->pixmap = 0;
397    buf->tbm.surface = tbm_surface;
398    buf->tbm.owned = EINA_FALSE;
399    buf->is_imported = EINA_FALSE;
400
401    if (ret_w) *ret_w = buf->w;
402    if (ret_h) *ret_h = buf->h;
403    if (ret_format) *ret_format = buf->format;
404
405    return buf;
406 }
407
408 static Eina_Bool
409 _ecore_buffer_x11_dri2_buffer_info_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata, Ecore_Buffer_Info *info)
410 {
411    Ecore_Buffer_X11_Dri2_Data *buf = bdata;
412    tbm_surface_info_s tinfo;
413    int i, res;
414
415    if (!buf->tbm.surface)
416      return EINA_FALSE;
417
418    res = tbm_surface_get_info(buf->tbm.surface, &tinfo);
419    if (res != TBM_SURFACE_ERROR_NONE)
420      return EINA_FALSE;
421
422    if (info)
423      {
424         info->width = tinfo.width;
425         info->height = tinfo.height;
426         info->format = tinfo.format;
427         info->bpp = tinfo.bpp;
428         info->size = tinfo.size;
429         info->num_planes = tinfo.num_planes;
430         info->pixmap = buf->pixmap;
431
432         for (i = 0; i < tinfo.num_planes; i++)
433           {
434              info->planes[i].size = tinfo.planes[i].size;
435              info->planes[i].offset = tinfo.planes[i].offset;
436              info->planes[i].stride = tinfo.planes[i].stride;
437           }
438      }
439
440    return EINA_TRUE;
441 }
442
443 static void
444 _ecore_buffer_x11_dri2_buffer_free(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
445 {
446    Ecore_Buffer_X11_Dri2_Data *buf = bdata;
447
448    if (buf->pixmap)
449      {
450         DRI2DestroyDrawable(ecore_x_display_get(), buf->pixmap);
451
452         if (!buf->is_imported)
453           ecore_x_pixmap_free(buf->pixmap);
454      }
455
456    if (buf->tbm.surface)
457      tbm_surface_destroy(buf->tbm.surface);
458
459    free(buf);
460
461    return;
462 }
463
464 static Ecore_Export_Type
465 _ecore_buffer_x11_dri2_buffer_export(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata, int *id)
466 {
467    Ecore_Buffer_X11_Dri2_Data *buf = bdata;
468    tbm_bo bo;
469
470    if (id)
471      {
472         if (buf->pixmap)
473           *id = buf->pixmap;
474         else
475           {
476              tbm_bo bo;
477              /* NOTE: constraints - cannot support more than two bos */
478              bo = tbm_surface_internal_get_bo(buf->tbm.surface, 0);
479              *id = (int)(tbm_bo_export(bo));
480           }
481      }
482
483    return EXPORT_TYPE_ID;
484 }
485
486 static tbm_bo
487 _x11_dri2_bo_get_from_pixmap(tbm_bufmgr tbm_mgr, Ecore_Pixmap pixmap, int width, int height)
488 {
489    Ecore_X_Display *xdpy;
490    DRI2Buffer *bufs = NULL;
491    tbm_bo bo = NULL;
492    int rw, rh, rx, ry;
493    int rcount;
494    unsigned int attachment = DRI2BufferFrontLeft;
495
496    // Check valid pixmap
497    ecore_x_pixmap_geometry_get(pixmap, &rx, &ry, &rw, &rh);
498    if ((rw != width) || (rh != height))
499      return NULL;
500
501    xdpy = ecore_x_display_get();
502    DRI2CreateDrawable(xdpy, pixmap);
503    bufs = DRI2GetBuffers(xdpy, pixmap, &rw, &rh, &attachment, 1, &rcount);
504    if ((!bufs) || (width != rw) || (height != rh))
505      goto err;
506
507    bo = tbm_bo_import(tbm_mgr, bufs->name);
508    free(bufs);
509    if (!bo)
510      goto err;
511
512    return bo;
513 err:
514    DRI2DestroyDrawable(xdpy, pixmap);
515    return NULL;
516 }
517
518 static void *
519 _ecore_buffer_x11_dri2_buffer_import(Ecore_Buffer_Module_Data bmdata, Ecore_Buffer_Info *einfo, Ecore_Export_Type type, int export_id, unsigned int flags EINA_UNUSED)
520 {
521    Ecore_Buffer_Module_X11_Dri2_Data *bm = bmdata;
522    Ecore_Buffer_X11_Dri2_Data *buf;
523    tbm_bo bo = NULL;
524    tbm_surface_h surface;
525    tbm_surface_info_s tinfo;
526    int i;
527
528    if (type != EXPORT_TYPE_ID)
529      return NULL;
530
531    if (!einfo)
532      return NULL;
533
534    if (einfo->pixmap)
535      bo = _x11_dri2_bo_get_from_pixmap(bm->tbm_mgr, einfo->pixmap, einfo->width, einfo->height);
536    else
537      bo = tbm_bo_import(bm->tbm_mgr, export_id);
538
539    if (!bo)
540      goto err;
541
542    tinfo.width = einfo->width;
543    tinfo.height = einfo->height;
544    tinfo.format = einfo->format;
545    tinfo.bpp = _buf_get_bpp(einfo->format);
546    tinfo.size = einfo->height * einfo->planes[0].stride;
547    tinfo.num_planes = _buf_get_num_planes(einfo->format);
548    for (i = 0; i < tinfo.num_planes; i++)
549      {
550         tinfo.planes[i].size = einfo->height * einfo->planes[i].stride;
551         tinfo.planes[i].stride = einfo->planes[i].stride;
552         tinfo.planes[i].offset = einfo->planes[i].offset;
553      }
554
555    surface = tbm_surface_internal_create_with_bos(&tinfo, &bo, 1);
556    tbm_bo_unref(bo);
557    if (!surface)
558      goto err;
559
560    buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri2_Data));
561    if (!buf)
562      goto err_alloc;
563
564    buf->w = einfo->width;
565    buf->h = einfo->height;
566    buf->format = einfo->format;
567    buf->pixmap = einfo->pixmap;
568    buf->stride = einfo->planes[0].stride;
569    buf->is_imported = EINA_TRUE;
570    buf->tbm.surface = surface;
571    buf->tbm.owned = EINA_TRUE;
572
573    return buf;
574 err_alloc:
575    tbm_surface_internal_unref(surface);
576 err:
577    if ((bo) && (einfo->pixmap))
578      DRI2DestroyDrawable(ecore_x_display_get(), einfo->pixmap);
579
580    free(buf);
581
582    return NULL;
583 }
584
585 static Ecore_Pixmap
586 _ecore_buffer_x11_dri2_pixmap_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
587 {
588    Ecore_Buffer_X11_Dri2_Data *buf = bdata;
589
590    if (!buf)
591      return 0;
592
593    if (!buf->tbm.owned)
594      return 0;
595
596    return buf->pixmap;
597 }
598
599 static void *
600 _ecore_buffer_x11_dri2_tbm_bo_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
601 {
602    Ecore_Buffer_X11_Dri2_Data *buf = bdata;
603
604    if (!buf)
605      return NULL;
606
607    return buf->tbm.surface;
608 }
609
610 static Ecore_Buffer_Backend _ecore_buffer_x11_dri2_backend = {
611      "x11_dri2",
612      &_ecore_buffer_x11_dri2_init,
613      &_ecore_buffer_x11_dri2_shutdown,
614      &_ecore_buffer_x11_dri2_buffer_alloc,
615      &_ecore_buffer_x11_dri2_buffer_alloc_with_tbm_surface,
616      &_ecore_buffer_x11_dri2_buffer_info_get,
617      &_ecore_buffer_x11_dri2_buffer_free,
618      &_ecore_buffer_x11_dri2_buffer_export,
619      &_ecore_buffer_x11_dri2_buffer_import,
620      &_ecore_buffer_x11_dri2_pixmap_get,
621      &_ecore_buffer_x11_dri2_tbm_bo_get,
622 };
623
624 Eina_Bool x11_dri2_init(void)
625 {
626    return ecore_buffer_register(&_ecore_buffer_x11_dri2_backend);
627 }
628
629 void x11_dri2_shutdown(void)
630 {
631    ecore_buffer_unregister(&_ecore_buffer_x11_dri2_backend);
632 }
633
634 EINA_MODULE_INIT(x11_dri2_init);
635 EINA_MODULE_SHUTDOWN(x11_dri2_shutdown);