From: SooChan Lim Date: Mon, 19 Jun 2017 11:09:08 +0000 (+0900) Subject: e_output: refactor the synchronous unset of the plane. X-Git-Tag: submit/tizen_3.0/20170705.085031~43 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=58e0033d7bd1edab2b8047c5425d0e9903a2058f;p=platform%2Fupstream%2Fenlightenment.git e_output: refactor the synchronous unset of the plane. 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 --- diff --git a/src/bin/e_output.c b/src/bin/e_output.c index 747f30087d..9f401718a7 100644 --- a/src/bin/e_output.c +++ b/src/bin/e_output.c @@ -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; diff --git a/src/bin/e_plane.c b/src/bin/e_plane.c index cd316bab0b..57814ff9b6 100644 --- a/src/bin/e_plane.c +++ b/src/bin/e_plane.c @@ -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; diff --git a/src/bin/e_plane.h b/src/bin/e_plane.h index 2c7c2b1f5a..0410a314e5 100644 --- a/src/bin/e_plane.h +++ b/src/bin/e_plane.h @@ -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);