From 29f21c897e6e4282e4c1e4ab950f5a65398c1ec8 Mon Sep 17 00:00:00 2001 From: Sangjin Lee Date: Tue, 27 Jun 2017 14:48:46 +0900 Subject: [PATCH] wayland_shm: add implementation of tizen_shm_flusher Change-Id: I164e29e94a1873002afd1de6159d43261b6f7905 --- src/modules/evas/engines/wayland_shm/evas_shm.c | 47 +++++++++-- src/modules/evas/engines/wayland_shm/evas_tbmbuf.c | 90 +++++++++++++++++++++- .../engines/wayland_shm/tizen-surface-client.h | 23 ++++++ .../engines/wayland_shm/tizen-surface-protocol.c | 7 +- 4 files changed, 156 insertions(+), 11 deletions(-) diff --git a/src/modules/evas/engines/wayland_shm/evas_shm.c b/src/modules/evas/engines/wayland_shm/evas_shm.c index 0015264..74c250c 100755 --- a/src/modules/evas/engines/wayland_shm/evas_shm.c +++ b/src/modules/evas/engines/wayland_shm/evas_shm.c @@ -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 diff --git a/src/modules/evas/engines/wayland_shm/evas_tbmbuf.c b/src/modules/evas/engines/wayland_shm/evas_tbmbuf.c index 7bdb7ac..e5404fb 100644 --- a/src/modules/evas/engines/wayland_shm/evas_tbmbuf.c +++ b/src/modules/evas/engines/wayland_shm/evas_tbmbuf.c @@ -8,6 +8,8 @@ #include #include +#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: diff --git a/src/modules/evas/engines/wayland_shm/tizen-surface-client.h b/src/modules/evas/engines/wayland_shm/tizen-surface-client.h index e4be021c..6eaa459 100644 --- a/src/modules/evas/engines/wayland_shm/tizen-surface-client.h +++ b/src/modules/evas/engines/wayland_shm/tizen-surface-client.h @@ -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) { diff --git a/src/modules/evas/engines/wayland_shm/tizen-surface-protocol.c b/src/modules/evas/engines/wayland_shm/tizen-surface-protocol.c index 8420280..bd5e8a6 100644 --- a/src/modules/evas/engines/wayland_shm/tizen-surface-protocol.c +++ b/src/modules/evas/engines/wayland_shm/tizen-surface-protocol.c @@ -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, }; -- 2.7.4