add ds_tizen_blur 12/305612/1 accepted/tizen/unified/20240207.171601 accepted/tizen/unified/x/20240208.023004
authorChangyeon Lee <cyeon.lee@samsung.com>
Wed, 15 Nov 2023 10:12:45 +0000 (19:12 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Mon, 5 Feb 2024 09:53:23 +0000 (18:53 +0900)
implementation of wtz-blur protocol

Change-Id: Idcf10764a957e53ce6aa3bc49381d4dbbfd37aea

include/libds-tizen/blur.h [new file with mode: 0644]
packaging/libds-tizen.spec
src/blur/blur.c [new file with mode: 0644]
src/meson.build

diff --git a/include/libds-tizen/blur.h b/include/libds-tizen/blur.h
new file mode 100644 (file)
index 0000000..84fe80f
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef LIBDS_TIZEN_BLUR_H
+#define LIBDS_TIZEN_BLUR_H
+
+#include <stdint.h>
+#include <wayland-server.h>
+#include <libds/surface.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ds_tizen_blur_manager;
+struct ds_tizen_blur;
+
+enum ds_tizen_blur_state_field {
+    DS_TIZEN_BLUR_STATE_NONE = 0,
+    DS_TIZEN_BLUR_STATE_REGION = (1 << 0),
+    DS_TIZEN_BLUR_STATE_RADIUS = (1 << 1),
+};
+
+struct ds_tizen_blur_state
+{
+    enum ds_tizen_blur_state_field committed;
+
+    pixman_region32_t region;
+    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,
+        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,
+        struct wl_listener *listener);
+
+void
+ds_tizen_blur_add_destroy_listener(struct ds_tizen_blur *blur,
+        struct wl_listener *listener);
+
+void
+ds_tizen_blur_add_commit_listener(struct ds_tizen_blur *blur,
+        struct wl_listener *listener);
+
+struct ds_surface *
+ds_tizen_blur_get_surface(struct ds_tizen_blur *blur);
+
+struct ds_tizen_blur_state *
+ds_tizen_blur_get_state(struct ds_tizen_blur *blur);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index e2c980c..0de56b1 100644 (file)
@@ -47,6 +47,7 @@ BuildRequires:  pkgconfig(eom)
 BuildRequires:  pkgconfig(xdg-shell-unstable-v6-server)
 BuildRequires:  pkgconfig(gbm)
 BuildRequires:  pkgconfig(wtz-blender-server)
+BuildRequires:  pkgconfig(wtz-blur-server)
 
 %description
 Wayland Compositor Library for Tizen
@@ -434,6 +435,7 @@ Group:   Development/Libraries
 %description gbm-server-devel
 Development package for tizen wayland-gbm-server
 
+
 %prep
 %setup -q
 cp %{SOURCE1001} .
diff --git a/src/blur/blur.c b/src/blur/blur.c
new file mode 100644 (file)
index 0000000..ad75eb9
--- /dev/null
@@ -0,0 +1,426 @@
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <wayland-server.h>
+#include <tizen-surface-server-protocol.h>
+#include <wtz-blur-server-protocol.h>
+#include <libds/log.h>
+#include <libds/region.h>
+#include <libds/util/addon.h>
+#include <libds/types/ds_surface.h>
+#include <pixman.h>
+
+#include "util.h"
+#include "libds-tizen/blur.h"
+
+#define TIZEN_BLUR_VERSION 1
+
+struct ds_tizen_blur_manager
+{
+    struct wl_global *global;
+
+    struct wl_list clients;
+
+    struct wl_listener destroy;
+
+    struct {
+        struct wl_signal destroy;
+        struct wl_signal new_blur;
+    } events;
+};
+
+struct ds_tizen_blur_client
+{
+    struct wl_list link; //clients
+
+    struct ds_tizen_blur_manager *blur_manager;
+
+    struct wl_resource *resource;
+    struct wl_client *wl_client;
+
+    struct {
+        struct wl_signal destroy;
+    } events;
+};
+
+struct ds_tizen_blur
+{
+    struct wl_resource *resource;
+    struct wl_client *wl_client;
+
+    struct ds_tizen_blur_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
+blur_manager_bind(struct wl_client *wl_client, void *data, uint32_t version,
+        uint32_t id);
+
+WL_EXPORT struct ds_tizen_blur_manager *
+ds_tizen_blur_manager_create(struct wl_display *display)
+{
+    struct ds_tizen_blur_manager *blur_manager;
+
+    blur_manager = calloc(1, sizeof *blur_manager);
+    if (!blur_manager) {
+        ds_err("calloc() failed.");
+        return NULL;
+    }
+
+    blur_manager->global = wl_global_create(display, &wtz_blur_manager_interface,
+            TIZEN_BLUR_VERSION, blur_manager, blur_manager_bind);
+    if (!blur_manager->global) {
+        ds_err("wl_global_create() failed. tizen_surface_shm_interface");
+        free(blur_manager);
+        return NULL;
+    }
+
+    wl_list_init(&blur_manager->clients);
+
+    blur_manager->destroy.notify = blur_manager_handle_display_destroy;
+    wl_display_add_destroy_listener(display, &blur_manager->destroy);
+
+    wl_signal_init(&blur_manager->events.destroy);
+    wl_signal_init(&blur_manager->events.new_blur);
+
+    ds_inf("Global created: tizen_blur_manager(%p)", blur_manager);
+
+    return blur_manager;
+}
+
+WL_EXPORT void
+ds_tizen_blur_manager_add_destroy_listener(struct ds_tizen_blur_manager *blur,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&blur->events.destroy, listener);
+}
+
+WL_EXPORT void
+ds_tizen_blur_manager_add_new_blur_listener(struct ds_tizen_blur_manager *blur,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&blur->events.new_blur, listener);
+}
+
+WL_EXPORT void
+ds_tizen_blur_add_destroy_listener(struct ds_tizen_blur *blur,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&blur->events.destroy, listener);
+}
+
+WL_EXPORT void
+ds_tizen_blur_add_commit_listener(struct ds_tizen_blur *blur,
+        struct wl_listener *listener)
+{
+    wl_signal_add(&blur->events.commit, listener);
+}
+
+WL_EXPORT struct ds_surface *
+ds_tizen_blur_get_surface(struct ds_tizen_blur *blur)
+{
+    return blur->surface;
+}
+
+WL_EXPORT struct ds_tizen_blur_state *
+ds_tizen_blur_get_state(struct ds_tizen_blur *blur)
+{
+    return &blur->current;
+}
+
+static void
+blur_manager_handle_display_destroy(struct wl_listener *listener, void *data)
+{
+    struct ds_tizen_blur_manager *blur_manager;
+
+    blur_manager = wl_container_of(listener, blur_manager, destroy);
+
+    ds_inf("Global destroy: blur_manager(%p)", blur_manager);
+
+    wl_signal_emit_mutable(&blur_manager->events.destroy, blur_manager);
+    wl_list_remove(&blur_manager->destroy.link);
+    wl_global_destroy(blur_manager->global);
+    free(blur_manager);
+}
+
+static void
+blur_handle_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+    wl_resource_destroy(resource);
+}
+
+static void
+blur_handle_set_region(struct wl_client *client, struct wl_resource *resource,
+        struct wl_resource *region_resource)
+{
+    struct ds_tizen_blur *blur;
+    pixman_region32_t *region;
+
+    blur = wl_resource_get_user_data(resource);
+    region = ds_region_from_resource(region_resource);
+
+    if (region) {
+        pixman_region32_copy(&blur->pending.region, region);
+    } else {
+        pixman_region32_fini(&blur->pending.region);
+        pixman_region32_init_rect(&blur->pending.region, INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX);
+    }
+
+    blur->pending.committed |= DS_TIZEN_BLUR_STATE_REGION;
+}
+
+static void
+blur_handle_set_radius(struct wl_client *client, struct wl_resource *resource,
+        uint32_t radius)
+{
+    struct ds_tizen_blur *blur;
+
+    blur = wl_resource_get_user_data(resource);
+
+    blur->pending.radius = radius;
+    blur->pending.committed |= DS_TIZEN_BLUR_STATE_RADIUS;
+}
+
+static const struct wtz_blur_interface blur_impl = {
+   blur_handle_destroy,
+   blur_handle_set_region,
+   blur_handle_set_radius,
+};
+
+static void
+blur_destroy(struct ds_tizen_blur *blur)
+{
+    ds_inf("blur_destroy (blur:%p)", blur);
+
+    wl_signal_emit_mutable(&blur->events.destroy, blur);
+
+    if (blur->listener.surface_commit.notify)
+        wl_list_remove(&blur->listener.surface_commit.link);
+
+    if (blur->surface)
+        ds_addon_finish(&blur->surface_addon);
+
+    pixman_region32_fini(&blur->pending.region);
+    pixman_region32_fini(&blur->current.region);
+    free(blur);
+}
+
+static void
+blur_handle_resource_destroy(struct wl_resource *resource)
+{
+    struct ds_tizen_blur *blur;
+
+    blur = wl_resource_get_user_data(resource);
+
+    ds_inf("blur_handle_resource_destroy (blur:%p)", blur);
+
+    if (blur->surface) {
+        blur->resource = NULL;
+        return;
+    }
+
+    blur_destroy(blur);
+}
+
+static void
+blur_handle_surface_commit(struct wl_listener *listener, void *data)
+{
+    struct ds_tizen_blur *blur;
+
+    blur = wl_container_of(listener, blur, listener.surface_commit);
+
+    if (!blur->resource) {
+        blur_destroy(blur);
+        return;
+    }
+
+    if (blur->pending.committed == DS_TIZEN_BLUR_STATE_NONE)
+        return;
+
+    if (blur->pending.committed & DS_TIZEN_BLUR_STATE_REGION)
+        pixman_region32_copy(&blur->current.region, &blur->pending.region);
+
+    if (blur->pending.committed & DS_TIZEN_BLUR_STATE_RADIUS)
+        blur->current.radius = blur->pending.radius;
+
+    blur->current.committed = blur->pending.committed;
+    blur->pending.committed = DS_TIZEN_BLUR_STATE_NONE;
+
+    wl_signal_emit_mutable(&blur->events.commit, blur);
+}
+
+static void
+blur_handle_surface_destroy(struct ds_addon *addon)
+{
+    struct ds_tizen_blur *blur;
+
+    blur = wl_container_of(addon, blur, surface_addon);
+
+    if (blur->listener.surface_commit.notify) {
+        wl_list_remove(&blur->listener.surface_commit.link);
+        blur->listener.surface_commit.notify = NULL;
+    }
+
+    ds_addon_finish(&blur->surface_addon);
+    blur->surface = NULL;
+
+    if (!blur->resource)
+        blur_destroy(blur);
+}
+
+static struct ds_addon_interface blur_addon_impl = {
+       .name = "ds_tizen_blur",
+       .destroy = blur_handle_surface_destroy,
+};
+
+static struct ds_tizen_blur *
+blur_client_get_from_surface(struct ds_tizen_blur_client *client, struct ds_surface *surface)
+{
+   struct ds_addon *addon;
+   struct ds_tizen_blur *blur;
+
+    addon = ds_addon_find(&surface->addons, client, &blur_addon_impl);
+    if (!addon) return NULL;
+
+    blur = wl_container_of(addon, blur, surface_addon);
+
+    return blur;
+}
+
+static void
+blur_manager_handle_get_blur(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 *blur;
+
+    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 = blur_client_get_from_surface(client, surface);
+    if (blur) {
+        wl_resource_post_error(resource, WTZ_BLUR_MANAGER_ERROR_BLUR_EXISTS,
+                "blend object already exists");
+        return;
+    }
+
+    blur = calloc(1, sizeof *blur);
+    if (blur == NULL) {
+        ds_err("calloc() failed. tizen_blur");
+        wl_client_post_no_memory(wl_client);
+        return;
+    }
+
+    blur->resource = wl_resource_create(wl_client, &wtz_blur_interface,
+           wl_resource_get_version(resource), id);
+    if (blur->resource == NULL) {
+        ds_err("tizen_blur : wl_resource_create() failed.");
+        free(blur);
+        wl_client_post_no_memory(wl_client);
+        return;
+    }
+
+    pixman_region32_init_rect(&blur->pending.region, INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX);
+    pixman_region32_init_rect(&blur->current.region, INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX);
+
+    wl_resource_set_implementation(blur->resource, &blur_impl, blur,
+        blur_handle_resource_destroy);
+
+    ds_addon_init(&blur->surface_addon, &surface->addons, client, &blur_addon_impl);
+
+    blur->listener.surface_commit.notify = blur_handle_surface_commit;
+    ds_surface_add_commit_listener(surface, &blur->listener.surface_commit);
+
+    blur->surface = surface;
+
+    wl_signal_init(&blur->events.destroy);
+    wl_signal_init(&blur->events.commit);
+
+    wl_signal_emit_mutable(&client->blur_manager->events.new_blur, blur);
+}
+
+static void
+blur_manager_handle_destroy(struct wl_client *wl_client,
+        struct wl_resource *resource)
+{
+    wl_resource_destroy(resource);
+}
+
+static const struct wtz_blur_manager_interface blur_manager_impl =
+{
+    blur_manager_handle_destroy,
+    blur_manager_handle_get_blur,
+};
+
+static void
+blur_manager_client_handle_destroy(struct wl_resource *resource)
+{
+    struct ds_tizen_blur_client *client;
+
+    client = wl_resource_get_user_data(resource);
+
+    ds_inf("blur_manager_client_handle_destroy (client:%p)", client);
+
+    wl_list_remove(&client->link);
+    free(client);
+}
+
+static void
+blur_manager_bind(struct wl_client *wl_client, void *data, uint32_t version,
+        uint32_t id)
+{
+    struct ds_tizen_blur_manager *blur_manager = data;
+    struct ds_tizen_blur_client *client;
+
+    client = calloc(1, sizeof *client);
+    if (client == NULL) {
+        ds_err("calloc() failed. tizen_blur");
+        wl_client_post_no_memory(wl_client);
+        return;
+    }
+
+    ds_inf("tizen_blur_client binds. (client:%p)", client);
+
+    client->blur_manager = blur_manager;
+    client->wl_client = wl_client;
+
+    client->resource = wl_resource_create(wl_client, &wtz_blur_manager_interface,
+            MIN(version, TIZEN_BLUR_VERSION), id);
+    if (client->resource == NULL) {
+        ds_err("tizen_blur : wl_resource_create() failed.");
+        free(client);
+        wl_client_post_no_memory(wl_client);
+        return;
+    }
+
+    wl_resource_set_implementation(client->resource, &blur_manager_impl, client,
+            blur_manager_client_handle_destroy);
+
+    wl_signal_init(&client->events.destroy);
+
+    wl_list_insert(&blur_manager->clients, &client->link);
+}
index 4a3a6b5..2e0d09d 100644 (file)
@@ -90,6 +90,7 @@ libds_tizen_files = [
   'display_policy/display_policy.c',
   'screen/screen.c',
   'blender/blender.c',
+  'blur/blur.c',
 ]
 
 libds_tizen_deps = [
@@ -115,6 +116,7 @@ libds_tizen_deps = [
   dependency('xkbcommon', required: true),
   dependency('wtz-screen-server', required: true),
   dependency('wtz-blender-server', required: true),
+  dependency('wtz-blur-server', required: true),
   dependency('pixman-1', required: true),
 ]
 
@@ -132,6 +134,7 @@ lib_libds_tizen = shared_library('ds-tizen', libds_tizen_files,
                          include_directories('./tbm_server'),
                          include_directories('./video'),
                          include_directories('./blender'),
+                         include_directories('./blur'),
                        ],
   version: meson.project_version(),
   c_args: [ '-DKEYLAYOUT_DIR="@0@"'.format(keylayout_dir) ],