e_hwc_windows: move the target_window stuffs to the e_hwc_windows 24/194024/1
authorSooChan Lim <sc1.lim@samsung.com>
Wed, 28 Nov 2018 08:04:49 +0000 (17:04 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Wed, 28 Nov 2018 10:29:52 +0000 (19:29 +0900)
Change-Id: I686d7ce05c70459540cdb6811bddbf44e58bfef2

src/bin/e_comp_object.c
src/bin/e_hwc.c
src/bin/e_hwc_window.c
src/bin/e_hwc_window.h
src/bin/e_hwc_windows.c
src/bin/e_hwc_windows.h

index 0d2a1f10cfb0b814197ad55e3067f31dd393d442..afd9b5affb48bcfea94635984ad598ed0774ac74 100644 (file)
@@ -1240,7 +1240,7 @@ _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
 
    if (!ec->hwc_window) return;
 
-   e_hwc_window_render_list_add(ec->hwc_window);
+   e_hwc_windows_rendered_window_add(ec->hwc_window);
 }
 
 /////////////////////////////////////////////
index 5d32d0e4bdce93517791726617fdde2bf1b3dac0..412ca95c3b810782d0bc633aa983edb6ccae45bf 100644 (file)
@@ -354,12 +354,6 @@ e_hwc_new(E_Output *output)
      }
    else
      {
-        if (!e_hwc_windows_init(hwc))
-          {
-             ERR("hwc_opt: e_hwc_windows_init failed");
-             goto fail;
-          }
-
         if (!e_hwc_window_queue_init(hwc))
           {
              ERR("hwc_opt: E_Hwc_Window_Queue init failed");
@@ -372,6 +366,12 @@ e_hwc_new(E_Output *output)
              goto fail;
           }
 
+        if (!e_hwc_windows_init(hwc))
+          {
+             ERR("hwc_opt: e_hwc_windows_init failed");
+             goto fail;
+          }
+
         /* turn on sw compositor at the start */
         ecore_event_add(E_EVENT_COMPOSITOR_ENABLE, NULL, NULL, NULL);
 
@@ -397,9 +397,9 @@ e_hwc_del(E_Hwc *hwc)
       e_hwc_planes_deinit();
    else
      {
+        e_hwc_windows_deinit(hwc);
         e_hwc_window_deinit(hwc);
         e_hwc_window_queue_deinit();
-        e_hwc_windows_deinit();
      }
 
    E_FREE(hwc);
index 8eda898cfe47647180df0144d0616ae3048e1e64..df40cf4290095890f2f3a11818e225064ed7336c 100644 (file)
@@ -1,16 +1,8 @@
 #include "e.h"
 
-# include <Evas_Engine_GL_Tbm.h>
-# include <Evas_Engine_Software_Tbm.h>
-# include <sys/eventfd.h>
-# include <gbm/gbm_tbm.h>
 # include <pixman.h>
 # include <wayland-tbm-server.h>
 
-#ifndef CLEAR
-#define CLEAR(x) memset(&(x), 0, sizeof (x))
-#endif
-
 #define EHWINF(f, ec, ehw, x...)                                \
    do                                                           \
      {                                                          \
@@ -49,7 +41,6 @@
 static Eina_Bool ehw_trace = EINA_TRUE;
 static Eina_List *hwc_window_client_hooks = NULL;
 static Eina_List *hwc_window_event_hdlrs = NULL;
-static uint64_t ee_rendered_hw_list_key;
 
 static int _e_hwc_window_hooks_delete = 0;
 static int _e_hwc_window_hooks_walking = 0;
@@ -236,136 +227,6 @@ _e_hwc_window_buffer_set(E_Hwc_Window_Buffer *window_buffer,
    window_buffer->tsurface = tsurface;
 }
 
-static void
-_e_hwc_window_target_window_surface_data_free(void *data)
-{
-   Eina_List *ee_rendered_hw_list = (Eina_List *)data;
-   E_Hwc_Window *hwc_window = NULL;
-
-  if (eina_list_count(ee_rendered_hw_list))
-    {
-        EINA_LIST_FREE(ee_rendered_hw_list, hwc_window)
-          e_object_unref(E_OBJECT(hwc_window));
-    }
-}
-
-/* gets called as somebody modifies target_window's queue */
-static void
-_e_hwc_window_target_window_surface_queue_trace_cb(tbm_surface_queue_h surface_queue,
-        tbm_surface_h tsurface, tbm_surface_queue_trace trace, void *data)
-{
-   E_Hwc_Window_Target *target_hwc_window = (E_Hwc_Window_Target *)data;
-
-   /* gets called as evas_renderer dequeues a new buffer from the queue */
-   if (trace == TBM_SURFACE_QUEUE_TRACE_DEQUEUE)
-     {
-        if (!target_hwc_window->is_rendering) return;
-
-        EHWTRACE("gets dequeue noti ts:%p -- {%s}.",
-                 NULL, target_hwc_window, tsurface, "@TARGET WINDOW@");
-
-        tbm_surface_internal_add_user_data(tsurface,
-                                           (unsigned long)&ee_rendered_hw_list_key,
-                                           _e_hwc_window_target_window_surface_data_free);
-        target_hwc_window->dequeued_tsurface = tsurface;
-        target_hwc_window->rendered_tsurface_list = eina_list_append(target_hwc_window->rendered_tsurface_list,
-                                                                     tsurface);
-     }
-   /* tsurface has been released at the queue */
-   if (trace == TBM_SURFACE_QUEUE_TRACE_RELEASE)
-     {
-        tbm_surface_internal_delete_user_data(tsurface, (unsigned long)&ee_rendered_hw_list_key);
-        target_hwc_window->rendered_tsurface_list = eina_list_remove(target_hwc_window->rendered_tsurface_list,
-                                                                     tsurface);
-     }
-}
-
-/* gets called as evas_renderer enqueues a new buffer into the queue */
-static void
-_e_hwc_window_target_window_surface_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
-{
-    E_Hwc_Window_Target *target_hwc_window = (E_Hwc_Window_Target *)data;
-    uint64_t value = 1;
-    int ret;
-
-    ret = write(target_hwc_window->event_fd, &value, sizeof(value));
-    if (ret == -1)
-      ERR("failed to send acquirable event:%m");
-}
-
-/* gets called at the beginning of an ecore_main_loop iteration */
-static Eina_Bool
-_e_hwc_window_target_window_render_finished_cb(void *data, Ecore_Fd_Handler *fd_handler)
-{
-   int len;
-   int fd;
-   char buffer[64];
-
-   fd = ecore_main_fd_handler_fd_get(fd_handler);
-   if (fd < 0) return ECORE_CALLBACK_RENEW;
-
-   len = read(fd, buffer, sizeof(buffer));
-   if (len == -1)
-     ERR("failed to read queue acquire event fd:%m");
-
-   return ECORE_CALLBACK_RENEW;
-}
-
-static void
-_e_hwc_window_target_window_render_flush_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
-{
-   E_Hwc_Window_Target *target_hwc_window = (E_Hwc_Window_Target *)data;
-   E_Hwc_Window *hwc_window = NULL;
-   Eina_List *ee_rendered_hw_list;
-
-   EHWTRACE("gets render_flush_post noti ------ {@TARGET WINDOW@}", NULL, target_hwc_window);
-
-   if (!target_hwc_window->dequeued_tsurface)
-     {
-        WRN("flush_post_cb is called but tsurface isn't dequeued");
-
-        if (eina_list_count(target_hwc_window->ee_rendered_hw_list))
-          {
-             EINA_LIST_FREE(target_hwc_window->ee_rendered_hw_list, hwc_window)
-               e_object_unref(E_OBJECT(hwc_window));
-          }
-
-        target_hwc_window->ee_rendered_hw_list = NULL;
-        return;
-     }
-
-   /* all ecs have been composited so we can attach a list of composited e_hwc_windows to the surface
-    * which contains their ecs composited */
-   ee_rendered_hw_list = eina_list_clone(target_hwc_window->ee_rendered_hw_list);
-
-   tbm_surface_internal_set_user_data(target_hwc_window->dequeued_tsurface,
-           (unsigned long)&ee_rendered_hw_list_key, ee_rendered_hw_list);
-
-   eina_list_free(target_hwc_window->ee_rendered_hw_list);
-   target_hwc_window->ee_rendered_hw_list = NULL;
-   target_hwc_window->dequeued_tsurface = NULL;
-}
-
-static void
-_e_hwc_window_target_free(E_Hwc_Window_Target *target_hwc_window)
-{
-   E_Hwc_Window *target_window = (E_Hwc_Window *)target_hwc_window;
-
-   evas_event_callback_del(target_hwc_window->evas,
-                           EVAS_CALLBACK_RENDER_FLUSH_POST,
-                           _e_hwc_window_target_window_render_flush_post_cb);
-
-   ecore_main_fd_handler_del(target_hwc_window->event_hdlr);
-   close(target_hwc_window->event_fd);
-
-   if (target_window->queue->tqueue)
-     tbm_surface_queue_destroy(target_window->queue->tqueue);
-
-   EHWINF("Free target window", NULL, target_hwc_window);
-
-   E_FREE(target_hwc_window);
-}
-
 static void
 _e_hwc_window_cb_queue_destroy(struct wl_listener *listener, void *data)
 {
@@ -379,99 +240,6 @@ _e_hwc_window_cb_queue_destroy(struct wl_listener *listener, void *data)
    hwc_window->queue = NULL;
 }
 
-static E_Hwc_Window_Target *
-_e_hwc_window_target_new(E_Hwc *hwc)
-{
-   const char *name = NULL;
-   E_Hwc_Window_Target *target_hwc_window = NULL;
-   Evas *evas = NULL;
-   E_Hwc_Window_Queue *queue = NULL;
-
-   name = ecore_evas_engine_name_get(e_comp->ee);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
-
-   evas = ecore_evas_get(e_comp->ee);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(evas, NULL);
-
-   if(!strcmp("gl_drm_tbm", name) ||
-      !strcmp("drm_tbm", name) ||
-      !strcmp("gl_tbm", name) ||
-      !strcmp("software_tbm", name) ||
-      !strcmp("gl_tbm_ES", name))
-     {
-        ecore_evas_manual_render_set(e_comp->ee, 1);
-     }
-
-   target_hwc_window = E_OBJECT_ALLOC(E_Hwc_Window_Target, E_HWC_WINDOW_TYPE, _e_hwc_window_target_free);
-   EINA_SAFETY_ON_NULL_GOTO(target_hwc_window, fail);
-
-   ((E_Hwc_Window *)target_hwc_window)->is_target = EINA_TRUE;
-   ((E_Hwc_Window *)target_hwc_window)->state = E_HWC_WINDOW_STATE_DEVICE;
-   ((E_Hwc_Window *)target_hwc_window)->accepted_state = E_HWC_WINDOW_STATE_DEVICE;
-   ((E_Hwc_Window *)target_hwc_window)->hwc = hwc;
-
-   target_hwc_window->ee = e_comp->ee;
-   target_hwc_window->evas = ecore_evas_get(target_hwc_window->ee);
-   target_hwc_window->event_fd = eventfd(0, EFD_NONBLOCK);
-   target_hwc_window->event_hdlr =
-            ecore_main_fd_handler_add(target_hwc_window->event_fd, ECORE_FD_READ,
-                                      _e_hwc_window_target_window_render_finished_cb,
-                                      (void *)target_hwc_window, NULL, NULL);
-
-   ecore_evas_manual_render(target_hwc_window->ee);
-
-   queue = e_hwc_window_queue_user_set((E_Hwc_Window *)target_hwc_window);
-   if (!queue) goto fail;
-
-   wl_signal_add(&queue->destroy_signal, &((E_Hwc_Window *)target_hwc_window)->queue_destroy_listener);
-   ((E_Hwc_Window *)target_hwc_window)->queue_destroy_listener.notify = _e_hwc_window_cb_queue_destroy;
-   ((E_Hwc_Window *)target_hwc_window)->queue = queue;
-
-   /* as evas_renderer has finished its work (to provide a composited buffer) it enqueues
-    * the result buffer into this queue and acquirable cb gets called; this cb does nothing
-    * except the writing into the event_fd object, this writing causes the new ecore_main loop
-    * iteration to be triggered ('cause we've registered ecore_main fd handler to check this writing);
-    * so it's just a way to inform E20's HWC that evas_renderer has done its work */
-   tbm_surface_queue_add_acquirable_cb(queue->tqueue,
-                                       _e_hwc_window_target_window_surface_queue_acquirable_cb,
-                                       (void *)target_hwc_window);
-
-   /* TODO: we can use this call instead of an add_acquirable_cb and an add_dequeue_cb calls. */
-   tbm_surface_queue_add_trace_cb(queue->tqueue,
-                                  _e_hwc_window_target_window_surface_queue_trace_cb,
-                                  (void *)target_hwc_window);
-
-   evas_event_callback_add(evas,
-                           EVAS_CALLBACK_RENDER_FLUSH_POST,
-                           _e_hwc_window_target_window_render_flush_post_cb,
-                           target_hwc_window);
-#if 0
-   /* sorry..., current version of gcc requires an initializer to be evaluated at compile time */
-   ee_rendered_hw_list_key = (uintptr_t)&ee_rendered_hw_list_key;
-#endif
-   return target_hwc_window;
-
-fail:
-   ecore_evas_manual_render_set(e_comp->ee, 0);
-
-   return NULL;
-}
-
-static E_Hwc_Window_Target *
-_e_hwc_window_target_window_get(E_Hwc_Window *hwc_window)
-{
-   E_Hwc_Window_Target *target_hwc_window;
-   E_Hwc *hwc;
-
-   hwc = hwc_window->hwc;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
-
-   target_hwc_window = hwc->target_hwc_window;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, NULL);
-
-   return target_hwc_window;
-}
-
 static void
 _e_hwc_window_constraints_reset(E_Hwc_Window *hwc_window)
 {
@@ -865,29 +633,6 @@ _e_hwc_window_cursor_position_get(E_Pointer *ptr, int width, int height, unsigne
      }
 }
 
-static Eina_List *
-_e_hwc_window_target_window_ee_rendered_hw_list_get(E_Hwc_Window_Target *target_window)
-{
-   Eina_List *ee_rendered_hw_list = NULL, *new_list = NULL;
-   E_Hwc_Window *hw1, *hw2;
-   const Eina_List *l, *ll;
-   E_Hwc *hwc;
-   tbm_surface_h target_tsurface;
-
-   hwc = target_window->hwc_window.hwc;
-
-   target_tsurface = target_window->hwc_window.buffer.tsurface;
-   tbm_surface_internal_get_user_data(target_tsurface, (unsigned long)&ee_rendered_hw_list_key,
-                            (void**)&ee_rendered_hw_list);
-
-   /* refresh list of composited e_thwc_windows according to existed ones */
-   EINA_LIST_FOREACH(ee_rendered_hw_list, l, hw1)
-      EINA_LIST_FOREACH(hwc->hwc_windows, ll, hw2)
-         if (hw1 == hw2) new_list = eina_list_append(new_list, hw1);
-
-   return new_list;
-}
-
 static void
 _e_hwc_window_free(E_Hwc_Window *hwc_window)
 {
@@ -927,8 +672,6 @@ done:
 EINTERN Eina_Bool
 e_hwc_window_init(E_Hwc *hwc)
 {
-   E_Hwc_Window_Target *target_hwc_window;
-
    EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
 
    if (e_hwc_policy_get(hwc) == E_HWC_POLICY_PLANES)
@@ -941,15 +684,6 @@ e_hwc_window_init(E_Hwc *hwc)
    E_LIST_HANDLER_APPEND(hwc_window_event_hdlrs, E_EVENT_CLIENT_ZONE_SET,
                          _e_hwc_window_client_cb_zone_set, NULL);
 
-   target_hwc_window = _e_hwc_window_target_new(hwc);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
-   target_hwc_window->hwc = hwc;
-
-   /* set the target_window to the hwc */
-   hwc->target_hwc_window = target_hwc_window;
-
-   hwc->hwc_windows = eina_list_append(hwc->hwc_windows, target_hwc_window);
-
    return EINA_TRUE;
 }
 
@@ -963,10 +697,6 @@ e_hwc_window_deinit(E_Hwc *hwc)
 
    E_FREE_LIST(hwc_window_client_hooks, e_client_hook_del);
    E_FREE_LIST(hwc_window_event_hdlrs, ecore_event_handler_del);
-
-   hwc->hwc_windows = eina_list_remove(hwc->hwc_windows, hwc->target_hwc_window);
-   e_object_del(E_OBJECT(hwc->target_hwc_window));
-   hwc->target_hwc_window = NULL;
 }
 
 EINTERN void
@@ -1418,178 +1148,6 @@ e_hwc_window_commit_data_release(E_Hwc_Window *hwc_window)
    return EINA_TRUE;
 }
 
-EINTERN Eina_Bool
-e_hwc_window_target_can_render(E_Hwc_Window_Target *target_hwc_window)
-{
-   E_Hwc_Window *hwc_window = (E_Hwc_Window *)target_hwc_window;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->queue, EINA_FALSE);
-
-   if (e_hwc_window_queue_buffer_can_dequeue(hwc_window->queue))
-     return EINA_TRUE;
-
-   return EINA_FALSE;
-}
-
-EINTERN Eina_Bool
-e_hwc_window_target_enabled(E_Hwc_Window_Target *target_hwc_window)
-{
-   E_Hwc_Window *hwc_window;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
-
-   hwc_window = (E_Hwc_Window *)target_hwc_window;
-
-   if (hwc_window->state != E_HWC_WINDOW_STATE_DEVICE)
-      return EINA_FALSE;
-
-   return EINA_TRUE;
-}
-
-EINTERN Eina_Bool
-e_hwc_window_target_buffer_skip(E_Hwc_Window_Target *target_hwc_window)
-{
-   E_Hwc_Window *hwc_window = NULL;
-   E_Hwc_Window_Queue_Buffer *queue_buffer;
-   E_Hwc *hwc = NULL;
-   tdm_hwc *thwc = NULL;
-   tdm_region fb_damage;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
-
-   hwc_window = (E_Hwc_Window *)target_hwc_window;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->queue, EINA_FALSE);
-
-   hwc = hwc_window->hwc;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
-
-   thwc = hwc->thwc;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(thwc, EINA_FALSE);
-
-   CLEAR(fb_damage);
-
-   if (hwc_window->buffer.tsurface &&
-       hwc_window->buffer.tsurface != hwc_window->display.buffer.tsurface)
-     {
-        if (hwc_window->buffer.queue)
-          {
-             queue_buffer = e_hwc_window_queue_buffer_find(hwc_window->buffer.queue,
-                                                          hwc_window->buffer.tsurface);
-             if (queue_buffer)
-               e_hwc_window_queue_buffer_release(hwc_window->buffer.queue, queue_buffer);
-          }
-
-        _e_hwc_window_buffer_set(&hwc_window->buffer, hwc_window->display.buffer.tsurface,
-                                  hwc_window->display.buffer.queue);
-        tdm_hwc_set_client_target_buffer(thwc, hwc_window->display.buffer.tsurface, fb_damage);
-     }
-
-   return EINA_TRUE;
-}
-
-/* set the tsurface to the target_window->tsurface according to the state.
- *  1. try to set the tsurface to the target_window at E_HWC_WINDOW_STATE_DEVICE.
- *  2. try to set NULL and release(clear) tsurface_queue of the target_window at E_HWC_WINDOW_STATE_NONE.
- *  Returing EINA_FALSE means that there is no update for the target_window->tsurface.
- **/
-EINTERN Eina_Bool
-e_hwc_window_target_buffer_fetch(E_Hwc_Window_Target *target_hwc_window)
-{
-   E_Hwc *hwc;
-   E_Hwc_Window *hwc_window, *hw;
-   tdm_hwc *thwc;
-   tbm_surface_h tsurface;
-   tdm_region fb_damage;
-   Eina_List *ee_rendered_hw_list = NULL;
-   E_Hwc_Window_Queue_Buffer *queue_buffer = NULL;
-   uint32_t n_thw = 0;
-   const Eina_List *l;
-   int i;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
-
-   hwc_window = (E_Hwc_Window *)target_hwc_window;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->queue , EINA_FALSE);
-
-   hwc = hwc_window->hwc;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
-
-   thwc = hwc->thwc;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(thwc, EINA_FALSE);
-
-   if (hwc_window->state == E_HWC_WINDOW_STATE_DEVICE)
-     {
-        /* acquire the surface */
-        queue_buffer = e_hwc_window_queue_buffer_acquire(hwc_window->queue);
-        if (!queue_buffer) return EINA_FALSE;
-
-        tsurface = queue_buffer->tsurface;
-        EINA_SAFETY_ON_NULL_RETURN_VAL(tsurface, EINA_FALSE);
-
-        if (hwc_window->buffer.tsurface &&
-            hwc_window->buffer.tsurface != hwc_window->display.buffer.tsurface)
-          {
-             queue_buffer = e_hwc_window_queue_buffer_find(hwc_window->buffer.queue, hwc_window->buffer.tsurface);
-             if (queue_buffer)
-               e_hwc_window_queue_buffer_release(hwc_window->buffer.queue, queue_buffer);
-          }
-
-        _e_hwc_window_buffer_set(&hwc_window->buffer, tsurface, hwc_window->queue);
-
-        /* the damage isn't supported by hwc extension yet */
-        CLEAR(fb_damage);
-
-        tdm_hwc_set_client_target_buffer(thwc, hwc_window->buffer.tsurface, fb_damage);
-
-        if (ehw_trace)
-          {
-             ee_rendered_hw_list = _e_hwc_window_target_window_ee_rendered_hw_list_get(target_hwc_window);
-             n_thw = eina_list_count(ee_rendered_hw_list);
-             if (n_thw)
-               {
-                  EHWTRACE("FET ts:%10p ------- {%25s}, state:%s",
-                           NULL, hwc_window, hwc_window->buffer.tsurface, "@TARGET WINDOW@",
-                           e_hwc_window_state_string_get(hwc_window->state));
-
-                  i = 0;
-                  EINA_LIST_FOREACH(ee_rendered_hw_list, l, hw)
-                    {
-                       EHWTRACE("  (%d) with ------- {%25s}, state:%s, zpos:%d, deleted:%s",
-                                hwc_window->ec, hw,
-                                i++, e_hwc_window_name_get(hw),
-                                e_hwc_window_state_string_get(hw->state),
-                                hwc_window->zpos, (hwc_window->is_deleted ? "yes" : "no"));
-                    }
-                }
-              else
-                EHWTRACE("FET ts:%10p ------- {%25s}, state:%s, zpos:%d no hwc_windows to render.",
-                         NULL, hwc_window, hwc_window->buffer.tsurface, "@TARGET WINDOW@",
-                         e_hwc_window_state_string_get(hwc_window->state), hwc_window->zpos);
-          }
-     }
-   else
-     {
-        if (!hwc_window->buffer.tsurface) return EINA_FALSE;
-
-        if (hwc_window->buffer.tsurface != hwc_window->display.buffer.tsurface)
-          {
-             queue_buffer = e_hwc_window_queue_buffer_find(hwc_window->buffer.queue, hwc_window->buffer.tsurface);
-             if (queue_buffer)
-               e_hwc_window_queue_buffer_release(hwc_window->buffer.queue, queue_buffer);
-          }
-
-        _e_hwc_window_buffer_set(&hwc_window->buffer, NULL, NULL);
-
-        CLEAR(fb_damage);
-
-        tdm_hwc_set_client_target_buffer(thwc, NULL, fb_damage);
-     }
-
-   return EINA_TRUE;
-}
-
 EINTERN Eina_Bool
 e_hwc_window_activate(E_Hwc_Window *hwc_window, E_Hwc_Window_Queue *queue)
 {
@@ -1855,57 +1413,6 @@ e_hwc_window_device_state_available_check(E_Hwc_Window *hwc_window)
    return EINA_TRUE;
 }
 
-
-// add hwc_window to the render_list
-EINTERN void
-e_hwc_window_render_list_add(E_Hwc_Window *hwc_window)
-{
-   E_Hwc_Window_Target *target_hwc_window;
-   E_Client *ec;
-
-   EINA_SAFETY_ON_NULL_RETURN(hwc_window);
-
-   ec = hwc_window->ec;
-   EINA_SAFETY_ON_NULL_RETURN(ec);
-
-   target_hwc_window = _e_hwc_window_target_window_get(hwc_window);
-   EINA_SAFETY_ON_NULL_RETURN(target_hwc_window);
-
-   target_hwc_window->ee_rendered_hw_list =
-           eina_list_append(target_hwc_window->ee_rendered_hw_list, hwc_window);
-
-   e_object_ref(E_OBJECT(hwc_window));
-
-   EHWTRACE(" added the render_list -- {%25s}.", ec, hwc_window, e_hwc_window_name_get(hwc_window));
-}
-
-EINTERN Eina_Bool
-e_hwc_window_is_on_target_window(E_Hwc_Window *hwc_window)
-{
-   Eina_List *ee_rendered_hw_list = NULL;
-   E_Hwc_Window_Target *target_hwc_window;
-   E_Hwc_Window *target_window;
-   E_Hwc_Window *hw;
-   const Eina_List *l = NULL;
-   int n_thw;
-
-   target_hwc_window = _e_hwc_window_target_window_get(hwc_window);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
-
-   target_window = (E_Hwc_Window *)target_hwc_window;
-   if (e_hwc_window_state_get(target_window) != E_HWC_WINDOW_STATE_DEVICE) return EINA_FALSE;
-
-   ee_rendered_hw_list = _e_hwc_window_target_window_ee_rendered_hw_list_get(target_hwc_window);
-   n_thw = eina_list_count(ee_rendered_hw_list);
-   if (n_thw)
-     {
-        EINA_LIST_FOREACH(ee_rendered_hw_list, l, hw)
-          if (hw == hwc_window) return EINA_TRUE;
-     }
-
-   return EINA_FALSE;
-}
-
 EINTERN Eina_Bool
 e_hwc_window_constraints_update(E_Hwc_Window *hwc_window)
 {
@@ -1984,7 +1491,7 @@ _e_hwc_window_client_recover(E_Hwc_Window *hwc_window)
 }
 
 static Eina_Bool
-_e_hwc_window_render_target_window_set(E_Hwc_Window *hwc_window, Eina_Bool set)
+_e_hwc_window_rendered_window_set(E_Hwc_Window *hwc_window, Eina_Bool set)
 {
    E_Client *ec = NULL;
 
@@ -2031,7 +1538,7 @@ _e_hwc_window_render_target_window_set(E_Hwc_Window *hwc_window, Eina_Bool set)
 }
 
 EINTERN Eina_Bool
-e_hwc_window_render_target_window_update(E_Hwc_Window *hwc_window)
+e_hwc_window_rendered_window_update(E_Hwc_Window *hwc_window)
 {
    E_Client *ec = NULL;
    E_Pointer *pointer = NULL;
@@ -2051,13 +1558,13 @@ e_hwc_window_render_target_window_update(E_Hwc_Window *hwc_window)
      {
        case E_HWC_WINDOW_STATE_DEVICE:
        case E_HWC_WINDOW_STATE_CURSOR:
-         _e_hwc_window_render_target_window_set(hwc_window, EINA_FALSE);
+         _e_hwc_window_rendered_window_set(hwc_window, EINA_FALSE);
          if (pointer)
            e_pointer_hwc_set(pointer, EINA_TRUE);
          break;
        case E_HWC_WINDOW_STATE_CLIENT:
        case E_HWC_WINDOW_STATE_NONE:
-         _e_hwc_window_render_target_window_set(hwc_window, EINA_TRUE);
+         _e_hwc_window_rendered_window_set(hwc_window, EINA_TRUE);
          if (pointer)
            e_pointer_hwc_set(pointer, EINA_FALSE);
          break;
@@ -2069,6 +1576,13 @@ e_hwc_window_render_target_window_update(E_Hwc_Window *hwc_window)
    return EINA_TRUE;
 }
 
+EINTERN void
+e_hwc_window_buffer_set(E_Hwc_Window *hwc_window, tbm_surface_h tsurface, E_Hwc_Window_Queue *queue)
+{
+   EINA_SAFETY_ON_NULL_RETURN(hwc_window);
+
+   _e_hwc_window_buffer_set(&hwc_window->buffer, tsurface,queue);
+}
 
 EINTERN const char*
 e_hwc_window_state_string_get(E_Hwc_Window_State hwc_window_state)
index 70fd93f7ade7cef19b6b208e7559d82d5dc7b687..ee2d4bbe5a8526607b0b6545f65178f07f58ee3a 100644 (file)
@@ -126,8 +126,8 @@ struct _E_Hwc_Window_Target
 
    /* a surface the rendering is currently performing at */
    tbm_surface_h       dequeued_tsurface;
-   Eina_List          *rendered_tsurface_list;
-   Eina_List          *ee_rendered_hw_list;
+   Eina_List          *target_buffer_list;
+   Eina_List          *rendered_windows;
    Eina_Bool           is_rendering;
 
    Eina_Bool skip_surface_set;
@@ -156,11 +156,6 @@ EINTERN Eina_Bool          e_hwc_window_is_cursor(E_Hwc_Window *hwc_window);
 EINTERN Eina_Bool          e_hwc_window_commit_data_acquire(E_Hwc_Window *hwc_window);
 EINTERN Eina_Bool          e_hwc_window_commit_data_release(E_Hwc_Window *hwc_window);
 
-EINTERN Eina_Bool          e_hwc_window_target_can_render(E_Hwc_Window_Target *target_hwc_window);
-EINTERN Eina_Bool          e_hwc_window_target_enabled(E_Hwc_Window_Target *target_hwc_window);
-EINTERN Eina_Bool          e_hwc_window_target_buffer_fetch(E_Hwc_Window_Target *target_hwc_window);
-EINTERN Eina_Bool          e_hwc_window_target_buffer_skip(E_Hwc_Window_Target *target_hwc_window);
-
 EINTERN Eina_Bool          e_hwc_window_activate(E_Hwc_Window *hwc_window, E_Hwc_Window_Queue *queue);
 EINTERN Eina_Bool          e_hwc_window_deactivate(E_Hwc_Window *hwc_window);
 EINTERN Eina_Bool          e_hwc_window_is_on_hw_overlay(E_Hwc_Window *hwc_window);
@@ -173,11 +168,8 @@ EINTERN E_Hwc_Window_State e_hwc_window_accepted_state_get(E_Hwc_Window *hwc_win
 EINTERN Eina_Bool          e_hwc_window_device_state_available_check(E_Hwc_Window *hwc_window);
 
 EINTERN Eina_Bool          e_hwc_window_constraints_update(E_Hwc_Window *hwc_window);
-
-EINTERN void               e_hwc_window_render_list_add(E_Hwc_Window *hwc_window);
-EINTERN Eina_Bool          e_hwc_window_is_on_target_window(E_Hwc_Window *hwc_window);
-EINTERN Eina_Bool          e_hwc_window_render_target_window_update(E_Hwc_Window *hwc_window);
-
+EINTERN Eina_Bool          e_hwc_window_rendered_window_update(E_Hwc_Window *hwc_window);
+EINTERN void               e_hwc_window_buffer_set(E_Hwc_Window *hwc_window, tbm_surface_h tsurface, E_Hwc_Window_Queue *queue);
 EINTERN const char        *e_hwc_window_state_string_get(E_Hwc_Window_State hwc_window_state);
 EINTERN const char        *e_hwc_window_name_get(E_Hwc_Window *hwc_window);
 
index 07201c03718a4025e7f4d68b2b6073c0db481ad5..96728fd1fb6f71fc6547e3a76e21df82bdac11b2 100644 (file)
@@ -1,10 +1,17 @@
 #include "e.h"
 #include "services/e_service_quickpanel.h"
+# include <Evas_Engine_GL_Tbm.h>
+# include <Evas_Engine_Software_Tbm.h>
+# include <sys/eventfd.h>
 
 #define DBG_EVALUATE 1
 
 #define ZPOS_NONE -999
 
+#ifndef CLEAR
+#define CLEAR(x) memset(&(x), 0, sizeof (x))
+#endif
+
 #define EHWSINF(f, ec, x...)                                \
    do                                                       \
      {                                                      \
@@ -39,6 +46,7 @@
    while (0)
 
 static Eina_Bool ehws_trace = EINA_TRUE;
+static uint64_t rendered_windows_key;
 
 static Eina_Bool _e_hwc_windows_pp_output_data_commit(E_Hwc *hwc, E_Hwc_Window_Commit_Data *data);
 static Eina_Bool _e_hwc_windows_pp_window_commit(E_Hwc *hwc, E_Hwc_Window *hwc_window);
@@ -185,6 +193,413 @@ _e_hwc_windows_offscreen_commit(E_Hwc *hwc)
      }
 }
 
+static Eina_List *
+_e_hwc_windows_target_window_rendered_windows_get(E_Hwc *hwc)
+{
+   E_Hwc_Window_Target *target_hwc_window;
+   Eina_List *rendered_windows = NULL, *new_list = NULL;
+   E_Hwc_Window *hw1, *hw2;
+   const Eina_List *l, *ll;
+   tbm_surface_h target_tsurface;
+
+   target_hwc_window = hwc->target_hwc_window;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, NULL);
+
+   target_tsurface = target_hwc_window->hwc_window.buffer.tsurface;
+   tbm_surface_internal_get_user_data(target_tsurface, (unsigned long)&rendered_windows_key,
+                            (void**)&rendered_windows);
+
+   /* refresh list of composited e_thwc_windows according to existed ones */
+   EINA_LIST_FOREACH(rendered_windows, l, hw1)
+      EINA_LIST_FOREACH(hwc->hwc_windows, ll, hw2)
+         if (hw1 == hw2) new_list = eina_list_append(new_list, hw1);
+
+   return new_list;
+}
+
+static Eina_Bool
+_e_hwc_windows_target_window_buffer_skip(E_Hwc *hwc)
+{
+   E_Hwc_Window_Target *target_hwc_window;
+   E_Hwc_Window *hwc_window = NULL;
+   E_Hwc_Window_Queue_Buffer *queue_buffer;
+   tdm_hwc *thwc = NULL;
+   tdm_region fb_damage;
+
+   target_hwc_window = hwc->target_hwc_window;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
+
+   hwc_window = (E_Hwc_Window *)target_hwc_window;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->queue, EINA_FALSE);
+
+   thwc = hwc->thwc;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(thwc, EINA_FALSE);
+
+   CLEAR(fb_damage);
+
+   if (hwc_window->buffer.tsurface &&
+       hwc_window->buffer.tsurface != hwc_window->display.buffer.tsurface)
+     {
+        if (hwc_window->buffer.queue)
+          {
+             queue_buffer = e_hwc_window_queue_buffer_find(hwc_window->buffer.queue, hwc_window->buffer.tsurface);
+             if (queue_buffer)
+               e_hwc_window_queue_buffer_release(hwc_window->buffer.queue, queue_buffer);
+          }
+
+        e_hwc_window_buffer_set(hwc_window, hwc_window->display.buffer.tsurface, hwc_window->display.buffer.queue);
+        tdm_hwc_set_client_target_buffer(thwc, hwc_window->display.buffer.tsurface, fb_damage);
+     }
+
+   return EINA_TRUE;
+}
+
+/* set the tsurface to the target_window->tsurface according to the state.
+ *  1. try to set the tsurface to the target_window at E_HWC_WINDOW_STATE_DEVICE.
+ *  2. try to set NULL and release(clear) tsurface_queue of the target_window at E_HWC_WINDOW_STATE_NONE.
+ *  Returing EINA_FALSE means that there is no update for the target_window->tsurface.
+ **/
+static Eina_Bool
+_e_hwc_windows_target_buffer_fetch(E_Hwc *hwc)
+{
+   E_Hwc_Window_Target *target_hwc_window;
+   E_Hwc_Window *hwc_window, *hw;
+   tdm_hwc *thwc;
+   tbm_surface_h tsurface;
+   tdm_region fb_damage;
+   Eina_List *rendered_windows = NULL;
+   E_Hwc_Window_Queue_Buffer *queue_buffer = NULL;
+   uint32_t n_thw = 0;
+   const Eina_List *l;
+   int i;
+
+   target_hwc_window = hwc->target_hwc_window;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
+
+   hwc_window = (E_Hwc_Window *)target_hwc_window;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->queue , EINA_FALSE);
+
+   thwc = hwc->thwc;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(thwc, EINA_FALSE);
+
+   if (hwc_window->state == E_HWC_WINDOW_STATE_DEVICE)
+     {
+        /* acquire the surface */
+        queue_buffer = e_hwc_window_queue_buffer_acquire(hwc_window->queue);
+        if (!queue_buffer) return EINA_FALSE;
+
+        tsurface = queue_buffer->tsurface;
+        EINA_SAFETY_ON_NULL_RETURN_VAL(tsurface, EINA_FALSE);
+
+        if (hwc_window->buffer.tsurface &&
+            hwc_window->buffer.tsurface != hwc_window->display.buffer.tsurface)
+          {
+             queue_buffer = e_hwc_window_queue_buffer_find(hwc_window->buffer.queue, hwc_window->buffer.tsurface);
+             if (queue_buffer)
+               e_hwc_window_queue_buffer_release(hwc_window->buffer.queue, queue_buffer);
+          }
+
+        e_hwc_window_buffer_set(hwc_window, tsurface, hwc_window->queue);
+
+        /* the damage isn't supported by hwc extension yet */
+        CLEAR(fb_damage);
+
+        tdm_hwc_set_client_target_buffer(thwc, hwc_window->buffer.tsurface, fb_damage);
+
+        if (ehws_trace)
+          {
+             rendered_windows = _e_hwc_windows_target_window_rendered_windows_get(hwc);
+             n_thw = eina_list_count(rendered_windows);
+             if (n_thw)
+               {
+                  EHWSTRACE("FET {%s} ts:%p state:%s has hwc_windows to render below.",
+                           NULL, "@TARGET WINDOW@", hwc_window->buffer.tsurface,
+                           e_hwc_window_state_string_get(hwc_window->state));
+
+                  i = 0;
+                  EINA_LIST_FOREACH(rendered_windows, l, hw)
+                    {
+                       EHWSTRACE("  (%d) ehw:%p ts:%p -- {%25s}, state:%s, zpos:%d, deleted:%s",
+                                hwc_window->ec, i++, hw, hw->buffer.tsurface, e_hwc_window_name_get(hw),
+                                e_hwc_window_state_string_get(hw->state), hwc_window->zpos,
+                                (hwc_window->is_deleted ? "yes" : "no"));
+                    }
+                }
+              else
+                EHWSTRACE("FET {%s} ts:%p state:%s has no hwc_windows to render.",
+                         NULL, "@TARGET WINDOW@", hwc_window->buffer.tsurface,
+                         e_hwc_window_state_string_get(hwc_window->state));
+          }
+     }
+   else
+     {
+        if (!hwc_window->buffer.tsurface) return EINA_FALSE;
+
+        if (hwc_window->buffer.tsurface != hwc_window->display.buffer.tsurface)
+          {
+             queue_buffer = e_hwc_window_queue_buffer_find(hwc_window->buffer.queue, hwc_window->buffer.tsurface);
+             if (queue_buffer)
+               e_hwc_window_queue_buffer_release(hwc_window->buffer.queue, queue_buffer);
+          }
+
+        e_hwc_window_buffer_set(hwc_window, NULL, NULL);
+
+        CLEAR(fb_damage);
+
+        tdm_hwc_set_client_target_buffer(thwc, NULL, fb_damage);
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_hwc_windows_target_window_rendered_window_has(E_Hwc *hwc, E_Hwc_Window *hwc_window)
+{
+   Eina_List *rendered_windows = NULL;
+   E_Hwc_Window_Target *target_hwc_window;
+   E_Hwc_Window *target_window;
+   E_Hwc_Window *hw;
+   const Eina_List *l = NULL;
+   int n_thw;
+
+   target_hwc_window = hwc->target_hwc_window;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
+
+   target_window = (E_Hwc_Window *)target_hwc_window;
+   if (e_hwc_window_state_get(target_window) != E_HWC_WINDOW_STATE_DEVICE) return EINA_FALSE;
+
+   rendered_windows = _e_hwc_windows_target_window_rendered_windows_get(hwc);
+   n_thw = eina_list_count(rendered_windows);
+   if (n_thw)
+     {
+        EINA_LIST_FOREACH(rendered_windows, l, hw)
+          if (hw == hwc_window) return EINA_TRUE;
+     }
+
+   return EINA_FALSE;
+}
+
+static void
+_e_hwc_windows_rendered_windows_free(void *data)
+{
+   Eina_List *rendered_windows = (Eina_List *)data;
+   E_Hwc_Window *hwc_window = NULL;
+
+  if (eina_list_count(rendered_windows))
+    {
+        EINA_LIST_FREE(rendered_windows, hwc_window)
+          e_object_unref(E_OBJECT(hwc_window));
+    }
+}
+
+/* gets called as somebody modifies target_window's queue */
+static void
+_e_hwc_windows_target_window_surface_queue_trace_cb(tbm_surface_queue_h surface_queue,
+        tbm_surface_h tsurface, tbm_surface_queue_trace trace, void *data)
+{
+   E_Hwc_Window_Target *target_hwc_window = (E_Hwc_Window_Target *)data;
+
+   /* gets called as evas_renderer dequeues a new buffer from the queue */
+   if (trace == TBM_SURFACE_QUEUE_TRACE_DEQUEUE)
+     {
+        if (!target_hwc_window->is_rendering) return;
+
+        EHWSTRACE("{%s} dequeue ts:%p", NULL, "@TARGET WINDOW@", tsurface);
+
+        tbm_surface_internal_add_user_data(tsurface,
+                                           (unsigned long)&rendered_windows_key,
+                                           _e_hwc_windows_rendered_windows_free);
+        target_hwc_window->dequeued_tsurface = tsurface;
+        target_hwc_window->target_buffer_list = eina_list_append(target_hwc_window->target_buffer_list,
+                                                                     tsurface);
+     }
+
+   /* tsurface has been released at the queue */
+   if (trace == TBM_SURFACE_QUEUE_TRACE_RELEASE)
+     {
+        EHWSTRACE("{%s} release ts:%p", NULL, "@TARGET WINDOW@", tsurface);
+
+        tbm_surface_internal_delete_user_data(tsurface, (unsigned long)&rendered_windows_key);
+        target_hwc_window->target_buffer_list = eina_list_remove(target_hwc_window->target_buffer_list,
+                                                                     tsurface);
+     }
+}
+
+/* gets called as evas_renderer enqueues a new buffer into the queue */
+static void
+_e_hwc_windows_target_window_surface_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
+{
+    E_Hwc_Window_Target *target_hwc_window = (E_Hwc_Window_Target *)data;
+    uint64_t value = 1;
+    int ret;
+
+    ret = write(target_hwc_window->event_fd, &value, sizeof(value));
+    if (ret == -1)
+      ERR("failed to send acquirable event:%m");
+}
+
+/* gets called at the beginning of an ecore_main_loop iteration */
+static Eina_Bool
+_e_hwc_windows_target_window_render_finished_cb(void *data, Ecore_Fd_Handler *fd_handler)
+{
+   int len;
+   int fd;
+   char buffer[64];
+
+   fd = ecore_main_fd_handler_fd_get(fd_handler);
+   if (fd < 0) return ECORE_CALLBACK_RENEW;
+
+   len = read(fd, buffer, sizeof(buffer));
+   if (len == -1)
+     ERR("failed to read queue acquire event fd:%m");
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_e_hwc_windows_target_window_render_flush_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   E_Hwc_Window_Target *target_hwc_window = (E_Hwc_Window_Target *)data;
+   E_Hwc_Window *hwc_window = NULL;
+   Eina_List *rendered_windows;
+
+   EHWSTRACE("{%s} gets render_flush_post noti.", NULL, "@TARGET WINDOW@");
+
+   if (!target_hwc_window->dequeued_tsurface)
+     {
+        WRN("flush_post_cb is called but tsurface isn't dequeued");
+
+        if (eina_list_count(target_hwc_window->rendered_windows))
+          {
+             EINA_LIST_FREE(target_hwc_window->rendered_windows, hwc_window)
+               e_object_unref(E_OBJECT(hwc_window));
+          }
+
+        target_hwc_window->rendered_windows = NULL;
+        return;
+     }
+
+   /* all ecs have been composited so we can attach a list of composited e_hwc_windows to the surface
+    * which contains their ecs composited */
+   rendered_windows = eina_list_clone(target_hwc_window->rendered_windows);
+
+   tbm_surface_internal_set_user_data(target_hwc_window->dequeued_tsurface,
+           (unsigned long)&rendered_windows_key, rendered_windows);
+
+   eina_list_free(target_hwc_window->rendered_windows);
+   target_hwc_window->rendered_windows = NULL;
+   target_hwc_window->dequeued_tsurface = NULL;
+}
+
+static void
+_e_hwc_windows_target_window_free(E_Hwc_Window_Target *target_hwc_window)
+{
+   E_Hwc_Window *target_window = (E_Hwc_Window *)target_hwc_window;
+
+   evas_event_callback_del(target_hwc_window->evas,
+                           EVAS_CALLBACK_RENDER_FLUSH_POST,
+                           _e_hwc_windows_target_window_render_flush_post_cb);
+
+   ecore_main_fd_handler_del(target_hwc_window->event_hdlr);
+   close(target_hwc_window->event_fd);
+
+   if (target_window->queue->tqueue)
+     tbm_surface_queue_destroy(target_window->queue->tqueue);
+
+   EHWSINF("Free target window", NULL);
+
+   E_FREE(target_hwc_window);
+}
+
+static void
+_e_hwc_windows_target_cb_queue_destroy(struct wl_listener *listener, void *data)
+{
+   E_Hwc_Window *hwc_window = NULL;
+
+   hwc_window = container_of(listener, E_Hwc_Window, queue_destroy_listener);
+   EINA_SAFETY_ON_NULL_RETURN(hwc_window);
+
+   if ((E_Hwc_Window_Queue *)data != hwc_window->queue) return;
+
+   hwc_window->queue = NULL;
+}
+
+static E_Hwc_Window_Target *
+_e_hwc_windows_target_window_new(E_Hwc *hwc)
+{
+   const char *name = NULL;
+   E_Hwc_Window_Target *target_hwc_window = NULL;
+   Evas *evas = NULL;
+   E_Hwc_Window_Queue *queue = NULL;
+
+   name = ecore_evas_engine_name_get(e_comp->ee);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
+
+   evas = ecore_evas_get(e_comp->ee);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(evas, NULL);
+
+   if(!strcmp("gl_drm_tbm", name) ||
+      !strcmp("drm_tbm", name) ||
+      !strcmp("gl_tbm", name) ||
+      !strcmp("software_tbm", name) ||
+      !strcmp("gl_tbm_ES", name))
+     {
+        ecore_evas_manual_render_set(e_comp->ee, 1);
+     }
+
+   target_hwc_window = E_OBJECT_ALLOC(E_Hwc_Window_Target, E_HWC_WINDOW_TYPE, _e_hwc_windows_target_window_free);
+   EINA_SAFETY_ON_NULL_GOTO(target_hwc_window, fail);
+
+   ((E_Hwc_Window *)target_hwc_window)->is_target = EINA_TRUE;
+   ((E_Hwc_Window *)target_hwc_window)->state = E_HWC_WINDOW_STATE_DEVICE;
+   ((E_Hwc_Window *)target_hwc_window)->accepted_state = E_HWC_WINDOW_STATE_DEVICE;
+   ((E_Hwc_Window *)target_hwc_window)->hwc = hwc;
+
+   target_hwc_window->ee = e_comp->ee;
+   target_hwc_window->evas = ecore_evas_get(target_hwc_window->ee);
+   target_hwc_window->event_fd = eventfd(0, EFD_NONBLOCK);
+   target_hwc_window->event_hdlr =
+            ecore_main_fd_handler_add(target_hwc_window->event_fd, ECORE_FD_READ,
+                                      _e_hwc_windows_target_window_render_finished_cb,
+                                      (void *)target_hwc_window, NULL, NULL);
+
+   ecore_evas_manual_render(target_hwc_window->ee);
+
+   queue = e_hwc_window_queue_user_set((E_Hwc_Window *)target_hwc_window);
+   if (!queue) goto fail;
+
+   wl_signal_add(&queue->destroy_signal, &((E_Hwc_Window *)target_hwc_window)->queue_destroy_listener);
+   ((E_Hwc_Window *)target_hwc_window)->queue_destroy_listener.notify = _e_hwc_windows_target_cb_queue_destroy;
+   ((E_Hwc_Window *)target_hwc_window)->queue = queue;
+
+   /* as evas_renderer has finished its work (to provide a composited buffer) it enqueues
+    * the result buffer into this queue and acquirable cb gets called; this cb does nothing
+    * except the writing into the event_fd object, this writing causes the new ecore_main loop
+    * iteration to be triggered ('cause we've registered ecore_main fd handler to check this writing);
+    * so it's just a way to inform E20's HWC that evas_renderer has done its work */
+   tbm_surface_queue_add_acquirable_cb(queue->tqueue,
+                                       _e_hwc_windows_target_window_surface_queue_acquirable_cb,
+                                       (void *)target_hwc_window);
+
+   /* TODO: we can use this call instead of an add_acquirable_cb and an add_dequeue_cb calls. */
+   tbm_surface_queue_add_trace_cb(queue->tqueue,
+                                  _e_hwc_windows_target_window_surface_queue_trace_cb,
+                                  (void *)target_hwc_window);
+
+   evas_event_callback_add(evas,
+                           EVAS_CALLBACK_RENDER_FLUSH_POST,
+                           _e_hwc_windows_target_window_render_flush_post_cb,
+                           target_hwc_window);
+
+   return target_hwc_window;
+
+fail:
+   ecore_evas_manual_render_set(e_comp->ee, 0);
+
+   return NULL;
+}
+
 static E_Hwc_Window *
 _e_hwc_windows_pp_window_get(E_Hwc *hwc, tbm_surface_h tsurface)
 {
@@ -788,7 +1203,7 @@ _e_hwc_windows_transition_check(E_Hwc *hwc)
         if (hwc_window->state == E_HWC_WINDOW_STATE_CLIENT &&
             hwc_window->accepted_state == E_HWC_WINDOW_STATE_DEVICE)
           {
-             if (!e_hwc_window_is_on_target_window(hwc_window))
+             if (!_e_hwc_windows_target_window_rendered_window_has(hwc, hwc_window))
                {
                   hwc_window->transition = E_HWC_WINDOW_TRANSITION_DEVICE_TO_CLIENT;
                   transition = EINA_TRUE;
@@ -798,7 +1213,7 @@ _e_hwc_windows_transition_check(E_Hwc *hwc)
         else if (hwc_window->state == E_HWC_WINDOW_STATE_CLIENT &&
                  hwc_window->accepted_state == E_HWC_WINDOW_STATE_CURSOR)
           {
-             if (!e_hwc_window_is_on_target_window(hwc_window))
+             if (!_e_hwc_windows_target_window_rendered_window_has(hwc, hwc_window))
                {
                   hwc_window->transition = E_HWC_WINDOW_TRANSITION_CURSOR_TO_CLIENT;
                   transition = EINA_TRUE;
@@ -808,7 +1223,7 @@ _e_hwc_windows_transition_check(E_Hwc *hwc)
         else if (hwc_window->state == E_HWC_WINDOW_STATE_DEVICE &&
                  hwc_window->accepted_state == E_HWC_WINDOW_STATE_NONE)
           {
-             if (e_hwc_window_is_on_target_window(hwc_window))
+             if (_e_hwc_windows_target_window_rendered_window_has(hwc, hwc_window))
                {
                   hwc_window->transition = E_HWC_WINDOW_TRANSITION_NONE_TO_DEVICE;
                   transition = EINA_TRUE;
@@ -818,7 +1233,7 @@ _e_hwc_windows_transition_check(E_Hwc *hwc)
         else if (hwc_window->state == E_HWC_WINDOW_STATE_CURSOR &&
                  hwc_window->accepted_state == E_HWC_WINDOW_STATE_NONE)
           {
-             if (e_hwc_window_is_on_target_window(hwc_window))
+             if (_e_hwc_windows_target_window_rendered_window_has(hwc, hwc_window))
                {
                   hwc_window->transition = E_HWC_WINDOW_TRANSITION_NONE_TO_CURSOR;
                   transition = EINA_TRUE;
@@ -828,7 +1243,7 @@ _e_hwc_windows_transition_check(E_Hwc *hwc)
         else if (hwc_window->state == E_HWC_WINDOW_STATE_DEVICE &&
                  hwc_window->accepted_state == E_HWC_WINDOW_STATE_CLIENT)
           {
-             if (e_hwc_window_is_on_target_window(hwc_window))
+             if (_e_hwc_windows_target_window_rendered_window_has(hwc, hwc_window))
                {
                   hwc_window->transition = E_HWC_WINDOW_TRANSITION_CLIENT_TO_DEVICE;
                   transition = EINA_TRUE;
@@ -838,7 +1253,7 @@ _e_hwc_windows_transition_check(E_Hwc *hwc)
         else if (hwc_window->state == E_HWC_WINDOW_STATE_CURSOR &&
                  hwc_window->accepted_state == E_HWC_WINDOW_STATE_CLIENT)
           {
-             if (e_hwc_window_is_on_target_window(hwc_window))
+             if (_e_hwc_windows_target_window_rendered_window_has(hwc, hwc_window))
                {
                   hwc_window->transition = E_HWC_WINDOW_TRANSITION_CLIENT_TO_CURSOR;
                   transition = EINA_TRUE;
@@ -998,29 +1413,6 @@ error:
    return EINA_FALSE;
 }
 
-static Eina_Bool
-_e_hwc_windows_target_window_render(E_Output *output, E_Hwc_Window_Target *target_hwc_window)
-{
-   if (target_hwc_window->hwc_window.state == E_HWC_WINDOW_STATE_NONE) return EINA_TRUE;
-
-   if (e_comp_canvas_norender_get() > 0)
-     {
-        EHWSTRACE(" NoRender get. Do not ecore_evas_manual_render.", NULL);
-        return EINA_TRUE;
-     }
-
-   if (e_hwc_window_target_can_render(target_hwc_window))
-     {
-        TRACE_DS_BEGIN(MANUAL RENDER);
-        target_hwc_window->is_rendering = EINA_TRUE;
-        ecore_evas_manual_render(target_hwc_window->ee);
-        target_hwc_window->is_rendering = EINA_FALSE;
-        TRACE_DS_END();
-     }
-
-   return EINA_TRUE;
-}
-
 static Eina_List *
 _e_hwc_windows_visible_windows_list_get(E_Hwc *hwc)
 {
@@ -1265,7 +1657,7 @@ _e_hwc_windows_changes_update(E_Hwc *hwc)
      update_changes = EINA_TRUE;
 
    /* fetch the target buffer */
-   if (e_hwc_window_target_buffer_fetch(hwc->target_hwc_window)) // try aquire
+   if (_e_hwc_windows_target_buffer_fetch(hwc)) // try aquire
      update_changes = EINA_TRUE;
 
    EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
@@ -1290,7 +1682,10 @@ _e_hwc_windows_changes_update(E_Hwc *hwc)
 
    /* update the states of the visible windows when there is something to update */
    if (update_changes)
-     _e_hwc_windows_visible_windows_states_update(hwc);
+     {
+        EHWSTRACE("======= HWC Update the Windows' Changes =====", NULL);
+        _e_hwc_windows_visible_windows_states_update(hwc);
+     }
 
    return update_changes;
 }
@@ -1340,7 +1735,7 @@ _e_hwc_windows_evaluate(E_Hwc *hwc)
         if (e_hwc_window_is_target(hwc_window)) continue;
 
         e_hwc_window_constraints_update(hwc_window);
-        e_hwc_window_render_target_window_update(hwc_window);
+        e_hwc_window_rendered_window_update(hwc_window);
 
         if (hwc_window->state == E_HWC_WINDOW_STATE_CLIENT) num_client++;
         if (hwc_window->state == E_HWC_WINDOW_STATE_DEVICE) num_device++;
@@ -1370,7 +1765,7 @@ _e_hwc_windows_evaluate(E_Hwc *hwc)
    /* skip the target_buffer when the window is on trainsition of the composition */
    if (hwc_mode != E_HWC_MODE_FULL && _e_hwc_windows_transition_check(hwc))
      {
-        e_hwc_window_target_buffer_skip(hwc->target_hwc_window);
+        _e_hwc_windows_target_window_buffer_skip(hwc);
         goto re_evaluate;
      }
 
@@ -1405,29 +1800,68 @@ _e_hwc_windows_target_buffer_prepared(E_Hwc *hwc)
 EINTERN Eina_Bool
 e_hwc_windows_init(E_Hwc *hwc)
 {
+   E_Hwc_Window_Target *target_hwc_window;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
+
+   if (e_hwc_policy_get(hwc) == E_HWC_POLICY_PLANES)
+     return EINA_FALSE;
+
+   target_hwc_window = _e_hwc_windows_target_window_new(hwc);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
+   target_hwc_window->hwc = hwc;
+
+   /* set the target_window to the hwc */
+   hwc->target_hwc_window = target_hwc_window;
+
+   hwc->hwc_windows = eina_list_append(hwc->hwc_windows, target_hwc_window);
+
    return EINA_TRUE;
 }
 
 EINTERN void
-e_hwc_windows_deinit(void)
+e_hwc_windows_deinit(E_Hwc *hwc)
 {
+   EINA_SAFETY_ON_NULL_RETURN(hwc);
+
+   if (e_hwc_policy_get(hwc) == E_HWC_POLICY_PLANES)
+     return;
+
+   hwc->hwc_windows = eina_list_remove(hwc->hwc_windows, hwc->target_hwc_window);
+   e_object_del(E_OBJECT(hwc->target_hwc_window));
+   hwc->target_hwc_window = NULL;
 }
 
 EINTERN Eina_Bool
 e_hwc_windows_render(E_Hwc *hwc)
 {
-   E_Output *output = hwc->output;
    E_Hwc_Window_Target *target_hwc_window;
+   E_Hwc_Window *target_window;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
 
    target_hwc_window = hwc->target_hwc_window;
-   if (!target_hwc_window)
+   EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
+
+   target_window = (E_Hwc_Window *)target_hwc_window;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(target_window->queue, EINA_FALSE);
+
+   if (e_hwc_window_state_get(target_window) == E_HWC_WINDOW_STATE_NONE) return EINA_TRUE;
+
+   if (e_comp_canvas_norender_get() > 0)
      {
-        ERR("fail to get target hwc_window for output(%p).", output);
-        return EINA_FALSE;
+        EHWSTRACE(" NoRender get. Do not ecore_evas_manual_render.", NULL);
+        return EINA_TRUE;
      }
 
-   if (!_e_hwc_windows_target_window_render(output, target_hwc_window))
-     ERR("fail to render output(%p).", output);
+   if (e_hwc_window_queue_buffer_can_dequeue(target_window->queue))
+     {
+        TRACE_DS_BEGIN(MANUAL RENDER);
+        target_hwc_window->is_rendering = EINA_TRUE;
+        ecore_evas_manual_render(target_hwc_window->ee);
+        target_hwc_window->is_rendering = EINA_FALSE;
+        TRACE_DS_END();
+     }
 
    return EINA_TRUE;
 }
@@ -1628,3 +2062,31 @@ e_hwc_windows_zoom_unset(E_Hwc *hwc)
    if (write(hwc->target_hwc_window->event_fd, &value, sizeof(value)) < 0)
      ERR("failed to wake up main loop:%m");
 }
+
+// add hwc_window to the render_list
+EINTERN void
+e_hwc_windows_rendered_window_add(E_Hwc_Window *hwc_window)
+{
+   E_Hwc *hwc;
+   E_Hwc_Window_Target *target_hwc_window;
+   E_Client *ec;
+
+   EINA_SAFETY_ON_NULL_RETURN(hwc_window);
+
+   ec = hwc_window->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   hwc = hwc_window->hwc;
+   EINA_SAFETY_ON_NULL_RETURN(hwc);
+
+   target_hwc_window = hwc->target_hwc_window;
+   EINA_SAFETY_ON_NULL_RETURN(target_hwc_window);
+
+   target_hwc_window->rendered_windows =
+           eina_list_append(target_hwc_window->rendered_windows, hwc_window);
+
+   e_object_ref(E_OBJECT(hwc_window));
+
+   EHWSTRACE(" add ehw:%p ts:%p to the render_list -- {%25s}.", ec, hwc_window,
+            hwc_window->buffer.tsurface, e_hwc_window_name_get(hwc_window));
+}
index 084b7ba1a7efb537c38623196465d56a77b01ea7..43cce175cd2803ca46915c2bd21adcab1713dbf5 100644 (file)
@@ -4,11 +4,10 @@
 #define E_HWC_WINDOWS_H
 
 EINTERN Eina_Bool            e_hwc_windows_init(E_Hwc *hwc);
-EINTERN void                 e_hwc_windows_deinit(void);
-
+EINTERN void                 e_hwc_windows_deinit(E_Hwc *hwc);
 EINTERN Eina_Bool            e_hwc_windows_render(E_Hwc *hwc);
 EINTERN Eina_Bool            e_hwc_windows_commit(E_Hwc *hwc);
-
+EINTERN void                 e_hwc_windows_rendered_window_add(E_Hwc_Window *hwc_window);
 EINTERN Eina_Bool            e_hwc_windows_pp_commit_possible_check(E_Hwc *hwc);
 EINTERN Eina_Bool            e_hwc_windows_zoom_set(E_Hwc *hwc, Eina_Rectangle *rect);
 EINTERN void                 e_hwc_windows_zoom_unset(E_Hwc *hwc);