From: SooChan Lim Date: Thu, 21 Jul 2022 06:41:35 +0000 (+0900) Subject: impelement libds-tizen-memory-flusher X-Git-Tag: accepted/tizen/unified/20220808.135412~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=37cc0df45ca457624d751e907104bc9b008eff71;p=platform%2Fcore%2Fuifw%2Flibds-tizen.git impelement libds-tizen-memory-flusher This is the server implementation for tizen_surface_shm/tizen_surface_shm_flusher protocol. Change-Id: I0731be582066cd3085fb03da9000b6a1697e093b --- diff --git a/include/libds-tizen/memory_flusher.h b/include/libds-tizen/memory_flusher.h new file mode 100644 index 0000000..0b72425 --- /dev/null +++ b/include/libds-tizen/memory_flusher.h @@ -0,0 +1,49 @@ +#ifndef LIBDS_TIZEN_MEMORY_FLUSHER_H +#define LIBDS_TIZEN_MEMORY_FLUSHER_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ds_tizen_memory_flusher; +struct ds_tizen_memory_flusher_info; + +struct ds_tizen_memory_flusher * +ds_tizen_memory_flusher_create(struct wl_display *display); + +void +ds_tizen_memory_flusher_add_destroy_listener( + struct ds_tizen_memory_flusher *memory_flusher, + struct wl_listener *listener); + +void +ds_tizen_memory_flusher_add_get_flusher_info_listener( + struct ds_tizen_memory_flusher *memory_flusher, + struct wl_listener *listener); + +void +ds_tizen_memory_flusher_info_add_destroy_listener( + struct ds_tizen_memory_flusher_info *info, + struct wl_listener *listener); + +struct ds_surface * +ds_tizen_memory_flusher_info_get_surface( + struct ds_tizen_memory_flusher_info *info); + +void +ds_tizen_memory_flusher_info_send_flush( + struct ds_tizen_memory_flusher_info *info); + +void +ds_tizen_memory_flusher_info_send_free_flush( + struct ds_tizen_memory_flusher_info *info); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 5ec3a14..d1db0c9 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -26,6 +26,8 @@ BuildRequires: pkgconfig(wayland-tbm-server) BuildRequires: pkgconfig(wayland-tbm-client) BuildRequires: pkgconfig(tizen-dpms-server) BuildRequires: pkgconfig(tizen-dpms-client) +BuildRequires: pkgconfig(tizen-surface-server) +BuildRequires: pkgconfig(tizen-surface-client) BuildRequires: pkgconfig(cynara-client) BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(libsmack) @@ -184,6 +186,21 @@ Group: Development/Libraries %description display-policy-devel Development package for tizen display-policy +## libds-tizen-memory-flusher +%package memory-flusher +Summary: Library for tizen memory flusher +Group: Development/Libraries + +%description memory-flusher +Library for tizen memory flusher + +%package memory-flusher-devel +Summary: Development package for tizen memory flusher +Group: Development/Libraries + +%description memory-flusher-devel +Development package for tizen memory flusher + %prep %setup -q cp %{SOURCE1001} . @@ -355,3 +372,17 @@ ninja -C builddir install %{_libdir}/pkgconfig/libds-tizen-display-policy.pc %{_libdir}/libds-tizen-display-policy.so %{_bindir}/libds-tizen-display-policy-tests + +%files memory-flusher +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_libdir}/libds-tizen-memory-flusher.so.* + +%files memory-flusher-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/memory_flusher.h +%{_libdir}/pkgconfig/libds-tizen-memory-flusher.pc +%{_libdir}/libds-tizen-memory-flusher.so diff --git a/src/memory_flusher/memory_flusher.c b/src/memory_flusher/memory_flusher.c new file mode 100644 index 0000000..499e05d --- /dev/null +++ b/src/memory_flusher/memory_flusher.c @@ -0,0 +1,341 @@ +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "libds-tizen/memory_flusher.h" + +#define TIZEN_MEMORY_FLUSHER_VERSION 2 + +struct ds_tizen_memory_flusher +{ + struct wl_global *global; + + struct wl_list clients; + + struct wl_listener destroy; + + struct { + struct wl_signal destroy; + struct wl_signal get_flusher; + } events; +}; + +struct ds_tizen_memory_flusher_client +{ + struct ds_tizen_memory_flusher *memory_flusher; + + struct wl_resource *resource; + struct wl_client *wl_client; + + struct wl_list infos; + + struct { + struct wl_signal destroy; + } events; + + struct wl_list link; // ds_tizen_memory_flusher::clients +}; + +struct ds_tizen_memory_flusher_info +{ + struct ds_tizen_memory_flusher_client *client; + + struct wl_resource *resource; + + struct ds_surface *surface; + + struct wl_list link; // ds_tizen_memory_flusher_client::infos +}; + +static void memory_flusher_handle_display_destroy(struct wl_listener *listener, + void *data); + +static void memory_flusher_bind(struct wl_client *wl_client, void *data, + uint32_t version, uint32_t id); + +static struct ds_tizen_memory_flusher_info *tizen_memory_flusher_client_find_info( + struct ds_tizen_memory_flusher_client *client, + struct ds_surface *surface); + +static struct ds_tizen_memory_flusher_info *tizen_memory_flusher_client_get_info( + struct ds_tizen_memory_flusher_client *client, + struct ds_surface *surface); + +WL_EXPORT struct ds_tizen_memory_flusher * +ds_tizen_memory_flusher_create(struct wl_display *display) +{ + struct ds_tizen_memory_flusher *memory_flusher; + + memory_flusher = calloc(1, sizeof *memory_flusher); + if (!memory_flusher) { + ds_err("calloc() failed."); + return NULL; + } + + memory_flusher->global = wl_global_create(display, &tizen_surface_shm_interface, + TIZEN_MEMORY_FLUSHER_VERSION, memory_flusher, memory_flusher_bind); + if (!memory_flusher->global) { + ds_err("wl_global_create() failed. tizen_surface_shm_interface"); + free(memory_flusher); + return NULL; + } + + wl_list_init(&memory_flusher->clients); + + memory_flusher->destroy.notify = memory_flusher_handle_display_destroy; + wl_display_add_destroy_listener(display, &memory_flusher->destroy); + + wl_signal_init(&memory_flusher->events.destroy); + wl_signal_init(&memory_flusher->events.get_flusher); + + ds_inf("Global created: tizen_memory_flusher(%p)", memory_flusher); + + return memory_flusher; +} + +WL_EXPORT void +ds_tizen_memory_flusher_add_destroy_listener( + struct ds_tizen_memory_flusher *memory_flusher, + struct wl_listener *listener) +{ + wl_signal_add(&memory_flusher->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_memory_flusher_add_get_flusher_info_listener( + struct ds_tizen_memory_flusher *memory_flusher, + struct wl_listener *listener) +{ + wl_signal_add(&memory_flusher->events.get_flusher, listener); +} + +WL_EXPORT void +ds_tizen_memory_flusher_info_add_destroy_listener( + struct ds_tizen_memory_flusher_info *info, + struct wl_listener *listener) +{ + wl_signal_add(&info->client->events.destroy, listener); +} + +WL_EXPORT struct ds_surface * +ds_tizen_memory_flusher_info_get_surface( + struct ds_tizen_memory_flusher_info *info) +{ + return info->surface; +} + +WL_EXPORT void +ds_tizen_memory_flusher_info_send_flush( + struct ds_tizen_memory_flusher_info *info) +{ + tizen_surface_shm_flusher_send_flush(info->resource); +} + +WL_EXPORT void +ds_tizen_memory_flusher_info_send_free_flush( + struct ds_tizen_memory_flusher_info *info) +{ + tizen_surface_shm_flusher_send_free_flush(info->resource); +} + +static struct ds_tizen_memory_flusher_info * +tizen_memory_flusher_client_find_info(struct ds_tizen_memory_flusher_client *client, + struct ds_surface *surface) +{ + struct ds_tizen_memory_flusher_info *info; + + wl_list_for_each(info, &client->infos, link) { + if (surface == info->surface) + return info; + } + + return NULL; +} + +static struct ds_tizen_memory_flusher_info * +tizen_memory_flusher_client_get_info(struct ds_tizen_memory_flusher_client *client, + struct ds_surface *surface) +{ + struct ds_tizen_memory_flusher_info *info; + + info = tizen_memory_flusher_client_find_info(client, surface); + if (info) + return info; + + info = calloc(1, sizeof *info); + if (info == NULL) { + ds_err("calloc() failed. tizen_memory_flusher"); + return NULL; + } + + info->client = client; + info->surface = surface; + + wl_list_insert(&client->infos, &info->link); + + return info; +} + +static void +memory_flusher_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_memory_flusher *memory_flusher; + + memory_flusher = wl_container_of(listener, memory_flusher, destroy); + + ds_inf("Global destroy: memory_flusher(%p)", memory_flusher); + + wl_signal_emit(&memory_flusher->events.destroy, memory_flusher); + wl_list_remove(&memory_flusher->destroy.link); + wl_global_destroy(memory_flusher->global); + free(memory_flusher); +} + +static void +flusher_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static const struct tizen_surface_shm_flusher_interface flusher_impl = +{ + flusher_handle_destroy, +}; + +static void +_tizen_memory_flusher_info_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_memory_flusher_info *info; + + info = wl_resource_get_user_data(resource); + + ds_inf("_tizen_memory_flusher_info_handle_destroy (info:%p)", info); + + wl_signal_emit(&info->client->events.destroy, info); + wl_list_remove(&info->link); + free(info); +} + +static void +memory_flusher_handle_get_flusher(struct wl_client *wl_client, + struct wl_resource *resource,uint32_t id, + struct wl_resource *surface_resource) +{ + struct ds_tizen_memory_flusher_client *client; + struct ds_tizen_memory_flusher_info *info; + struct ds_surface *surface; + + ds_inf("tizen_memory_flusher: get_flusher"); + + client = wl_resource_get_user_data(resource); + surface = ds_surface_from_resource(surface_resource); + + info = tizen_memory_flusher_client_get_info(client, surface); + if (info == NULL) { + ds_err("tizen_memory_flusher_client_get_info() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + info->resource = wl_resource_create(wl_client, + &tizen_surface_shm_flusher_interface, wl_resource_get_version(resource), + id); + if (info->resource == NULL) { + ds_err("tizen_memory_flusher : wl_resource_create() failed."); + wl_list_remove(&info->link); + free(info); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(info->resource, &flusher_impl, info, + _tizen_memory_flusher_info_handle_destroy); + + wl_signal_emit(&client->memory_flusher->events.get_flusher, info); +} + +static void +memory_flusher_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + struct ds_tizen_memory_flusher_client *client; + + client = wl_resource_get_user_data(resource); + + if (!wl_list_empty(&client->infos)) { + ds_err("tizen_memory_flusher was destroyed before children"); + return; + } + + wl_resource_destroy(resource); +} + +static const struct tizen_surface_shm_interface memory_flusher_impl = +{ + memory_flusher_handle_get_flusher, + memory_flusher_handle_destroy, +}; + +static void +_tizen_memory_flusher_client_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_memory_flusher_client *client; + struct ds_tizen_memory_flusher_info *info, *tmp; + + client = wl_resource_get_user_data(resource); + + ds_inf("_tizen_memory_flusher_client_handle_destroy (client:%p)", client); + + wl_list_for_each_safe(info, tmp, &client->infos, link) { + wl_signal_emit(&client->events.destroy, info); + wl_list_remove(&info->link); + free(info); + } + + wl_list_remove(&client->link); + free(client); +} + +static void +memory_flusher_bind(struct wl_client *wl_client, void *data, uint32_t version, + uint32_t id) +{ + struct ds_tizen_memory_flusher *memory_flusher = data; + struct ds_tizen_memory_flusher_client *client; + + client = calloc(1, sizeof *client); + if (client == NULL) { + ds_err("calloc() failed. tizen_memory_flusher"); + wl_client_post_no_memory(wl_client); + return; + } + + ds_inf("tizen_memory_flusher_client binds. (client:%p)", client); + + client->memory_flusher = memory_flusher; + client->wl_client = wl_client; + + wl_list_init(&client->infos); + + client->resource = wl_resource_create(wl_client, &tizen_surface_shm_interface, + MIN(version, TIZEN_MEMORY_FLUSHER_VERSION), id); + + if (client->resource == NULL) { + ds_err("tizen_memory_flusher : wl_resource_create() failed."); + free(client); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(client->resource, &memory_flusher_impl, client, + _tizen_memory_flusher_client_handle_destroy); + + wl_signal_init(&client->events.destroy); + + wl_list_insert(&memory_flusher->clients, &client->link); +} diff --git a/src/memory_flusher/meson.build b/src/memory_flusher/meson.build new file mode 100644 index 0000000..440022a --- /dev/null +++ b/src/memory_flusher/meson.build @@ -0,0 +1,29 @@ +libds_tizen_memory_flusher_files = [ + 'memory_flusher.c', +] + +libds_tizen_memory_flusher_deps = [ + deps_libds_tizen, + dependency('tizen-surface-server', required: true), +] + +lib_libds_tizen_memory_flusher = shared_library('ds-tizen-memory-flusher', libds_tizen_memory_flusher_files, + dependencies: libds_tizen_memory_flusher_deps, + include_directories: [ common_inc, include_directories('.'), include_directories('..') ], + version: meson.project_version(), + install: true +) + +deps_libds_tizen_memory_flusher = declare_dependency( + link_with: lib_libds_tizen_memory_flusher, + dependencies: libds_tizen_memory_flusher_deps, + include_directories: [ common_inc, include_directories('.') ], +) + +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen_memory_flusher, + version: meson.project_version(), + filebase: 'libds-tizen-memory-flusher', + name: 'libds-tizen-memory-flusher', + description: 'tizen memory flusher extension of libds-tizen for tizen platform', +) diff --git a/src/meson.build b/src/meson.build index d0bb024..c1c88ac 100644 --- a/src/meson.build +++ b/src/meson.build @@ -37,3 +37,4 @@ subdir('indicator') subdir('clipboard') subdir('launch') subdir('display_policy') +subdir('memory_flusher')