[evas_sw_backend] 1. evas sw tbm backend implement 97/166397/2
authorJoogab Yun <joogab.yun@samsung.com>
Thu, 28 Dec 2017 07:06:11 +0000 (16:06 +0900)
committerjoogab yun <joogab.yun@samsung.com>
Wed, 10 Jan 2018 05:00:00 +0000 (05:00 +0000)
                  2. wayland_tbm_client_init / deinit in ecore_evas

Change-Id: Ia605be8f0cac12b1873d82392d894b89f88543b1

src/Makefile_Ecore_Wl2.am [changed mode: 0644->0755]
src/lib/ecore_wl2/ecore_wl2_private.h [changed mode: 0644->0755]
src/lib/ecore_wl2/ecore_wl2_tbmsurface.c [new file with mode: 0755]
src/modules/evas/engines/wayland_shm/evas_engine.h
src/modules/evas/engines/wayland_shm/evas_outbuf.c
src/modules/evas/engines/wayland_shm/evas_tbmbuf.c [deleted file]

old mode 100644 (file)
new mode 100755 (executable)
index fb1e787..dbe14b2
@@ -20,6 +20,7 @@ lib/ecore_wl2/tizen-policy-ext-protocol.c \
 lib/ecore_wl2/ecore_wl2_private.h \
 lib/ecore_wl2/ecore_wl2_buffer.c \
 lib/ecore_wl2/ecore_wl2_surface.c \
+lib/ecore_wl2/ecore_wl2_tbmsurface.c \
 static_libs/libdrm/drm_fourcc.h \
 static_libs/libdrm/drm.h \
 static_libs/libdrm/drm_mode.h \
old mode 100644 (file)
new mode 100755 (executable)
index 866f9bd..3ded1c6
 # include "tizen-policy-ext-client-protocol.h"
 //
 
+// TIZEN_ONLY(20171226) : evas tbm_buf backend
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+#include <tbm_surface_queue.h>
+//
+
 extern int _ecore_wl2_log_dom;
 extern Eina_Bool no_session_recovery;
 
@@ -700,6 +706,20 @@ typedef struct _Buffer_Handle Buffer_Handle;
 typedef struct _Ecore_Wl2_Buffer
 {
    struct wl_buffer *wl_buffer;
+   // TIZEN_ONLY(20171226) : evas tbm_buf backend
+   struct wl_display *wl_display;
+   struct wl_surface *wl_surface;
+   struct wl_registry *registry;
+   struct wayland_tbm_client *tbm_client;
+   tbm_surface_h tbm_surface;
+   tbm_surface_info_s tbm_info;
+   void *tbm_queue;
+   int wait_release;
+   Eina_Bool resize : 1;
+   int compositor_version;
+   int frame_age;
+   // TIZEN_ONLY(20171226) : evas tbm_buf backend
+
    int size;
    int w, h;
    int age;
@@ -732,6 +752,7 @@ typedef struct _Ecore_Wl2_Surface
         void (*post)(Ecore_Wl2_Surface *surface, Eina_Rectangle *rects, unsigned int count);
         void (*flush)(Ecore_Wl2_Surface *surface);
      } funcs;
+   unsigned int frame_age;  // TIZEN_ONLY(20171226) : evas tbm_buf backend
 } Ecore_Wl2_Surface;
 
 Ecore_Wl2_Window *_ecore_wl2_display_window_surface_find(Ecore_Wl2_Display *display, struct wl_surface *wl_surface);
diff --git a/src/lib/ecore_wl2/ecore_wl2_tbmsurface.c b/src/lib/ecore_wl2/ecore_wl2_tbmsurface.c
new file mode 100755 (executable)
index 0000000..48a5f8d
--- /dev/null
@@ -0,0 +1,438 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ecore_wl2_private.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include <wayland-client.h>
+#include <wayland-tbm-client.h>
+#include <tbm_surface_internal.h>
+
+#define KEY_WINDOW (unsigned long)(&key_window)
+#define KEY_WL_BUFFER (unsigned long)(&key_wl_buffer)
+#define KEY_SURFACE_INFO (unsigned long)(&key_surface_info)
+
+static int key_window;
+static int key_wl_buffer;
+static int key_surface_info;
+
+typedef struct {
+  unsigned int age;
+  unsigned int num_surface;
+} tbm_buffer_info;
+
+
+static int   tbm_queue_ref = 0;
+static Eina_Bool need_to_tbm_queue = EINA_TRUE;
+static void *tbm_queue;
+
+typedef enum
+{
+  MODE_FULL,
+  MODE_COPY,
+  MODE_DOUBLE,
+  MODE_TRIPLE,
+  MODE_QUADRUPLE,
+  MODE_AUTO
+} Render_Output_Swap_Mode;
+
+
+static void
+_evas_tbmbuf_buffer_unmap(Ecore_Wl2_Buffer *surf)
+{
+  tbm_surface_unmap(surf->tbm_surface);
+}
+
+
+static void
+_evas_tbmbuf_surface_reconfigure(Ecore_Wl2_Surface *surface, int w, int h, uint32_t flags , Eina_Bool force )
+{
+  Ecore_Wl2_Buffer *surf;
+
+  if (!surface) return;
+
+  surf = surface->current;
+
+  if (!surf) return;
+
+  /* TIZEN_ONLY(20171204) : temporary patch */
+  if (w < 1) w = 1;
+  if (h < 1) h = 1;
+
+  if ((w >= surf->w) && (w <= surf->stride / 4) && (h == surf->h))
+    {
+      surf->w = w;
+      return;
+    }
+  surf->resize = EINA_TRUE;
+  surf->w = w;
+  surf->h = h;
+}
+
+static void
+_wait_free_buffer(Ecore_Wl2_Buffer *surf)
+{
+  if (!surf) return;
+
+  wl_display_dispatch_pending(surf->wl_display);
+  if ( tbm_surface_queue_can_dequeue(surf->tbm_queue, 0))
+    return;
+
+  DBG("WAIT free buffer");
+
+  while (! tbm_surface_queue_can_dequeue(surf->tbm_queue, 0)) {
+      wl_display_dispatch(surf->wl_display);
+  }
+}
+
+static void
+buffer_release(void *data, struct wl_buffer *buffer EINA_UNUSED)
+{
+  if (!data) return;
+  void *tbm_queue = NULL;
+  tbm_surface_h tbm_surface = data;
+  tbm_surface_internal_get_user_data(tbm_surface, KEY_WINDOW, (void **)&tbm_queue);
+  tbm_surface_internal_unref(tbm_surface);
+  if (tbm_queue)
+    {
+      ERR("tbm_surface_queue_release");
+      tbm_surface_queue_release(tbm_queue, tbm_surface);
+    }
+}
+
+static void
+buffer_destroy(void *data)
+{
+  if (!data) return;
+  struct wl_buffer* buffer = data;
+  wl_buffer_destroy(buffer);
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+    buffer_release
+};
+
+
+static int
+_evas_tbmbuf_surface_assign(Ecore_Wl2_Surface *surface)
+{
+  Ecore_Wl2_Buffer *surf;
+
+  Render_Output_Swap_Mode mode = MODE_FULL;
+  tbm_buffer_info *tbuf_info = NULL;
+  if (!surface) return 0;
+
+  surf = surface->current;
+  if (!surf)
+    {
+      ERR("surface is NULL");
+      return 0;
+    }
+
+  if (surf->resize)
+    {
+      // reset tbm_surface
+      int width, height, format;
+      width = surf->w;
+      height = surf->h;
+      format =  tbm_surface_queue_get_format(surf->tbm_queue);
+      tbm_surface_queue_reset(surf->tbm_queue, width, height, format);
+      surf->resize = EINA_FALSE;
+    }
+
+  surf->tbm_surface = NULL;
+  tbm_surface_queue_error_e ret = TBM_SURFACE_QUEUE_ERROR_NONE;
+  struct wl_buffer *buffer;
+
+  _wait_free_buffer(surf);
+
+  // check num of tbm surface
+  int num_surface, i;
+  tbm_surface_h surfaces[5];
+  tbm_surface_queue_get_surfaces(surf->tbm_queue, surfaces, &num_surface);
+
+  ret =  tbm_surface_queue_dequeue(surf->tbm_queue, &surf->tbm_surface);
+
+  if (ret != TBM_SURFACE_QUEUE_ERROR_NONE ||
+      surf->tbm_surface == NULL) {
+      ERR("dequeue:%p from queue:%p err:%d\n", surf->tbm_surface, surf->tbm_queue, ret);
+      surf->wait_release = 1;
+      return 0;
+  }
+
+  tbm_surface_internal_ref(surf->tbm_surface);
+
+  surf->wait_release = 0;
+  if(! tbm_surface_internal_get_user_data(surf->tbm_surface, KEY_WL_BUFFER, (void **)&buffer)) {
+      buffer =  wayland_tbm_client_create_buffer(surf->tbm_client, surf->tbm_surface);
+      if (!buffer)
+        {
+          ERR("wayland_tbm_client_create_buffer is NULL");
+          tbm_surface_internal_unref(surf->tbm_surface);
+          tbm_surface_queue_release(surf->tbm_queue, surf->tbm_surface);
+          return 0;
+        }
+
+      wl_proxy_set_queue((struct wl_proxy *)buffer, NULL);
+
+      tbm_surface_internal_add_user_data(surf->tbm_surface, KEY_WL_BUFFER, (tbm_data_free)buffer_destroy);
+      tbm_surface_internal_set_user_data(surf->tbm_surface, KEY_WL_BUFFER, buffer);
+
+      tbm_surface_internal_add_user_data(surf->tbm_surface, KEY_WINDOW, NULL);
+      tbm_surface_internal_set_user_data(surf->tbm_surface, KEY_WINDOW, surf->tbm_queue);
+
+      wl_buffer_add_listener(buffer, &buffer_listener, surf->tbm_surface);
+  }
+
+
+  tbm_surface_info_s info;
+  tbm_surface_map(surf->tbm_surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
+  surf->tbm_info = info;
+
+  // check buffer age
+  if (! tbm_surface_internal_get_user_data(surf->tbm_surface, KEY_SURFACE_INFO, (void**)&tbuf_info)) {
+      tbuf_info = calloc(1, sizeof(tbm_buffer_info));
+      if (tbuf_info) {
+          tbuf_info->age = 0;
+          tbuf_info->num_surface = num_surface;
+      }
+      tbm_surface_internal_add_user_data(surf->tbm_surface, KEY_SURFACE_INFO, free);
+      tbm_surface_internal_set_user_data(surf->tbm_surface, KEY_SURFACE_INFO, tbuf_info);
+  }
+
+  //reset
+  if (tbuf_info && (unsigned int)num_surface != tbuf_info->num_surface)
+    {
+      surface->frame_age = 0;
+
+      for(i=0; i<num_surface; i++) {
+          tbm_surface_internal_get_user_data(surfaces[i], KEY_SURFACE_INFO, (void **)&tbuf_info);
+          if (tbuf_info) {
+              tbuf_info->age = 0;
+              tbuf_info->num_surface = num_surface;
+          }
+      }
+    }
+
+  if (!tbuf_info || !tbuf_info->age)
+    return MODE_FULL;
+
+  if (tbuf_info && tbuf_info->age < surface->frame_age)
+    {
+      unsigned int diff;
+      diff = surface->frame_age - tbuf_info->age + 1;
+      if (diff > (unsigned int)num_surface) return MODE_FULL;
+      switch(diff)
+      {
+        case 1:
+          mode = MODE_COPY;
+          break;
+        case 2:
+          mode = MODE_DOUBLE;
+          break;
+        case 3:
+          mode = MODE_TRIPLE;
+          break;
+        default:
+          mode = MODE_FULL;
+      }
+    }
+
+  return mode;
+}
+
+
+static void *
+_evas_tbmbuf_surface_data_get(Ecore_Wl2_Surface *surface, int *w, int *h)
+{
+  Ecore_Wl2_Buffer *surf;
+  void *image;
+
+  surf = surface->current;
+  if (!surf)
+    {
+      ERR("surface is NULL");
+      return 0;
+    }
+
+  image = surf->tbm_info.planes[0].ptr;
+
+  surf->stride = surf->tbm_info.planes[0].stride;
+  if (w) *w = surf->stride / 4;
+  if (h) *h = surf->tbm_info.height;
+
+  return image;
+}
+
+void
+_evas_surface_damage(struct wl_surface *s, int compositor_version, int w, int h, Eina_Rectangle *rects, unsigned int count)
+{
+  void (*damage)(struct wl_surface *, int32_t, int32_t, int32_t, int32_t);
+  unsigned int k;
+
+  if (compositor_version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
+    damage = wl_surface_damage_buffer;
+  else
+    damage = wl_surface_damage;
+
+  if ((rects) && (count > 0))
+    for (k = 0; k < count; k++)
+      damage(s, rects[k].x, rects[k].y, rects[k].w, rects[k].h);
+  else
+    damage(s, 0, 0, w, h);
+}
+
+
+static void
+_evas_tbmbuf_surface_post(Ecore_Wl2_Surface *surface, Eina_Rectangle *rects, unsigned int count)
+{
+  Ecore_Wl2_Buffer *surf;
+  tbm_buffer_info *tbuf_info = NULL;
+  if (!surface) return;
+
+  surf = surface->current;
+  if (!surf->wl_surface) return;
+
+  struct wl_buffer *buffer = NULL;
+
+  _evas_tbmbuf_buffer_unmap(surf);
+
+  tbm_surface_internal_get_user_data(surf->tbm_surface, KEY_WL_BUFFER, (void **)&buffer);
+  if (!buffer) {
+      ERR("Enqueue:%p from queue:%p", surf->tbm_surface, surf->tbm_queue);
+      return;
+  }
+
+  ++surface->frame_age;
+  tbm_surface_internal_get_user_data(surf->tbm_surface, KEY_SURFACE_INFO, (void **)&tbuf_info);
+  if (tbuf_info)
+    tbuf_info->age = surface->frame_age;
+
+  ecore_wl2_window_buffer_attach(surface->wl2_win, buffer, 0, 0, EINA_FALSE);
+
+  _evas_surface_damage(surf->wl_surface, surf->compositor_version,
+                       surf->w, surf->h, rects, count);
+
+  tbm_surface_internal_ref(surf->tbm_surface);
+  ecore_wl2_window_commit(surface->wl2_win, EINA_TRUE);
+
+  tbm_surface_internal_unref(surf->tbm_surface);
+  tbm_surface_queue_enqueue(surf->tbm_queue, surf->tbm_surface);
+
+  tbm_surface_queue_acquire(surf->tbm_queue, &surf->tbm_surface);
+
+  return;
+}
+
+static void
+_evas_tbmbuf_surface_destroy(Ecore_Wl2_Surface *surface)
+{
+  Ecore_Wl2_Buffer *surf = NULL;
+  if (!surface) return;
+
+  surf = surface->current;
+  if (surf)
+    {
+      if (surf->tbm_queue && tbm_queue_ref == 0)
+        {
+          if (surf->tbm_surface)
+            tbm_surface_internal_set_user_data(surf->tbm_surface, KEY_WINDOW, NULL);
+          tbm_surface_queue_destroy(surf->tbm_queue);
+          need_to_tbm_queue = EINA_TRUE;
+          tbm_queue = NULL;
+        }
+      if (tbm_queue_ref)
+        --tbm_queue_ref;
+      free(surf);
+      surface->current = NULL;
+    }
+}
+
+static void
+_evas_tbmbuf_surface_flush(Ecore_Wl2_Surface *surface EINA_UNUSED)
+{
+}
+
+EAPI Ecore_Wl2_Surface *
+ecore_wl2_tbmbuf_surface_create(Ecore_Wl2_Window *win, Eina_Bool alpha,
+                                struct wayland_tbm_client *tbm_client, int w, int h, int num_buff)
+{
+  Ecore_Wl2_Buffer *surf = NULL;
+
+  Ecore_Wl2_Surface *out;
+  out = calloc(1, sizeof(*out));
+  if (!out) return NULL;
+  if (!(surf = calloc(1, sizeof(Ecore_Wl2_Buffer)))) goto err;
+
+  out->wl2_win = win;
+  out->current = surf;
+  /* TIZEN_ONLY(20171204) : temporary patch */
+  if (w < 1) w = 1;
+  if (h < 1) h = 1;
+
+  surf->w = w;
+  surf->h = h;
+  Ecore_Wl2_Display *wl2_display = ecore_wl2_window_display_get(win);
+  surf->wl_display = ecore_wl2_display_get(wl2_display);
+  surf->wl_surface = ecore_wl2_window_surface_get(win);
+  if (!surf->wl_surface)  goto err;
+  surf->alpha = alpha;
+  surf->compositor_version = 3;
+
+  /* get tbm_client */
+  surf->tbm_client = tbm_client;
+  if (surf->tbm_client == NULL) {
+      ERR("No wayland_tbm global");
+      goto err;
+  }
+
+  /* check num_buff, not yet support single buffer */
+  if (num_buff == 1) num_buff = 2;
+
+  /* create surface buffers */
+  if (need_to_tbm_queue)
+    {
+      tbm_queue =  wayland_tbm_client_create_surface_queue(surf->tbm_client,
+                                                           surf->wl_surface,
+                                                           num_buff,
+                                                           w, h,
+                                                           TBM_FORMAT_ARGB8888);
+      surf->tbm_queue = tbm_queue;
+      need_to_tbm_queue = EINA_FALSE;
+    }
+  else
+    {
+      /* reuse tbm_queue */
+      surf->tbm_queue = tbm_queue;
+      tbm_surface_queue_reset(surf->tbm_queue, w, h, TBM_FORMAT_ARGB8888);
+
+      tbm_queue_ref++;
+    }
+  if (surf->tbm_queue == NULL)
+    {
+      ERR("surf->tbm_queue NULL");
+      goto err;
+    }
+  surf->tbm_surface = NULL;
+
+
+  out->funcs.destroy = _evas_tbmbuf_surface_destroy;
+  out->funcs.reconfigure = _evas_tbmbuf_surface_reconfigure;
+  out->funcs.data_get = _evas_tbmbuf_surface_data_get;
+  out->funcs.assign = _evas_tbmbuf_surface_assign;
+  out->funcs.post = _evas_tbmbuf_surface_post;
+  out->funcs.flush = _evas_tbmbuf_surface_flush;
+  win->wl2_surface = out;
+  return out;
+
+  err:
+  if (surf)
+    {
+      free(surf);
+    }
+  return NULL;
+}
index 7291b40..60422a5 100755 (executable)
@@ -115,6 +115,10 @@ void *_evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int
 void _evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
 void _evas_outbuf_redraws_clear(Outbuf *ob);
 
+// TIZEN_ONLY(20171226) : evas tbm_buf backend
+Ecore_Wl2_Surface *ecore_wl2_tbmbuf_surface_create(Ecore_Wl2_Window *win, Eina_Bool alpha,
+                                                   struct wayland_tbm_client *tbm_client, int w, int h, int num_buff);
+//
 Ecore_Wl2_Surface *ecore_wl2_surface_create(Ecore_Wl2_Window *win, Eina_Bool alpha);
 void ecore_wl2_surface_destroy(Ecore_Wl2_Surface *surface);
 void ecore_wl2_surface_reconfigure(Ecore_Wl2_Surface *surface, int w, int h, uint32_t flags, Eina_Bool force);
@@ -123,4 +127,5 @@ int  ecore_wl2_surface_assign(Ecore_Wl2_Surface *surface);
 void ecore_wl2_surface_post(Ecore_Wl2_Surface *surface, Eina_Rectangle *rects, unsigned int count);
 
 
+
 #endif
index f5d32bb..f4a6a9d 100755 (executable)
@@ -27,9 +27,33 @@ _evas_outbuf_setup(int w, int h, Evas_Engine_Info_Wayland *info)
    ob->depth = info->info.depth;
    ob->priv.destination_alpha = info->info.destination_alpha;
    ob->ewd = ecore_wl2_window_display_get(info->info.wl2_win);
+   ob->surface = NULL;
+
+   // TIZEN_ONLY(20171226) : evas tbm_buf backend
+   if (!getenv("EVAS_WAYLAND_USE_SHMBUF"))
+     {
+       int sw = 0;
+       int sh = 0;
+       /* try to create the outbuf surface */
+       if ((ob->rotation == 0) || (ob->rotation == 180))
+         {
+           sw = w;
+           sh = h;
+         }
+       else if ((ob->rotation == 90) || (ob->rotation == 270))
+         {
+           sw = h;
+           sh = w;
+         }
+       ob->surface = ecore_wl2_tbmbuf_surface_create(info->info.wl2_win, ob->priv.destination_alpha, info->info.tbm_client, sw, sh, 3);
+     }
+   // fallback
+   if (!ob->surface)
+     {
+       ob->surface = ecore_wl2_surface_create(info->info.wl2_win,
+                                              ob->priv.destination_alpha);
+     }
 
-   ob->surface = ecore_wl2_surface_create(info->info.wl2_win,
-                                          ob->priv.destination_alpha);
    if (!ob->surface) goto surf_err;
 
    eina_array_step_set(&ob->priv.onebuf_regions, sizeof(Eina_Array), 8);
diff --git a/src/modules/evas/engines/wayland_shm/evas_tbmbuf.c b/src/modules/evas/engines/wayland_shm/evas_tbmbuf.c
deleted file mode 100755 (executable)
index f26c736..0000000
+++ /dev/null
@@ -1,650 +0,0 @@
-#include "evas_common_private.h"
-#include "evas_private.h"
-#include "evas_engine.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dlfcn.h>
-#include <wayland-client.h>
-
-#define KEY_WINDOW (unsigned long)(&key_window)
-#define KEY_WL_BUFFER (unsigned long)(&key_wl_buffer)
-#define KEY_SURFACE_INFO (unsigned long)(&key_surface_info)
-
-
-static int key_window;
-static int key_wl_buffer;
-static int key_surface_info;
-
-
-
-#define __tbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
-      ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
-
-#define TBM_FORMAT_XRGB8888 __tbm_fourcc_code('X', 'R', '2', '4')
-#define TBM_FORMAT_ARGB8888 __tbm_fourcc_code('A', 'R', '2', '4')
-#define TBM_SURF_PLANE_MAX 4 /**< maximum number of the planes  */
-/* option to map the tbm_surface */
-#define TBM_SURF_OPTION_READ      (1 << 0) /**< access option to read  */
-#define TBM_SURF_OPTION_WRITE     (1 << 1) /**< access option to write */
-
-typedef struct _tbm_surface * tbm_surface_h;
-//typedef struct _tbm_surface_queue *tbm_surface_queue_h;
-typedef uint32_t tbm_format;
-typedef void (*tbm_data_free) (void *user_data);
-
-typedef struct _tbm_surface_plane
-{
-   unsigned char *ptr;   /**< Plane pointer */
-   uint32_t size;        /**< Plane size */
-   uint32_t offset;      /**< Plane offset */
-   uint32_t stride;      /**< Plane stride */
-
-   void *reserved1;      /**< Reserved pointer1 */
-   void *reserved2;      /**< Reserved pointer2 */
-   void *reserved3;      /**< Reserved pointer3 */
-} tbm_surface_plane_s;
-
-typedef struct _tbm_surface_info
-{
-   uint32_t width;      /**< TBM surface width */
-   uint32_t height;     /**< TBM surface height */
-   tbm_format format;   /**< TBM surface format*/
-   uint32_t bpp;        /**< TBM surface bbp */
-   uint32_t size;       /**< TBM surface size */
-
-   uint32_t num_planes;                            /**< The number of planes */
-   tbm_surface_plane_s planes[TBM_SURF_PLANE_MAX]; /**< Array of planes */
-
-   void *reserved4;   /**< Reserved pointer4 */
-   void *reserved5;   /**< Reserved pointer5 */
-   void *reserved6;   /**< Reserved pointer6 */
-} tbm_surface_info_s;
-
-
-typedef enum _queue_node_type {
-   QUEUE_NODE_TYPE_NONE,
-   QUEUE_NODE_TYPE_DEQUEUE,
-   QUEUE_NODE_TYPE_ENQUEUE,
-   QUEUE_NODE_TYPE_ACQUIRE,
-   QUEUE_NODE_TYPE_RELEASE
-} Queue_Node_Type;
-
-typedef enum {
-   TBM_SURFACE_QUEUE_ERROR_NONE = 0,                             /**< Successful */
-   TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE = -1,
-   TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE = -2,
-   TBM_SURFACE_QUEUE_ERROR_EMPTY = -3,
-   TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER = -4,
-   TBM_SURFACE_QUEUE_ERROR_SURFACE_ALLOC_FAILED = -5,
-} tbm_surface_queue_error_e;
-
-typedef struct _Tbmbuf_Surface Tbmbuf_Surface;
-
-struct _Tbmbuf_Surface
-{
-   struct wl_display *wl_display;
-   struct wl_surface *wl_surface;
-   struct wl_buffer *wl_buffer;
-   struct wl_registry *registry;
-   struct wayland_tbm_client *tbm_client;
-   tbm_surface_h tbm_surface;
-   tbm_surface_info_s tbm_info;
-   void *tbm_queue;
-   int wait_release;
-   Eina_Bool resize : 1;
-
-   int compositor_version;
-
-   int w, h;
-   int dx, dy;
-   int stride;
-   int frame_age;
-   Eina_Bool alpha : 1;
-
-};
-
-
-typedef struct {
-   unsigned int age;
-   unsigned int num_surface;
-} tbm_buffer_info;
-
-
-static void *tbm_lib = NULL;
-static void *tbm_client_lib = NULL;
-static int   tbm_ref = 0;
-static int   tbm_queue_ref = 0;
-
-static int (*sym_tbm_surface_map) (tbm_surface_h surface, int opt, tbm_surface_info_s *info) = NULL;
-static int (*sym_tbm_surface_unmap) (tbm_surface_h surface) = NULL;
-static int (*sym_tbm_surface_queue_can_dequeue) (void *tbm_queue, int value) = NULL;
-static int (*sym_tbm_surface_queue_dequeue) (void *tbm_queue, tbm_surface_h *surface) = NULL;
-static int (*sym_tbm_surface_queue_enqueue) (void *tbm_queue, tbm_surface_h surface) = NULL;
-static tbm_surface_queue_error_e (*sym_tbm_surface_queue_acquire) (void *tbm_queue, tbm_surface_h *surface) = NULL;
-static tbm_surface_queue_error_e (*sym_tbm_surface_queue_get_surfaces) (void *surface_queue,
-                                                                        tbm_surface_h *surfaces, int *num) = NULL;
-static tbm_surface_queue_error_e (*sym_tbm_surface_queue_release) (void *surface_queue, tbm_surface_h surface) = NULL;
-static void (*sym_tbm_surface_queue_destroy) (void *surface_queue) = NULL;
-static void (*sym_tbm_surface_internal_unref) (tbm_surface_h surface) = NULL;
-static void (*sym_tbm_surface_internal_ref) (tbm_surface_h surface) = NULL;
-static int (*sym_tbm_surface_internal_get_user_data) (tbm_surface_h surface, unsigned long key, void **data) = NULL;
-static int (*sym_tbm_surface_internal_add_user_data) (tbm_surface_h surface, unsigned long key, tbm_data_free data_free_func) = NULL;
-static int (*sym_tbm_surface_internal_set_user_data) (tbm_surface_h surface, unsigned long key, void *data) = NULL;
-static int (*sym_tbm_surface_queue_get_format) (void *surface_queue) = NULL;
-static tbm_surface_queue_error_e (*sym_tbm_surface_queue_reset) (void *surface_queue, int width, int height, int format) = NULL;
-
-static struct wl_buffer * (*sym_wayland_tbm_client_create_buffer) (struct wayland_tbm_client *tbm_client, tbm_surface_h surface) = NULL;
-static struct wl_tbm * (*sym_wayland_tbm_client_get_wl_tbm) (struct wayland_tbm_client *tbm_client) = NULL;
-static void *(*sym_wayland_tbm_client_create_surface_queue) (struct wayland_tbm_client *tbm_client,
-                                                             struct wl_surface *surface,
-                                                             int queue_size,
-                                                             int width, int height, tbm_format format) = NULL;
-
-static Eina_Bool
-tbm_init(void)
-{
-   if (tbm_lib)
-      {
-         tbm_ref++;
-         return EINA_TRUE;
-      }
-
-   const char *tbm_libs[] =
-         {
-               LIBDIR"/libtbm.so.1",
-               LIBDIR"/libtbm.so.0",
-               NULL,
-         };
-   const char *tbm_clients[] =
-         {
-               LIBDIR"/libwayland-tbm-client.so.0",
-               NULL,
-         };
-   int i, fail;
-#define SYM(lib, xx)                            \
-      do {                                          \
-            sym_ ## xx = dlsym(lib, #xx);            \
-            if (!(sym_ ## xx)) {                     \
-                  ERR("%s", dlerror());               \
-                  fail = 1;                           \
-            }                                      \
-      } while (0)
-
-   for (i = 0; tbm_libs[i]; i++)
-      {
-         tbm_lib = dlopen(tbm_libs[i], RTLD_LOCAL | RTLD_LAZY);
-         if (tbm_lib)
-            {
-               fail = 0;
-               SYM(tbm_lib, tbm_surface_map);
-               SYM(tbm_lib, tbm_surface_unmap);
-               SYM(tbm_lib, tbm_surface_queue_can_dequeue);
-               SYM(tbm_lib, tbm_surface_queue_dequeue);
-               SYM(tbm_lib, tbm_surface_queue_enqueue);
-               SYM(tbm_lib, tbm_surface_queue_acquire);
-               SYM(tbm_lib, tbm_surface_queue_get_surfaces);
-               SYM(tbm_lib, tbm_surface_queue_release);
-               SYM(tbm_lib, tbm_surface_queue_destroy);
-               SYM(tbm_lib, tbm_surface_internal_ref);
-               SYM(tbm_lib, tbm_surface_internal_unref);
-               SYM(tbm_lib, tbm_surface_internal_get_user_data);
-               SYM(tbm_lib, tbm_surface_internal_add_user_data);
-               SYM(tbm_lib, tbm_surface_internal_set_user_data);
-               SYM(tbm_lib, tbm_surface_queue_get_format);
-               SYM(tbm_lib, tbm_surface_queue_reset);
-               if (fail)
-                  {
-                     dlclose(tbm_lib);
-                     tbm_lib = NULL;
-                  }
-               else break;
-            }
-      }
-   if (!tbm_lib) return EINA_FALSE;
-
-   for (i = 0; tbm_clients[i]; i++)
-      {
-         tbm_client_lib = dlopen(tbm_clients[i], RTLD_LOCAL | RTLD_LAZY);
-         if (tbm_client_lib)
-            {
-               fail = 0;
-               SYM(tbm_client_lib, wayland_tbm_client_get_wl_tbm);
-               SYM(tbm_client_lib, wayland_tbm_client_create_buffer);
-               SYM(tbm_client_lib, wayland_tbm_client_create_surface_queue);
-               if (fail)
-                  {
-                     dlclose(tbm_client_lib);
-                     tbm_client_lib = NULL;
-                  }
-               else break;
-            }
-      }
-   if (!tbm_client_lib) return EINA_FALSE;
-
-   tbm_ref++;
-   return EINA_TRUE;
-}
-
-static void
-tbm_shutdown(void)
-{
-   if (tbm_ref > 0)
-      {
-         tbm_ref--;
-
-         if (tbm_ref == 0)
-            {
-               if (tbm_lib)
-                  {
-                     dlclose(tbm_lib);
-                     tbm_lib = NULL;
-                  }
-               if (tbm_client_lib)
-                  {
-                     dlclose(tbm_client_lib);
-                     tbm_client_lib = NULL;
-                  }
-            }
-      }
-}
-
-
-static void
-_evas_tbmbuf_buffer_unmap(Tbmbuf_Surface *surface)
-{
-   sym_tbm_surface_unmap(surface->tbm_surface);
-}
-
-
-static void
-_evas_tbmbuf_surface_reconfigure(Surface *s, int w, int h, uint32_t flags, Eina_Bool force)
-{
-   Tbmbuf_Surface *surface;
-
-   if (!s) return;
-
-   surface = s->surf.tbm;
-
-   if (!surface) return;
-
-   /* TIZEN_ONLY(20171204) : temporary patch */
-   if (w < 1) w = 1;
-   if (h < 1) h = 1;
-
-   if ((w >= surface->w) && (w <= surface->stride / 4) && (h == surface->h))
-      {
-         surface->w = w;
-         return;
-      }
-   surface->resize = EINA_TRUE;
-   surface->w = w;
-   surface->h = h;
-}
-
-static void
-_wait_free_buffer(Tbmbuf_Surface *surface)
-{
-   if (!surface) return;
-
-   wl_display_dispatch_pending(surface->wl_display);
-   if (sym_tbm_surface_queue_can_dequeue(surface->tbm_queue, 0))
-      return;
-
-   DBG("WAIT free buffer");
-
-   while (!sym_tbm_surface_queue_can_dequeue(surface->tbm_queue, 0)) {
-         wl_display_dispatch(surface->wl_display);
-   }
-}
-
-static void
-buffer_release(void *data, struct wl_buffer *buffer EINA_UNUSED)
-{
-   if (!data) return;
-   void *tbm_queue = NULL;
-   tbm_surface_h tbm_surface = data;
-   sym_tbm_surface_internal_get_user_data(tbm_surface, KEY_WINDOW, (void **)&tbm_queue);
-   sym_tbm_surface_internal_unref(tbm_surface);
-   if (tbm_queue)
-      sym_tbm_surface_queue_release(tbm_queue, tbm_surface);
-}
-
-static void
-buffer_destroy(void *data)
-{
-   if (!data) return;
-   struct wl_buffer* buffer = data;
-   wl_buffer_destroy(buffer);
-}
-
-static const struct wl_buffer_listener buffer_listener = {
-      buffer_release
-};
-
-
-static int
-_evas_tbmbuf_surface_assign(Surface *s)
-{
-   Tbmbuf_Surface *surface;
-   Render_Output_Swap_Mode mode = MODE_FULL;
-   tbm_buffer_info *tbuf_info = NULL;
-   if (!s) return 0;
-
-   surface = s->surf.tbm;
-   if (!surface)
-      {
-         ERR("surface is NULL");
-         return 0;
-      }
-
-   if (surface->resize)
-      {
-         // reset tbm_surface
-         int width, height, format;
-         width = surface->w;
-         height = surface->h;
-         format = sym_tbm_surface_queue_get_format(surface->tbm_queue);
-         sym_tbm_surface_queue_reset(surface->tbm_queue, width, height, format);
-         surface->resize = EINA_FALSE;
-      }
-
-   surface->tbm_surface = NULL;
-   tbm_surface_queue_error_e ret = TBM_SURFACE_QUEUE_ERROR_NONE;
-   struct wl_buffer *buffer;
-
-   _wait_free_buffer(surface);
-
-   // check num of tbm surface
-   int num_surface, i;
-   tbm_surface_h surfaces[5];
-   sym_tbm_surface_queue_get_surfaces(surface->tbm_queue, surfaces, &num_surface);
-
-   ret = sym_tbm_surface_queue_dequeue(surface->tbm_queue, &surface->tbm_surface);
-
-   if (ret != TBM_SURFACE_QUEUE_ERROR_NONE ||
-         surface->tbm_surface == NULL) {
-         ERR("dequeue:%p from queue:%p err:%d\n", surface->tbm_surface, surface->tbm_queue, ret);
-         surface->wait_release = 1;
-         return 0;
-   }
-
-   sym_tbm_surface_internal_ref(surface->tbm_surface);
-
-   surface->wait_release = 0;
-   if(!sym_tbm_surface_internal_get_user_data(surface->tbm_surface, KEY_WL_BUFFER, (void **)&buffer)) {
-         buffer = sym_wayland_tbm_client_create_buffer(surface->tbm_client, surface->tbm_surface);
-         if (!buffer)
-           {
-             ERR("wayland_tbm_client_create_buffer is NULL");
-             sym_tbm_surface_internal_unref(surface->tbm_surface);
-             sym_tbm_surface_queue_release(surface->tbm_queue, surface->tbm_surface);
-             return 0;
-           }
-
-         wl_proxy_set_queue((struct wl_proxy *)buffer, NULL);
-
-         sym_tbm_surface_internal_add_user_data(surface->tbm_surface, KEY_WL_BUFFER, (tbm_data_free)buffer_destroy);
-         sym_tbm_surface_internal_set_user_data(surface->tbm_surface, KEY_WL_BUFFER, buffer);
-
-         sym_tbm_surface_internal_add_user_data(surface->tbm_surface, KEY_WINDOW, NULL);
-         sym_tbm_surface_internal_set_user_data(surface->tbm_surface, KEY_WINDOW, surface->tbm_queue);
-
-         wl_buffer_add_listener(buffer, &buffer_listener, surface->tbm_surface);
-   }
-
-
-   tbm_surface_info_s info;
-   sym_tbm_surface_map(surface->tbm_surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
-   surface->tbm_info = info;
-
-   // check buffer age
-   if (!sym_tbm_surface_internal_get_user_data(surface->tbm_surface, KEY_SURFACE_INFO, (void**)&tbuf_info)) {
-       tbuf_info = calloc(1, sizeof(tbm_buffer_info));
-       if (tbuf_info) {
-           tbuf_info->age = 0;
-           tbuf_info->num_surface = num_surface;
-         }
-       sym_tbm_surface_internal_add_user_data(surface->tbm_surface, KEY_SURFACE_INFO, free);
-       sym_tbm_surface_internal_set_user_data(surface->tbm_surface, KEY_SURFACE_INFO, tbuf_info);
-   }
-
-   //reset
-   if (tbuf_info && (unsigned int)num_surface != tbuf_info->num_surface)
-     {
-       s->frame_age = 0;
-
-       for(i=0; i<num_surface; i++) {
-           sym_tbm_surface_internal_get_user_data(surfaces[i], KEY_SURFACE_INFO, (void **)&tbuf_info);
-           if (tbuf_info) {
-               tbuf_info->age = 0;
-               tbuf_info->num_surface = num_surface;
-           }
-       }
-     }
-
-   if (!tbuf_info || !tbuf_info->age)
-     return MODE_FULL;
-
-   if (tbuf_info && tbuf_info->age < s->frame_age)
-     {
-       unsigned int diff;
-       diff = s->frame_age - tbuf_info->age + 1;
-       if (diff > (unsigned int)num_surface) return MODE_FULL;
-       switch(diff)
-       {
-         case 1:
-           mode = MODE_COPY;
-           break;
-         case 2:
-           mode = MODE_DOUBLE;
-           break;
-         case 3:
-           mode = MODE_TRIPLE;
-           break;
-         default:
-           mode = MODE_FULL;
-       }
-     }
-   return mode;
-}
-
-
-static void *
-_evas_tbmbuf_surface_data_get(Surface *s, int *w, int *h)
-{
-   Tbmbuf_Surface *surface;
-   void *image;
-
-   surface = s->surf.tbm;
-   if (!surface)
-      {
-         ERR("surface is NULL");
-         return 0;
-      }
-
-   image = surface->tbm_info.planes[0].ptr;
-
-   surface->stride = surface->tbm_info.planes[0].stride;
-   if (w) *w = surface->stride / 4;
-   if (h) *h = surface->tbm_info.height;
-
-   return image;
-}
-
-
-
-static void
-__cb_client_frame_callback(void *data EINA_UNUSED, struct wl_callback *callback,
-                           uint32_t time EINA_UNUSED)
-{
-   wl_callback_destroy(callback);
-}
-
-static const struct wl_callback_listener frame_listener = {
-      __cb_client_frame_callback
-};
-
-
-static void
-_evas_tbmbuf_surface_post(Surface *s, Eina_Rectangle *rects, unsigned int count, Eina_Bool hidden)
-{
-   Tbmbuf_Surface *surface;
-   struct wl_callback *frame_callback = NULL;
-   tbm_buffer_info *tbuf_info = NULL;
-   if (!s) return;
-
-   surface = s->surf.tbm;
-   if (!surface->wl_surface) return;
-
-   struct wl_buffer *buffer = NULL;
-
-   _evas_tbmbuf_buffer_unmap(surface);
-
-   sym_tbm_surface_internal_get_user_data(surface->tbm_surface, KEY_WL_BUFFER, (void **)&buffer);
-   if (!buffer) {
-         ERR("Enqueue:%p from queue:%p", surface->tbm_surface, surface->tbm_queue);
-         return;
-   }
-
-   ++s->frame_age;
-   sym_tbm_surface_internal_get_user_data(surface->tbm_surface, KEY_SURFACE_INFO, (void **)&tbuf_info);
-   if (tbuf_info)
-     tbuf_info->age = s->frame_age;
-
-   if (!hidden)
-     {
-       ecore_wl2_window_buffer_attach(s->info->info.wl2_win, buffer, 0, 0, EINA_FALSE);
-
-       _evas_surface_damage(surface->wl_surface, surface->compositor_version,
-                            surface->w, surface->h, rects, count);
-     }
-
-   frame_callback = wl_surface_frame(surface->wl_surface);
-   wl_callback_add_listener(frame_callback, &frame_listener, surface->tbm_surface);
-
-   sym_tbm_surface_internal_ref(surface->tbm_surface);
-   ecore_wl2_window_commit(s->info->info.wl2_win, EINA_TRUE);
-
-   sym_tbm_surface_internal_unref(surface->tbm_surface);
-   sym_tbm_surface_queue_enqueue(surface->tbm_queue, surface->tbm_surface);
-
-   sym_tbm_surface_queue_acquire(surface->tbm_queue, &surface->tbm_surface);
-
-   return;
-}
-
-static void
-_evas_tbmbuf_surface_destroy(Surface *s)
-{
-   Tbmbuf_Surface *surf = NULL;
-   if (!s) return;
-
-   surf = s->surf.tbm;
-   if (surf)
-      {
-         if (surf->tbm_queue && tbm_queue_ref == 0)
-            {
-               if (surf->tbm_surface)
-                  sym_tbm_surface_internal_set_user_data(surf->tbm_surface, KEY_WINDOW, NULL);
-               sym_tbm_surface_queue_destroy(surf->tbm_queue);
-               if (s->info) s->info->info.tbm_queue = NULL;
-            }
-         if (tbm_queue_ref)
-            --tbm_queue_ref;
-         free(surf);
-         s->surf.tbm = NULL;
-      }
-   tbm_shutdown();
-}
-
-Eina_Bool
-_evas_tbmbuf_surface_surface_set(Surface *s, struct wl_shm *wl_shm EINA_UNUSED, struct zwp_linux_dmabuf_v1 *wl_dmabuf)
-{
-   return EINA_TRUE;
-}
-
-Eina_Bool
-_evas_tbmbuf_surface_create(Surface *s, int w, int h, int num_buff)
-{
-   Tbmbuf_Surface *surf = NULL;
-
-   if (!tbm_init())
-      {
-         ERR("Could not initialize TBM!");
-         goto err;
-      }
-
-   if (!(s->surf.tbm = calloc(1, sizeof(Tbmbuf_Surface)))) goto err;
-   surf = s->surf.tbm;
-
-   surf->dx = 0;
-   surf->dy = 0;
-
-   /* TIZEN_ONLY(20171204) : temporary patch */
-   if (w < 1) w = 1;
-   if (h < 1) h = 1;
-
-   surf->w = w;
-   surf->h = h;
-   surf->wl_display = ecore_wl2_display_get(s->info->info.wl2_display);
-   surf->wl_surface = ecore_wl2_window_surface_get(s->info->info.wl2_win);
-   if (!surf->wl_surface)  goto err;
-   surf->alpha = s->info->info.destination_alpha;
-   surf->compositor_version = 3;
-
-   /* get tbm_client */
-   surf->tbm_client = s->info->info.tbm_client;
-   if (surf->tbm_client == NULL) {
-         ERR("No wayland_tbm global");
-         goto err;
-   }
-
-   /* check num_buff, not yet support single buffer */
-   if (num_buff == 1) num_buff = 2;
-
-   /* create surface buffers */
-   if (!s->info->info.tbm_queue)
-      {
-         s->info->info.tbm_queue = sym_wayland_tbm_client_create_surface_queue(surf->tbm_client,
-                                                                       surf->wl_surface,
-                                                                       num_buff,
-                                                                       w, h,
-                                                                       TBM_FORMAT_ARGB8888);
-         surf->tbm_queue = s->info->info.tbm_queue;
-      }
-   else
-      {
-         /* reuse tbm_queue */
-         surf->tbm_queue = s->info->info.tbm_queue;
-         sym_tbm_surface_queue_reset(surf->tbm_queue, w, h, TBM_FORMAT_ARGB8888);
-
-         tbm_queue_ref++;
-      }
-   if (surf->tbm_queue == NULL) {
-         ERR("surf->tbm_queue NULL");
-         goto err;
-   }
-   surf->tbm_surface = NULL;
-
-   s->type = SURFACE_TBM;
-   s->funcs.destroy = _evas_tbmbuf_surface_destroy;
-   s->funcs.reconfigure = _evas_tbmbuf_surface_reconfigure;
-   s->funcs.data_get = _evas_tbmbuf_surface_data_get;
-   s->funcs.assign = _evas_tbmbuf_surface_assign;
-   s->funcs.post = _evas_tbmbuf_surface_post;
-   s->funcs.surface_set = _evas_tbmbuf_surface_surface_set;
-
-
-
-   return EINA_TRUE;
-
-err:
-   if (surf)
-      {
-         free(surf);
-         s->surf.tbm = NULL;
-      }
-   return EINA_FALSE;
-}