e_blur: Support ds_tizen_blur_behind 21/317121/1
authorChangyeon Lee <cyeon.lee@samsung.com>
Wed, 28 Aug 2024 08:04:01 +0000 (17:04 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Wed, 4 Sep 2024 07:46:20 +0000 (16:46 +0900)
Change-Id: Ieb798c460cece1a411badb7a4a30baf0e668bc64

src/bin/displaymgr/e_hwc_window.c
src/bin/server/e_blur.c
src/bin/server/e_blur_intern.h
src/bin/server/e_blur_video_capture.c

index edad9b7..e90771d 100644 (file)
@@ -1452,10 +1452,11 @@ _e_hwc_window_cb_pixmap_buffer_clear_done(void *data EINA_UNUSED, E_Pixmap *cp)
 }
 
 static void
-_e_hwc_window_cb_blur_set(void *data, E_Blur *blur)
+_e_hwc_window_cb_blur_set(void *data, E_Blur_Hook_Data *hook_data)
 {
    E_Client *ec;
    E_Hwc_Window *hwc_window;
+   E_Blur *blur = hook_data->blur;
 
    ec = e_blur_client_get(blur);
    if (!ec) return;
@@ -1467,10 +1468,11 @@ _e_hwc_window_cb_blur_set(void *data, E_Blur *blur)
 }
 
 static void
-_e_hwc_window_cb_blur_unset(void *data, E_Blur *blur)
+_e_hwc_window_cb_blur_unset(void *data, E_Blur_Hook_Data *hook_data)
 {
    E_Client *ec;
    E_Hwc_Window *hwc_window;
+   E_Blur *blur = hook_data->blur;
 
    ec = e_blur_client_get(blur);
    if (!ec) return;
@@ -1481,6 +1483,38 @@ _e_hwc_window_cb_blur_unset(void *data, E_Blur *blur)
    e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
 }
 
+static void
+_e_hwc_window_cb_blur_behind_set(void *data, E_Blur_Hook_Data *hook_data)
+{
+   E_Client *ec;
+   E_Hwc_Window *hwc_window;
+   E_Blur_Behind *blur_behind = hook_data->blur_behind;
+
+   ec = e_blur_behind_client_get(blur_behind);
+   if (!ec) return;
+
+   hwc_window = ec->hwc_window;
+   if (!hwc_window) return;
+
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+}
+
+static void
+_e_hwc_window_cb_blur_behind_unset(void *data, E_Blur_Hook_Data *hook_data)
+{
+   E_Client *ec;
+   E_Hwc_Window *hwc_window;
+   E_Blur_Behind *blur_behind = hook_data->blur_behind;
+
+   ec = e_blur_behind_client_get(blur_behind);
+   if (!ec) return;
+
+   hwc_window = ec->hwc_window;
+   if (!hwc_window) return;
+
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+}
+
 EINTERN Eina_Bool
 e_hwc_window_init(void)
 {
@@ -1512,7 +1546,10 @@ e_hwc_window_init(void)
                       _e_hwc_window_cb_blur_set, NULL);
    E_BLUR_HOOK_APPEND(hwc_window_blur_hooks, E_BLUR_HOOK_UNSET,
                       _e_hwc_window_cb_blur_unset, NULL);
-
+   E_BLUR_HOOK_APPEND(hwc_window_blur_hooks, E_BLUR_HOOK_BEHIND_SET,
+                      _e_hwc_window_cb_blur_behind_set, NULL);
+   E_BLUR_HOOK_APPEND(hwc_window_blur_hooks, E_BLUR_HOOK_BEHIND_UNSET,
+                      _e_hwc_window_cb_blur_behind_unset, NULL);
    return EINA_TRUE;
 }
 
index 2bf1933..03400c5 100644 (file)
@@ -24,12 +24,15 @@ struct _E_Blur_Manager
    struct {
       struct wl_listener destroy;
       struct wl_listener new_blur;
+      struct wl_listener new_blur_behind;
    } listener;
 
    Eina_Bool video_capture_enabled;
    Eina_Bool blur_enabled;
+   Eina_Bool blur_behind_enabled;
 
    Eina_List *blurs;
+   Eina_List *blurs_behind;
 };
 
 struct _E_Blur
@@ -37,7 +40,7 @@ struct _E_Blur
    struct ds_tizen_blur *tizen_blur;
 
    struct {
-      struct wl_listener surface_commit;
+      struct wl_listener commit;
       struct wl_listener destroy;
       struct wl_listener new_rectangle;
    } listener;
@@ -67,6 +70,24 @@ struct _E_Blur_Rectangle
    Evas_Object *obj;
 };
 
+struct _E_Blur_Behind
+{
+   struct ds_tizen_blur_behind *tizen_blur_behind;
+
+   struct {
+      struct wl_listener commit;
+      struct wl_listener destroy;
+   } listener;
+
+   E_Client *ec;
+   E_Object_Delfn *ec_delfn;
+
+   uint32_t radius;
+   Evas_Object *obj;
+
+   Eina_Bool enabled;
+};
+
 static int _e_blur_hooks_delete = 0;
 static int _e_blur_hooks_walking = 0;
 
@@ -75,12 +96,16 @@ static Eina_Inlist *_e_blur_hooks[] =
    [E_BLUR_HOOK_SET] = NULL,
    [E_BLUR_HOOK_UNSET] = NULL,
    [E_BLUR_HOOK_RECTANGLE_CREATE] = NULL,
+   [E_BLUR_HOOK_BEHIND_CREATE] = NULL,
+   [E_BLUR_HOOK_BEHIND_SET] = NULL,
+   [E_BLUR_HOOK_BEHIND_UNSET] = NULL,
 };
 
 static E_Blur_Manager *_blur_manager = NULL;
 static Eina_Bool blur_trace = EINA_FALSE;
 
 static void _e_blur_ec_set(E_Blur *blur, E_Client *ec);
+static void _e_blur_behind_ec_set(E_Blur_Behind *blur, E_Client *ec);
 
 static void
 _e_blur_hooks_clean(void)
@@ -100,7 +125,7 @@ _e_blur_hooks_clean(void)
 }
 
 static void
-_e_blur_hook_call(E_Blur_Hook_Point hookpoint, E_Blur *blur)
+_e_blur_hook_call(E_Blur_Hook_Point hookpoint, E_Blur_Hook_Data *hook_data)
 {
    E_Blur_Hook *ch;
 
@@ -108,7 +133,7 @@ _e_blur_hook_call(E_Blur_Hook_Point hookpoint, E_Blur *blur)
    EINA_INLIST_FOREACH(_e_blur_hooks[hookpoint], ch)
      {
         if (ch->delete_me) continue;
-        ch->func(ch->data, blur);
+        ch->func(ch->data, hook_data);
      }
    _e_blur_hooks_walking--;
    if ((_e_blur_hooks_walking == 0) && (_e_blur_hooks_delete > 0))
@@ -128,56 +153,67 @@ _e_blur_manager_blur_enabled_changed(Eina_Bool set)
    E_Blur *blur;
    Eina_List *l;
 
-   if (set)
-     {
-        if (blur_manager->blur_enabled == set)
-          return;
+   if (blur_manager->blur_enabled == set)
+     return;
 
-        if (!blur_manager->video_capture_enabled)
-          e_video_debug_display_primary_plane_set(EINA_TRUE);
-     }
-   else
+   if (!set)
      {
         EINA_LIST_FOREACH(blur_manager->blurs, l, blur)
           {
              if (_e_blur_enabled_get(blur))
                return;
           }
-
-        if (blur_manager->blur_enabled == set)
-          return;
-
-        if (!blur_manager->video_capture_enabled)
-          e_video_debug_display_primary_plane_set(EINA_FALSE);
      }
 
    blur_manager->blur_enabled = set;
+
+   if (blur_manager->video_capture_enabled)
+     return;
+
+   if (blur_manager->blur_enabled || blur_manager->blur_behind_enabled)
+     e_video_debug_display_primary_plane_set(EINA_TRUE);
+   else
+     e_video_debug_display_primary_plane_set(EINA_FALSE);
 }
 
 static void
 _e_blur_enabled_set(E_Blur *blur, Eina_Bool set)
 {
+   E_Blur_Hook_Data hook_data = { .blur = blur };
+
    if (blur->enabled == set) return;
 
    blur->enabled = set;
 
    if (set)
-     _e_blur_hook_call(E_BLUR_HOOK_SET, blur);
+     _e_blur_hook_call(E_BLUR_HOOK_SET, &hook_data);
    else
-     _e_blur_hook_call(E_BLUR_HOOK_UNSET, blur);
+     _e_blur_hook_call(E_BLUR_HOOK_UNSET, &hook_data);
 
    _e_blur_manager_blur_enabled_changed(set);
 }
 
 static void
-_e_blur_rectangle_free(E_Blur_Rectangle *blur_rectangle)
+_e_blur_rectangle_add(E_Blur *blur, E_Blur_Rectangle *blur_rectangle)
 {
-   E_Blur *blur;
+   blur->blur_rectangles = eina_list_append(blur->blur_rectangles, blur_rectangle);
+}
+
+static void
+_e_blur_rectangle_remove(E_Blur *blur, E_Blur_Rectangle *blur_rectangle)
+{
+   blur->blur_rectangles = eina_list_remove(blur->blur_rectangles, blur_rectangle);
+
+   if (!eina_list_count(blur->blur_rectangles))
+     _e_blur_enabled_set(blur, EINA_FALSE);
+}
 
+static void
+_e_blur_rectangle_free(E_Blur_Rectangle *blur_rectangle)
+{
    ELOGF("E_BLUR", "E_Blur_Rectangle:%p Free", NULL, blur_rectangle);
 
-   blur = blur_rectangle->blur;
-   blur->blur_rectangles = eina_list_remove(blur->blur_rectangles, blur_rectangle);
+   _e_blur_rectangle_remove(blur_rectangle->blur, blur_rectangle);
 
    evas_object_del(blur_rectangle->obj);
 
@@ -267,10 +303,10 @@ _e_blur_cb_ds_tizen_blur_commit(struct wl_listener *listener, void *data)
    E_Blur *blur;
    E_Blur_Rectangle *blur_rectangle;
    Eina_List *l;
-   struct ds_tizen_blur_state *state;
+   const struct ds_tizen_blur_state *state;
    Eina_Bool radius_changed = EINA_FALSE, rectangle_changed = EINA_FALSE;
 
-   blur = container_of(listener, E_Blur, listener.surface_commit);
+   blur = container_of(listener, E_Blur, listener.commit);
    if (!blur->ec) return;
 
    state = ds_tizen_blur_get_state(blur->tizen_blur);
@@ -281,6 +317,7 @@ _e_blur_cb_ds_tizen_blur_commit(struct wl_listener *listener, void *data)
      {
         blur->radius = state->radius;
         radius_changed = EINA_TRUE;
+        ELOGF("E_BLUR", "E_Blur:%p Radius:%d changed", NULL, blur, blur->radius);
      }
 
    if (state->committed & DS_TIZEN_BLUR_STATE_RECTANGLE)
@@ -458,6 +495,7 @@ _e_blur_rectangle_cb_ds_tizen_blur_rectangle_destroy(struct wl_listener *listene
 {
    E_Blur_Rectangle *blur_rectangle;
    E_Blur *blur;
+   E_Blur_Hook_Data hook_data;
 
    blur_rectangle = wl_container_of(listener, blur_rectangle, listener.destroy);
    blur = blur_rectangle->blur;
@@ -465,7 +503,10 @@ _e_blur_rectangle_cb_ds_tizen_blur_rectangle_destroy(struct wl_listener *listene
    _e_blur_rectangle_free(blur_rectangle);
 
    if (!eina_list_count(blur->blur_rectangles))
-     _e_blur_hook_call(E_BLUR_HOOK_UNSET, blur);
+     {
+        hook_data.blur = blur;
+        _e_blur_hook_call(E_BLUR_HOOK_UNSET, &hook_data);
+     }
 }
 
 static void
@@ -475,6 +516,7 @@ _e_blur_cb_new_rectangle(struct wl_listener *listener, void *data)
    E_Blur_Rectangle *blur_rectangle;
    struct ds_tizen_blur_rectangle *tizen_blur_rectangle = data;
    Evas_Object *obj;
+   E_Blur_Hook_Data hook_data;
 
    blur = wl_container_of(listener, blur, listener.new_rectangle);
    EINA_SAFETY_ON_NULL_RETURN(blur);
@@ -500,13 +542,11 @@ _e_blur_cb_new_rectangle(struct wl_listener *listener, void *data)
    ds_tizen_blur_rectangle_add_destroy_listener(tizen_blur_rectangle, &blur_rectangle->listener.destroy);
    blur_rectangle->tizen_blur_rectangle = tizen_blur_rectangle;
 
-   evas_object_image_snapshot_set(obj, EINA_TRUE);
-   evas_object_name_set(obj, "blur_obj");
    blur_rectangle->obj = obj;
-
+   evas_object_image_snapshot_set(blur_rectangle->obj, EINA_TRUE);
+   evas_object_name_set(blur_rectangle->obj, "blur_obj");
    blur_rectangle->blur = blur;
-   blur->blur_rectangles = eina_list_append(blur->blur_rectangles, blur_rectangle);
-
+   _e_blur_rectangle_add(blur, blur_rectangle);
    _e_blur_rectangle_filter_set(blur_rectangle);
    _e_blur_rectangle_geometry_set(blur_rectangle, blur->ec);
    evas_object_layer_set(blur_rectangle->obj, evas_object_layer_get(blur->ec->frame));
@@ -517,7 +557,8 @@ _e_blur_cb_new_rectangle(struct wl_listener *listener, void *data)
 
    ELOGF("E_BLUR", "E_Blur_Rectangle:%p Create", blur->ec, blur_rectangle);
 
-   _e_blur_hook_call(E_BLUR_HOOK_RECTANGLE_CREATE, blur);
+   hook_data.blur_rectangle = blur_rectangle;
+   _e_blur_hook_call(E_BLUR_HOOK_RECTANGLE_CREATE, &hook_data);
 }
 
 static void
@@ -551,8 +592,8 @@ _e_blur_manager_cb_new_blur(struct wl_listener *listener, void *data)
    blur->listener.destroy.notify = _e_blur_cb_ds_tizen_blur_destroy;
    ds_tizen_blur_add_destroy_listener(tizen_blur, &blur->listener.destroy);
 
-   blur->listener.surface_commit.notify = _e_blur_cb_ds_tizen_blur_commit;
-   ds_tizen_blur_add_commit_listener(tizen_blur, &blur->listener.surface_commit);
+   blur->listener.commit.notify = _e_blur_cb_ds_tizen_blur_commit;
+   ds_tizen_blur_add_commit_listener(tizen_blur, &blur->listener.commit);
 
    blur->tizen_blur = tizen_blur;
 
@@ -568,6 +609,288 @@ _e_blur_manager_cb_new_blur(struct wl_listener *listener, void *data)
    return;
 }
 
+static Eina_Bool
+_e_blur_behind_enabled_get(E_Blur_Behind *blur_behind)
+{
+   return blur_behind->enabled;
+}
+
+static void
+_e_blur_manager_blur_behind_enabled_changed(Eina_Bool set)
+{
+   E_Blur_Manager *blur_manager = _blur_manager;
+   E_Blur_Behind *blur_behind;
+   Eina_List *l;
+
+   if (blur_manager->blur_behind_enabled == set)
+     return;
+
+   if (!set)
+     {
+        EINA_LIST_FOREACH(blur_manager->blurs_behind, l, blur_behind)
+          {
+             if (_e_blur_behind_enabled_get(blur_behind))
+               return;
+          }
+     }
+
+   blur_manager->blur_behind_enabled = set;
+
+   if (blur_manager->video_capture_enabled)
+     return;
+
+   if (blur_manager->blur_enabled || blur_manager->blur_behind_enabled)
+     e_video_debug_display_primary_plane_set(EINA_TRUE);
+   else
+     e_video_debug_display_primary_plane_set(EINA_FALSE);
+}
+
+static void
+_e_blur_behind_enabled_set(E_Blur_Behind *blur_behind, Eina_Bool set)
+{
+   E_Blur_Hook_Data hook_data = { .blur_behind = blur_behind };
+
+   if (blur_behind->enabled == set) return;
+
+   blur_behind->enabled = set;
+
+   if (set)
+     _e_blur_hook_call(E_BLUR_HOOK_BEHIND_SET, &hook_data);
+   else
+     _e_blur_hook_call(E_BLUR_HOOK_BEHIND_UNSET, &hook_data);
+
+   _e_blur_manager_blur_behind_enabled_changed(set);
+}
+
+static void
+_e_blur_behind_free(E_Blur_Behind *blur_behind)
+{
+   ELOGF("E_BLUR", "E_Blur_Behind:%p Free", blur_behind->ec, blur_behind);
+
+   _e_blur_behind_ec_set(blur_behind, NULL);
+   evas_object_del(blur_behind->obj);
+   _e_blur_behind_enabled_set(blur_behind, EINA_FALSE);
+
+   free(blur_behind);
+}
+
+static void
+_e_blur_behind_cb_ds_tizen_blur_behind_destroy(struct wl_listener *listener, void *data)
+{
+   E_Blur_Behind *blur_behind;
+   E_Blur_Manager *blur_manager = _blur_manager;
+
+   blur_behind = wl_container_of(listener, blur_behind, listener.destroy);
+
+   if (blur_manager)
+      blur_manager->blurs_behind = eina_list_remove(blur_manager->blurs, blur_behind);
+
+   _e_blur_behind_free(blur_behind);
+}
+
+static void
+_e_blur_behind_filter_set(E_Blur_Behind *blur_behind)
+{
+   char program[256];
+
+   snprintf(program, sizeof(program), "blur (%d) padding_set (0)", blur_behind->radius);
+
+   efl_gfx_filter_program_set(blur_behind->obj, program, "image_filter");
+}
+
+static void
+_e_blur_behind_cb_ds_tizen_blur_behind_commit(struct wl_listener *listener, void *data)
+{
+   E_Blur_Behind *blur_behind;
+   const struct ds_tizen_blur_behind_state *state;
+   Eina_Bool radius_changed = EINA_FALSE;
+
+   blur_behind = container_of(listener, E_Blur_Behind, listener.commit);
+   if (!blur_behind->ec) return;
+
+   state = ds_tizen_blur_behind_get_state(blur_behind->tizen_blur_behind);
+   if (!state) return;
+
+   if ((state->committed & DS_TIZEN_BLUR_BEHIND_STATE_RADIUS) &&
+       (blur_behind->radius != state->radius))
+     {
+        blur_behind->radius = state->radius;
+        radius_changed = EINA_TRUE;
+        ELOGF("E_BLUR", "E_Blur_Behind:%p Radius:%d changed", NULL, blur_behind, blur_behind->radius);
+     }
+
+   if (!radius_changed)
+     return;
+
+   if (blur_behind->radius)
+     {
+         _e_blur_behind_filter_set(blur_behind);
+        if (!evas_object_visible_get(blur_behind->ec->frame))
+          evas_object_show(blur_behind->obj);
+
+        _e_blur_behind_enabled_set(blur_behind, EINA_TRUE);
+     }
+   else
+     {
+        evas_object_hide(blur_behind->obj);
+
+        _e_blur_behind_enabled_set(blur_behind, EINA_FALSE);
+     }
+}
+
+static Evas_Object *
+_e_blur_behind_bottom_object_get(Evas_Object *obj)
+{
+   Evas_Object *below_obj, *bottom_obj = obj;
+
+   below_obj = evas_object_below_get(bottom_obj);
+   while (!e_util_strcmp(evas_object_name_get(below_obj), "blur_obj"))
+     {
+        bottom_obj = below_obj;
+        below_obj = evas_object_below_get(bottom_obj);
+     }
+
+   return bottom_obj;
+}
+
+static void
+_e_blur_behind_evas_cb_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+   E_Blur_Behind *blur_behind;
+
+   if (!(blur_behind = data)) return;
+   if (!_e_blur_behind_enabled_get(blur_behind)) return;
+
+   evas_object_show(blur_behind->obj);
+}
+
+static void
+_e_blur_behind_evas_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+   E_Blur_Behind *blur_behind;
+
+   if (!(blur_behind = data)) return;
+
+   evas_object_hide(blur_behind->obj);
+}
+
+static void
+_e_blur_behind_evas_cb_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   E_Blur_Behind *blur_behind;
+
+   if (!(blur_behind = data)) return;
+
+   evas_object_layer_set(blur_behind->obj, evas_object_layer_get(obj));
+   evas_object_stack_below(blur_behind->obj, _e_blur_behind_bottom_object_get(obj));
+}
+
+static void
+_e_blur_behind_cb_ec_free(void *data, void *obj)
+{
+   E_Blur_Behind *blur_behind = data;
+
+   blur_behind->ec_delfn = NULL;
+   _e_blur_behind_ec_set(blur_behind, NULL);
+}
+
+static void
+_e_blur_behind_ec_set(E_Blur_Behind *blur_behind, E_Client *ec)
+{
+   if (blur_behind->ec == ec) return;
+
+   if (blur_behind->ec)
+     {
+        evas_object_event_callback_del(blur_behind->ec->frame, EVAS_CALLBACK_SHOW,
+                                      _e_blur_behind_evas_cb_show);
+        evas_object_event_callback_del(blur_behind->ec->frame, EVAS_CALLBACK_HIDE,
+                                      _e_blur_behind_evas_cb_hide);
+        evas_object_event_callback_del(blur_behind->ec->frame, EVAS_CALLBACK_RESTACK,
+                                      _e_blur_behind_evas_cb_restack);
+
+        if (blur_behind->ec_delfn)
+          {
+             e_object_delfn_del(E_OBJECT(blur_behind->ec), blur_behind->ec_delfn);
+             blur_behind->ec_delfn = NULL;
+          }
+
+        blur_behind->ec = NULL;
+     }
+
+   if (ec)
+     {
+        evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW,
+                                       _e_blur_behind_evas_cb_show, blur_behind);
+        evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE,
+                                       _e_blur_behind_evas_cb_hide, blur_behind);
+        evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESTACK,
+                                       _e_blur_behind_evas_cb_restack, blur_behind);
+
+        blur_behind->ec_delfn = e_object_delfn_add(E_OBJECT(ec),
+                                                   _e_blur_behind_cb_ec_free,
+                                                   blur_behind);
+        blur_behind->ec = ec;
+     }
+}
+
+static void
+_e_blur_manager_cb_new_blur_behind(struct wl_listener *listener, void *data)
+{
+   E_Blur_Behind *blur_behind;
+   E_Blur_Manager *blur_manager = _blur_manager;
+   struct ds_tizen_blur_behind *tizen_blur_behind = data;
+   struct ds_surface *surface;
+   struct wl_resource *surface_resource;
+   E_Client *ec;
+   Evas_Object *obj;
+   E_Blur_Hook_Data hook_data;
+
+   if (!blur_manager)
+     {
+        ERR("blur is not initialized");
+        return;
+     }
+
+   surface = ds_tizen_blur_behind_get_surface(tizen_blur_behind);
+   EINA_SAFETY_ON_NULL_RETURN(surface);
+
+   surface_resource = ds_surface_get_wl_resource(surface);
+   EINA_SAFETY_ON_NULL_RETURN(surface_resource);
+
+   ec = e_client_from_surface_resource(surface_resource);
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   obj = evas_object_image_filled_add(e_comp->evas);
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+
+   blur_behind = E_NEW(E_Blur_Behind, 1);
+   EINA_SAFETY_ON_NULL_RETURN(blur_behind);
+
+   blur_behind->listener.destroy.notify = _e_blur_behind_cb_ds_tizen_blur_behind_destroy;
+   ds_tizen_blur_behind_add_destroy_listener(tizen_blur_behind, &blur_behind->listener.destroy);
+
+   blur_behind->listener.commit.notify = _e_blur_behind_cb_ds_tizen_blur_behind_commit;
+   ds_tizen_blur_behind_add_commit_listener(tizen_blur_behind, &blur_behind->listener.commit);
+
+   blur_behind->tizen_blur_behind = tizen_blur_behind;
+
+   _e_blur_behind_ec_set(blur_behind, ec);
+
+   blur_behind->obj = obj;
+   evas_object_image_snapshot_set(blur_behind->obj, EINA_TRUE);
+   evas_object_name_set(blur_behind->obj, "blur_obj");
+   evas_object_geometry_set(blur_behind->obj, 0, 0, e_comp->w, e_comp->h);
+   evas_object_layer_set(blur_behind->obj, evas_object_layer_get(ec->frame));
+   evas_object_stack_below(blur_behind->obj, _e_blur_behind_bottom_object_get(ec->frame));
+
+   blur_manager->blurs_behind = eina_list_append(blur_manager->blurs_behind, blur_behind);
+
+   ELOGF("E_BLUR", "E_Blur_Behind:%p Create", ec, blur_behind);
+
+   hook_data.blur_behind = blur_behind;
+   _e_blur_hook_call(E_BLUR_HOOK_BEHIND_CREATE, &hook_data);
+}
+
 static void
 _e_blur_manager_cb_destroy(struct wl_listener *listener, void *data)
 {
@@ -607,6 +930,10 @@ e_blur_manager_init(void)
    ds_tizen_blur_manager_add_new_blur_listener(blur_manager->tizen_blur_manager,
                                                &blur_manager->listener.new_blur);
 
+   blur_manager->listener.new_blur_behind.notify = _e_blur_manager_cb_new_blur_behind;
+   ds_tizen_blur_manager_add_new_blur_behind_listener(blur_manager->tizen_blur_manager,
+                                                      &blur_manager->listener.new_blur_behind);
+
    if (conf->blur_video_capture)
      {
         e_blur_video_capture_init();
@@ -684,6 +1011,16 @@ e_blur_manager_blurs_get(void)
    return blur_manager->blurs;
 }
 
+EINTERN Eina_List *
+e_blur_manager_blurs_behind_get(void)
+{
+   E_Blur_Manager *blur_manager = _blur_manager;
+
+   if (!_blur_manager) return NULL;
+
+   return blur_manager->blurs_behind;
+}
+
 EINTERN Evas_Object *
 e_blur_rectangle_object_get(E_Blur_Rectangle *blur_rectangle)
 {
@@ -701,6 +1038,22 @@ e_blur_rectangle_corner_radius_get(E_Blur_Rectangle *blur_rectangle, int *rx, in
    if (ry) *ry = blur_rectangle->ry;
 }
 
+EINTERN E_Client *
+e_blur_behind_client_get(E_Blur_Behind *blur_behind)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(blur_behind, NULL);
+
+   return blur_behind->ec;
+}
+
+EINTERN Evas_Object *
+e_blur_behind_object_get(E_Blur_Behind *blur_behind)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(blur_behind, NULL);
+
+   return blur_behind->obj;
+}
+
 EINTERN void
 e_blur_trace_debug(Eina_Bool onoff)
 {
index 4ae88e6..f14e403 100644 (file)
 typedef struct _E_Blur E_Blur;
 typedef struct _E_Blur_Rectangle E_Blur_Rectangle;
 typedef struct _E_Blur_Hook E_Blur_Hook;
-typedef void (*E_Blur_Hook_Cb) (void *data, E_Blur *blur);
+typedef struct _E_Blur_Behind E_Blur_Behind;
+typedef struct _E_Blur_Hook_Data E_Blur_Hook_Data;
+
+typedef void (*E_Blur_Hook_Cb) (void *data, E_Blur_Hook_Data *hook_data);
 
 typedef enum _E_Blur_Hook_Point
 {
    E_BLUR_HOOK_SET,
    E_BLUR_HOOK_UNSET,
    E_BLUR_HOOK_RECTANGLE_CREATE,
+   E_BLUR_HOOK_BEHIND_CREATE,
+   E_BLUR_HOOK_BEHIND_SET,
+   E_BLUR_HOOK_BEHIND_UNSET,
    E_BLUR_HOOK_LAST
 } E_Blur_Hook_Point;
 
@@ -35,15 +41,26 @@ struct _E_Blur_Hook
    unsigned char delete_me : 1;
 };
 
+struct _E_Blur_Hook_Data
+{
+   E_Blur *blur;
+   E_Blur_Rectangle *blur_rectangle;
+
+   E_Blur_Behind *blur_behind;
+};
+
 EINTERN Eina_Bool e_blur_manager_init(void);
 EINTERN void e_blur_manager_shutdown(void);
 EINTERN Eina_List *e_blur_manager_blurs_get(void);
+EINTERN Eina_List *e_blur_manager_blurs_behind_get(void);
 EINTERN E_Client *e_blur_client_get(E_Blur *blur);
 EINTERN Eina_List *e_blur_rectangles_get(E_Blur *blur);
 EINTERN Evas_Object *e_blur_rectangle_object_get(E_Blur_Rectangle *blur_rectangle);
+EINTERN void e_blur_rectangle_corner_radius_get(E_Blur_Rectangle *blur_rectangle, int *rx, int *ry);
+EINTERN E_Client *e_blur_behind_client_get(E_Blur_Behind *blur_behind);
+EINTERN Evas_Object *e_blur_behind_object_get(E_Blur_Behind *blur_behind);
+EINTERN void e_blur_trace_debug(Eina_Bool onoff);
 EINTERN E_Blur_Hook *e_blur_hook_add(E_Blur_Hook_Point hookpoint, E_Blur_Hook_Cb func, const void *data);
 EINTERN void e_blur_hook_del(E_Blur_Hook *ch);
-EINTERN void e_blur_trace_debug(Eina_Bool onoff);
-EINTERN void e_blur_rectangle_corner_radius_get(E_Blur_Rectangle *blur_rectangle, int *rx, int *ry);
 
 #endif // E_BLUR_INTERN_H
index 508fe52..6f9d165 100644 (file)
@@ -21,6 +21,13 @@ typedef struct _E_Blur_Video_Capture E_Blur_Video_Capture;
 typedef struct _E_Blur_Video_Capture_Client E_Blur_Video_Capture_Client;
 typedef struct _E_Blur_Video_Capture_Object E_Blur_Video_Capture_Object;
 
+typedef enum
+{
+   E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_NONE = 0,
+   E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_RECTANGLE = 1,
+   E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_BEHIND = 2,
+} E_Blur_Video_Capture_Object_Type;
+
 struct _E_Blur_Video_Capture
 {
    int width, height, fps;
@@ -53,15 +60,16 @@ struct _E_Blur_Video_Capture_Client
 struct _E_Blur_Video_Capture_Object
 {
    E_Blur_Video_Capture_Client *client;
-   E_Blur_Rectangle *blur_rectangle;
 
-   Evas_Object *blur_rectangle_obj;
+   Evas_Object *blur_obj;
 
    Evas_Object *blur_clip_obj;
    Evas_Object *source_clip_obj;
    Evas_Object *source_obj;
 
    Eina_Bool visible;
+
+   E_Blur_Video_Capture_Object_Type type;
 };
 
 typedef struct {
@@ -239,48 +247,44 @@ _e_blur_video_capture_object_evas_cb_move(void *data, Evas *e EINA_UNUSED, Evas_
 }
 
 static void
-_e_blur_video_capture_object_evas_cb_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+_e_blur_video_capture_object_evas_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
 {
    E_Blur_Video_Capture_Object *object;
 
    if (!(object = data)) return;
 
-   /* TODO:restack capture object */
+   _e_blur_video_capture_object_destroy(object);
+   _e_blur_video_capture_stop();
 }
 
-static void
-_e_blur_video_capture_object_evas_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+static Evas_Object *
+_e_blur_video_capture_topmost_object_get(Evas_Object *obj)
 {
-   E_Blur_Video_Capture_Object *object;
+   Evas_Object *above_obj, *topmost_obj = obj;
+   const char *name;
 
-   if (!(object = data)) return;
+   above_obj = evas_object_above_get(topmost_obj);
+   name = evas_object_name_get(above_obj);
+   while (name && strstr(name, "blur_video_capture"))
+     {
+        topmost_obj = above_obj;
+        above_obj = evas_object_above_get(topmost_obj);
+        name = evas_object_name_get(above_obj);
+     }
 
-   _e_blur_video_capture_object_destroy(object);
-   _e_blur_video_capture_stop();
+   return topmost_obj;
 }
 
 static E_Blur_Video_Capture_Object *
-_e_blur_video_capture_object_get(E_Blur_Video_Capture_Client *client, E_Blur_Rectangle *blur_rectangle)
+_e_blur_video_capture_object_create(E_Blur_Video_Capture_Client *client, Evas_Object *blur_obj,
+                                    E_Blur_Video_Capture_Object_Type type)
 {
    E_Blur_Video_Capture *video_capture = _video_capture;
-   Evas_Object *obj;
    E_Blur_Video_Capture_Object *object;
    int x, y, w, h;
-   Eina_List *l;
    unsigned int *pixels;
-   char program[256];
-   int rx = 0, ry = 0;
 
-   if (!blur_rectangle) return NULL;
-
-   EINA_LIST_FOREACH(client->capture_objs, l, object)
-     {
-        if (object->blur_rectangle == blur_rectangle)
-          return object;
-     }
-
-   obj = e_blur_rectangle_object_get(blur_rectangle);
-   if (!obj) return NULL;;
+   if (!blur_obj) return NULL;
 
    object = E_NEW(E_Blur_Video_Capture_Object, 1);
    EINA_SAFETY_ON_NULL_RETURN_VAL(object, NULL);
@@ -293,12 +297,6 @@ _e_blur_video_capture_object_get(E_Blur_Video_Capture_Client *client, E_Blur_Rec
    *pixels = 0xffffffff;
    evas_object_image_data_set(object->blur_clip_obj, pixels);
    evas_object_image_data_update_add(object->blur_clip_obj, 0, 0, 1, 1);
-   e_blur_rectangle_corner_radius_get(blur_rectangle, &rx, &ry);
-   if ((rx != 0) && (ry != 0))
-     {
-        snprintf(program, sizeof(program), "rounded_corner { rx = %d, ry = %d}", rx, ry);
-        efl_gfx_filter_program_set(object->blur_clip_obj, program, "rounded_corner");
-     }
    evas_object_name_set(object->blur_clip_obj, "blur_video_capture_blur_clip_obj");
    evas_object_pass_events_set(object->blur_clip_obj, EINA_TRUE);
 
@@ -315,23 +313,25 @@ _e_blur_video_capture_object_get(E_Blur_Video_Capture_Client *client, E_Blur_Rec
    if (_e_blur_video_capture_source_object_visible_get())
      evas_object_image_source_set(object->source_obj, video_capture->source_obj);
 
-   object->blur_rectangle_obj = obj;
-
-   evas_object_event_callback_add(object->blur_rectangle_obj, EVAS_CALLBACK_SHOW,
-                                 _e_blur_video_capture_object_evas_cb_show, object);
-   evas_object_event_callback_add(object->blur_rectangle_obj, EVAS_CALLBACK_HIDE,
-                                 _e_blur_video_capture_object_evas_cb_hide, object);
-   evas_object_event_callback_add(object->blur_rectangle_obj, EVAS_CALLBACK_RESIZE,
-                                 _e_blur_video_capture_object_evas_cb_resize, object);
-   evas_object_event_callback_add(object->blur_rectangle_obj, EVAS_CALLBACK_MOVE,
-                                 _e_blur_video_capture_object_evas_cb_move, object);
-   evas_object_event_callback_add(object->blur_rectangle_obj, EVAS_CALLBACK_RESTACK,
-                                 _e_blur_video_capture_object_evas_cb_restack, object);
-   evas_object_event_callback_add(object->blur_rectangle_obj, EVAS_CALLBACK_DEL,
-                                 _e_blur_video_capture_object_evas_cb_del, object);
+   object->blur_obj = blur_obj;
+
+   evas_object_event_callback_add(object->blur_obj, EVAS_CALLBACK_SHOW,
+                                  _e_blur_video_capture_object_evas_cb_show, object);
+   evas_object_event_callback_add(object->blur_obj, EVAS_CALLBACK_HIDE,
+                                  _e_blur_video_capture_object_evas_cb_hide, object);
+   evas_object_event_callback_add(object->blur_obj, EVAS_CALLBACK_RESIZE,
+                                  _e_blur_video_capture_object_evas_cb_resize, object);
+   evas_object_event_callback_add(object->blur_obj, EVAS_CALLBACK_MOVE,
+                                  _e_blur_video_capture_object_evas_cb_move, object);
+   evas_object_event_callback_add(object->blur_obj, EVAS_CALLBACK_DEL,
+                                  _e_blur_video_capture_object_evas_cb_del, object);
 
    evas_object_layer_set(object->blur_clip_obj, evas_object_layer_get(client->ec->frame));
-   evas_object_stack_above(object->blur_clip_obj, client->ec->frame);
+   if (type == E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_BEHIND)
+     evas_object_stack_above(object->blur_clip_obj,
+                             _e_blur_video_capture_topmost_object_get(client->ec->frame));
+   else
+     evas_object_stack_above(object->blur_clip_obj, client->ec->frame);
 
    evas_object_layer_set(object->source_clip_obj, evas_object_layer_get(client->ec->frame));
    evas_object_stack_below(object->source_clip_obj, object->blur_clip_obj);
@@ -339,7 +339,7 @@ _e_blur_video_capture_object_get(E_Blur_Video_Capture_Client *client, E_Blur_Rec
    evas_object_layer_set(object->source_obj, evas_object_layer_get(client->ec->frame));
    evas_object_stack_below(object->source_obj, object->source_clip_obj);
 
-   evas_object_geometry_get(object->blur_rectangle_obj, &x, &y, &w, &h);
+   evas_object_geometry_get(object->blur_obj, &x, &y, &w, &h);
    evas_object_geometry_set(object->blur_clip_obj, x, y, w, h);
 
    e_client_geometry_get(client->ec, &x, &y, &w, &h);
@@ -350,11 +350,11 @@ _e_blur_video_capture_object_get(E_Blur_Video_Capture_Client *client, E_Blur_Rec
    evas_object_clip_set(object->source_obj, object->source_clip_obj);
    evas_object_clip_set(object->source_clip_obj, object->blur_clip_obj);
 
-   object->blur_rectangle = blur_rectangle;
+   object->type = type;
    object->client = client;
    client->capture_objs = eina_list_append(client->capture_objs, object);
 
-   ELOGF("E_BLUR", "Create Video_Capture_Object:%p", client->ec, object);
+   ELOGF("E_BLUR", "Create Video_Capture_Object:%p type:%d", client->ec, object, object->type);
 
    return object;
 
@@ -490,7 +490,7 @@ _e_blur_video_capture_thread_run_notify_cb(void *data, Ecore_Thread *thread, voi
 
              EINA_LIST_FOREACH(client->capture_objs, l2, object)
                {
-                  if (!evas_object_visible_get(object->blur_rectangle_obj)) continue;
+                  if (!evas_object_visible_get(object->blur_obj)) continue;
 
                   _e_blur_video_capture_object_show(object);
                }
@@ -540,7 +540,7 @@ _e_blur_video_capture_visible_get()
 
         EINA_LIST_FOREACH(client->capture_objs, l2, object)
           {
-             if (evas_object_visible_get(object->blur_rectangle_obj))
+             if (evas_object_visible_get(object->blur_obj))
                return EINA_TRUE;
           }
      }
@@ -622,35 +622,110 @@ _e_blur_video_capture_stop(void)
    return EINA_TRUE;
 }
 
+static E_Blur_Video_Capture_Object *
+_e_blur_video_capture_client_object_find(E_Blur_Video_Capture_Client *client, Evas_Object *blur_obj)
+{
+   E_Blur_Video_Capture_Object *object;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(client->capture_objs, l, object)
+     {
+        if (object->blur_obj == blur_obj)
+          return object;
+     }
+
+   return NULL;
+}
+
+static void
+_e_blur_video_capture_client_object_rectangle_init(E_Blur_Video_Capture_Client *client, E_Blur_Rectangle *blur_rectangle)
+{
+   E_Blur_Video_Capture_Object *object;
+   Evas_Object *blur_obj;
+   int rx = 0, ry = 0;
+   char program[256];
+
+   blur_obj = e_blur_rectangle_object_get(blur_rectangle);
+   EINA_SAFETY_ON_NULL_RETURN(blur_obj);
+
+   object = _e_blur_video_capture_client_object_find(client, blur_obj);
+   if (!object)
+     {
+        object = _e_blur_video_capture_object_create(client, blur_obj,
+                                                     E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_RECTANGLE);
+        EINA_SAFETY_ON_NULL_RETURN(object);
+
+        e_blur_rectangle_corner_radius_get(blur_rectangle, &rx, &ry);
+        if ((rx != 0) && (ry != 0))
+          {
+             snprintf(program, sizeof(program), "rounded_corner { rx = %d, ry = %d}", rx, ry);
+             efl_gfx_filter_program_set(object->blur_clip_obj, program, "rounded_corner");
+          }
+     }
+
+   if (!client->presentation_visible) return;
+   if (!evas_object_visible_get(object->blur_obj)) return;
+   if (_e_blur_video_capture_source_object_visible_get()) return;
+
+   _e_blur_video_capture_object_show(object);
+}
+
+static void
+_e_blur_video_capture_client_object_behind_init(E_Blur_Video_Capture_Client *client, E_Blur_Behind *blur_behind)
+{
+   E_Blur_Video_Capture_Object *object;
+   Evas_Object *blur_obj;
+
+   blur_obj = e_blur_behind_object_get(blur_behind);
+   EINA_SAFETY_ON_NULL_RETURN(blur_obj);
+
+   object = _e_blur_video_capture_client_object_find(client, blur_obj);
+   if (!object)
+     {
+        object = _e_blur_video_capture_object_create(client, blur_obj,
+                                                     E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_BEHIND);
+        EINA_SAFETY_ON_NULL_RETURN(object);
+     }
+
+   if (!client->presentation_visible) return;
+   if (!evas_object_visible_get(object->blur_obj)) return;
+   if (_e_blur_video_capture_source_object_visible_get()) return;
+
+   _e_blur_video_capture_object_show(object);
+}
+
 static void
-_e_blur_video_capture_cb_rectangle_create(void *data, E_Blur *blur)
+_e_blur_video_capture_cb_blur_rectangle_create(void *data, E_Blur_Hook_Data *hook_data)
 {
    E_Blur_Video_Capture *video_capture = _video_capture;
    E_Blur_Video_Capture_Client *client;
-   E_Blur_Video_Capture_Object *object;
-   E_Blur_Rectangle *blur_rectangle;
-   Eina_List *blur_rectangles;
-   Eina_List *l, *l2;
+   E_Blur_Rectangle *blur_rectangle = hook_data->blur_rectangle;
+   Eina_List *l;
 
    EINA_SAFETY_ON_NULL_RETURN(video_capture->funcs);
 
-   blur_rectangles = e_blur_rectangles_get(blur);
-   if (!blur_rectangles) return;
    if (!video_capture->clients) return;
 
-   EINA_LIST_FOREACH(blur_rectangles, l, blur_rectangle)
-     {
-        EINA_LIST_FOREACH(video_capture->clients, l2, client)
-          {
-             object = _e_blur_video_capture_object_get(client, blur_rectangle);
+   EINA_LIST_FOREACH(video_capture->clients, l, client)
+     _e_blur_video_capture_client_object_rectangle_init(client, blur_rectangle);
 
-             if (!client->presentation_visible) continue;
-             if (!evas_object_visible_get(object->blur_rectangle_obj)) continue;
-             if (!_e_blur_video_capture_source_object_visible_get()) continue;
+   _e_blur_video_capture_start();
+}
 
-             _e_blur_video_capture_object_show(object);
-          }
-     }
+static void
+_e_blur_video_capture_cb_blur_behind_create(void *data, E_Blur_Hook_Data *hook_data)
+{
+   E_Blur_Video_Capture *video_capture = _video_capture;
+   E_Blur_Video_Capture_Client *client;
+   E_Blur_Behind *blur_behind = hook_data->blur_behind;
+   Eina_List *l;
+
+   EINA_SAFETY_ON_NULL_RETURN(video_capture->funcs);
+
+   if (!video_capture->clients) return;
+
+   EINA_LIST_FOREACH(video_capture->clients, l, client)
+     _e_blur_video_capture_client_object_behind_init(client, blur_behind);
 
    _e_blur_video_capture_start();
 }
@@ -673,7 +748,7 @@ _e_blur_video_capture_client_cb_presentation_callback(void *data, E_Hwc_Presenta
      {
         EINA_LIST_FOREACH(client->capture_objs, l, object)
            {
-              if (!evas_object_visible_get(object->blur_rectangle_obj))
+              if (!evas_object_visible_get(object->blur_obj))
                 continue;
 
               _e_blur_video_capture_object_show(object);
@@ -704,7 +779,7 @@ _e_blur_video_capture_client_evas_cb_show(void *data, Evas *evas EINA_UNUSED, Ev
           {
              EINA_LIST_FOREACH(client->capture_objs, l, object)
                {
-                  if (!evas_object_visible_get(object->blur_rectangle_obj))
+                  if (!evas_object_visible_get(object->blur_obj))
                     continue;
 
                   _e_blur_video_capture_object_show(object);
@@ -806,8 +881,25 @@ _e_blur_video_capture_client_evas_cb_restack(void *data, Evas *e EINA_UNUSED, Ev
 
    layer = evas_object_layer_get(obj);
 
+
+   EINA_LIST_FOREACH(client->capture_objs, l, object)
+     {
+        if (object->type != E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_BEHIND)
+          continue;
+
+        evas_object_layer_set(object->blur_clip_obj, layer);
+        evas_object_stack_above(object->blur_clip_obj, obj);
+        evas_object_layer_set(object->source_clip_obj, layer);
+        evas_object_stack_below(object->source_clip_obj, object->blur_clip_obj);
+        evas_object_layer_set(object->source_obj, layer);
+        evas_object_stack_below(object->source_obj, object->source_clip_obj);
+     }
+
    EINA_LIST_FOREACH(client->capture_objs, l, object)
      {
+        if (object->type != E_BLUR_VIDEO_CAPTURE_OBJECT_TYPE_RECTANGLE)
+          continue;
+
         evas_object_layer_set(object->blur_clip_obj, layer);
         evas_object_stack_above(object->blur_clip_obj, obj);
         evas_object_layer_set(object->source_clip_obj, layer);
@@ -834,17 +926,15 @@ _e_blur_video_capture_client_cb_ec_free(void *data, void *obj)
 
    EINA_LIST_FOREACH_SAFE(client->capture_objs, l, ll, object)
      {
-        evas_object_event_callback_del(object->blur_rectangle_obj, EVAS_CALLBACK_SHOW,
+        evas_object_event_callback_del(object->blur_obj, EVAS_CALLBACK_SHOW,
                                        _e_blur_video_capture_object_evas_cb_show);
-        evas_object_event_callback_del(object->blur_rectangle_obj, EVAS_CALLBACK_HIDE,
+        evas_object_event_callback_del(object->blur_obj, EVAS_CALLBACK_HIDE,
                                        _e_blur_video_capture_object_evas_cb_hide);
-        evas_object_event_callback_del(object->blur_rectangle_obj, EVAS_CALLBACK_RESIZE,
+        evas_object_event_callback_del(object->blur_obj, EVAS_CALLBACK_RESIZE,
                                        _e_blur_video_capture_object_evas_cb_resize);
-        evas_object_event_callback_del(object->blur_rectangle_obj, EVAS_CALLBACK_MOVE,
+        evas_object_event_callback_del(object->blur_obj, EVAS_CALLBACK_MOVE,
                                        _e_blur_video_capture_object_evas_cb_move);
-        evas_object_event_callback_del(object->blur_rectangle_obj, EVAS_CALLBACK_RESTACK,
-                                       _e_blur_video_capture_object_evas_cb_restack);
-        evas_object_event_callback_del(object->blur_rectangle_obj, EVAS_CALLBACK_DEL,
+        evas_object_event_callback_del(object->blur_obj, EVAS_CALLBACK_DEL,
                                        _e_blur_video_capture_object_evas_cb_del);
 
         _e_blur_video_capture_object_destroy(object);
@@ -869,14 +959,43 @@ _e_blur_video_capture_client_cb_ec_free(void *data, void *obj)
 }
 
 static void
+_e_blur_video_capture_client_blurs_init(E_Blur_Video_Capture_Client *client)
+{
+   E_Blur *blur;
+   E_Blur_Rectangle *blur_rectangle;
+   Eina_List *blurs, *blur_rectangles, *l, *l2;
+
+   blurs = e_blur_manager_blurs_get();
+   if (!blurs) return;
+
+   EINA_LIST_FOREACH(blurs, l, blur)
+     {
+        blur_rectangles = e_blur_rectangles_get(blur);
+        if (!blur_rectangles) continue;
+
+        EINA_LIST_FOREACH(blur_rectangles, l2, blur_rectangle)
+          _e_blur_video_capture_client_object_rectangle_init(client, blur_rectangle);
+     }
+}
+
+static void
+_e_blur_video_capture_client_blurs_behind_init(E_Blur_Video_Capture_Client *client)
+{
+   E_Blur_Behind *blur_behind;
+   Eina_List *blurs_behind, *l;
+
+   blurs_behind = e_blur_manager_blurs_behind_get();
+   if (!blurs_behind) return;
+
+   EINA_LIST_FOREACH(blurs_behind, l, blur_behind)
+      _e_blur_video_capture_client_object_behind_init(client, blur_behind);
+}
+
+static void
 _e_blur_video_capture_cb_hwc_window_video_set(void *data, E_Hwc_Window *hwc_window)
 {
    E_Blur_Video_Capture_Client *client;
    E_Blur_Video_Capture *video_capture = _video_capture;
-   E_Blur_Video_Capture_Object *object;
-   Eina_List *blurs, *blur_rectangles, *l, *l2;
-   E_Blur *blur;
-   E_Blur_Rectangle *blur_rectangle;
 
    EINA_SAFETY_ON_NULL_RETURN(video_capture->funcs);
 
@@ -909,25 +1028,8 @@ _e_blur_video_capture_cb_hwc_window_video_set(void *data, E_Hwc_Window *hwc_wind
 
    ELOGF("E_BLUR", "Create Video_Capture_Client:%p", client->ec, client);
 
-   blurs = e_blur_manager_blurs_get();
-   if (!blurs) return;
-
-   EINA_LIST_FOREACH(blurs, l, blur)
-     {
-        blur_rectangles = e_blur_rectangles_get(blur);
-        if (!blur_rectangles) return;
-
-        EINA_LIST_FOREACH(blur_rectangles, l2, blur_rectangle)
-          {
-             object = _e_blur_video_capture_object_get(client, blur_rectangle);
-
-             if (!client->presentation_visible) continue;
-             if (!evas_object_visible_get(object->blur_rectangle_obj)) continue;
-             if (_e_blur_video_capture_source_object_visible_get()) continue;
-
-             _e_blur_video_capture_object_show(object);
-          }
-     }
+  _e_blur_video_capture_client_blurs_init(client);
+  _e_blur_video_capture_client_blurs_behind_init(client);
 
    _e_blur_video_capture_start();
 }
@@ -945,7 +1047,9 @@ e_blur_video_capture_init(void)
    E_HWC_WINDOW_HOOK_APPEND(_e_blur_video_capture_hwc_window_hooks, E_HWC_WINDOW_HOOK_VIDEO_SET,
                             _e_blur_video_capture_cb_hwc_window_video_set, NULL);
    E_BLUR_HOOK_APPEND(_e_blur_video_capture_blur_hooks, E_BLUR_HOOK_RECTANGLE_CREATE,
-                      _e_blur_video_capture_cb_rectangle_create, NULL);
+                      _e_blur_video_capture_cb_blur_rectangle_create, NULL);
+   E_BLUR_HOOK_APPEND(_e_blur_video_capture_blur_hooks, E_BLUR_HOOK_BEHIND_CREATE,
+                      _e_blur_video_capture_cb_blur_behind_create, NULL);
 
    _video_capture = video_capture;