From: Seunghun Lee Date: Thu, 29 Jun 2023 06:27:13 +0000 (+0900) Subject: Implement linux_explicit_sync (wip) X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Fdev%2Fshiin;p=platform%2Fcore%2Fuifw%2Flibds.git Implement linux_explicit_sync (wip) --- diff --git a/include/libds/linux_explicit_sync_v1.h b/include/libds/linux_explicit_sync_v1.h new file mode 100644 index 0000000..70a8991 --- /dev/null +++ b/include/libds/linux_explicit_sync_v1.h @@ -0,0 +1,19 @@ +#ifndef LIBDS_COMPOSITOR_H +#define LIBDS_COMPOSITOR_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ds_linux_explicit_sync_v1; + +struct ds_linux_explicit_sync_v1 * +ds_linux_explicit_sync_v1_create(struct wl_display *display); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libds/types/ds_surface.h b/include/libds/types/ds_surface.h index c1bb45a..5d1ee5d 100644 --- a/include/libds/types/ds_surface.h +++ b/include/libds/types/ds_surface.h @@ -54,6 +54,8 @@ struct ds_surface_state struct ds_fbox src; int dst_width, dst_height; } viewport; + + int acquire_fence_fd; }; struct ds_surface_viewport diff --git a/src/linux_explicit_sync_v1.c b/src/linux_explicit_sync_v1.c new file mode 100644 index 0000000..fd1b717 --- /dev/null +++ b/src/linux_explicit_sync_v1.c @@ -0,0 +1,233 @@ +#include +#include + +#include "libds/types/ds_surface.h" +#include "libds/log.h" +#include "libds/util/defs.h" +#include "libds/util/addon.h" +#include "util.h" + +#define ZWP_LINUX_EXPLICIT_SYNCHRONIZATION_VERSION 2 + +struct ds_linux_explicit_sync_v1 { + struct wl_global *global; + + struct wl_listener display_destroy; +}; + +struct ds_linux_explicit_sync_v1_state { + int acquire_fence_fd; +}; + +struct ds_linux_explicit_sync_v1_surface { + struct wl_resource *resource; + struct ds_linux_explicit_sync_v1 *explicit_sync; + struct ds_surface *surface; + + struct ds_linux_explicit_sync_v1_state pending, cache, current; + struct ds_addon addon; + + struct wl_listener surface_destroy; +}; + +static void linux_explicit_sync_v1_handle_display_destroy(struct wl_listener *listener, void *data); +static void linux_explicit_sync_v1_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id); + +WL_EXPORT struct ds_linux_explicit_sync_v1 * +ds_linux_explicit_sync_v1_create(struct wl_display *display); +{ + struct ds_linux_explicit_sync_v1 *explicit_sync; + + explicit_sync = calloc(1, sizeof *explicit_sync); + if (!explicit_sync) + return NULL; + + explicit_sync->global = wl_global_create(display, + &zwp_linux_explicit_synchronization_v1_interface, + ZWP_LINUX_EXPLICIT_SYNCHRONIZATION_VERSION, + explicit_sync, + linux_explicit_sync_v1_bind); + if (!explicit_sync->global) { + ds_err("Could not create global"); + free(explicit_sync); + return NULL; + } + + explicit_sync->display_destroy.notify = + linux_explicit_sync_v1_handle_display_destroy; + wl_display_add_destroy_listener(display, &explicit_sync->display_destroy); + + ds_inf("Create ds_linux_explicit_sync_v1"); + + return explicit_sync; +} + +static void +linux_explicit_sync_v1_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct ds_linux_explicit_sync_v1 *explicit_sync; + + explicit_sync = wl_container_of(listener, explicit_sync, display_destroy); + + wl_global_destroy(explicit_sync->global); + free(explicit_sync); +} + +static void +surface_destroy(struct ds_linux_explicit_sync_v1_surface *surface) +{ + fd_clear(&surface->pending.acquire_fence_fd); + ds_addon_finish(&surface->addon); + free(surface); +} + +static void +surface_addon_destroy(struct ds_addon *addon) +{ + struct ds_linux_explicit_sync_v1_surface *surface; + + surface = wl_container_of(addon, surface, addon); + surface_destroy(surface); +} + +static const struct ds_addon_interface surface_addon_impl = { + .name = "ds_linux_explicit_sync_v1_surface", + .destroy = surface_addon_destroy, +}; + +static ds_linux_explicit_sync_v1_surface * +create_surface(struct ds_linux_explicit_sync_v1 *explicit_sync, + struct ds_surface *ds_surface) +{ + struct ds_linux_explicit_sync_v1_surface *surface; + + surface = calloc(1, sizeof(*surface)); + if (!surface) + return NULL; + + surface->surface = ds_surface; + surface->explicit_sync = explicit_sync; + + ds_addon_init(&surface->addon, &ds_surface->addons, explicit_sync, + &surface_addon_impl); +} + +static void +linux_explicit_sync_v1_destroy(struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +surface_handle_resource_destroy(struct wl_resource *resource) +{ + struct ds_linux_explicit_sync_v1_surface *surface; + + surface = wl_resource_get_user_data(resource); + if (!surface) + return; + + surface_destroy(surface); + surface->synchronization_resource = NULL; +} + +static void +surface_sync_handle_destroy(struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +surface_sync_handle_set_acquire_fence(struct wl_client *client, + struct wl_resource *resource, int32_t fd) +{ + struct ds_surface *surface; + + surface = wl_resource_get_user_data(resource); +} + +static void +surface_sync_handle_get_release(struct wl_client *client, + struct wl_resource *resource, int32_t id) +{ + +} + +const struct zwp_linux_surface_synchronization_v1_interface +surface_impl = { + .destroy = surface_sync_handle_destroy, + .set_acquire_fence = surface_sync_handle_set_acquire_fence, + .get_release = surface_sync_handle_get_release, +} + +static void +linux_explicit_sync_handle_get_synchronization(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + struct ds_linux_explicit_sync_v1 *explicit_sync; + struct ds_linux_explicit_sync_v1_surface *surface; + struct ds_surface *ds_surface; + struct ds_addon *addon; + + explicit_sync = wl_resource_get_user_data(resource); + + ds_surface = ds_surface_from_resource(surface_resource); + DS_ASSERT(ds_surface); + + addon = ds_addon_find(&ds_surface->addons, explicit_sync, &surface_addon_impl); + if (addon) { + wl_resource_post_error(resource, + ZWP_LINUX_EXPLICIT_SYNCHRONIZATION_V1_ERROR_SYNCHRONIZATION_EXISTS, + "wl_surface@d already has a synchronization object", + wl_resource_get_id(surface_resource)); + return; + } + + surface = create_surface(explicit_sync, ds_surface); + if (!surface) { + wl_client_post_no_memory(client); + return; + } + + surface->resource = wl_resource_create(client, + &zwp_linux_surface_synchronization_v1_interface, + wl_resource_get_version(resource), id); + if (!surface->resource) { + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation(surface->resource, + &surface_impl, + surface, + surface_handle_resource_destroy); +} + +static const struct zwp_linux_explicit_synchronization_v1_interface +linux_explicit_sync_v1_impl = { + .destroy = linux_explicit_sync_v1_destroy, + .get_synchronization = linux_explicit_sync_handle_get_synchronization, +} + +static void +linux_explicit_sync_v1_bind(struct wl_client *client, void *data, uint32_t version, + uint32_t id) +{ + struct ds_linux_explicit_sync_v1 *explicit_sync = data; + struct wl_resource *resource; + + resource = wl_resource_create(client, + &zwp_linux_explicit_synchronization_v1_interface, version, id); + if (!resource) { + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation(resource, &linux_explicit_sync_v1_impl, + explicit_sync, NULL); +} + diff --git a/src/meson.build b/src/meson.build index 7bed33b..28efbde 100644 --- a/src/meson.build +++ b/src/meson.build @@ -30,11 +30,13 @@ libds_files = [ 'seat/seat_touch.c', 'shell.c', 'shell_surface.c', + 'explicit_sync.c', ] protocols = { 'xdg-shell': wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml', 'single-pixel-buffer-v1': wl_protocol_dir / 'staging/single-pixel-buffer/single-pixel-buffer-v1.xml', + 'linux-explicit-synchronization': wl_protocol_dir / 'unstable/linux-explicit-synchronization/linux-explicit-synchronization-unstable-v1.xml', } protocols_code = {} diff --git a/src/util.h b/src/util.h index 26a63eb..708da90 100644 --- a/src/util.h +++ b/src/util.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "libds/util/defs.h" @@ -20,4 +21,29 @@ allocate_shm_file(size_t size); bool allocate_shm_file_pair(size_t size, int *rw_fd_ptr, int *ro_fd_ptr); +static inline void +fd_update(int *fd, int new_fd) +{ + if (*fd == new_fd) + return; + if (*fd >= 0) + close(*fd); + *fd = new_fd; +} + +static inline void +fd_move(int *dest, int *src) +{ + if (dest == src) + return; + fd_update(dest, *src); + *src = -1; +} + +static inline void +fd_clear(int *fd) +{ + fd_update(fd, -1); +} + #endif