e_comp_hwc: change logic for creating and destoying backup buffer 45/76345/3
authorChangyeon Lee <cyeon.lee@samsung.com>
Thu, 23 Jun 2016 06:15:38 +0000 (15:15 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Thu, 23 Jun 2016 16:53:12 +0000 (01:53 +0900)
Create backup buffer and set to e_pixmap and reference comp_data
when deactiavte or client send scanout buffer in comp mode.
backup buffer will be destroyed unreference comp_data and clear e_pixmap.

Change-Id: I4194491cbb4ee6dc717b04e54f433e4b95dd3e49

src/bin/e_comp_hwc.c
src/bin/e_comp_wl.c
src/bin/e_comp_wl_tbm.c
src/bin/e_comp_wl_tbm.h

index e077622fb73fd5dae4db8ea553ec5fea598525bb..42d54ab73010a9f9af8286dc053453b26b18a4a3 100644 (file)
@@ -45,7 +45,7 @@ struct _E_Comp_Hwc_Client
    Eina_Bool activated;
 
    E_Comp_Wl_Buffer *buffer;
-   E_Comp_Wl_Buffer *backup_buffer;
+   struct wl_listener buffer_destroy_listener;
 
    Eina_Bool wait_for_commit;
 };
@@ -156,14 +156,17 @@ _e_comp_hwc_create_copied_surface(E_Client *ec, Eina_Bool refresh)
    if (!buffer) return NULL;
 
    tsurface = wayland_tbm_server_get_surface(wl_comp_data->tbm.server, buffer->resource);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(tsurface, NULL);
 
    tbm_surface_map(tsurface, TBM_SURF_OPTION_READ, &src_info);
    tbm_surface_unmap(tsurface);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(src_info.planes[0].ptr, NULL);
 
    new_tsurface = tbm_surface_create(src_info.width, src_info.height, src_info.format);
 
    tbm_surface_map(new_tsurface, TBM_SURF_OPTION_WRITE, &dst_info);
    tbm_surface_unmap(new_tsurface);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dst_info.planes[0].ptr, NULL);
 
    /* copy from src to dst */
 #if HAVE_MEMCPY_SWC
@@ -183,43 +186,73 @@ _e_comp_hwc_destroy_copied_surface(tbm_surface_h tbm_surface)
    tbm_surface_internal_unref(tbm_surface);
 }
 
-static E_Comp_Wl_Buffer *
-_e_comp_hwc_client_create_backup_buffer(E_Comp_Hwc_Client *hwc_client)
+static void
+_e_comp_hwc_backup_buffer_cb_destroy(struct wl_listener *listener, void *data)
 {
-   E_Comp_Wl_Buffer *buffer = NULL;
-   tbm_surface_h tsurface = NULL;
+   E_Comp_Hwc_Client *hwc_client = NULL;
+   E_Client *ec = NULL;
 
-   tsurface = _e_comp_hwc_create_copied_surface(hwc_client->ec, EINA_TRUE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(tsurface, NULL);
+   hwc_client = container_of(listener, E_Comp_Hwc_Client, buffer_destroy_listener);
+   EINA_SAFETY_ON_NULL_RETURN(hwc_client);
+
+   if ((E_Comp_Wl_Buffer *)data != hwc_client->buffer) return;
+
+   ec = hwc_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
-   if (!(buffer = E_NEW(E_Comp_Wl_Buffer, 1)))
+   if (e_pixmap_resource_get(ec->pixmap) == (E_Comp_Wl_Buffer *)data)
      {
-        _e_comp_hwc_destroy_copied_surface(tsurface);
-        return NULL;
+         e_pixmap_resource_set(ec->pixmap, NULL);
+         e_comp_object_native_surface_set(ec->frame, 0);
      }
 
-   buffer->type = E_COMP_WL_BUFFER_TYPE_TBM;
-   buffer->w = tbm_surface_get_width(tsurface);
-   buffer->h = tbm_surface_get_height(tsurface);
-   buffer->resource = NULL;
-   buffer->tbm_surface = tsurface;
-   wl_signal_init(&buffer->destroy_signal);
-
-   return buffer;
+   hwc_client->buffer = NULL;
 }
 
-static void
-_e_comp_hwc_client_destroy_backup_buffer(E_Comp_Wl_Buffer *buffer)
+static Eina_Bool
+_e_comp_hwc_set_backup_buffer(E_Comp_Hwc_Client *hwc_client)
 {
-   if (!buffer) return;
-   if (buffer->tbm_surface)
-     {
-        _e_comp_hwc_destroy_copied_surface(buffer->tbm_surface);
-        buffer->tbm_surface = NULL;
-     }
+   E_Comp_Wl_Buffer *backup_buffer = NULL;
+   tbm_surface_h copied_tsurface = NULL;
+   E_Client *ec = NULL;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_client, EINA_FALSE);
+
+   ec = hwc_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+
+   copied_tsurface = _e_comp_hwc_create_copied_surface(ec, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(copied_tsurface, EINA_FALSE);
+
+   backup_buffer = e_comp_wl_tbm_buffer_get(copied_tsurface);
+   EINA_SAFETY_ON_NULL_GOTO(backup_buffer, fail);
+
+   if (hwc_client->buffer)
+      wl_list_remove(&hwc_client->buffer_destroy_listener.link);
+
+   hwc_client->buffer = backup_buffer;
+   wl_signal_add(&backup_buffer->destroy_signal, &hwc_client->buffer_destroy_listener);
+   hwc_client->buffer_destroy_listener.notify = _e_comp_hwc_backup_buffer_cb_destroy;
+
+   /* reference backup buffer to comp data */
+   e_comp_wl_buffer_reference(&ec->comp_data->buffer_ref, backup_buffer);
+
+   /* set the backup buffer resource to the pixmap */
+   e_pixmap_resource_set(ec->pixmap, backup_buffer);
+   e_pixmap_image_refresh(ec->pixmap);
 
-   wl_signal_emit(&buffer->destroy_signal, buffer);
-   E_FREE(buffer);
+   /* force update */
+   e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
+   e_comp_object_dirty(ec->frame);
+   e_comp_object_render(ec->frame);
+
+   return EINA_TRUE;
+
+fail :
+   if (copied_tsurface)
+      _e_comp_hwc_destroy_copied_surface(copied_tsurface);
+
+   return EINA_FALSE;
 }
 
 static void
@@ -639,8 +672,10 @@ _e_comp_hwc_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
         if (hwc_client->ec == ec)
           {
              g_hwc->hwc_clients = eina_list_remove_list(g_hwc->hwc_clients, l);
-             if (hwc_client->backup_buffer)
-               _e_comp_hwc_client_destroy_backup_buffer(hwc_client->backup_buffer);
+
+             if (hwc_client->buffer)
+                wl_list_remove(&hwc_client->buffer_destroy_listener.link);
+
              free(hwc_client);
              break;
           }
@@ -773,38 +808,13 @@ _e_comp_hwc_renderer_deactivate(E_Comp_Hwc_Renderer *hwc_renderer)
    /* deactive */
    wayland_tbm_server_client_queue_deactivate(cqueue);
 
-   if (!hwc_client->backup_buffer)
-     {
-#ifdef USE_DLOG_HWC
-        HWC_DLOG("hwc_client,%p create the backup_buffer.\n");
-#endif
-        /* get the tsurface for setting the native surface with it
-          compositing is processed not calling e_comp_update_cb*/
-        hwc_client->buffer = e_pixmap_resource_get(ec->pixmap);
-        hwc_client->backup_buffer = _e_comp_hwc_client_create_backup_buffer(hwc_client);
-        hwc_client->activated = EINA_FALSE;
-        hwc_client->wait_for_commit = EINA_TRUE;
-
-        /* set the backup buffer resource to the pixmap */
-        e_pixmap_resource_set(ec->pixmap, hwc_client->backup_buffer);
-
-        e_comp->nocomp = 0;
-        e_comp->nocomp_ec = NULL;
-
-        /* force update */
-        e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
-        e_comp_object_dirty(ec->frame);
-        e_comp_object_render(ec->frame);
-
-        /* set the native surface with tbm type for compositing */
-        e_comp_object_native_surface_set(ec->frame, EINA_TRUE);
-     }
-   else
-     {
-#ifdef USE_DLOG_HWC
-        HWC_DLOG("hwc_client,%p dose not commit wl_buffer after the previous deactive.\n");
-#endif
-     }
+   if (!_e_comp_hwc_set_backup_buffer(hwc_client))
+      ERR("fail to _e_comp_hwc_set_backup_buffer");
+
+   hwc_client->activated = EINA_FALSE;
+
+   e_comp->nocomp = 0;
+   e_comp->nocomp_ec = NULL;
 
 #ifdef USE_DLOG_HWC
    HWC_DLOG("hwc_client,%p deactivated\n", hwc_client);
@@ -1168,15 +1178,6 @@ _e_comp_hwc_output_display_client_reserved_memory(E_Comp_Hwc_Output *hwc_output,
    hwc_client = _e_comp_hwc_client_find(ec);
    EINA_SAFETY_ON_NULL_RETURN(hwc_client);
 
-   if (hwc_client->backup_buffer)
-     {
-#ifdef USE_DLOG_HWC
-        HWC_DLOG("hwc_client,%p display client. destroy the backup_buffer.\n", hwc_client);
-#endif
-        _e_comp_hwc_client_destroy_backup_buffer(hwc_client->backup_buffer);
-        hwc_client->backup_buffer = NULL;
-     }
-
    /* acquire the surface from the client_queue */
    tsurface = _e_comp_hwc_renderer_recieve_surface(hwc_renderer, ec);
    if (!tsurface)
@@ -1826,15 +1827,8 @@ e_comp_hwc_native_surface_set(E_Client *ec)
         return EINA_FALSE;
      }
 
-   if (hwc_client->wait_for_commit &&
-       hwc_client->backup_buffer)
-     {
-#ifdef USE_DLOG_HWC
-        HWC_DLOG("hwc_client,%p NEVER BE HEAR.\n", hwc_client);
-#endif
-        _e_comp_hwc_client_destroy_backup_buffer(hwc_client->backup_buffer);
-        hwc_client->buffer = NULL;
-     }
+   if (!_e_comp_hwc_set_backup_buffer(hwc_client))
+      ERR("fail to _e_comp_hwc_set_backup_buffer");
 
 #ifdef USE_DLOG_HWC
    HWC_DLOG("hwc_client,%p copy and native set\n", hwc_client);
index 7c8fc7bf673748c8dc2d7eaf32ba8de56cd5a9bc..f0b726b5b96c313b5ff2ecb8cf72af27c86825ca 100644 (file)
@@ -4883,7 +4883,11 @@ e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer)
         ref->buffer->busy--;
         if (ref->buffer->busy == 0)
           {
-             if (ref->buffer->type != E_COMP_WL_BUFFER_TYPE_TBM)
+             if (ref->buffer->type == E_COMP_WL_BUFFER_TYPE_TBM)
+               {
+                  e_comp_wl_tbm_buffer_destroy(ref->buffer);
+               }
+             else
                {
                   if (!wl_resource_get_client(ref->buffer->resource)) return;
                   wl_buffer_send_release(ref->buffer->resource);
index 972b6837c71ba73229931b8583c7f3cb48035c7e..147e79155bfb869e690d75cd667ddb03be3da2d7 100644 (file)
@@ -2,6 +2,7 @@
 #include <Ecore_Drm.h>
 #include <wayland-tbm-server.h>
 #include <tbm_bufmgr.h>
+#include <tbm_surface_internal.h>
 
 static int
 _e_comp_wl_tbm_bind_wl_display(struct wayland_tbm_server *tbm_server, struct wl_display *display)
@@ -83,3 +84,38 @@ e_comp_wl_tbm_shutdown(void)
    e_comp->wl_comp_data->tbm.server = NULL;
 }
 
+E_API void
+e_comp_wl_tbm_buffer_destroy(E_Comp_Wl_Buffer *buffer)
+{
+   if (!buffer) return;
+
+   if (buffer->tbm_surface)
+     {
+        tbm_surface_internal_unref(buffer->tbm_surface);
+        buffer->tbm_surface = NULL;
+     }
+
+   wl_signal_emit(&buffer->destroy_signal, buffer);
+   free(buffer);
+}
+
+E_API E_Comp_Wl_Buffer *
+e_comp_wl_tbm_buffer_get(tbm_surface_h tsurface)
+{
+   E_Comp_Wl_Buffer *buffer = NULL;
+
+   if (!tsurface) return NULL;
+
+   if (!(buffer = E_NEW(E_Comp_Wl_Buffer, 1)))
+      return NULL;
+
+   buffer->type = E_COMP_WL_BUFFER_TYPE_TBM;
+   buffer->w = tbm_surface_get_width(tsurface);
+   buffer->h = tbm_surface_get_height(tsurface);
+   buffer->tbm_surface = tsurface;
+   buffer->resource = NULL;
+   buffer->shm_buffer = NULL;
+   wl_signal_init(&buffer->destroy_signal);
+
+   return buffer;
+}
index 833d32350c887427e871781b4dc0892fef8c4f30..162150af4db3874f913d6a5af0d5fe2e414faded 100644 (file)
@@ -4,8 +4,13 @@
 # ifndef E_COMP_WL_TBM_H
 #  define E_COMP_WL_TBM_H
 
+#include <tbm_surface.h>
+
 EINTERN Eina_Bool e_comp_wl_tbm_init(void);
 EINTERN void e_comp_wl_tbm_shutdown(void);
 
+E_API E_Comp_Wl_Buffer *e_comp_wl_tbm_buffer_get(tbm_surface_h tsurface);
+E_API void e_comp_wl_tbm_buffer_destroy(E_Comp_Wl_Buffer *buffer);
+
 # endif
 #endif