subsurface: remove below_obj when it becomes useless. 78/238278/7
authorSeunghun Lee <shiin.lee@samsung.com>
Fri, 10 Jul 2020 06:49:44 +0000 (15:49 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 13 Jul 2020 09:22:16 +0000 (09:22 +0000)
this patch is to fix the problem that some animation of surface
underneath 'below_obj' can't be shown.

NOTE: The main purpose behind 'below_obj' is probably for using it as a
background of 24bit toplevel surface, which has to be displayed on the
screen with subsurfaces placed underneath a toplevel surface. In this
case, enlightenment supposes that a buffer for contents of toplevel
surface has an alpha channel to show below subsurfaces. Yet, having an
alpha channel means that other surfaces, not associated subsurfaces, can
be exposed somewhere unexpectedly even though it's 24bit
surface(opaque). In the same time, if the associated subsurface is to
show contents displaying on the overlay, then enlightenment has to make
a hole with alpha value to show a overlay layer. For that reason, a
'below_obj' probably has become transparent and had an render copy
attribute.
Yet, what if an application destroys all subsurfaces including
video surface? Well, in this case, since we can consider that the
application dones't want to show below subsurfaces, 'below_obj' can be
removed.

Change-Id: I3b4f251adbef0034d5cfacde291005ed4ad1a5ed

src/bin/e_comp_wl_subsurface.c

index 103316aa0979edc6c4219dd96e91d12f8e14bf90..bfce3eed09bd2875b376ee33b170dea99a99aa53 100644 (file)
@@ -130,51 +130,63 @@ _e_comp_wl_subsurface_check_below_bg_rectangle(E_Client *ec)
          return;
      }
 
-   if ((!ec->comp_data->sub.below_obj) &&
-       (ec->comp_data->sub.below_list ||
-        ec->comp_data->sub.below_list_pending ||
-        _e_comp_wl_subsurface_video_has(ec)))
+   if (!ec->comp_data->sub.below_obj)
      {
-        /* create a bg rectangle if topmost window is 24 depth window */
-        ec->comp_data->sub.below_obj = evas_object_rectangle_add(e_comp->evas);
-        EINA_SAFETY_ON_NULL_RETURN(ec->comp_data->sub.below_obj);
-
-        ELOGF("COMP", "         |bg_rectangle(%p) created", ec, ec->comp_data->sub.below_obj);
-
-        layer = evas_object_layer_get(ec->frame);
-        evas_object_layer_set(ec->comp_data->sub.below_obj, layer);
-        evas_object_render_op_set(ec->comp_data->sub.below_obj, EVAS_RENDER_COPY);
-
-        /* It's more reasonable to use the transparent color instead of black because
-         * we can show the alpha value of the 24 depth topmost window.
-         */
-        evas_object_color_set(ec->comp_data->sub.below_obj, 0x00, 0x00, 0x00, 0x00);
-        evas_object_move(ec->comp_data->sub.below_obj, ec->x, ec->y);
-        evas_object_resize(ec->comp_data->sub.below_obj, ec->w, ec->h);
-        evas_object_name_set(ec->comp_data->sub.below_obj, "below_bg_rectangle");
-
-        evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESIZE,
-                                       _e_comp_wl_subsurface_bg_evas_cb_resize, ec);
-
-        /* set alpha only if SW path */
-        e_comp_object_alpha_set(ec->frame, EINA_TRUE);
-
-        /* force update for changing alpha value. if the native surface has been already
-         * set before, changing alpha value can't be applied to egl image.
-         */
-        e_comp_object_native_surface_set(ec->frame, EINA_FALSE);
-        e_pixmap_image_refresh(ec->pixmap);
-        e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
-        e_comp_object_dirty(ec->frame);
-        e_comp_object_render(ec->frame);
-
-        _e_comp_wl_subsurface_restack(ec);
-        _e_comp_wl_subsurface_restack_bg_rectangle(ec);
-
-        if (evas_object_visible_get(ec->frame))
-          evas_object_show(ec->comp_data->sub.below_obj);
-
-        e_client_transform_core_update(ec);
+        if (ec->comp_data->sub.below_list ||
+            ec->comp_data->sub.below_list_pending ||
+            _e_comp_wl_subsurface_video_has(ec))
+          {
+             /* create a bg rectangle if topmost window is 24 depth window */
+             ec->comp_data->sub.below_obj = evas_object_rectangle_add(e_comp->evas);
+             EINA_SAFETY_ON_NULL_RETURN(ec->comp_data->sub.below_obj);
+
+             ELOGF("COMP", "         |bg_rectangle(%p) created", ec, ec->comp_data->sub.below_obj);
+
+             layer = evas_object_layer_get(ec->frame);
+             evas_object_layer_set(ec->comp_data->sub.below_obj, layer);
+             evas_object_render_op_set(ec->comp_data->sub.below_obj, EVAS_RENDER_COPY);
+
+             /* It's more reasonable to use the transparent color instead of black because
+              * we can show the alpha value of the 24 depth topmost window.
+              */
+             evas_object_color_set(ec->comp_data->sub.below_obj, 0x00, 0x00, 0x00, 0x00);
+             evas_object_move(ec->comp_data->sub.below_obj, ec->x, ec->y);
+             evas_object_resize(ec->comp_data->sub.below_obj, ec->w, ec->h);
+             evas_object_name_set(ec->comp_data->sub.below_obj, "below_bg_rectangle");
+
+             evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESIZE,
+                                            _e_comp_wl_subsurface_bg_evas_cb_resize, ec);
+
+             /* set alpha only if SW path */
+             e_comp_object_alpha_set(ec->frame, EINA_TRUE);
+
+             /* force update for changing alpha value. if the native surface has been already
+              * set before, changing alpha value can't be applied to egl image.
+              */
+             e_comp_object_native_surface_set(ec->frame, EINA_FALSE);
+             e_pixmap_image_refresh(ec->pixmap);
+             e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
+             e_comp_object_dirty(ec->frame);
+             e_comp_object_render(ec->frame);
+
+             _e_comp_wl_subsurface_restack(ec);
+             _e_comp_wl_subsurface_restack_bg_rectangle(ec);
+
+             if (evas_object_visible_get(ec->frame))
+               evas_object_show(ec->comp_data->sub.below_obj);
+
+             e_client_transform_core_update(ec);
+          }
+     }
+   else
+     {
+        /* 'below_obj' has to be removed if it becomes useless. */
+        if ((!ec->comp_data->sub.below_list) &&
+            (!ec->comp_data->sub.below_list_pending) &&
+            (!_e_comp_wl_subsurface_video_has(ec)))
+          {
+             E_FREE_FUNC(ec->comp_data->sub.below_obj, evas_object_del);
+          }
      }
 }