From 3c50dd641442b51d06453d7f9071314526e5b6a0 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 19 Feb 2020 09:47:28 +0900 Subject: [PATCH] video:hwc_planes: add a pending buffer for use when plane is not ready. Change-Id: Ia9b628141e15ae61dc5b8ac61146416bd10f3bf2 --- src/bin/video/iface/e_video_hwc_planes.c | 140 ++++++++++++++++------- 1 file changed, 99 insertions(+), 41 deletions(-) diff --git a/src/bin/video/iface/e_video_hwc_planes.c b/src/bin/video/iface/e_video_hwc_planes.c index b1e4ffed0e..613ec5ae7b 100644 --- a/src/bin/video/iface/e_video_hwc_planes.c +++ b/src/bin/video/iface/e_video_hwc_planes.c @@ -24,6 +24,12 @@ struct _E_Video_Hwc_Planes Eina_List *late_prop_list; } tdm; + struct + { + E_Comp_Wl_Video_Buf *vbuf; + E_Client_Video_Info info; + } pending; + Eina_Bool waiting_vblank; }; @@ -36,6 +42,22 @@ typedef struct _Tdm_Prop_Value static Eina_List *video_layers = NULL; +static Eina_Bool _e_video_hwc_planes_buffer_commit(E_Video_Hwc_Planes *evhp, E_Comp_Wl_Video_Buf *vbuf, E_Client_Video_Info *info); + +static void +_e_video_hwc_planes_pending_buffer_commit(E_Video_Hwc_Planes *evhp) +{ + if (evhp->pending.vbuf) + { + _e_video_hwc_planes_buffer_commit(evhp, + evhp->pending.vbuf, + &evhp->pending.info); + evhp->pending.vbuf = NULL; + } + else + e_video_hwc_wait_buffer_commit((E_Video_Hwc *)evhp); +} + static Eina_Bool _e_video_hwc_planes_prop_list_update(Eina_List *prop_list, const char *name, tdm_value value) { @@ -296,7 +318,7 @@ _e_video_hwc_planes_cb_eplane_video_set_hook(void *data, E_Plane *plane) if (evhp->waiting_vblank) return; - e_video_hwc_wait_buffer_commit((E_Video_Hwc *)evhp); + _e_video_hwc_planes_pending_buffer_commit(evhp); } static void @@ -500,24 +522,17 @@ _e_video_hwc_planes_cb_vblank_handler(tdm_output *output, unsigned int sequence, if (evhp->video_plane_ready_handler) return; - e_video_hwc_wait_buffer_commit((E_Video_Hwc *)evhp); + _e_video_hwc_planes_pending_buffer_commit(evhp); } static Eina_Bool -_e_video_hwc_planes_buffer_commit(E_Video_Hwc_Planes *evhp, E_Comp_Wl_Video_Buf *vbuf) +_e_video_hwc_planes_buffer_commit(E_Video_Hwc_Planes *evhp, E_Comp_Wl_Video_Buf *vbuf, E_Client_Video_Info *info) { - E_Client_Video_Info info, old_info; + E_Client_Video_Info old_info; tdm_error ret; - if (!evhp->tdm.layer) + if (evhp->tdm.prop_list) { - VIN("set layer: show", evhp->base.ec); - if (!_e_video_hwc_planes_tdm_layer_set(evhp)) - { - VER("set layer failed", evhp->base.ec); - return EINA_FALSE; - } - // need call tdm property in list _tdm_layer_property_list_set(evhp->tdm.layer, &evhp->tdm.prop_list); } @@ -526,23 +541,9 @@ _e_video_hwc_planes_buffer_commit(E_Video_Hwc_Planes *evhp, E_Comp_Wl_Video_Buf ret = _tdm_layer_info_get(evhp->tdm.layer, &old_info); EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE); - CLEAR(info); - info.src_config.size.h = vbuf->width_from_pitch; - info.src_config.size.v = vbuf->height_from_size; - info.src_config.pos.x = vbuf->content_r.x; - info.src_config.pos.y = vbuf->content_r.y; - info.src_config.pos.w = vbuf->content_r.w; - info.src_config.pos.h = vbuf->content_r.h; - info.src_config.format = vbuf->tbmfmt; - info.dst_pos.x = evhp->base.geo.tdm.output_r.x; - info.dst_pos.y = evhp->base.geo.tdm.output_r.y; - info.dst_pos.w = evhp->base.geo.tdm.output_r.w; - info.dst_pos.h = evhp->base.geo.tdm.output_r.h; - info.transform = vbuf->content_t; - - if (memcmp(&old_info, &info, sizeof(tdm_info_layer))) + if (memcmp(&old_info, info, sizeof(tdm_info_layer))) { - ret = _tdm_layer_info_set(evhp->tdm.layer, &info); + ret = _tdm_layer_info_set(evhp->tdm.layer, info); EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE); } @@ -566,10 +567,9 @@ _e_video_hwc_planes_buffer_commit(E_Video_Hwc_Planes *evhp, E_Comp_Wl_Video_Buf " dst(%d,%d, %dx%d), transform(%d)", e_client_util_name_get(evhp->base.ec) ?: "No Name" , evhp->base.ec->netwm.pid, wl_resource_get_id(evhp->base.ec->comp_data->surface), vbuf, vbuf->ref_cnt, - info.src_config.size.h, info.src_config.size.v, info.src_config.pos.x, - info.src_config.pos.y, info.src_config.pos.w, info.src_config.pos.h, - info.dst_pos.x, info.dst_pos.y, info.dst_pos.w, info.dst_pos.h, info.transform); - + info->src_config.size.h, info->src_config.size.v, info->src_config.pos.x, + info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h, + info->dst_pos.x, info->dst_pos.y, info->dst_pos.w, info->dst_pos.h, info->transform); return EINA_TRUE; } @@ -809,17 +809,17 @@ _e_video_hwc_planes_iface_property_set(E_Video_Hwc *evh, unsigned int id, tdm_va VER("set layer failed", evhp->base.ec); return EINA_FALSE; } + + if (evhp->video_plane_ready_handler) + { + VIN("wait for video plane ready", evhp->base.ec); + goto save; + } } else { - VIN("no layer: save property value", evhp->base.ec); - if (!_e_video_hwc_planes_property_save(evhp, id, name, value)) - { - VER("save property failed", evhp->base.ec); - return EINA_FALSE; - } - - return EINA_TRUE; + VIN("layer is not yet assigned", evhp->base.ec); + goto save; } } @@ -830,6 +830,16 @@ _e_video_hwc_planes_iface_property_set(E_Video_Hwc *evh, unsigned int id, tdm_va _tdm_layer_property_set(evhp->tdm.layer, &prop); return EINA_TRUE; + +save: + VIN("save property value", evhp->base.ec); + if (!_e_video_hwc_planes_property_save(evhp, id, name, value)) + { + VER("save property failed", evhp->base.ec); + return EINA_FALSE; + } + + return EINA_TRUE; } static Eina_Bool @@ -850,6 +860,7 @@ static Eina_Bool _e_video_hwc_planes_iface_buffer_commit(E_Video_Hwc *evh, E_Comp_Wl_Video_Buf *vbuf) { E_Video_Hwc_Planes *evhp; + E_Client_Video_Info info; Eina_Bool ret = EINA_TRUE; evhp = (E_Video_Hwc_Planes *)evh; @@ -862,7 +873,54 @@ _e_video_hwc_planes_iface_buffer_commit(E_Video_Hwc *evh, E_Comp_Wl_Video_Buf *v } } else - ret = _e_video_hwc_planes_buffer_commit(evhp, vbuf); + { + CLEAR(info); + info.src_config.size.h = vbuf->width_from_pitch; + info.src_config.size.v = vbuf->height_from_size; + info.src_config.pos.x = vbuf->content_r.x; + info.src_config.pos.y = vbuf->content_r.y; + info.src_config.pos.w = vbuf->content_r.w; + info.src_config.pos.h = vbuf->content_r.h; + info.src_config.format = vbuf->tbmfmt; + info.dst_pos.x = evhp->base.geo.tdm.output_r.x; + info.dst_pos.y = evhp->base.geo.tdm.output_r.y; + info.dst_pos.w = evhp->base.geo.tdm.output_r.w; + info.dst_pos.h = evhp->base.geo.tdm.output_r.h; + info.transform = vbuf->content_t; + + if (!evhp->tdm.layer) + { + VIN("set layer: show", evhp->base.ec); + if (!_e_video_hwc_planes_tdm_layer_set(evhp)) + { + VER("set layer failed", evhp->base.ec); + return EINA_FALSE; + } + } + + if (evhp->video_plane_ready_handler) + { + VIN("wait for video plane ready: Pending commit vbuf(%p)", + evhp->base.ec, vbuf); + + if (evhp->pending.vbuf) + { + /* Cannot reach here because following buffers are supposed + * to be queued by 'e_video_hwc' until calling fb_update by + * this child module. */ + NEVER_GET_HERE(); + + return EINA_FALSE; + } + + evhp->pending.vbuf = vbuf; + memcpy(&evhp->pending.info, &info, sizeof(E_Client_Video_Info)); + + return EINA_TRUE; + } + + ret = _e_video_hwc_planes_buffer_commit(evhp, vbuf, &info); + } return ret; } -- 2.34.1