From 9ffc2bb6a993ee8e10c2bb608b571b5501ffab2f Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Mon, 21 Mar 2016 21:24:18 +0200 Subject: [PATCH] add reinitialization of external output layer and buffer Change-Id: I642afed3fa954abed2dd0149127bab572c02dd19 Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 326 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 270 insertions(+), 56 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 241dd4d..7784bce 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -20,6 +20,10 @@ struct _E_Eom struct wl_global *global; struct wl_resource *resource; Eina_List *handlers; + + tdm_display *dpy; + tbm_bufmgr bufmgr; + int fd; }; typedef struct _Ecore_Drm_Hal_Output @@ -32,6 +36,7 @@ typedef struct { tdm_layer *layer; tdm_output *output; + tbm_surface_h dst_buffers; } Eom_Event; static Eom_Event g_eom_event; @@ -42,12 +47,11 @@ E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "EOM Module" }; static E_Client_Hook *fullscreen_pre_hook = NULL; - static E_Comp_Wl_Output * _e_eom_e_comp_wl_output_get(Eina_List *outputs, const char *id) { Eina_List *l; - E_Comp_Wl_Output *output, *out; + E_Comp_Wl_Output *output = NULL, *out; int num_outputs = 0; EINA_LIST_FOREACH(outputs, l, out) @@ -79,18 +83,21 @@ _e_eom_e_comp_wl_output_get(Eina_List *outputs, const char *id) return output; } -static Ecore_Drm_Hal_Output * -_e_eom_e_comp_hal_output_get(const char *id, int primary_output_id) +static tdm_output * +_e_eom_hal_output_get(const char *id, int primary_output_id) { - Ecore_Drm_Hal_Output * hal_output; Ecore_Drm_Output *drm_output; Ecore_Drm_Device *dev; Eina_List *l; + int crtc_id = 0; + tdm_error err = TDM_ERROR_NONE; + + tdm_output *output = NULL; /* - * Temporary take into account only HDMI - */ + * Temporary take into account only HDMI + */ if (strcmp(id, "HDMI-A-0")) { EOM_DBG("not find output\n"); @@ -108,36 +115,100 @@ _e_eom_e_comp_hal_output_get(const char *id, int primary_output_id) return NULL; } - hal_output = ecore_drm_output_hal_private_get(drm_output); - if (!hal_output) + crtc_id = ecore_drm_output_crtc_id_get(drm_output); + if (crtc_id == 0) + { + EOM_DBG("crtc is 0\n"); + return NULL; + } + + output = tdm_display_get_output(g_eom->dpy, crtc_id, NULL); + if (!output) { - EOM_DBG("not find hal output output\n"); + EOM_DBG("there is no HAL output for:%d\n", crtc_id); return NULL; } EOM_DBG("find\n"); - return hal_output; + return output; +} + +static tdm_layer * +_e_eom_hal_layer_get(tdm_output *output, int width, int height) +{ + int i = 0; + int count = 0; + tdm_layer *layer; + tdm_error err = TDM_ERROR_NONE; + tdm_layer_capability capa; + + tdm_info_layer set_layer_info; + + err = tdm_output_get_layer_count(output, &count); + if (err != TDM_ERROR_NONE) + { + EOM_DBG ("tdm_output_get_layer_count fail(%d)\n", err); + return NULL; + } + + for (i = 0; i < count; i++) + { + layer = (tdm_layer *)tdm_output_get_layer(output, i, &err); + if (err != TDM_ERROR_NONE) + { + EOM_DBG ("tdm_output_get_layer fail(%d)\n", err); + return NULL; + } + + err = tdm_layer_get_capabilities(layer, &capa); + if (err != TDM_ERROR_NONE) + { + EOM_DBG ("tdm_layer_get_capabilities fail(%d)\n", err); + return NULL; + } + + if (capa & TDM_LAYER_CAPABILITY_PRIMARY) + { + EOM_DBG("TDM_LAYER_CAPABILITY_PRIMARY layer found : %d\n", i); + break; + } + } + + memset(&set_layer_info, 0x0, sizeof(tdm_info_layer)); + set_layer_info.src_config.size.h = width; + set_layer_info.src_config.size.v = height; + set_layer_info.src_config.pos.x = 0; + set_layer_info.src_config.pos.y = 0; + set_layer_info.src_config.pos.w = width; + set_layer_info.src_config.pos.h = height; + set_layer_info.src_config.format = TBM_FORMAT_ARGB8888; + set_layer_info.dst_pos.x = 0; + set_layer_info.dst_pos.y = 0; + set_layer_info.dst_pos.w = width; + set_layer_info.dst_pos.h = height; + set_layer_info.transform = TDM_TRANSFORM_NORMAL; + + err = tdm_layer_set_info(layer, &set_layer_info); + if (err != TDM_ERROR_NONE) + { + EOM_DBG ("tdm_layer_set_info fail(%d)\n", err); + return NULL; + } + + return layer; } static tbm_surface_h -_e_eom_e_comp_tdm_surface_get() +_e_eom_root_window_tdm_surface_get() { Evas_Engine_Info_Drm *einfo; Ecore_Drm_Fb* fb; - Ecore_Evas *ee; - Evas *evas; - EOM_DBG("1\n"); - - if (!e_comp || !e_comp->evas /*|| e_comp->ee->evas*/) - return NULL; - - EOM_DBG("2\n"); + if (!e_comp || !e_comp->evas) + return NULL; einfo = (Evas_Engine_Info_Drm *)evas_engine_info_get(e_comp->evas); - EOM_DBG("3\n"); - fb = _ecore_drm_display_fb_find_with_id(einfo->info.buffer_id); if (!fb) { @@ -156,22 +227,28 @@ _e_eom_e_comp_tdm_surface_get() } static void -_ecore_drm_display_output_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUSED, +_e_eom_output_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUSED, unsigned int tv_sec EINA_UNUSED, unsigned int tv_usec EINA_UNUSED, void *user_data) { Eom_Event *eom_event = (Eom_Event *)user_data; tdm_error err = TDM_ERROR_NONE; + tbm_surface_h src_buffer; + tbm_surface_h dst_buffer; + + EOM_ERR("Event\n"); - tbm_surface_h tdm_buffer = _e_eom_e_comp_tdm_surface_get(); - if (!tdm_buffer) + src_buffer = _e_eom_root_window_tdm_surface_get(); + if (!src_buffer ) { EOM_ERR("Event: tdm_buffer is NULL\n"); return; } + dst_buffer = eom_event->dst_buffers; + /* Do clone */ - tdm_layer_set_buffer(eom_event->layer, tdm_buffer); + tdm_layer_set_buffer(eom_event->layer, dst_buffer); err = tdm_output_commit(eom_event->output, 0, NULL, eom_event); if (err != TDM_ERROR_NONE) @@ -181,23 +258,68 @@ _ecore_drm_display_output_cb_commit(tdm_output *output EINA_UNUSED, unsigned int } } +static tbm_surface_h +_e_eom_create_extrenal_output_buffer(int width, int height) +{ + tbm_surface_h buffer; + tbm_surface_info_s buffer_info; + + /* + * TODO: Add support of other formats + */ + buffer = tbm_surface_internal_create_with_flags(width, height, + TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); + if (!buffer) + { + EOM_DBG("can not create dst_buffer\n"); + return NULL; + } + + /* + * TODO: temp code for testing, actual convert will be in _e_eom_put_src_to_dst() + */ + memset(&buffer_info, 0x0, sizeof(tbm_surface_info_s)); + if (tbm_surface_map(buffer, + TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, + &buffer_info) != TBM_SURFACE_ERROR_NONE) + { + EOM_DBG("can not mmap buffer\n"); + return NULL; + } + + memset(buffer_info.planes[0].ptr, 0xff, buffer_info.planes[0].size); + tbm_surface_unmap(buffer); + + return buffer; +} + +static void +_e_eom_put_src_to_dst( tbm_surface_h src_buffer, tbm_surface_h dst_buffer) +{ + + + +} + static Eina_Bool _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { Ecore_Drm_Event_Output *e; E_EomPtr eom = data; E_Comp_Wl_Output *wl_output; - Ecore_Drm_Hal_Output *hal_output; - tbm_surface_h tdm_buffer; - tbm_surface_info_s tdm_buffer_info; - Ecore_Drm_Fb *fb; - Ecore_Drm_Device *dev; - Eina_List *l, *l2; + tdm_output *hal_output; + tdm_layer *hal_layer; + tdm_info_layer layer_info; + tbm_surface_h src_buffer; + tbm_surface_h dst_buffer; + tbm_surface_info_s src_buffer_info ; + Eina_List *l2; Eom_Event *eom_event = &g_eom_event; struct wl_resource *output_resource; enum wl_eom_type eom_type = WL_EOM_TYPE_NONE; char buff[PATH_MAX]; - tdm_error err = TDM_ERROR_NONE; + tdm_error tdm_err = TDM_ERROR_NONE; + int tbm_err = 0; if (!(e = event)) goto end; @@ -217,58 +339,101 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e } /* Get hal output */ - hal_output = _e_eom_e_comp_hal_output_get(buff, e->id); + hal_output = _e_eom_hal_output_get(buff, e->id); if (!hal_output) { EOM_ERR("no hal outputs, (%s)\n", buff); goto end; } + hal_layer = _e_eom_hal_layer_get(hal_output, e->w, e->h); + if (!hal_layer) + { + EOM_ERR("no hal layer\n"); + goto end; + } + /* Get main frame buffer */ - tdm_buffer = _e_eom_e_comp_tdm_surface_get(); - if (!tdm_buffer ) + src_buffer = _e_eom_root_window_tdm_surface_get(); + if (!src_buffer ) { EOM_ERR("no framebuffer\n"); goto end; } - tbm_surface_get_info(tdm_buffer, tdm_buffer_info ); + dst_buffer = _e_eom_create_extrenal_output_buffer(e->w, e->h); + if (!dst_buffer ) + { + EOM_ERR("no framebuffer\n"); + goto end; + } - EOM_DBG("%dx%d bpp:%d size:%d", tdm_buffer_info->width, - tdm_buffer_info->height, tdm_buffer_info->bpp, tdm_buffer_info->size); + tbm_surface_get_info(src_buffer, &src_buffer_info ); - /* - * TODO: convert primary output size to external one - */ + EOM_DBG("FRAMEBUFFER buffer: %dx%d bpp:%d size:%d", + src_buffer_info.width, + src_buffer_info.height, + src_buffer_info.bpp, + src_buffer_info.size); - /* Do clone */ - tdm_layer_set_buffer(hal_output->primary_layer, tdm_buffer); + _e_eom_put_src_to_dst(src_buffer, dst_buffer); - eom_event->layer = hal_output->primary_layer; - eom_event->output = hal_output->output; - err = tdm_output_commit(hal_output->output, 0, _ecore_drm_display_output_cb_commit, &eom_event); - if (err != TDM_ERROR_NONE) + tdm_err = tdm_layer_get_info(hal_layer, &layer_info); + if (tdm_err != TDM_ERROR_NONE) { - EOM_ERR("Cannot commit crtc\n"); - return ECORE_CALLBACK_PASS_ON; + EOM_ERR ("failed get layer info", tdm_err); + goto end; + } + + EOM_DBG("LAYER INFO: %dx%d, pos (x:%d, y:%d, w:%d, h:%d, dpos (x:%d, y:%d, w:%d, h:%d))", + layer_info.src_config.size.h, layer_info.src_config.size.v, + layer_info.src_config.pos.x, layer_info.src_config.pos.y, + layer_info.src_config.pos.w, layer_info.src_config.pos.h, + layer_info.dst_pos.x, layer_info.dst_pos.y, + layer_info.dst_pos.w, layer_info.dst_pos.h); + + tdm_err = tdm_layer_set_buffer(hal_layer, dst_buffer); + if (tdm_err != TDM_ERROR_NONE) + { + EOM_ERR("Failed set buffer on layer:%d\n", tdm_err); + goto end; } + eom_event->layer = hal_layer; + eom_event->output = hal_output; + eom_event->dst_buffers = dst_buffer; + + tdm_err = tdm_output_commit(hal_output, 0, _e_eom_output_cb_commit, &eom_event); + if (tdm_err != TDM_ERROR_NONE) + { + EOM_ERR("Cannot commit crtc:%d\n", tdm_err); + goto end; + } EINA_LIST_FOREACH(wl_output->resources, l2, output_resource) { if (e->plug) - wl_eom_send_output_type(eom->resource, + { + + wl_eom_send_output_type(eom->resource, output_resource, eom_type, WL_EOM_STATUS_CONNECTION); + } else + { + EOM_DBG("7\n"); + wl_eom_send_output_type(eom->resource, output_resource, eom_type, WL_EOM_STATUS_DISCONNECTION); + } } + EOM_DBG("8\n"); + end: return ECORE_CALLBACK_PASS_ON; } @@ -416,11 +581,11 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32 MIN(version, 1), id); if (!resource) - { - EOM_ERR("error. resource is null. (version :%d, id:%d)\n", version, id); - wl_client_post_no_memory(client); - return; - } + { + EOM_ERR("error. resource is null. (version :%d, id:%d)\n", version, id); + wl_client_post_no_memory(client); + return; + } wl_resource_set_implementation(resource, &_e_eom_wl_implementation, @@ -456,11 +621,53 @@ _e_eom_deinit() E_FREE(g_eom); } +int +_e_eom_init_internal() +{ + tdm_error err = TDM_ERROR_NONE; + + EOM_DBG("1\n"); + + g_eom->dpy = tdm_display_init(&err); + if (err != TDM_ERROR_NONE) + { + EOM_DBG("failed initialize TDM\n"); + goto err; + } + + EOM_DBG("2\n"); + + err = tdm_display_get_fd(g_eom->dpy, &g_eom->fd); + if (err != TDM_ERROR_NONE) + { + EOM_DBG("failed get FD\n"); + goto err; + } + + EOM_DBG("3\n"); + + g_eom->bufmgr = tbm_bufmgr_init(g_eom->fd); + if (!g_eom->bufmgr) + { + EOM_DBG("failed initialize buffer manager\n"); + goto err; + } + + EOM_DBG("4\n"); + + return 1; +err: + return 0; +} + static Eina_Bool _e_eom_init() { + int ret = 0; + EINA_SAFETY_ON_NULL_GOTO(e_comp_wl, err); + g_eom = E_NEW(E_Eom, 1); EINA_SAFETY_ON_NULL_RETURN_VAL(g_eom, EINA_FALSE); @@ -471,6 +678,13 @@ _e_eom_init() _e_eom_wl_bind_cb); EINA_SAFETY_ON_NULL_GOTO(g_eom->global, err); + ret = _e_eom_init_internal(); + if (!ret) + { + EOM_ERR("failed init_internal()"); + goto err; + } + E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_ACTIVATE, _e_eom_ecore_drm_activate_cb, g_eom); E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_OUTPUT, _e_eom_ecore_drm_output_cb, g_eom); -- 2.7.4