e_output: refactor the synchronous unset of the plane.
authorSooChan Lim <sc1.lim@samsung.com>
Mon, 19 Jun 2017 11:09:08 +0000 (20:09 +0900)
committerBoram Park <boram1288.park@samsung.com>
Wed, 5 Jul 2017 02:56:57 +0000 (11:56 +0900)
The plane is set to be null at the e_plane_ec_set(plane, NULL);
To set null to a plane means two things.
1. If the plane is fb target, the plane uses the ecore_evas.
2. If the plane is not fb target, the plane needs to unset
  at the time that the result of the ecore_evas renderer(compositing)
  is finished with the tsurface(ec) of the plane. For this,
  we set the unset_candidate flags to the plane and measure to unset
  the plane at the e_output_commit.

Change-Id: I6f91a143a0f30727d6284063063505c9ad3773f1
Signed-off-by: SooChan Lim <sc1.lim@samsung.com>
src/bin/e_output.c
src/bin/e_plane.c
src/bin/e_plane.h

index 747f300..9f40171 100644 (file)
@@ -650,7 +650,7 @@ e_output_render(E_Output *output)
 EINTERN Eina_Bool
 e_output_commit(E_Output *output)
 {
-   E_Plane *plane = NULL;
+   E_Plane *plane = NULL, *fb_target = NULL;
    Eina_List *l;
    Eina_Bool fb_commit = EINA_FALSE;
 
@@ -662,41 +662,54 @@ e_output_commit(E_Output *output)
         return EINA_FALSE;
      }
 
+   fb_target = e_output_fb_target_get(output);
+
+   /* fetch the fb_target at first */
+   fb_commit = e_plane_fetch(fb_target);
+   if (fb_commit && (output->dpms == E_OUTPUT_DPMS_OFF))
+     e_plane_unfetch(fb_target);
+
    /* set planes */
    EINA_LIST_FOREACH(output->planes, l, plane)
      {
-        if (plane->need_unset && plane->sync_unset_count)
+        /* skip the fb_target fetch because we do this previously */
+        if (e_plane_is_fb_target(plane)) continue;
+
+        /* if the plane is the candidate to unset,
+           set the plane to be unset_try */
+        if (e_plane_is_unset_candidate(plane))
+          e_plane_unset_try_set(plane, EINA_TRUE);
+
+        /* if the plane is trying to unset,
+           1. if fetching the fb is not available, continue.
+           2. if fetching the fb is available, verify the unset commit check.  */
+        if (e_plane_is_unset_try(plane))
           {
-             if (!fb_commit) continue;
-
-             plane->sync_unset_count--;
-             if (plane->sync_unset_count) continue;
+            if (!fb_commit) continue;
+            if (!e_plane_unset_commit_check(plane)) continue;
           }
 
+        /* fetch the surface to the plane */
         if (!e_plane_fetch(plane)) continue;
 
-        if (e_plane_is_fb_target(plane))
-          fb_commit = EINA_TRUE;
-
         if (output->dpms == E_OUTPUT_DPMS_OFF)
-          {
-             if (!plane->need_unset_commit)
-               e_plane_unfetch(plane);
-          }
+          e_plane_unfetch(plane);
+
+        if (e_plane_is_unset_try(plane))
+          e_plane_unset_try_set(plane, EINA_FALSE);
      }
 
    if (output->dpms == E_OUTPUT_DPMS_OFF) return EINA_TRUE;
 
    EINA_LIST_FOREACH(output->planes, l, plane)
      {
-        if (plane->need_unset_commit && plane->sync_unset_count)
-          continue;
-
-        if (e_plane_is_fb_target(plane) && fb_commit)
-          _e_output_update_fps();
+        if (e_plane_is_unset_try(plane)) continue;
 
         if (!e_plane_commit(plane))
           ERR("fail to e_plane_commit");
+
+        // TODO: to be fixed. check fps of fb_target currently.
+        if (fb_commit) _e_output_update_fps();
      }
 
    return EINA_TRUE;
index cd316ba..57814ff 100644 (file)
@@ -519,6 +519,38 @@ _e_plane_renderer_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
    ec->renderer_client = NULL;
 }
 
+static void
+_e_plane_unset_reset(E_Plane *plane)
+{
+   Eina_Bool print_log = EINA_FALSE;
+
+   /* reset the unset plane flags */
+   if (plane->unset_candidate) {plane->unset_candidate = EINA_FALSE; print_log = EINA_TRUE;}
+   if (plane->unset_counter > 0) {plane->unset_counter = 0; print_log = EINA_TRUE;}
+   if (plane->unset_try) {plane->unset_try = EINA_FALSE; print_log = EINA_TRUE;}
+   if (plane->unset_commit) {plane->unset_commit = EINA_FALSE; print_log = EINA_TRUE;}
+
+   if (print_log && plane_trace_debug)
+      ELOGF("E_PLANE", " Plane(%p) Unset flags Reset", NULL, NULL, plane);
+}
+
+static void
+_e_plane_unset_candidate_set(E_Plane *plane)
+{
+   E_Plane *fb_target = NULL;
+
+   fb_target = e_output_fb_target_get(plane->output);
+   if (fb_target)
+     {
+        if(fb_target->ec)
+          plane->unset_counter = 0;
+        else
+          plane->unset_counter = e_plane_renderer_render_count_get(fb_target->renderer) + 1;
+     }
+
+   plane->unset_candidate = EINA_TRUE;
+}
+
 EINTERN Eina_Bool
 e_plane_init(void)
 {
@@ -773,12 +805,6 @@ e_plane_fetch(E_Plane *plane)
    /* exist tsurface for update plane */
    if (tsurface)
      {
-        if (plane->need_unset)
-          plane->need_unset = EINA_FALSE;
-
-        if (plane->need_unset_commit)
-          plane->need_unset_commit = EINA_FALSE;
-
         plane->tsurface = tsurface;
 
         /* set plane info and set tsurface to the plane */
@@ -794,7 +820,7 @@ e_plane_fetch(E_Plane *plane)
      }
    else
      {
-        if (plane->need_unset)
+        if (e_plane_is_unset_try(plane))
           {
              if (eina_list_count(plane->pending_commit_data_list))
                return EINA_FALSE;
@@ -807,13 +833,10 @@ e_plane_fetch(E_Plane *plane)
                    ERR("failed to unset surface plane:%p", plane);
                    return EINA_FALSE;
                 }
-
-              plane->need_unset = EINA_FALSE;
-              plane->need_unset_commit = EINA_TRUE;
           }
         else
           {
-             if (!plane->need_unset_commit) return EINA_FALSE;
+             return EINA_FALSE;
           }
      }
 
@@ -828,6 +851,9 @@ e_plane_unfetch(E_Plane *plane)
    EINA_SAFETY_ON_NULL_RETURN(plane);
    EINA_SAFETY_ON_NULL_RETURN(plane->tsurface);
 
+   /* do not reset the plane when the plan is trying to unset */
+   if (e_plane_is_unset_try(plane)) return;
+
    if (plane->is_fb && !plane->ec)
      _e_plane_surface_on_ecore_evas_release(plane, plane->tsurface);
    else
@@ -921,15 +947,16 @@ e_plane_commit_data_aquire(E_Plane *plane)
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(plane, NULL);
 
-   if (plane->need_unset_commit)
+   if (plane->unset_commit)
      {
         data = E_NEW(E_Plane_Commit_Data, 1);
         data->plane = plane;
         data->renderer = NULL;
         data->tsurface = NULL;
         data->ec = NULL;
-        plane->need_unset_commit = EINA_FALSE;
-        plane->sync_unset_count = 0;
+
+        /* reset to be the initail unset values */
+        _e_plane_unset_reset(plane);
 
         plane->pending_commit_data_list = eina_list_append(plane->pending_commit_data_list, data);
 
@@ -1128,6 +1155,74 @@ e_plane_hwc_trace_debug(Eina_Bool onoff)
    INF("Plane: hwc trace_debug is %s", onoff?"ON":"OFF");
 }
 
+EINTERN Eina_Bool
+e_plane_is_unset_candidate(E_Plane *plane)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(plane, EINA_FALSE);
+
+   return plane->unset_candidate;
+}
+
+EINTERN Eina_Bool
+e_plane_is_unset_try(E_Plane *plane)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(plane, EINA_FALSE);
+
+   return plane->unset_try;
+}
+
+EINTERN void
+e_plane_unset_try_set(E_Plane *plane, Eina_Bool set)
+{
+   EINA_SAFETY_ON_NULL_RETURN(plane);
+
+   if (plane->unset_try == set) return;
+
+   if (set)
+     {
+        if (!e_plane_is_unset_candidate(plane))
+          {
+             WRN("Plane is not unset_candidate.");
+             return;
+          }
+
+       plane->unset_candidate = EINA_FALSE;
+       plane->unset_try = EINA_TRUE;
+
+       if (plane_trace_debug)
+         ELOGF("E_PLANE", "Plane(%p) Set unset_try. unset_counter(%d)", NULL, NULL, plane, plane->unset_counter);
+     }
+   else
+     {
+        plane->unset_commit = EINA_TRUE;
+        plane->unset_try = EINA_FALSE;
+
+       if (plane_trace_debug)
+         ELOGF("E_PLANE", "Plane(%p) UnSet unset_try. unset_counter(%d)", NULL, NULL, plane, plane->unset_counter);
+     }
+}
+
+EINTERN Eina_Bool
+e_plane_unset_commit_check(E_Plane *plane)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(plane, EINA_FALSE);
+
+   if (!e_plane_is_unset_try(plane))
+     {
+        WRN("Plane is not unset_try.");
+        return EINA_FALSE;
+     }
+
+   plane->unset_counter--;
+
+   if (plane_trace_debug)
+     ELOGF("E_PLANE", "Plane(%p) Check unset_commit. unset_counter(%d)", NULL, NULL, plane, plane->unset_counter);
+
+   if (plane->unset_counter > 0) return EINA_FALSE;
+
+   return EINA_TRUE;
+}
+
 E_API Eina_Bool
 e_plane_type_set(E_Plane *plane, E_Plane_Type type)
 {
@@ -1175,8 +1270,6 @@ e_plane_ec_get(E_Plane *plane)
 E_API Eina_Bool
 e_plane_ec_set(E_Plane *plane, E_Client *ec)
 {
-   E_Plane *fb_target = NULL;
-
    EINA_SAFETY_ON_NULL_RETURN_VAL(plane, EINA_FALSE);
 
    if (plane_trace_debug)
@@ -1236,24 +1329,35 @@ e_plane_ec_set(E_Plane *plane, E_Client *ec)
                _e_plane_surface_send_dequeuable_surfaces(plane);
           }
 
+        if (!plane->is_fb) _e_plane_unset_reset(plane);
+
         e_comp_object_hwc_update_set(ec->frame, EINA_TRUE);
      }
    else
      {
-        if (!plane->is_fb)
+        /* To set null to a plane means two things.
+           1. if the plane is fb target, the plane uses the ecore_evas.
+           2. if the plane is not fb target, the plane needs to unset
+              at the time that the result of the ecore_evas renderer(compositing)
+              is finished with the tsurface(ec) of the plane. For this,
+              we set the unset_candidate flags to the plane and measure to unset
+              the plane at the e_output_commit.
+         */
+        if (plane->is_fb)
+          {
+             if (!e_plane_renderer_ecore_evas_use(plane->renderer))
+               {
+                  ERR("failed to use ecore_evas plane:%p", plane);
+                  return EINA_FALSE;
+               }
+          }
+        else
           {
              if (plane->tsurface)
                {
-                  fb_target = e_output_fb_target_get(plane->output);
-                  if (fb_target)
-                    {
-                       if(fb_target->ec)
-                         plane->sync_unset_count = 0;
-                       else
-                         plane->sync_unset_count = e_plane_renderer_render_count_get(fb_target->renderer) + 1;
-                    }
-
-                  plane->need_unset = EINA_TRUE;
+                  _e_plane_unset_candidate_set(plane);
+                  if (plane_trace_debug)
+                    ELOGF("E_PLANE", "Plane(%p) Set the unset_candidate", (plane->ec ? ec->pixmap : NULL), ec, plane);
                }
 
              if (plane->renderer)
@@ -1262,14 +1366,6 @@ e_plane_ec_set(E_Plane *plane, E_Client *ec)
                   e_plane_role_set(plane, E_PLANE_ROLE_NONE);
                }
           }
-        else
-          {
-             if (!e_plane_renderer_ecore_evas_use(plane->renderer))
-               {
-                  ERR("failed to use ecore_evas plane:%p", plane);
-                  return EINA_FALSE;
-               }
-          }
      }
 
    plane->ec = ec;
index 2c7c2b1..0410a31 100644 (file)
@@ -63,9 +63,10 @@ struct _E_Plane
    unsigned int          buffer_flags;
    Eina_Bool             pending_commit;
    Eina_List            *pending_commit_data_list;
-   Eina_Bool             need_unset;
-   Eina_Bool             need_unset_commit;
-   int                   sync_unset_count;
+   Eina_Bool             unset_candidate;
+   Eina_Bool             unset_try;
+   Eina_Bool             unset_commit;
+   int                   unset_counter;
 
    /* true if plane's ec is set or unset.
     * false when E_Event_Plane_Win_Change has been generated.
@@ -115,6 +116,10 @@ EINTERN void                 e_plane_hwc_trace_debug(Eina_Bool onoff);
 EINTERN Eina_Bool            e_plane_render(E_Plane *plane);
 EINTERN Eina_Bool            e_plane_commit(E_Plane *plane);
 EINTERN void                 e_plane_show_state(E_Plane *plane);
+EINTERN Eina_Bool            e_plane_is_unset_candidate(E_Plane *plane);
+EINTERN Eina_Bool            e_plane_is_unset_try(E_Plane *plane);
+EINTERN void                 e_plane_unset_try_set(E_Plane *plane, Eina_Bool set);
+EINTERN Eina_Bool            e_plane_unset_commit_check(E_Plane *plane);
 
 E_API Eina_Bool              e_plane_type_set(E_Plane *plane, E_Plane_Type type);
 E_API E_Plane_Type           e_plane_type_get(E_Plane *plane);