From: Changyeon Lee Date: Thu, 22 Aug 2024 02:52:04 +0000 (+0900) Subject: blur: Support wtz_blur_behind protocol X-Git-Tag: accepted/tizen/unified/20240828.164010^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c124bd86fe332c84e3073f04f07fc896b1755669;p=platform%2Fcore%2Fuifw%2Flibds-tizen.git blur: Support wtz_blur_behind protocol Change-Id: I8d05b48842718f28af03c7d5191fa095eab4901e --- diff --git a/include/libds-tizen/blur.h b/include/libds-tizen/blur.h index 8112908..e66dcbd 100644 --- a/include/libds-tizen/blur.h +++ b/include/libds-tizen/blur.h @@ -12,6 +12,7 @@ extern "C" { struct ds_tizen_blur_manager; struct ds_tizen_blur; struct ds_tizen_blur_rectangle; +struct ds_tizen_blur_behind; enum ds_tizen_blur_state_field { DS_TIZEN_BLUR_STATE_NONE = 0, @@ -28,19 +29,27 @@ struct ds_tizen_blur_state uint32_t radius; }; +enum ds_tizen_blur_behind_state_field { + DS_TIZEN_BLUR_BEHIND_STATE_NONE = 0, + DS_TIZEN_BLUR_BEHIND_STATE_RADIUS = (1 << 0), +}; + +struct ds_tizen_blur_behind_state +{ + enum ds_tizen_blur_behind_state_field committed; + + uint32_t radius; +}; + struct ds_tizen_blur_manager * ds_tizen_blur_manager_create(struct wl_display *display); void -ds_tizen_blur_manager_add_destroy_listener(struct ds_tizen_blur_manager *blur, +ds_tizen_blur_manager_add_destroy_listener(struct ds_tizen_blur_manager *blur_manager, struct wl_listener *listener); void -ds_tizen_blur_manager_add_destroy_listener(struct ds_tizen_blur_manager *blur, - struct wl_listener *listener); - -void -ds_tizen_blur_manager_add_new_blur_listener(struct ds_tizen_blur_manager *blur, +ds_tizen_blur_manager_add_new_blur_listener(struct ds_tizen_blur_manager *blur_manager, struct wl_listener *listener); void @@ -73,6 +82,24 @@ void ds_tizen_blur_rectangle_get_corner_radius(struct ds_tizen_blur_rectangle *blur_rectangle, int *rx, int *ry); +void +ds_tizen_blur_manager_add_new_blur_behind_listener(struct ds_tizen_blur_manager *blur, + struct wl_listener *listener); + +void +ds_tizen_blur_behind_add_destroy_listener(struct ds_tizen_blur_behind *blur_behind, + struct wl_listener *listener); + +void +ds_tizen_blur_behind_add_commit_listener(struct ds_tizen_blur_behind *blur_behind, + struct wl_listener *listener); + +struct ds_surface * +ds_tizen_blur_behind_get_surface(struct ds_tizen_blur_behind *blur_behind); + +struct ds_tizen_blur_behind_state * +ds_tizen_blur_behind_get_state(struct ds_tizen_blur_behind *blur_behind); + #ifdef __cplusplus } #endif diff --git a/src/blur/blur.c b/src/blur/blur.c index 4cd3886..36e1d4c 100644 --- a/src/blur/blur.c +++ b/src/blur/blur.c @@ -26,6 +26,7 @@ struct ds_tizen_blur_manager struct { struct wl_signal destroy; struct wl_signal new_blur; + struct wl_signal new_blur_behind; } events; }; @@ -93,6 +94,26 @@ struct ds_tizen_blur_rectangle } events; }; +struct ds_tizen_blur_behind +{ + struct wl_resource *resource; + struct wl_client *wl_client; + + struct ds_tizen_blur_behind_state current, pending; + + struct ds_surface *surface; + struct ds_addon surface_addon; + + struct { + struct wl_listener surface_commit; + } listener; + + struct { + struct wl_signal commit; + struct wl_signal destroy; + } events; +}; + static void blur_manager_handle_display_destroy(struct wl_listener *listener, void *data); static void @@ -125,6 +146,7 @@ ds_tizen_blur_manager_create(struct wl_display *display) wl_signal_init(&blur_manager->events.destroy); wl_signal_init(&blur_manager->events.new_blur); + wl_signal_init(&blur_manager->events.new_blur_behind); ds_inf("Global created: tizen_blur_manager(%p)", blur_manager); @@ -132,17 +154,17 @@ ds_tizen_blur_manager_create(struct wl_display *display) } WL_EXPORT void -ds_tizen_blur_manager_add_destroy_listener(struct ds_tizen_blur_manager *blur, +ds_tizen_blur_manager_add_destroy_listener(struct ds_tizen_blur_manager *blur_manager, struct wl_listener *listener) { - wl_signal_add(&blur->events.destroy, listener); + wl_signal_add(&blur_manager->events.destroy, listener); } WL_EXPORT void -ds_tizen_blur_manager_add_new_blur_listener(struct ds_tizen_blur_manager *blur, +ds_tizen_blur_manager_add_new_blur_listener(struct ds_tizen_blur_manager *blur_manager, struct wl_listener *listener) { - wl_signal_add(&blur->events.new_blur, listener); + wl_signal_add(&blur_manager->events.new_blur, listener); } WL_EXPORT void @@ -203,6 +225,39 @@ ds_tizen_blur_rectangle_get_corner_radius(struct ds_tizen_blur_rectangle *blur_r if (ry) *ry = blur_rectangle->ry; } +WL_EXPORT void +ds_tizen_blur_manager_add_new_blur_behind_listener(struct ds_tizen_blur_manager *blur_manager, + struct wl_listener *listener) +{ + wl_signal_add(&blur_manager->events.new_blur_behind, listener); +} + +WL_EXPORT void +ds_tizen_blur_behind_add_destroy_listener(struct ds_tizen_blur_behind *blur_behind, + struct wl_listener *listener) +{ + wl_signal_add(&blur_behind->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_blur_behind_add_commit_listener(struct ds_tizen_blur_behind *blur_behind, + struct wl_listener *listener) +{ + wl_signal_add(&blur_behind->events.commit, listener); +} + +WL_EXPORT struct ds_surface * +ds_tizen_blur_behind_get_surface(struct ds_tizen_blur_behind *blur_behind) +{ + return blur_behind->surface; +} + +WL_EXPORT struct ds_tizen_blur_behind_state * +ds_tizen_blur_behind_get_state(struct ds_tizen_blur_behind *blur_behind) +{ + return &blur_behind->current; +} + static void blur_manager_handle_display_destroy(struct wl_listener *listener, void *data) { @@ -561,6 +616,180 @@ blur_manager_handle_get_blur(struct wl_client *wl_client, wl_signal_emit(&client->blur_manager->events.new_blur, blur); } +static void +blur_behind_destroy(struct ds_tizen_blur_behind *blur_behind) +{ + ds_inf("blur_behind_destroy (blur_behind:%p)", blur_behind); + + wl_signal_emit(&blur_behind->events.destroy, blur_behind); + + if (blur_behind->surface) { + wl_list_remove(&blur_behind->listener.surface_commit.link); + ds_addon_finish(&blur_behind->surface_addon); + } + + free(blur_behind); +} + +static void +blur_behind_handle_resource_destroy(struct wl_resource *resource) +{ + struct ds_tizen_blur_behind *blur_behind; + + blur_behind = wl_resource_get_user_data(resource); + + ds_inf("blur_behind_handle_resource_destroy (blur_behind:%p)", blur_behind); + + if (blur_behind->surface) { + blur_behind->resource = NULL; + return; + } + + blur_behind_destroy(blur_behind); +} + +static void +blur_behind_handle_surface_commit(struct wl_listener *listener, void *data) +{ + struct ds_tizen_blur_behind *blur_behind; + + blur_behind = wl_container_of(listener, blur_behind, listener.surface_commit); + + if (!blur_behind->resource) { + blur_behind_destroy(blur_behind); + return; + } + + if (blur_behind->pending.committed == DS_TIZEN_BLUR_BEHIND_STATE_NONE) { + blur_behind->current.committed = DS_TIZEN_BLUR_BEHIND_STATE_NONE; + return; + } + + if (blur_behind->pending.committed & DS_TIZEN_BLUR_BEHIND_STATE_RADIUS) + blur_behind->current.radius = blur_behind->pending.radius; + + blur_behind->current.committed = blur_behind->pending.committed; + blur_behind->pending.committed = DS_TIZEN_BLUR_BEHIND_STATE_NONE; + + wl_signal_emit(&blur_behind->events.commit, blur_behind); +} + +static void +blur_behind_handle_surface_destroy(struct ds_addon *addon) +{ + struct ds_tizen_blur_behind *blur_behind; + + blur_behind = wl_container_of(addon, blur_behind, surface_addon); + + wl_list_remove(&blur_behind->listener.surface_commit.link); + + ds_addon_finish(&blur_behind->surface_addon); + blur_behind->surface = NULL; + + if (!blur_behind->resource) + blur_behind_destroy(blur_behind); +} + +static struct ds_addon_interface blur_behind_addon_impl = { + .name = "ds_tizen_blur_behind", + .destroy = blur_behind_handle_surface_destroy, +}; + +static struct ds_tizen_blur_behind * +blur_behind_client_get_from_surface(struct ds_tizen_blur_client *client, struct ds_surface *surface) +{ + struct ds_addon *addon; + struct ds_tizen_blur_behind *blur_behind; + + addon = ds_addon_find(&surface->addons, client, &blur_behind_addon_impl); + if (!addon) return NULL; + + return wl_container_of(addon, blur_behind, surface_addon); +} + +static void +blur_behind_handle_destroy(struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +blur_behind_handle_set_radius(struct wl_client *client, struct wl_resource *resource, + uint32_t radius) +{ + struct ds_tizen_blur_behind *blur_behind; + + blur_behind = wl_resource_get_user_data(resource); + + blur_behind->pending.radius = radius; + blur_behind->pending.committed |= DS_TIZEN_BLUR_BEHIND_STATE_RADIUS; +} + +static const struct wtz_blur_behind_interface blur_behind_impl = { + blur_behind_handle_destroy, + blur_behind_handle_set_radius, +}; + +static void +blur_manager_handle_get_blur_behind(struct wl_client *wl_client, + struct wl_resource *resource, + uint32_t id, struct wl_resource *surface_resource) +{ + struct ds_tizen_blur_client *client; + struct ds_surface *surface; + struct ds_tizen_blur_behind *blur_behind; + + ds_inf("tizen_blur: get_blur"); + + client = wl_resource_get_user_data(resource); + + surface = ds_surface_from_resource(surface_resource); + if (!surface) { + wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, + "invalid wl_surface resource:%u", + (unsigned int)wl_resource_get_id(surface_resource)); + return; + } + + blur_behind = blur_behind_client_get_from_surface(client, surface); + if (blur_behind) { + wl_resource_post_error(resource, WTZ_BLUR_MANAGER_ERROR_BLUR_EXISTS, + "blend object already exists"); + return; + } + + blur_behind = calloc(1, sizeof *blur_behind); + if (blur_behind == NULL) { + ds_err("calloc() failed. tizen_blur"); + wl_client_post_no_memory(wl_client); + return; + } + + blur_behind->resource = wl_resource_create(wl_client, &wtz_blur_behind_interface, + wl_resource_get_version(resource), id); + if (blur_behind->resource == NULL) { + ds_err("tizen_blur : wl_resource_create() failed."); + free(blur_behind); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(blur_behind->resource, &blur_behind_impl, blur_behind, + blur_behind_handle_resource_destroy); + + ds_addon_init(&blur_behind->surface_addon, &surface->addons, client, &blur_behind_addon_impl); + + blur_behind->listener.surface_commit.notify = blur_behind_handle_surface_commit; + ds_surface_add_commit_listener(surface, &blur_behind->listener.surface_commit); + + blur_behind->surface = surface; + + wl_signal_init(&blur_behind->events.destroy); + wl_signal_init(&blur_behind->events.commit); + + wl_signal_emit(&client->blur_manager->events.new_blur_behind, blur_behind); +} + static void blur_manager_handle_destroy(struct wl_client *wl_client, struct wl_resource *resource) @@ -572,6 +801,7 @@ static const struct wtz_blur_manager_interface blur_manager_impl = { blur_manager_handle_destroy, blur_manager_handle_get_blur, + blur_manager_handle_get_blur_behind, }; static void