5 #include "e_video_internal.h"
6 #include "e_video_hwc.h"
8 #define CHECKING_PRIMARY_ZPOS
10 typedef struct _E_Video_Hwc_Planes E_Video_Hwc_Planes;
12 struct _E_Video_Hwc_Planes
16 E_Plane_Hook *video_plane_ready_handler;
24 Eina_List *late_prop_list;
29 E_Comp_Wl_Video_Buf *vbuf;
30 E_Client_Video_Info info;
40 typedef struct _Tdm_Prop_Value
43 char name[TDM_NAME_LEN];
47 static Eina_List *video_layers = NULL;
49 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);
52 _e_video_hwc_planes_pending_buffer_commit(E_Video_Hwc_Planes *evhp)
54 if (evhp->pending.vbuf)
56 _e_video_hwc_planes_buffer_commit(evhp,
59 evhp->pending.vbuf = NULL;
62 e_video_hwc_wait_buffer_commit((E_Video_Hwc *)evhp);
66 _e_video_hwc_planes_prop_list_update(Eina_List *prop_list, const char *name, tdm_value value)
71 EINA_LIST_FOREACH(prop_list, l, prop)
73 if (strncmp(name, prop->name, TDM_NAME_LEN))
76 VDB("update property(%s) value(%d -> %d)",
77 NULL, name, prop->value.u32, value.u32);
79 prop->value.u32 = value.u32;
88 _e_video_hwc_planes_prop_list_append(Eina_List **prop_list, unsigned int id, const char *name, tdm_value value)
92 prop = calloc(1, sizeof(Tdm_Prop_Value));
95 VER("failed to alloc memory: property(%s) value(%d)",
96 NULL, name, value.u32);
100 prop->value.u32 = value.u32;
102 memcpy(prop->name, name, sizeof(TDM_NAME_LEN));
104 VIN("Add property(%s) value(%d)", NULL, name, value.u32);
106 *prop_list = eina_list_append(*prop_list, prop);
112 _tdm_output_video_layer_get(tdm_output *output)
115 tdm_layer_capability capabilities = 0;
117 #ifdef CHECKING_PRIMARY_ZPOS
118 int primary_idx = 0, primary_zpos = 0;
119 tdm_layer *primary_layer;
122 EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
124 tdm_output_get_layer_count(output, &count);
125 for (i = 0; i < count; i++)
127 layer = tdm_output_get_layer(output, i, NULL);
128 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
130 tdm_layer_get_capabilities(layer, &capabilities);
131 if (capabilities & TDM_LAYER_CAPABILITY_VIDEO)
135 #ifdef CHECKING_PRIMARY_ZPOS
136 tdm_output_get_primary_index(output, &primary_idx);
137 primary_layer = tdm_output_get_layer(output, primary_idx, NULL);
138 EINA_SAFETY_ON_NULL_RETURN_VAL(primary_layer, NULL);
139 tdm_layer_get_zpos(primary_layer, &primary_zpos);
142 for (i = 0; i < count; i++)
144 layer = tdm_output_get_layer(output, i, NULL);
145 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
147 tdm_layer_get_capabilities(layer, &capabilities);
148 if (capabilities & TDM_LAYER_CAPABILITY_OVERLAY)
150 #ifdef CHECKING_PRIMARY_ZPOS
152 tdm_layer_get_zpos(layer, &zpos);
153 if (zpos >= primary_zpos) continue;
163 _tdm_output_video_layer_exists(tdm_output *toutput)
166 tdm_layer_capability lyr_capabilities = 0;
168 EINA_SAFETY_ON_NULL_RETURN_VAL(toutput, EINA_FALSE);
170 /* get the first suitable layer */
171 layer = _tdm_output_video_layer_get(toutput);
175 tdm_layer_get_capabilities(layer, &lyr_capabilities);
176 if (lyr_capabilities & TDM_LAYER_CAPABILITY_VIDEO)
183 _tdm_layer_info_get(tdm_layer *layer, E_Client_Video_Info *vinfo)
185 tdm_error ret = TDM_ERROR_NONE;
186 tdm_info_layer tinfo = {0};
188 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, TDM_ERROR_INVALID_PARAMETER);
189 EINA_SAFETY_ON_NULL_RETURN_VAL(vinfo, TDM_ERROR_INVALID_PARAMETER);
191 ret = tdm_layer_get_info(layer, &tinfo);
192 EINA_SAFETY_ON_TRUE_RETURN_VAL(ret != TDM_ERROR_NONE, ret);
194 memcpy(&vinfo->src_config, &tinfo.src_config, sizeof(tdm_info_config));
195 memcpy(&vinfo->dst_pos, &tinfo.dst_pos, sizeof(tdm_pos));
196 vinfo->transform = tinfo.transform;
202 _tdm_layer_info_set(tdm_layer *layer, E_Client_Video_Info *vinfo)
204 tdm_error ret = TDM_ERROR_NONE;
205 tdm_info_layer info_layer = {0};
207 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, TDM_ERROR_INVALID_PARAMETER);
208 EINA_SAFETY_ON_NULL_RETURN_VAL(vinfo, TDM_ERROR_INVALID_PARAMETER);
210 memcpy(&info_layer.src_config, &vinfo->src_config, sizeof(tdm_info_config));
211 memcpy(&info_layer.dst_pos, &vinfo->dst_pos, sizeof(tdm_pos));
212 info_layer.transform = vinfo->transform;
214 ret = tdm_layer_set_info(layer, &info_layer);
220 _tdm_layer_buffer_set(tdm_layer *layer, tbm_surface_h buff)
222 tdm_error ret = TDM_ERROR_NONE;
224 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, TDM_ERROR_BAD_REQUEST);
225 EINA_SAFETY_ON_NULL_RETURN_VAL(buff, TDM_ERROR_BAD_REQUEST);
227 ret = tdm_layer_set_buffer(layer, buff);
233 _tdm_layer_buffer_unset(tdm_layer *layer)
237 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, TDM_ERROR_BAD_REQUEST);
239 ret = tdm_layer_unset_buffer(layer);
245 * This function checks if this layer was set
248 _tdm_layer_usable_get(tdm_layer *layer, unsigned int *usable)
252 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, TDM_ERROR_BAD_REQUEST);
253 EINA_SAFETY_ON_NULL_RETURN_VAL(usable, TDM_ERROR_BAD_REQUEST);
255 ret = tdm_layer_is_usable(layer, usable);
260 _tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data)
262 tdm_error ret = TDM_ERROR_NONE;
264 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, TDM_ERROR_BAD_REQUEST);
266 ret = tdm_layer_commit(layer, func, user_data);
272 _tdm_layer_displaying_buffer_get(tdm_layer *layer, int *tdm_error)
274 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
276 return tdm_layer_get_displaying_buffer(layer, tdm_error);
280 _tdm_layer_property_set(tdm_layer *layer, Tdm_Prop_Value *prop)
284 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, TDM_ERROR_BAD_REQUEST);
286 ret = tdm_layer_set_property(layer, prop->id, prop->value);
291 _tdm_layer_property_get(tdm_layer *layer, unsigned id, tdm_value *value)
293 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, TDM_ERROR_BAD_REQUEST);
294 EINA_SAFETY_ON_NULL_RETURN_VAL(value, TDM_ERROR_BAD_REQUEST);
296 return tdm_layer_get_property(layer, id, value);
300 _tdm_layer_property_list_set(tdm_layer *layer, Eina_List **list)
302 Tdm_Prop_Value *prop;
304 EINA_LIST_FREE((*list), prop)
306 VIN("call property(%s), value(%d)", NULL, prop->name,
307 (unsigned int)prop->value.u32);
308 _tdm_layer_property_set(layer, prop);
314 _e_video_hwc_planes_cb_eplane_video_set_hook(void *data, E_Plane *plane)
316 E_Video_Hwc_Planes *evhp;
318 evhp = (E_Video_Hwc_Planes *)data;
319 if (evhp->e_plane != plane) return;
321 E_FREE_FUNC(evhp->video_plane_ready_handler, e_plane_hook_del);
323 if (evhp->wait_flag.vblank) return;
325 _e_video_hwc_planes_pending_buffer_commit(evhp);
329 _e_video_hwc_planes_tdm_layer_usable_set(tdm_layer *layer, Eina_Bool usable)
331 tdm_layer *used_layer;
335 video_layers = eina_list_remove(video_layers, layer);
338 EINA_LIST_FOREACH(video_layers, l, used_layer)
339 if (used_layer == layer) return;
340 video_layers = eina_list_append(video_layers, layer);
345 _e_video_hwc_planes_tdm_layer_usable_get(tdm_layer *layer)
347 tdm_layer *used_layer;
350 EINA_LIST_FOREACH(video_layers, l, used_layer)
351 if (used_layer == layer)
357 _e_video_hwc_planes_available_video_tdm_layer_get(tdm_output *output)
360 tdm_layer_capability capabilities = 0;
361 Eina_Bool has_video_layer = EINA_FALSE;
363 #ifdef CHECKING_PRIMARY_ZPOS
364 int primary_idx = 0, primary_zpos = 0;
365 tdm_layer *primary_layer;
368 EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
370 /* check video layers first */
371 tdm_output_get_layer_count(output, &count);
372 for (i = 0; i < count; i++)
374 layer = tdm_output_get_layer(output, i, NULL);
375 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
377 tdm_layer_get_capabilities(layer, &capabilities);
378 if (capabilities & TDM_LAYER_CAPABILITY_VIDEO)
380 has_video_layer = EINA_TRUE;
381 if (!_e_video_hwc_planes_tdm_layer_usable_get(layer)) continue;
386 /* if a output has video layers, it means that there is no available video layer for video */
390 /* check graphic layers second */
391 #ifdef CHECKING_PRIMARY_ZPOS
392 tdm_output_get_primary_index(output, &primary_idx);
393 primary_layer = tdm_output_get_layer(output, primary_idx, NULL);
394 EINA_SAFETY_ON_NULL_RETURN_VAL(primary_layer, NULL);
395 tdm_layer_get_zpos(primary_layer, &primary_zpos);
398 for (i = 0; i < count; i++)
400 layer = tdm_output_get_layer(output, i, NULL);
401 EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL);
403 tdm_layer_get_capabilities(layer, &capabilities);
404 if (capabilities & TDM_LAYER_CAPABILITY_OVERLAY)
406 #ifdef CHECKING_PRIMARY_ZPOS
408 tdm_layer_get_zpos(layer, &zpos);
409 if (zpos >= primary_zpos) continue;
411 if (!_e_video_hwc_planes_tdm_layer_usable_get(layer)) continue;
420 _e_video_hwc_planes_tdm_layer_set(E_Video_Hwc_Planes *evhp)
422 E_Plane *plane = NULL;
431 layer = _e_video_hwc_planes_available_video_tdm_layer_get(evhp->tdm.output);
434 VWR("no available layer for evhp", NULL);
438 _e_video_hwc_planes_tdm_layer_usable_set(layer, EINA_FALSE);
440 ret = tdm_layer_get_zpos(layer, &zpos);
441 if (ret == TDM_ERROR_NONE)
442 plane = e_output_plane_get_by_zpos(evhp->base.e_output, zpos);
446 VWR("fail get e_plane", NULL);
450 if (!e_plane_video_set(plane, EINA_TRUE, &need_wait))
452 VWR("fail set video to e_plane", NULL);
458 evhp->video_plane_ready_handler =
459 e_plane_hook_add(E_PLANE_HOOK_VIDEO_SET,
460 _e_video_hwc_planes_cb_eplane_video_set_hook, evhp);
463 evhp->tdm.layer = layer;
464 evhp->e_plane = plane;
466 VIN("assign layer: %p", NULL, evhp->tdm.layer);
471 _e_video_hwc_planes_tdm_layer_usable_set(evhp->tdm.layer, EINA_TRUE);
477 _e_video_hwc_planes_tdm_layer_unset(E_Video_Hwc_Planes *evhp)
479 unsigned int usable = 1;
481 if (!evhp->tdm.layer) return;
483 _tdm_layer_usable_get(evhp->tdm.layer, &usable);
484 if (!usable && !evhp->video_plane_ready_handler)
486 VIN("stop video", evhp->base.ec);
487 _tdm_layer_buffer_unset(evhp->tdm.layer);
488 _tdm_layer_commit(evhp->tdm.layer, NULL, NULL);
491 VIN("release layer: %p", evhp->base.ec, evhp->tdm.layer);
492 _e_video_hwc_planes_tdm_layer_usable_set(evhp->tdm.layer, EINA_TRUE);
493 evhp->tdm.layer = NULL;
494 evhp->base.old_comp_buffer = NULL;
496 e_plane_video_set(evhp->e_plane, EINA_FALSE, NULL);
497 evhp->e_plane = NULL;
499 E_FREE_FUNC(evhp->video_plane_ready_handler, e_plane_hook_del);
503 _e_video_hwc_planes_cb_commit_handler(tdm_layer *layer, unsigned int sequence,
504 unsigned int tv_sec, unsigned int tv_usec,
507 E_Video_Hwc_Planes *evhp;
512 if (!evhp->wait_flag.commit)
515 evhp->wait_flag.commit = EINA_FALSE;
517 e_video_hwc_current_fb_update((E_Video_Hwc *)evhp);
521 _e_video_hwc_planes_cb_vblank_handler(tdm_output *output, unsigned int sequence,
522 unsigned int tv_sec, unsigned int tv_usec,
525 E_Video_Hwc_Planes *evhp;
531 evhp->wait_flag.vblank = EINA_FALSE;
533 if (evhp->video_plane_ready_handler) return;
535 if (evhp->wait_flag.commit)
537 /* wait next vblank in case commit handler is not called yet. Because
538 * that means committed buffer is not on display yet. */
539 err = tdm_output_wait_vblank(evhp->tdm.output, 1, 0,
540 _e_video_hwc_planes_cb_vblank_handler,
542 if (err != TDM_ERROR_NONE)
544 VER("failed to set handler for wait vblank", evhp->base.ec);
548 evhp->wait_flag.vblank = EINA_TRUE;
551 _e_video_hwc_planes_pending_buffer_commit(evhp);
555 _e_video_hwc_planes_buffer_commit(E_Video_Hwc_Planes *evhp, E_Comp_Wl_Video_Buf *vbuf, E_Client_Video_Info *info)
557 E_Client_Video_Info old_info;
560 if (evhp->tdm.prop_list)
562 // need call tdm property in list
563 _tdm_layer_property_list_set(evhp->tdm.layer, &evhp->tdm.prop_list);
567 ret = _tdm_layer_info_get(evhp->tdm.layer, &old_info);
568 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
570 if (memcmp(&old_info, info, sizeof(tdm_info_layer)))
572 ret = _tdm_layer_info_set(evhp->tdm.layer, info);
573 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
576 ret = _tdm_layer_buffer_set(evhp->tdm.layer, vbuf->tbm_surface);
577 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
579 ret = _tdm_layer_commit(evhp->tdm.layer, _e_video_hwc_planes_cb_commit_handler, evhp);
580 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
582 ret = tdm_output_wait_vblank(evhp->tdm.output, 1, 0, _e_video_hwc_planes_cb_vblank_handler, evhp);
583 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
585 evhp->wait_flag.commit = EINA_TRUE;
586 evhp->wait_flag.vblank = EINA_TRUE;
588 _tdm_layer_property_list_set(evhp->tdm.layer, &evhp->tdm.late_prop_list);
590 e_video_hwc_client_mask_update((E_Video_Hwc *)evhp);
592 DBG("Client(%s):PID(%d) RscID(%d), Buffer(%p, refcnt:%d) is shown."
593 "Geometry details are : buffer size(%dx%d) src(%d,%d, %dx%d)"
594 " dst(%d,%d, %dx%d), transform(%d)",
595 e_client_util_name_get(evhp->base.ec) ?: "No Name" , evhp->base.ec->netwm.pid,
596 wl_resource_get_id(evhp->base.ec->comp_data->surface), vbuf, vbuf->ref_cnt,
597 info->src_config.size.h, info->src_config.size.v, info->src_config.pos.x,
598 info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h,
599 info->dst_pos.x, info->dst_pos.y, info->dst_pos.w, info->dst_pos.h, info->transform);
605 _e_video_hwc_planes_cb_evas_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
607 E_Video_Hwc_Planes *evhp = data;
609 if (e_object_is_del(E_OBJECT(evhp->base.ec))) return;
611 /* if stand_alone is true, not hide */
612 if (evhp->base.ec->comp_data->sub.data && evhp->base.ec->comp_data->sub.data->stand_alone)
615 VIN("evas hide", evhp->base.ec);
618 VIN("unset layer: hide", evhp->base.ec);
619 _e_video_hwc_planes_tdm_layer_unset(evhp);
624 _e_video_hwc_planes_available_properties_get(E_Video_Hwc_Planes *evhp,
625 const tdm_prop **props,
629 tdm_error ret = TDM_ERROR_OPERATION_FAILED;
631 EINA_SAFETY_ON_NULL_RETURN_VAL(evhp, TDM_ERROR_BAD_REQUEST);
632 EINA_SAFETY_ON_NULL_RETURN_VAL(props, TDM_ERROR_BAD_REQUEST);
633 EINA_SAFETY_ON_NULL_RETURN_VAL(count, TDM_ERROR_BAD_REQUEST);
635 tlayer = evhp->tdm.layer;
636 /* if layer wasn't set then get an any available tdm_layer */
638 tlayer = _e_video_hwc_planes_available_video_tdm_layer_get(evhp->tdm.output);
639 ret = tdm_layer_get_available_properties(tlayer, props, count);
645 _e_video_hwc_planes_init(E_Video_Hwc_Planes *evhp, E_Output *output)
647 /* If tdm offers video layers, we will assign a tdm layer when showing */
648 if (!_tdm_output_video_layer_exists(output->toutput))
650 /* If tdm doesn't offer video layers, we assign a tdm layer now. If
651 * failed, video will be displayed via the UI rendering path. */
652 if (!_e_video_hwc_planes_tdm_layer_set(evhp))
660 _e_video_hwc_planes_destroy(E_Video_Hwc_Planes *evhp)
662 Tdm_Prop_Value *tdm_prop;
667 VIN("destroy", evhp->base.ec);
669 if (evhp->tdm.prop_list)
671 EINA_LIST_FREE(evhp->tdm.prop_list, tdm_prop)
674 if (evhp->tdm.late_prop_list)
676 EINA_LIST_FREE(evhp->tdm.late_prop_list, tdm_prop)
680 if (evhp->tdm.prop_list)
682 if (evhp->tdm.late_prop_list)
687 VIN("unset layer: destroy", evhp->base.ec);
688 _e_video_hwc_planes_tdm_layer_unset(evhp);
695 _e_video_hwc_planes_ec_event_deinit(E_Video_Hwc_Planes *evhp)
701 evas_object_event_callback_del_full(ec->frame, EVAS_CALLBACK_HIDE,
702 _e_video_hwc_planes_cb_evas_hide, evhp);
706 _e_video_hwc_planes_prop_name_get_by_id(E_Video_Hwc_Planes *evhp, unsigned int id)
709 const tdm_prop *props;
712 layer = _tdm_output_video_layer_get(evhp->tdm.output);
713 tdm_layer_get_available_properties(layer, &props, &count);
714 for (i = 0; i < count; i++)
716 if (props[i].id == id)
718 VDB("check property(%s)", evhp->base.ec, props[i].name);
719 return props[i].name;
727 _e_video_hwc_planes_property_post_set(E_Video_Hwc_Planes *evhp,
734 VDB("property_post_set: property(%s) value(%d)",
735 evhp->base.ec, name, value.u32);
737 res = _e_video_hwc_planes_prop_list_update(evhp->tdm.late_prop_list,
743 _e_video_hwc_planes_prop_list_append(&evhp->tdm.late_prop_list,
748 _e_video_hwc_planes_property_pre_set(E_Video_Hwc_Planes *evhp,
755 VDB("property_pre_set: property(%s) value(%d)",
756 evhp->base.ec, name, value.u32);
758 res = _e_video_hwc_planes_prop_list_update(evhp->tdm.prop_list,
764 res = _e_video_hwc_planes_prop_list_update(evhp->tdm.late_prop_list,
770 res = _e_video_hwc_planes_prop_list_append(&evhp->tdm.prop_list,
777 _e_video_hwc_planes_property_save(E_Video_Hwc_Planes *evhp, unsigned int id, const char *name, tdm_value value)
779 return _e_video_hwc_planes_property_pre_set(evhp, id, name, value);
783 _e_video_hwc_planes_ec_event_init(E_Video_Hwc_Planes *evhp, E_Client *ec)
785 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE,
786 _e_video_hwc_planes_cb_evas_hide, evhp);
790 _e_video_hwc_planes_iface_destroy(E_Video_Hwc *evh)
792 E_Video_Hwc_Planes *evhp;
794 evhp = (E_Video_Hwc_Planes *)evh;
795 _e_video_hwc_planes_ec_event_deinit(evhp);
796 _e_video_hwc_planes_destroy(evhp);
800 _e_video_hwc_planes_iface_property_get(E_Video_Hwc *evh, unsigned int id, tdm_value *value)
802 E_Video_Hwc_Planes *evhp;
805 evhp = (E_Video_Hwc_Planes *)evh;
806 ret = _tdm_layer_property_get(evhp->tdm.layer, id, value);
807 if (ret != TDM_ERROR_NONE)
814 _e_video_hwc_planes_iface_property_set(E_Video_Hwc *evh, unsigned int id, tdm_value value, Eina_Bool sync)
816 E_Video_Hwc_Planes *evhp;
820 evhp = (E_Video_Hwc_Planes *)evh;
821 VIN("set layer: set_attribute", evhp->base.ec);
823 name = _e_video_hwc_planes_prop_name_get_by_id(evhp, id);
825 if (!evhp->tdm.layer)
828 * Set property with assigning layer right away if allowed_attribute
829 * flag is set. The reason why we have to do like this isn't figured
830 * yet. It's for backward compatibility. */
831 if ((e_client_video_property_allow_get(evhp->base.ecv)) ||
834 if (!_e_video_hwc_planes_tdm_layer_set(evhp))
836 VER("set layer failed", evhp->base.ec);
840 if (evhp->video_plane_ready_handler)
842 VIN("wait for video plane ready", evhp->base.ec);
848 VIN("layer is not yet assigned", evhp->base.ec);
853 VIN("set layer: call property(%s), value(%d)", evhp->base.ec, name, value.u32);
857 _tdm_layer_property_set(evhp->tdm.layer, &prop);
862 VIN("save property value", evhp->base.ec);
863 if (!_e_video_hwc_planes_property_save(evhp, id, name, value))
865 VER("save property failed", evhp->base.ec);
873 _e_video_hwc_planes_iface_available_properties_get(E_Video_Hwc *evh, const tdm_prop **props, int *count)
875 E_Video_Hwc_Planes *evhp;
878 evhp = (E_Video_Hwc_Planes *)evh;
879 ret = _e_video_hwc_planes_available_properties_get(evhp, props, count);
880 if (ret != TDM_ERROR_NONE)
887 _e_video_hwc_planes_iface_buffer_commit(E_Video_Hwc *evh, E_Comp_Wl_Video_Buf *vbuf)
889 E_Video_Hwc_Planes *evhp;
890 E_Client_Video_Info info;
891 Eina_Bool ret = EINA_TRUE;
893 evhp = (E_Video_Hwc_Planes *)evh;
898 VIN("unset layer: hide", evhp->base.ec);
899 _e_video_hwc_planes_tdm_layer_unset(evhp);
905 info.src_config.size.h = vbuf->width_from_pitch;
906 info.src_config.size.v = vbuf->height_from_size;
907 info.src_config.pos.x = vbuf->content_r.x;
908 info.src_config.pos.y = vbuf->content_r.y;
909 info.src_config.pos.w = vbuf->content_r.w;
910 info.src_config.pos.h = vbuf->content_r.h;
911 info.src_config.format = vbuf->tbmfmt;
912 info.dst_pos.x = evhp->base.geo.tdm.output_r.x;
913 info.dst_pos.y = evhp->base.geo.tdm.output_r.y;
914 info.dst_pos.w = evhp->base.geo.tdm.output_r.w;
915 info.dst_pos.h = evhp->base.geo.tdm.output_r.h;
916 info.transform = vbuf->content_t;
918 if (!evhp->tdm.layer)
920 VIN("set layer: show", evhp->base.ec);
921 if (!_e_video_hwc_planes_tdm_layer_set(evhp))
923 VER("set layer failed", evhp->base.ec);
928 if (evhp->video_plane_ready_handler)
930 VIN("wait for video plane ready: Pending commit vbuf(%p)",
931 evhp->base.ec, vbuf);
933 if (evhp->pending.vbuf)
935 /* Cannot reach here because following buffers are supposed
936 * to be queued by 'e_video_hwc' until calling fb_update by
937 * this child module. */
943 evhp->pending.vbuf = vbuf;
944 memcpy(&evhp->pending.info, &info, sizeof(E_Client_Video_Info));
949 ret = _e_video_hwc_planes_buffer_commit(evhp, vbuf, &info);
956 _e_video_hwc_planes_iface_check_if_pp_needed(E_Video_Hwc *evh)
958 E_Video_Hwc_Planes *evhp;
960 const tbm_format *formats;
961 Eina_Bool found = EINA_FALSE;
962 tdm_layer_capability capabilities = 0;
964 evhp = (E_Video_Hwc_Planes *)evh;
966 tdm_layer *layer = _tdm_output_video_layer_get(evhp->tdm.output);
968 tdm_layer_get_capabilities(layer, &capabilities);
970 /* don't need pp if a layer has TDM_LAYER_CAPABILITY_VIDEO capability*/
971 if (capabilities & TDM_LAYER_CAPABILITY_VIDEO)
975 tdm_layer_get_available_formats(layer, &formats, &count);
976 for (i = 0; i < count; i++)
977 if (formats[i] == evhp->base.tbmfmt)
985 if (formats && count > 0)
986 evhp->base.pp_tbmfmt = formats[0];
989 WRN("No layer format information!!!");
990 evhp->base.pp_tbmfmt = TBM_FORMAT_ARGB8888;
995 if (capabilities & TDM_LAYER_CAPABILITY_SCANOUT)
999 if (evhp->base.geo.input_r.w != evhp->base.geo.output_r.w || evhp->base.geo.input_r.h != evhp->base.geo.output_r.h)
1000 if (!(capabilities & TDM_LAYER_CAPABILITY_SCALE))
1004 if (evhp->base.geo.transform || e_comp->e_comp_screen->rotation > 0)
1005 if (!(capabilities & TDM_LAYER_CAPABILITY_TRANSFORM))
1011 evhp->base.pp_tbmfmt = evhp->base.tbmfmt;
1015 static tbm_surface_h
1016 _e_video_hwc_planes_iface_displaying_buffer_get(E_Video_Hwc *evh)
1018 E_Video_Hwc_Planes *evhp;
1020 evhp = (E_Video_Hwc_Planes *)evh;
1021 return _tdm_layer_displaying_buffer_get(evhp->tdm.layer, NULL);
1025 _e_video_hwc_planes_iface_set(E_Video_Hwc_Iface *iface)
1027 iface->destroy = _e_video_hwc_planes_iface_destroy;
1028 iface->property_get = _e_video_hwc_planes_iface_property_get;
1029 iface->property_set = _e_video_hwc_planes_iface_property_set;
1030 iface->available_properties_get = _e_video_hwc_planes_iface_available_properties_get;
1031 iface->buffer_commit = _e_video_hwc_planes_iface_buffer_commit;
1032 iface->check_if_pp_needed = _e_video_hwc_planes_iface_check_if_pp_needed;
1033 iface->displaying_buffer_get = _e_video_hwc_planes_iface_displaying_buffer_get;
1036 EINTERN E_Video_Hwc *
1037 e_video_hwc_planes_create(E_Output *output, E_Client *ec)
1039 E_Video_Hwc_Planes *evhp;
1041 EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
1042 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1044 VIN("Create HWC Planes backend", ec);
1046 evhp = E_NEW(E_Video_Hwc_Planes, 1);
1047 EINA_SAFETY_ON_NULL_RETURN_VAL(evhp, NULL);
1049 evhp->base.e_output = output;
1050 evhp->tdm.output = output->toutput;
1052 if (!_e_video_hwc_planes_init(evhp, output))
1054 ERR("Failed to init 'E_Video_Hwc_Planes'");
1059 _e_video_hwc_planes_ec_event_init(evhp, ec);
1060 _e_video_hwc_planes_iface_set(&evhp->base.backend);
1062 return (E_Video_Hwc *)evhp;
1066 e_video_hwc_planes_property_delay_set(E_Video_Hwc *evh, unsigned int id, tdm_value value)
1068 E_Video_Hwc_Planes *evhp;
1071 evhp = (E_Video_Hwc_Planes *)evh;
1072 name = _e_video_hwc_planes_prop_name_get_by_id(evhp, id);
1074 _e_video_hwc_planes_property_post_set(evhp, id, name, value);