video:hwc_planes: add a pending buffer for use when plane is not ready. 33/225333/2
authorSeunghun Lee <shiin.lee@samsung.com>
Wed, 19 Feb 2020 00:47:28 +0000 (09:47 +0900)
committerSeunghun Lee <shiin.lee@samsung.com>
Wed, 19 Feb 2020 07:48:51 +0000 (16:48 +0900)
Change-Id: Ia9b628141e15ae61dc5b8ac61146416bd10f3bf2

src/bin/video/iface/e_video_hwc_planes.c

index b1e4ffed0e2959e101805d99f80d5364de9fff23..613ec5ae7b3043319a126ac2ca3cd0befbf9da84 100644 (file)
@@ -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;
 }