Add API 'e_pixmap_buffer_clear()' and 'e_comp_object_clear' to clear the client buffer. 64/73764/12
authorSeunghun Lee <shiin.lee@samsung.com>
Wed, 1 Jun 2016 13:21:09 +0000 (22:21 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Fri, 17 Jun 2016 12:59:48 +0000 (05:59 -0700)
It will work according to setting of 'use_buffer_flush'.
pixmap buffer will be flushed by iconify.

Change-Id: I9a999d151d25c0efa9ef3ce13b1f3c618589c57d

12 files changed:
src/bin/Makefile.mk
src/bin/e_client.c
src/bin/e_comp_object.c
src/bin/e_comp_object.h
src/bin/e_comp_wl.c
src/bin/e_comp_wl.h
src/bin/e_config.c
src/bin/e_config.h
src/bin/e_pixmap.c
src/bin/e_pixmap.h
src/bin/tizen-surface-protocol.c [new file with mode: 0644]
src/bin/tizen-surface-server.h [new file with mode: 0644]

index 43fc5f483aad7cc0179989dd65d4a39fe4ce1937..b33539a72dea915ed8915356c520317cda58ac8a 100644 (file)
@@ -156,6 +156,7 @@ src/bin/e_comp_wl_screenshooter_server.h \
 src/bin/e_comp_wl_data.c \
 src/bin/e_comp_wl_input.c \
 src/bin/e_comp_wl.c \
+src/bin/tizen-surface-protocol.c \
 $(ENLIGHTENMENTHEADERS)
 
 if HAVE_WAYLAND_TBM
index f31d0a83f59029dee24f38102549c6c509683a96..9ed30ded438a59afcc5f471926472415b22005ee 100644 (file)
@@ -4824,6 +4824,9 @@ e_client_iconify(E_Client *ec)
 
    e_remember_update(ec);
 
+   if (e_config->use_buffer_flush)
+     e_pixmap_buffer_clear(ec->pixmap);
+
    TRACE_DS_END();
 }
 
index 938a62cdbfe61244ab0b2adb0b79707fec85a252..c8119ac787053181ffe5108d6a232f4fd801f1c5 100644 (file)
@@ -3516,6 +3516,31 @@ e_comp_object_shape_apply(Evas_Object *obj)
 // alpha channel content
 }
 
+static void
+_e_comp_object_clear(E_Comp_Object *cw)
+{
+   Eina_List *l;
+   Evas_Object *o;
+
+   EINA_SAFETY_ON_NULL_RETURN(cw->ec);
+
+   if (cw->ec->pixmap)
+     e_pixmap_clear(cw->ec->pixmap);
+   if (cw->native)
+     evas_object_image_native_surface_set(cw->obj, NULL);
+   evas_object_image_size_set(cw->obj, 1, 1);
+   evas_object_image_data_set(cw->obj, NULL);
+   EINA_LIST_FOREACH(cw->obj_mirror, l, o)
+     {
+        evas_object_image_size_set(o, 1, 1);
+        evas_object_image_data_set(o, NULL);
+        if (cw->native)
+          evas_object_image_native_surface_set(o, NULL);
+     }
+   cw->native = 0;
+   e_comp_object_render_update_del(cw->smart_obj);
+}
+
 /* helper function to simplify toggling of redirection for display servers which support it */
 E_API void
 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
@@ -3536,24 +3561,7 @@ e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
      }
    else
      {
-        Eina_List *l;
-        Evas_Object *o;
-
-        if (cw->ec->pixmap)
-          e_pixmap_clear(cw->ec->pixmap);
-        if (cw->native)
-          evas_object_image_native_surface_set(cw->obj, NULL);
-        evas_object_image_size_set(cw->obj, 1, 1);
-        evas_object_image_data_set(cw->obj, NULL);
-        EINA_LIST_FOREACH(cw->obj_mirror, l, o)
-          {
-             evas_object_image_size_set(o, 1, 1);
-             evas_object_image_data_set(o, NULL);
-             if (cw->native)
-               evas_object_image_native_surface_set(o, NULL);
-          }
-        cw->native = 0;
-        e_comp_object_render_update_del(obj);
+        _e_comp_object_clear(cw);
         evas_object_smart_callback_call(obj, "unredirected", NULL);
      }
 }
@@ -4608,3 +4616,10 @@ _e_comp_object_dim_update(E_Comp_Object *cw)
      }
 }
 
+E_API void
+e_comp_object_clear(Evas_Object *obj)
+{
+   API_ENTRY;
+
+   _e_comp_object_clear(cw);
+}
index a51acfabfd16989fad3ec4b08b3d7bbeefcb473d..32820678ca112e4874b3f8b507fa800462454323 100644 (file)
@@ -134,6 +134,8 @@ E_API Eina_Bool e_comp_object_content_unset(Evas_Object* obj);
 
 E_API void e_comp_object_dim_client_set(E_Client *ec);
 E_API E_Client *e_comp_object_dim_client_get(void);
+E_API void      e_comp_object_clear(Evas_Object *obj);
+
 #endif
 #endif
 
index ead0de89e1dddaa8a0c97f061ba28cca0e49dddf..c08c5c7c847a5c568d5a5752d63465a299cb32c2 100644 (file)
@@ -1705,6 +1705,12 @@ _e_comp_wl_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSE
 
    buffer = container_of(listener, E_Comp_Wl_Buffer, destroy_listener);
 
+   DBG("Wl Buffer Destroy: b %p owner '%s'(%p)",
+       buffer, buffer->debug_info.owner_name, buffer->debug_info.owner_ptr);
+
+   /* remove debug info */
+   eina_stringshare_del(buffer->debug_info.owner_name);
+
    if ((ec = eina_hash_find(clients_buffer_hash, &buffer->resource)))
      {
         eina_hash_del_by_key(clients_buffer_hash, &buffer->resource);
@@ -4615,6 +4621,8 @@ e_comp_wl_init(void)
    e_comp_wl_tbm_init();
 #endif
 
+   e_pixmap_init();
+
    /* add event handlers to catch E events */
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_SCREEN_CHANGE,            _e_comp_wl_cb_randr_change,        NULL);
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMP_OBJECT_ADD,         _e_comp_wl_cb_comp_object_add,     NULL);
@@ -4672,6 +4680,8 @@ e_comp_wl_shutdown(void)
    e_comp_wl_tbm_shutdown();
 #endif
 
+   e_pixmap_shutdown();
+
    e_comp_wl_input_shutdown();
 
    // TODO: yigl
@@ -4965,6 +4975,15 @@ e_comp_wl_buffer_get(struct wl_resource *resource, E_Client *ec)
    buffer->destroy_listener.notify = _e_comp_wl_buffer_cb_destroy;
    wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
 
+   if (ec)
+     {
+        buffer->debug_info.owner_ptr = (void *)ec;
+        buffer->debug_info.owner_name = eina_stringshare_add(ec->icccm.name?:"");
+     }
+
+   DBG("Wl Buffer Create: b %p owner '%s'(%p)",
+       buffer, buffer->debug_info.owner_name, buffer->debug_info.owner_ptr);
+
    return buffer;
 
 err:
index dcd9c541c176e1996bcf2877b37e537381b0452e..316e6c121196abdd0287f446318a67b024fe61b7 100644 (file)
@@ -80,6 +80,11 @@ struct _E_Comp_Wl_Buffer
    struct wl_listener destroy_listener;
    struct wl_shm_buffer *shm_buffer;
    tbm_surface_h tbm_surface;
+   struct
+   {
+      Eina_Stringshare *owner_name;
+      void *owner_ptr;
+   } debug_info;
    int32_t w, h;
    uint32_t busy;
 };
index 0da0e75b931c616f3c347a22241eba8bf64196b0..ae4e9c2865215f0c639957b33201126532c3ec1a 100644 (file)
@@ -224,6 +224,7 @@ _e_config_edd_init(Eina_Bool old)
    E_CONFIG_VAL(D, T, comp_canvas_bg.a, UCHAR);
    E_CONFIG_VAL(D, T, comp_canvas_bg.opmode, INT);
    E_CONFIG_VAL(D, T, delayed_load_idle_count, INT);
+   E_CONFIG_VAL(D, T, use_buffer_flush, UCHAR);
 }
 
 /* externally accessible functions */
@@ -401,6 +402,7 @@ e_config_load(void)
    E_CONFIG_LIMIT(e_config->comp_canvas_bg.a, 0, 255);
    E_CONFIG_LIMIT(e_config->comp_canvas_bg.opmode, 0, 11);
    E_CONFIG_LIMIT(e_config->delayed_load_idle_count, 0, 100);
+   E_CONFIG_LIMIT(e_config->use_buffer_flush, 0, 1);
 }
 
 E_API int
index af4931428473bcb624b7d3f33157802ce7892d3c..eac169109bc5295ffb7a0e87cd520b63e5c9931b 100644 (file)
@@ -169,6 +169,7 @@ struct _E_Config
       int opmode;
    } comp_canvas_bg;
    int delayed_load_idle_count;
+   Eina_Bool use_buffer_flush;
 };
 
 struct _E_Config_Desklock_Background
index 79ea7159f83e05adc559cd33418612eca9ec9e07..1952368e1de70183c304b65987377be7e43c7073 100644 (file)
@@ -3,6 +3,7 @@
 #include "e_comp_wl.h"
 #include <wayland-tbm-server.h>
 #include <tizen-extension-server-protocol.h>
+#include "tizen-surface-server.h"
 #ifndef EGL_TEXTURE_RGBA
 # define EGL_TEXTURE_RGBA 0x305E
 #endif
@@ -38,6 +39,8 @@ struct _E_Pixmap
    Eina_Rectangle opaque;
    uuid_t uuid;
 
+   struct wl_resource *shm_flusher;
+
    E_Comp_Wl_Client_Data *cdata;
    Eina_Bool own_cdata : 1;
 
@@ -126,6 +129,10 @@ _e_pixmap_free(E_Pixmap *cp)
      }
    _e_pixmap_clear(cp, 1);
    ELOG("PIXMAP FREE", cp, cp->client);
+
+   if (cp->shm_flusher)
+     wl_resource_destroy(cp->shm_flusher);
+
    free(cp);
 }
 
@@ -170,6 +177,78 @@ _e_pixmap_find(E_Pixmap_Type type, va_list *l)
    return cp;
 }
 
+// --------------------------------------------------------
+// tizen_surface_shm
+// --------------------------------------------------------
+static void
+_e_pixmap_tzsurf_shm_flusher_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static const struct tizen_surface_shm_flusher_interface _tzsurf_shm_flusher_iface =
+{
+   _e_pixmap_tzsurf_shm_flusher_cb_destroy,
+};
+
+static void
+_e_pixmap_tzsurf_shm_flusher_cb_res_destroy(struct wl_resource *resource)
+{
+   E_Pixmap *cp;
+
+   cp = wl_resource_get_user_data(resource);
+   cp->shm_flusher = NULL;
+}
+
+static void
+_e_pixmap_tzsurf_shm_cb_flusher_get(struct wl_client *client, struct wl_resource *flusher, uint32_t id, struct wl_resource *surface)
+{
+   E_Client *ec;
+   struct wl_resource *res;
+
+   ec = wl_resource_get_user_data(surface);
+   if ((!ec) || (!ec->pixmap))
+     {
+        wl_resource_post_error(flusher, WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "tizen_shm_flusher failed: wrong wl_surface@%d resource",
+                               wl_resource_get_id(surface));
+        return;
+     }
+
+   res = wl_resource_create(client, &tizen_surface_shm_flusher_interface,
+                            wl_resource_get_version(flusher), id);
+   if (!res)
+     {
+        wl_resource_post_no_memory(flusher);
+        return;
+     }
+
+   wl_resource_set_implementation(res, &_tzsurf_shm_flusher_iface, ec->pixmap,
+                                  _e_pixmap_tzsurf_shm_flusher_cb_res_destroy);
+
+   ec->pixmap->shm_flusher = res;
+}
+
+static const struct tizen_surface_shm_interface _tzsurf_shm_iface =
+{
+   _e_pixmap_tzsurf_shm_cb_flusher_get,
+};
+
+static void
+_e_pixmap_tzsurf_shm_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t ver, uint32_t id)
+{
+   struct wl_resource *res;
+
+   res = wl_resource_create(client, &tizen_surface_shm_interface, ver, id);
+   if (!res)
+     {
+        wl_client_post_no_memory(client);
+        return;
+     }
+
+   wl_resource_set_implementation(res, &_tzsurf_shm_iface, NULL, NULL);
+}
+
 E_API int
 e_pixmap_free(E_Pixmap *cp)
 {
@@ -890,3 +969,78 @@ e_pixmap_hook_del(E_Pixmap_Hook *ph)
    else
      _e_pixmap_hooks_delete++;
 }
+
+E_API Eina_Bool
+e_pixmap_init(void)
+{
+   struct wl_global *global;
+
+   if (!e_config->use_buffer_flush)
+     return EINA_TRUE;
+
+   if (!e_comp_wl)
+     return EINA_FALSE;
+
+   if (!e_comp_wl->wl.disp)
+     return EINA_FALSE;
+
+   global = wl_global_create(e_comp_wl->wl.disp, &tizen_surface_shm_interface,
+                             1, NULL, _e_pixmap_tzsurf_shm_cb_bind);
+   if (!global)
+     return EINA_FALSE;
+
+   return EINA_TRUE;
+}
+
+E_API void
+e_pixmap_shutdown(void)
+{
+}
+
+/* By this calling, client will destroy their buffer by this feature
+ * implementation. the implementation for shared memory is in evas_shm engine.
+ */
+E_API void
+e_pixmap_buffer_clear(E_Pixmap *cp)
+{
+   EINA_SAFETY_ON_NULL_RETURN(cp);
+
+   /* disabled this feature */
+   if (!e_config->use_buffer_flush)
+     return;
+
+   /* release the helded buffer by e_client */
+   e_comp_wl_buffer_reference(&cp->client->comp_data->buffer_ref, NULL);
+
+   /* composite object clear */
+   e_comp_object_clear(cp->client->frame);
+
+   DBG("PIXMAP: Buffer Flush(%s) '%s'(%p)", cp->shm_flusher ? "SHM" : "NATIVE",
+       cp->client->icccm.name?:"", cp->client);
+
+   if (cp->shm_flusher)
+     tizen_surface_shm_flusher_send_flush(cp->shm_flusher);
+   else if (cp->buffer)
+     {
+        switch (cp->buffer->type)
+          {
+           case E_COMP_WL_BUFFER_TYPE_TBM:
+           case E_COMP_WL_BUFFER_TYPE_NATIVE:
+                {
+                   struct wayland_tbm_client_queue *cqueue;
+
+                   cqueue =
+                      wayland_tbm_server_client_queue_get(e_comp_wl->tbm.server,
+                                                          cp->client->comp_data->wl_surface);
+                   if (!cqueue)
+                     return;
+
+                   wayland_tbm_server_client_queue_flush(cqueue);
+                }
+              break;
+           default:
+              /* Do nothing */
+              break;
+          }
+     }
+}
index 1bc4df58e80da2bb5bd79f185e40421ee9db52c9..cd519e8a78d73950097b478e640156896f93b51a 100644 (file)
@@ -79,6 +79,10 @@ E_API void e_pixmap_image_opaque_get(E_Pixmap *cp, int *x, int *y, int *w, int *
 E_API E_Pixmap_Hook *e_pixmap_hook_add(E_Pixmap_Hook_Point hookpoint, E_Pixmap_Hook_Cb func, const void *data);
 E_API void e_pixmap_hook_del(E_Pixmap_Hook *ph);
 
+E_API Eina_Bool e_pixmap_init(void);
+E_API void e_pixmap_shutdown(void);
+E_API void e_pixmap_buffer_clear(E_Pixmap *cp);
+
 static inline Eina_Bool
 e_pixmap_is_x(const E_Pixmap *cp)
 {
diff --git a/src/bin/tizen-surface-protocol.c b/src/bin/tizen-surface-protocol.c
new file mode 100644 (file)
index 0000000..8420280
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+
+extern const struct wl_interface tizen_surface_shm_flusher_interface;
+extern const struct wl_interface wl_surface_interface;
+
+static const struct wl_interface *types[] = {
+       &tizen_surface_shm_flusher_interface,
+       &wl_surface_interface,
+};
+
+static const struct wl_message tizen_surface_shm_requests[] = {
+       { "get_flusher", "no", types + 0 },
+};
+
+WL_EXPORT const struct wl_interface tizen_surface_shm_interface = {
+       "tizen_surface_shm", 1,
+       1, tizen_surface_shm_requests,
+       0, NULL,
+};
+
+static const struct wl_message tizen_surface_shm_flusher_requests[] = {
+       { "destroy", "", types + 0 },
+};
+
+static const struct wl_message tizen_surface_shm_flusher_events[] = {
+       { "flush", "", types + 0 },
+};
+
+WL_EXPORT const struct wl_interface tizen_surface_shm_flusher_interface = {
+       "tizen_surface_shm_flusher", 1,
+       1, tizen_surface_shm_flusher_requests,
+       1, tizen_surface_shm_flusher_events,
+};
+
diff --git a/src/bin/tizen-surface-server.h b/src/bin/tizen-surface-server.h
new file mode 100644 (file)
index 0000000..de98ffb
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef TIZEN_SURFACE_SERVER_PROTOCOL_H
+#define TIZEN_SURFACE_SERVER_PROTOCOL_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-util.h"
+
+struct wl_client;
+struct wl_resource;
+
+struct tizen_surface_shm;
+struct tizen_surface_shm_flusher;
+
+extern const struct wl_interface tizen_surface_shm_interface;
+extern const struct wl_interface tizen_surface_shm_flusher_interface;
+
+struct tizen_surface_shm_interface {
+       /**
+        * get_flusher - (none)
+        * @id: 
+        * @surface: surface object
+        */
+       void (*get_flusher)(struct wl_client *client,
+                           struct wl_resource *resource,
+                           uint32_t id,
+                           struct wl_resource *surface);
+};
+
+struct tizen_surface_shm_flusher_interface {
+       /**
+        * destroy - (none)
+        */
+       void (*destroy)(struct wl_client *client,
+                       struct wl_resource *resource);
+};
+
+#define TIZEN_SURFACE_SHM_FLUSHER_FLUSH        0
+
+static inline void
+tizen_surface_shm_flusher_send_flush(struct wl_resource *resource_)
+{
+       wl_resource_post_event(resource_, TIZEN_SURFACE_SHM_FLUSHER_FLUSH);
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif