const char *path;
char *name;
int fd = 0;
+ int len=0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
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)
_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
}
}
+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
#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)
int stride;
int frame_age;
Eina_Bool alpha : 1;
+
+ struct tizen_surface_shm_flusher *tzsurf_flusher;
};
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;
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;
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);
dlclose(tbm_client_lib);
tbm_client_lib = NULL;
}
+
+ if (tzsurf)
+ {
+ tizen_surface_shm_destroy(tzsurf);
+ tzsurf = NULL;
+ }
}
}
}
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
{
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);
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:
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)
{
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)
{
*/
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
#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)
{
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)
{
};
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,
};
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,
};