wayland_shm: add implementation of tizen_shm_flusher 70/135870/2
authorSangjin Lee <lsj119@samsung.com>
Tue, 27 Jun 2017 05:48:46 +0000 (14:48 +0900)
committerSangjin Lee <lsj119@samsung.com>
Tue, 27 Jun 2017 22:58:26 +0000 (07:58 +0900)
Change-Id: I164e29e94a1873002afd1de6159d43261b6f7905

src/modules/evas/engines/wayland_shm/evas_shm.c
src/modules/evas/engines/wayland_shm/evas_tbmbuf.c
src/modules/evas/engines/wayland_shm/tizen-surface-client.h
src/modules/evas/engines/wayland_shm/tizen-surface-protocol.c

index 0015264..74c250c 100755 (executable)
@@ -76,6 +76,7 @@ _shm_pool_make(struct wl_shm *shm, int size, void **data)
    const char *path;
    char *name;
    int fd = 0;
+   int len=0;
 
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
@@ -86,18 +87,27 @@ _shm_pool_make(struct wl_shm *shm, int size, void **data)
    if ((path = getenv("TIZEN_WAYLAND_SHM_DIR")) ||
        (path = getenv("XDG_RUNTIME_DIR")))
      {
-        if ((name = malloc(strlen(path) + sizeof(tmp))))
-          strcpy(name, path);
+        len = strlen(path) + sizeof(tmp);
+        if ((name = malloc(len+1)))
+          {
+             strncpy(name, path, len);
+             name[len]=0;
+          }
      }
    else
      {
-        if ((name = malloc(strlen("/tmp") + sizeof(tmp))))
-          strcpy(name, "/tmp");
+        len = strlen("/tmp") + sizeof(tmp);
+        if ((name = malloc(len+1)))
+          {
+             strncpy(name, "/tmp", len);
+             name[len]=0;
+          }
      }
 
    if (!name) return NULL;
 
-   strcat(name, tmp);
+   strncat(name, tmp, sizeof(tmp));
+   name[len]=0;
 
    /* try to create tmp file */
    if ((fd = mkstemp(name)) < 0)
@@ -382,7 +392,7 @@ static void
 _shm_wl_registry_global(void *data EINA_UNUSED, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
 {
    if (!strcmp(interface, "tizen_surface_shm"))
-     shmdat.tzsurf = wl_registry_bind(registry, name, &tizen_surface_shm_interface, version);
+     shmdat.tzsurf = wl_registry_bind(registry, name, &tizen_surface_shm_interface, 2);
 }
 
 static void
@@ -462,9 +472,32 @@ _shm_tzsurf_flusher_cb_flush(void *data, struct tizen_surface_shm_flusher *flush
      }
 }
 
+static void
+_shm_tzsurf_flusher_cb_free_flush(void *data, struct tizen_surface_shm_flusher *flusher EINA_UNUSED)
+{
+   Shm_Surface *surf;
+   Shm_Leaf *leaf;
+   int i = 0;
+
+   surf = data;
+
+   for (; i < surf->num_buff; i++)
+     {
+        leaf = &surf->leaf[i];
+        if (leaf->busy)
+          {
+             continue;
+          }
+
+        _shm_leaf_release(&surf->leaf[i]);
+        surf->leaf[i].freed = EINA_TRUE;
+     }
+}
+
 static const struct tizen_surface_shm_flusher_listener _tzsurf_flusher_listener =
 {
-      _shm_tzsurf_flusher_cb_flush
+      _shm_tzsurf_flusher_cb_flush,
+      _shm_tzsurf_flusher_cb_free_flush
 };
 
 void 
index 7bdb7ac..e5404fb 100644 (file)
@@ -8,6 +8,8 @@
 #include <dlfcn.h>
 #include <wayland-client.h>
 
+#include "tizen-surface-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)
@@ -102,6 +104,8 @@ struct _Tbmbuf_Surface
    int stride;
    int frame_age;
    Eina_Bool alpha : 1;
+
+   struct tizen_surface_shm_flusher *tzsurf_flusher;
 };
 
 
@@ -115,6 +119,7 @@ static void *tbm_lib = NULL;
 static void *tbm_client_lib = NULL;
 static int   tbm_ref = 0;
 static int   tbm_queue_ref = 0;
+static struct tizen_surface_shm *tzsurf;
 
 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;
@@ -133,7 +138,8 @@ static int (*sym_tbm_surface_internal_add_user_data) (tbm_surface_h surface, uns
 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 tbm_surface_queue_error_e (*sym_tbm_surface_queue_flush) (void* surface_queue) = NULL;
+static tbm_surface_queue_error_e (*sym_tbm_surface_queue_free_flush) (void* surface_queue) = 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;
@@ -194,6 +200,8 @@ tbm_init(void)
                SYM(tbm_lib, tbm_surface_internal_set_user_data);
                SYM(tbm_lib, tbm_surface_queue_get_format);
                SYM(tbm_lib, tbm_surface_queue_reset);
+               SYM(tbm_lib, tbm_surface_queue_flush);
+               SYM(tbm_lib, tbm_surface_queue_free_flush);
                if (fail)
                   {
                      dlclose(tbm_lib);
@@ -246,6 +254,12 @@ tbm_shutdown(void)
                      dlclose(tbm_client_lib);
                      tbm_client_lib = NULL;
                   }
+
+               if (tzsurf)
+                  {
+                     tizen_surface_shm_destroy(tzsurf);
+                     tzsurf = NULL;
+                  }
             }
       }
 }
@@ -460,6 +474,68 @@ _evas_tbmbuf_surface_data_get(Surface *s, int *w, int *h)
    return image;
 }
 
+static void
+_shm_wl_registry_global(void *data EINA_UNUSED, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version EINA_UNUSED)
+{
+   if (!strcmp(interface, "tizen_surface_shm"))
+     tzsurf = wl_registry_bind(registry, name, &tizen_surface_shm_interface, 2);
+}
+
+static void
+_shm_wl_registry_global_remove(void *data EINA_UNUSED, struct wl_registry *registry EINA_UNUSED, uint32_t name EINA_UNUSED)
+{
+}
+
+static void
+_shm_tzsurf_flusher_cb_flush(void *data, struct tizen_surface_shm_flusher *flusher EINA_UNUSED)
+{
+   Tbmbuf_Surface *surf = data;
+
+   sym_tbm_surface_queue_flush(surf->tbm_queue);
+}
+
+static void
+_shm_tzsurf_flusher_cb_free_flush(void *data, struct tizen_surface_shm_flusher *flusher EINA_UNUSED)
+{
+   Tbmbuf_Surface *surf = data;
+
+   sym_tbm_surface_queue_free_flush(surf->tbm_queue);
+}
+
+static const struct tizen_surface_shm_flusher_listener _tzsurf_flusher_listener =
+{
+      _shm_tzsurf_flusher_cb_flush,
+      _shm_tzsurf_flusher_cb_free_flush
+};
+
+static const struct wl_registry_listener _shm_wl_registry_listener =
+{
+   _shm_wl_registry_global,
+   _shm_wl_registry_global_remove
+};
+
+static void
+_shm_tzsurf_init(struct wl_display *disp)
+{
+   struct wl_event_queue *queue;
+   struct wl_registry *registry;
+
+   queue = wl_display_create_queue(disp);
+   registry = wl_display_get_registry(disp);
+
+   wl_proxy_set_queue((struct wl_proxy *)registry, queue);
+   wl_registry_add_listener(registry, &_shm_wl_registry_listener, NULL);
+   if ((wl_display_roundtrip_queue(disp, queue) < 0) || (!tzsurf))
+     goto err_registry;
+
+   /* use default queue */
+   wl_proxy_set_queue((struct wl_proxy *)tzsurf, NULL);
+
+err_registry:
+   wl_registry_destroy(registry);
+   wl_event_queue_destroy(queue);
+   return;
+}
 
 
 static void
@@ -530,6 +606,12 @@ _evas_tbmbuf_surface_destroy(Surface *s)
       {
          if (surf->tbm_queue && tbm_queue_ref == 0)
             {
+               if (surf->tzsurf_flusher)
+                 {
+                    tizen_surface_shm_flusher_destroy(surf->tzsurf_flusher);
+                    surf->tzsurf_flusher = NULL;
+                 }
+
                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);
@@ -607,6 +689,12 @@ _evas_tbmbuf_surface_create(Surface *s, int w, int h, int num_buff)
    s->funcs.assign = _evas_tbmbuf_surface_assign;
    s->funcs.post = _evas_tbmbuf_surface_post;
 
+   if (!tzsurf)
+      _shm_tzsurf_init(surf->wl_display);
+
+   surf->tzsurf_flusher = tizen_surface_shm_get_flusher(tzsurf, surf->wl_surface);
+   tizen_surface_shm_flusher_add_listener(surf->tzsurf_flusher, &_tzsurf_flusher_listener, surf);
+
    return EINA_TRUE;
 
 err:
index e4be021..6eaa459 100644 (file)
@@ -14,12 +14,15 @@ struct wl_resource;
 
 struct tizen_surface_shm;
 struct tizen_surface_shm_flusher;
+struct wl_surface;
 
 extern const struct wl_interface tizen_surface_shm_interface;
 extern const struct wl_interface tizen_surface_shm_flusher_interface;
 
 #define TIZEN_SURFACE_SHM_GET_FLUSHER  0
 
+#define TIZEN_SURFACE_SHM_GET_FLUSHER_SINCE_VERSION    1
+
 static inline void
 tizen_surface_shm_set_user_data(struct tizen_surface_shm *tizen_surface_shm, void *user_data)
 {
@@ -32,6 +35,12 @@ tizen_surface_shm_get_user_data(struct tizen_surface_shm *tizen_surface_shm)
        return wl_proxy_get_user_data((struct wl_proxy *) tizen_surface_shm);
 }
 
+static inline uint32_t
+tizen_surface_shm_get_version(struct tizen_surface_shm *tizen_surface_shm)
+{
+       return wl_proxy_get_version((struct wl_proxy *) tizen_surface_shm);
+}
+
 static inline void
 tizen_surface_shm_destroy(struct tizen_surface_shm *tizen_surface_shm)
 {
@@ -55,6 +64,12 @@ struct tizen_surface_shm_flusher_listener {
         */
        void (*flush)(void *data,
                      struct tizen_surface_shm_flusher *tizen_surface_shm_flusher);
+       /**
+        * free_flush - (none)
+        * @since: 2
+        */
+       void (*free_flush)(void *data,
+                          struct tizen_surface_shm_flusher *tizen_surface_shm_flusher);
 };
 
 static inline int
@@ -67,6 +82,8 @@ tizen_surface_shm_flusher_add_listener(struct tizen_surface_shm_flusher *tizen_s
 
 #define TIZEN_SURFACE_SHM_FLUSHER_DESTROY      0
 
+#define TIZEN_SURFACE_SHM_FLUSHER_DESTROY_SINCE_VERSION        1
+
 static inline void
 tizen_surface_shm_flusher_set_user_data(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher, void *user_data)
 {
@@ -79,6 +96,12 @@ tizen_surface_shm_flusher_get_user_data(struct tizen_surface_shm_flusher *tizen_
        return wl_proxy_get_user_data((struct wl_proxy *) tizen_surface_shm_flusher);
 }
 
+static inline uint32_t
+tizen_surface_shm_flusher_get_version(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher)
+{
+       return wl_proxy_get_version((struct wl_proxy *) tizen_surface_shm_flusher);
+}
+
 static inline void
 tizen_surface_shm_flusher_destroy(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher)
 {
index 8420280..bd5e8a6 100644 (file)
@@ -15,7 +15,7 @@ static const struct wl_message tizen_surface_shm_requests[] = {
 };
 
 WL_EXPORT const struct wl_interface tizen_surface_shm_interface = {
-       "tizen_surface_shm", 1,
+       "tizen_surface_shm", 2,
        1, tizen_surface_shm_requests,
        0, NULL,
 };
@@ -26,11 +26,12 @@ static const struct wl_message tizen_surface_shm_flusher_requests[] = {
 
 static const struct wl_message tizen_surface_shm_flusher_events[] = {
        { "flush", "", types + 0 },
+       { "free_flush", "2", types + 0 },
 };
 
 WL_EXPORT const struct wl_interface tizen_surface_shm_flusher_interface = {
-       "tizen_surface_shm_flusher", 1,
+       "tizen_surface_shm_flusher", 2,
        1, tizen_surface_shm_flusher_requests,
-       1, tizen_surface_shm_flusher_events,
+       2, tizen_surface_shm_flusher_events,
 };