e_output: reset all planes and layers when dpms off 18/157218/7
authorBoram Park <boram1288.park@samsung.com>
Mon, 23 Oct 2017 23:51:59 +0000 (08:51 +0900)
committerBoram Park <boram1288.park@samsung.com>
Wed, 25 Oct 2017 07:22:30 +0000 (16:22 +0900)
Change-Id: If87ba196d96ced11ae11146092c324b6070298d7

src/bin/e_output.c
src/bin/e_plane.c
src/bin/e_plane.h

index a8c276b5f96fcaa3713b5781f9949d6e9723ca9c..d3b4b2a9fc3ab33fff0c055204e7dbca8da626bb 100644 (file)
@@ -2035,6 +2035,17 @@ e_output_dpms_set(E_Output *output, E_OUTPUT_DPMS val)
 
    if (!ret) return EINA_FALSE;
 
+   if (val == E_OUTPUT_DPMS_OFF)
+     {
+        Eina_List *l;
+        E_Plane *ep;
+
+        EINA_LIST_FOREACH(output->planes, l, ep)
+          {
+             e_plane_dpms_off(ep);
+          }
+     }
+
    error = tdm_output_set_dpms(output->toutput, tval);
    if (error != TDM_ERROR_NONE)
      {
index feed3f94bb46affb30443ec5701f0e0510181025..7d07a32931bcea69f0ed0bd217286c2a86fab40b 100644 (file)
@@ -147,7 +147,7 @@ _e_plane_surface_unset(E_Plane *plane)
    error = tdm_layer_unset_buffer(tlayer);
    if (error != TDM_ERROR_NONE)
      {
-        ERR("fail to tdm_layer_unset_buffer");
+        ERR("fail to tdm_layer_unset_buffer: error(%d)", error);
         return EINA_FALSE;
      }
 
@@ -734,6 +734,16 @@ _e_plane_pp_pending_data_remove(E_Plane *plane)
    E_Plane_Commit_Data *data = NULL;
    Eina_List *l = NULL, *ll = NULL;
 
+   if (plane->pp_layer_commit_data)
+     {
+        data = plane->pp_layer_commit_data;
+        plane->pp_layer_commit_data = NULL;
+
+        tbm_surface_internal_unref(data->tsurface);
+        tbm_surface_queue_release(plane->pp_tqueue, data->tsurface);
+        E_FREE(data);
+     }
+
    if (eina_list_count(plane->pending_pp_commit_data_list) != 0)
      {
         EINA_LIST_FOREACH_SAFE(plane->pending_pp_commit_data_list, l, ll, data)
@@ -767,35 +777,42 @@ _e_plane_pp_layer_commit_handler(tdm_layer *layer, unsigned int sequence,
                                  unsigned int tv_sec, unsigned int tv_usec,
                                  void *user_data)
 {
-   E_Plane_Commit_Data *data = (E_Plane_Commit_Data *)user_data;
+   E_Plane *plane;
+   E_Plane_Commit_Data *data;
    E_Output *output = NULL;
-   E_Plane *plane = NULL;
 
-   EINA_SAFETY_ON_NULL_RETURN(data);
+   EINA_SAFETY_ON_NULL_RETURN(user_data);
 
-   plane = data->plane;
+   plane = user_data;
 
    plane->pp_layer_commit = EINA_FALSE;
 
-   /* if pp_set is false, do not deal with pending list */
-   if (!plane->pp_set)
+   /* layer already resetted */
+   if (plane->pp_layer_commit_data)
      {
-        tbm_surface_internal_unref(data->tsurface);
-        E_FREE(data);
-        return;
-     }
+        data = plane->pp_layer_commit_data;
+        plane->pp_layer_commit_data = NULL;
 
-   if (plane->pp_tqueue && plane->pp_tsurface)
-     {
-        /* release and unref the current pp surface on the plane */
-        tbm_surface_queue_release(plane->pp_tqueue, plane->pp_tsurface);
-        tbm_surface_internal_unref(plane->pp_tsurface);
-     }
+        /* if pp_set is false, do not deal with pending list */
+        if (!plane->pp_set)
+          {
+             tbm_surface_internal_unref(data->tsurface);
+             E_FREE(data);
+             return;
+          }
 
-   /* set the new pp surface to the plane */
-   plane->pp_tsurface = data->tsurface;
+        if (plane->pp_tqueue && plane->pp_tsurface)
+          {
+             /* release and unref the current pp surface on the plane */
+             tbm_surface_queue_release(plane->pp_tqueue, plane->pp_tsurface);
+             tbm_surface_internal_unref(plane->pp_tsurface);
+          }
 
-   E_FREE(data);
+        /* set the new pp surface to the plane */
+        plane->pp_tsurface = data->tsurface;
+
+        E_FREE(data);
+     }
 
    if (plane_trace_debug)
      ELOGF("E_PLANE", "PP Layer Commit Handler Plane(%p)", NULL, NULL, plane);
@@ -953,7 +970,7 @@ _e_plane_pp_layer_data_commit(E_Plane *plane, E_Plane_Commit_Data *data)
         goto fail;
      }
 
-   tdm_err = tdm_layer_commit(tlayer, _e_plane_pp_layer_commit_handler, data);
+   tdm_err = tdm_layer_commit(tlayer, _e_plane_pp_layer_commit_handler, plane);
    if (tdm_err != TDM_ERROR_NONE)
      {
         ERR("fail to tdm_layer_commit plane:%p, zpos:%d", plane, plane->zpos);
@@ -961,6 +978,7 @@ _e_plane_pp_layer_data_commit(E_Plane *plane, E_Plane_Commit_Data *data)
      }
 
    plane->pp_layer_commit = EINA_TRUE;
+   plane->pp_layer_commit_data = data;
 
    return EINA_TRUE;
 
@@ -2708,3 +2726,31 @@ e_plane_fps_get(E_Plane *plane, double *fps)
    return EINA_FALSE;
 }
 
+EINTERN void
+e_plane_dpms_off(E_Plane *plane)
+{
+   E_Plane_Commit_Data *data;
+   Eina_List *l = NULL, *ll = NULL;
+
+   /* pp */
+   _e_plane_pp_pending_data_remove(plane);
+
+   /* TODO: fine to skip primary layer? If DRM system, the only way to unset
+    * primary layer's buffer is resetting mode setting.
+    */
+   if (e_plane_is_primary(plane)) return;
+
+   /* layer */
+   e_plane_ec_prepare_set(plane, NULL);
+   e_plane_ec_set(plane, NULL);
+
+   _e_plane_unset_reset(plane);
+   _e_plane_surface_unset(plane);
+
+   tdm_layer_commit(plane->tlayer, NULL, NULL);
+
+   EINA_LIST_FOREACH_SAFE(plane->commit_data_list, l, ll, data)
+     {
+        e_plane_commit_data_release(data);
+     }
+}
index db43dca0499025560e2522b00125c6a1b0ea5007..e75073034acf8d78875d2cf10677d2f931fcc718 100644 (file)
@@ -103,6 +103,7 @@ struct _E_Plane
    Eina_Bool             pp_set;
    Eina_Bool             pp_commit;
    Eina_Bool             pp_layer_commit;
+   E_Plane_Commit_Data  *pp_layer_commit_data;
    Eina_Rectangle        pp_rect;
 
    /* current display information */
@@ -179,6 +180,7 @@ EINTERN Eina_Bool            e_plane_pp_commit_possible_check(E_Plane *plane);
 EINTERN Eina_Bool            e_plane_zoom_set(E_Plane *plane, Eina_Rectangle *rect);
 EINTERN void                 e_plane_zoom_unset(E_Plane *plane);
 EINTERN Eina_Bool            e_plane_fps_get(E_Plane *plane, double *fps);
+EINTERN void                 e_plane_dpms_off(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);