From ca549860d787aeb0ddfb30fa1165334acf1aa3ca Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Thu, 5 May 2016 17:11:50 +0300 Subject: [PATCH 01/16] correct notifications of clients Change-Id: I7f582f3025c39cd1effdf6f1ee3b01fb814e6016 Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 115 ++++++++++++++++++++++++++----------------------------- 1 file changed, 55 insertions(+), 60 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 4b851be..03a619a 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -10,7 +10,6 @@ #include "eom-server-protocol.h" #include "Ecore_Drm.h" - #define NUM_MAIN_BUF 2 #define NUM_ATTR 3 @@ -58,7 +57,7 @@ struct _E_Eom_Output struct _E_Eom { struct wl_global *global; - struct wl_resource *resource; + Eina_List *eom_clients; Eina_List *handlers; tdm_display *dpy; @@ -160,8 +159,6 @@ static E_EomClientBufferPtr _e_eom_get_client_buffer_from_list(); /*eom utils functions*/ static int _e_eom_get_time_in_mseconds(); - - static void _e_eom_create_fake_buffers(int width, int height); static inline enum wl_eom_mode @@ -245,12 +242,10 @@ _e_eom_pp_cb(tbm_surface_h surface, void *user_data) /* If a client has committed its buffer stop mirror mode */ if (g_eom->is_mirror_mode == 0) { - EOM_DBG("PP STOP\n"); + EOM_DBG("PP STOP\n"); return; } - EOM_DBG("PP\n"); - tbm_surface_h src_buffer; src_buffer = _e_eom_root_internal_tdm_surface_get(g_eom->int_output_name); if (!src_buffer ) @@ -304,8 +299,6 @@ _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS /* TODO: Maybe better to separating that callback on to mirror and extended callbacks */ if (g_eom->is_mirror_mode == 1) { - EOM_ERR("MIRROR MODE\n"); - if (eom_data->current_buffer == 1) { eom_data->current_buffer = 0; @@ -340,12 +333,7 @@ _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS } else { - EOM_DBG("EXTENDED MODE\n"); - - client_buffer = _e_eom_get_client_buffer_from_list(); - - EOM_DBG("EXTENDED MODE: client_buffer %p\n", client_buffer); - + client_buffer = _e_eom_get_client_buffer_from_list(); err = tdm_layer_set_buffer(eom_data->layer, client_buffer->tbm_buffer); if (err != TDM_ERROR_NONE) { @@ -972,15 +960,12 @@ static int flag = 0; 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; - const Eina_List *l; - struct wl_resource *output_resource; - */ - E_Comp_Wl_Output *wl_output = NULL; enum wl_eom_type eom_type = WL_EOM_TYPE_NONE; + struct wl_resource *resource_iterator; + E_Comp_Wl_Output *wl_output = NULL; + Ecore_Drm_Event_Output *e; char buff[PATH_MAX]; + Eina_List *l; int ret = 0; if (!(e = event)) goto end; @@ -1043,28 +1028,26 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e g_eom->wl_output = wl_output; - /* - EINA_LIST_FOREACH(wl_output->resources, l, output_resource) + EINA_LIST_FOREACH(g_eom->eom_clients, l, resource_iterator) { - - EOM_DBG("e->plug:%d\n", e->plug); - - wl_eom_send_output_type(eom->resource, - output_resource, - eom_type, - _e_eom_get_eom_status()); - - wl_eom_send_output_attribute(eom->resource, - output_resource, - _e_eom_get_eom_attribute(), - _e_eom_get_eom_attribute_state(), - WL_EOM_ERROR_NONE); - - wl_eom_send_output_mode(eom->resource, - output_resource, - _e_eom_get_eom_mode()); + if (resource_iterator) + { + wl_eom_send_output_type(resource_iterator, + g_eom->id, + eom_type, + _e_eom_get_eom_status()); + + wl_eom_send_output_attribute(resource_iterator, + g_eom->id, + _e_eom_get_eom_attribute(), + _e_eom_get_eom_attribute_state(), + WL_EOM_ERROR_NONE); + + wl_eom_send_output_mode(resource_iterator, + g_eom->id, + _e_eom_get_eom_mode()); + } } - */ } else if (strcmp(e->name, "DSI-0") == 0 && g_eom->is_external_init && flag == 2) { @@ -1217,6 +1200,7 @@ _e_eom_client_buffers_list_free() } } + static E_EomClientBufferPtr _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer) { @@ -1240,6 +1224,7 @@ _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffe return buffer; } + static E_EomClientBufferPtr _e_eom_get_client_buffer_from_list() { @@ -1257,6 +1242,7 @@ _e_eom_get_client_buffer_from_list() return NULL; } + static int _e_eom_get_time_in_mseconds() { @@ -1267,6 +1253,7 @@ _e_eom_get_time_in_mseconds() return ((tp.tv_sec * 1000) + (tp.tv_nsec / 1000)); } + static Eina_Bool _e_eom_ecore_drm_activate_cb(void *data, int type EINA_UNUSED, void *event) { @@ -1296,7 +1283,7 @@ end: return ECORE_CALLBACK_PASS_ON; } -/* wl_eom_set_keygrab request handler */ + static void _e_eom_wl_request_set_attribute_cb(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, uint32_t attribute) { @@ -1304,6 +1291,7 @@ _e_eom_wl_request_set_attribute_cb(struct wl_client *client, struct wl_resource EOM_DBG("attribute:%d +++ output:%d\n", attribute, output_id); + /* TODO: Add notifications when more prior client changes eom state */ ret = _e_eom_set_eom_attribute(attribute); if (ret == 0) { @@ -1383,7 +1371,10 @@ static const struct wl_eom_interface _e_eom_wl_implementation = static void _e_eom_wl_resource_destory_cb(struct wl_resource *resource) { + struct wl_resource *resource_iterator; + Eina_List *l; int ret; + EOM_DBG("client unbind\n"); ret = _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); @@ -1402,19 +1393,28 @@ _e_eom_wl_resource_destory_cb(struct wl_resource *resource) _e_eom_client_buffers_list_free(); ret = _e_eom_mirror_start(g_eom->int_output_name, - g_eom->src_mode.w, - g_eom->src_mode.h); + g_eom->src_mode.w, + g_eom->src_mode.h); if (!ret) { EOM_ERR("ERROR: restore mirror mode after a client disconnection\n"); - goto err; + return; } - } - /*TODO: notify clients that EOM has just changed status*/ + /* Notify eom clients that eom state has been changed */ + EINA_LIST_FOREACH(g_eom->eom_clients, l, resource_iterator) + { + if (resource_iterator) + { + wl_eom_send_output_attribute(resource_iterator, + g_eom->id, + _e_eom_get_eom_attribute(), + _e_eom_get_eom_attribute_state(), + WL_EOM_ERROR_NONE); + } -err: - return; + } + } } /* wl_eom global object bind function */ @@ -1443,11 +1443,6 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32 eom, _e_eom_wl_resource_destory_cb); - /*TODO: We have to store all clients in list to make it possible to send - * events when a client free external output or has been destroyed - */ - eom->resource = resource; - #if 0 wl_output = _e_eom_e_comp_wl_output_get(e_comp_wl->outputs, g_eom->ext_output_name); if (!wl_output) @@ -1463,23 +1458,23 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32 return; } - wl_eom_send_output_type(eom->resource, + wl_eom_send_output_type(resource, eom->id, eom_type, _e_eom_get_eom_status()); - wl_eom_send_output_attribute(eom->resource, + wl_eom_send_output_attribute(resource, eom->id, _e_eom_get_eom_attribute(), _e_eom_get_eom_attribute_state(), WL_EOM_ERROR_NONE); - wl_eom_send_output_mode(eom->resource, + wl_eom_send_output_mode(resource, eom->id, _e_eom_get_eom_mode()); #else EOM_DBG("send - output count : %d\n", g_eom->output_count); - wl_eom_send_output_count(eom->resource, + wl_eom_send_output_count(resource, g_eom->output_count); if (g_eom->outputs) @@ -1498,7 +1493,7 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32 } #endif - EOM_DBG("create wl_eom global resource.\n"); + g_eom->eom_clients = eina_list_append(g_eom->eom_clients, resource); } static void -- 2.7.4 From 4b6a30d30a0f1d86ba4e96606d2cc9395d5b8080 Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Thu, 5 May 2016 20:29:07 +0300 Subject: [PATCH 02/16] allow clients binding to eom when there is no external output Change-Id: I6f131c6b8664a9617168ed7696d133c1673a08ae Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 03a619a..8f49b1c 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -357,13 +357,14 @@ _e_eom_e_comp_wl_output_get(const Eina_List *outputs, const char *id) E_Comp_Wl_Output *output = NULL, *o; int loc = 0; + if (id == NULL) + return NULL; + EINA_LIST_FOREACH(outputs, l, o) { char *temp_id = NULL; temp_id = strchr(o->id, '/'); - EOM_DBG("o->id=%s", o->id); - if (temp_id == NULL) { if (strcmp(o->id, id) == 0) @@ -779,6 +780,9 @@ _e_eom_output_name_to_eom_type(const char *output_name) { enum wl_eom_type eom_type; + if (output_name == NULL) + return WL_EOM_TYPE_NONE; + /* TODO: Add other external outputs */ if (strcmp(output_name, "HDMI-A-0") == 0) eom_type = WL_EOM_TYPE_HDMIA; @@ -1200,7 +1204,6 @@ _e_eom_client_buffers_list_free() } } - static E_EomClientBufferPtr _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer) { @@ -1224,7 +1227,6 @@ _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffe return buffer; } - static E_EomClientBufferPtr _e_eom_get_client_buffer_from_list() { @@ -1242,7 +1244,6 @@ _e_eom_get_client_buffer_from_list() return NULL; } - static int _e_eom_get_time_in_mseconds() { @@ -1253,7 +1254,6 @@ _e_eom_get_time_in_mseconds() return ((tp.tv_sec * 1000) + (tp.tv_nsec / 1000)); } - static Eina_Bool _e_eom_ecore_drm_activate_cb(void *data, int type EINA_UNUSED, void *event) { @@ -1283,14 +1283,11 @@ end: return ECORE_CALLBACK_PASS_ON; } - static void _e_eom_wl_request_set_attribute_cb(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, uint32_t attribute) { int ret = 0; - EOM_DBG("attribute:%d +++ output:%d\n", attribute, output_id); - /* TODO: Add notifications when more prior client changes eom state */ ret = _e_eom_set_eom_attribute(attribute); if (ret == 0) @@ -1421,8 +1418,7 @@ _e_eom_wl_resource_destory_cb(struct wl_resource *resource) static void _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32_t id) { - /* enum wl_eom_type eom_type = WL_EOM_TYPE_NONE; */ - /* E_Comp_Wl_Output *wl_output = NULL; */ + enum wl_eom_type eom_type = WL_EOM_TYPE_NONE; struct wl_resource *resource; E_EomPtr eom = data; @@ -1437,26 +1433,12 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32 return; } - wl_resource_set_implementation(resource, &_e_eom_wl_implementation, eom, _e_eom_wl_resource_destory_cb); -#if 0 - wl_output = _e_eom_e_comp_wl_output_get(e_comp_wl->outputs, g_eom->ext_output_name); - if (!wl_output) - { - EOM_DBG("failed to get wl_output\n"); - return; - } - eom_type = _e_eom_output_name_to_eom_type(g_eom->ext_output_name); - if (eom_type == WL_EOM_TYPE_NONE) - { - EOM_DBG("create wl_eom global resource.\n"); - return; - } wl_eom_send_output_type(resource, eom->id, @@ -1472,7 +1454,7 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32 wl_eom_send_output_mode(resource, eom->id, _e_eom_get_eom_mode()); -#else + EOM_DBG("send - output count : %d\n", g_eom->output_count); wl_eom_send_output_count(resource, g_eom->output_count); @@ -1491,7 +1473,6 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32 output->phys_width, output->phys_height, output->status); } } -#endif g_eom->eom_clients = eina_list_append(g_eom->eom_clients, resource); } @@ -1728,6 +1709,8 @@ _e_eom_init() g_eom->is_external_init = 0; g_eom->is_internal_grab = 0; + g_eom->ext_output_name = NULL; + g_eom->int_output_name = NULL; _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_NONE); _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); -- 2.7.4 From 574fd03b3b54f928d041f56f292616bb6f173917 Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Fri, 6 May 2016 17:22:31 +0300 Subject: [PATCH 03/16] clean code Change-Id: I3d3b789253ff4f25a526f0a362378de6950b8b48 Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 258 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 132 insertions(+), 126 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 8f49b1c..76564eb 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -135,15 +135,15 @@ static int eom_output_attributes[NUM_ATTR][NUM_ATTR] = /* handle external output */ static E_Comp_Wl_Output *_e_eom_e_comp_wl_output_get(const Eina_List *outputs, const char *id); -static int _e_eom_set_up_external_output(const char *output_name, int width, int height); +static Eina_Bool _e_eom_set_up_external_output(const char *output_name, int width, int height); static tdm_output * _e_eom_hal_output_get(const char *id); static tdm_layer * _e_eom_hal_layer_get(tdm_output *output, int width, int height); -static int _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height); +static Eina_Bool _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height); static enum wl_eom_type _e_eom_output_name_to_eom_type(const char *output_name); /* handle internal output, pp */ -static int _e_eom_mirror_start(const char *output_name, int width, int height); +static Eina_Bool _e_eom_mirror_start(const char *output_name, int width, int height); static tbm_surface_h _e_eom_root_internal_tdm_surface_get(const char *name); -static int _e_eom_pp_src_to_dst( tbm_surface_h src_buffer); +static Eina_Bool _e_eom_pp_src_to_dst( tbm_surface_h src_buffer); /* tdm handlers */ static void _e_eom_pp_cb(tbm_surface_h surface, void *user_data); static void _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUSED, @@ -191,22 +191,22 @@ _e_eom_get_eom_attribute() return g_eom->eom_attribute; } -static inline int +static inline Eina_Bool _e_eom_set_eom_attribute(enum wl_eom_attribute attribute) { if (attribute == WL_EOM_ATTRIBUTE_NONE || g_eom->eom_attribute == WL_EOM_ATTRIBUTE_NONE) { g_eom->eom_attribute = attribute; - return 1; + return EINA_TRUE; } if (eom_output_attributes[g_eom->eom_attribute - 1][attribute - 1] == 1) { g_eom->eom_attribute = attribute; - return 1; + return EINA_TRUE; } - return 0; + return EINA_FALSE; } static inline enum wl_eom_status @@ -224,10 +224,10 @@ _e_eom_set_eom_status(enum wl_eom_status status) static void _e_eom_pp_cb(tbm_surface_h surface, void *user_data) { - E_EomEventDataPtr eom_data = NULL; tdm_error tdm_err = TDM_ERROR_NONE; + E_EomEventDataPtr eom_data = NULL; - if (!user_data) + if (user_data == NULL) { EOM_DBG("ERROR: PP EVENT: user data is NULL\n"); return; @@ -236,19 +236,16 @@ _e_eom_pp_cb(tbm_surface_h surface, void *user_data) eom_data = (E_EomEventDataPtr)user_data; tdm_buffer_remove_release_handler(eom_data->dst_buffers[eom_data->pp_buffer], - _e_eom_pp_cb, eom_data); + _e_eom_pp_cb, eom_data); /* TODO: lock that flag??? */ /* If a client has committed its buffer stop mirror mode */ if (g_eom->is_mirror_mode == 0) - { - EOM_DBG("PP STOP\n"); - return; - } + return; tbm_surface_h src_buffer; src_buffer = _e_eom_root_internal_tdm_surface_get(g_eom->int_output_name); - if (!src_buffer ) + if (src_buffer == EINA_FALSE) { EOM_DBG("ERROR: PP EVENT: get root tdm surfcae\n"); return; @@ -284,11 +281,11 @@ _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS unsigned int tv_sec EINA_UNUSED, unsigned int tv_usec EINA_UNUSED, void *user_data) { - E_EomEventDataPtr eom_data; - E_EomClientBufferPtr client_buffer; + E_EomClientBufferPtr client_buffer = NULL; + E_EomEventDataPtr eom_data = NULL; tdm_error err = TDM_ERROR_NONE; - if (!user_data) + if (user_data == NULL) { EOM_ERR("ERROR: EVENT: user_data is NULL\n"); return; @@ -334,6 +331,12 @@ _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS else { client_buffer = _e_eom_get_client_buffer_from_list(); + if (client_buffer == NULL) + { + EOM_ERR("ERROR: EVENT: client buffer is NULL\n"); + return; + } + err = tdm_layer_set_buffer(eom_data->layer, client_buffer->tbm_buffer); if (err != TDM_ERROR_NONE) { @@ -353,8 +356,8 @@ _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS static E_Comp_Wl_Output * _e_eom_e_comp_wl_output_get(const Eina_List *outputs, const char *id) { + E_Comp_Wl_Output *output = NULL, *o = NULL; const Eina_List *l; - E_Comp_Wl_Output *output = NULL, *o; int loc = 0; if (id == NULL) @@ -384,32 +387,34 @@ _e_eom_e_comp_wl_output_get(const Eina_List *outputs, const char *id) return output; } -static int +static Eina_Bool _e_eom_set_up_external_output(const char *output_name, int width, int height) { - tdm_output *hal_output; - tdm_layer *hal_layer; - tdm_info_layer layer_info; tdm_error tdm_err = TDM_ERROR_NONE; - E_EomEventDataPtr eom_data = &g_eom_event_data; - int ret = 0; + E_EomEventDataPtr eom_data = NULL; + tdm_output *hal_output = NULL; + tdm_layer *hal_layer = NULL; + Eina_Bool ret = EINA_FALSE; + tdm_info_layer layer_info; + + eom_data = &g_eom_event_data; hal_output = _e_eom_hal_output_get(output_name); - if (!hal_output) + if (hal_output == NULL) { EOM_ERR("ERROR: get hal output for, (%s)\n", output_name); goto err; } hal_layer = _e_eom_hal_layer_get(hal_output, width, height); - if (!hal_layer) + if (hal_layer == NULL) { EOM_ERR("ERROR: get hal layer\n"); goto err; } ret = _e_eom_create_output_buffers(eom_data, width, height); - if (!ret ) + if (ret == EINA_FALSE) { EOM_ERR("ERROR: create buffers \n"); goto err; @@ -462,14 +467,13 @@ _e_eom_set_up_external_output(const char *output_name, int width, int height) goto err; } - - return 1; + return EINA_TRUE; err: /* * TODO: add deinitialization */ - return 0; + return EINA_FALSE; } static void @@ -506,6 +510,18 @@ _e_eom_deinit_external_output() } } + if (g_eom->int_output_name) + { + free(g_eom->int_output_name); + g_eom->int_output_name = NULL; + } + + if (g_eom->ext_output_name) + { + free(g_eom->ext_output_name); + g_eom->ext_output_name = NULL; + } + if (g_eom->wl_output) g_eom->wl_output = NULL; } @@ -513,15 +529,16 @@ _e_eom_deinit_external_output() static tdm_output * _e_eom_hal_output_get(const char *id) { - Ecore_Drm_Device *dev; - Ecore_Drm_Output *drm_output = NULL, *o; - tdm_output *output; - const tdm_output_mode *modes; - const tdm_output_mode *big_mode; + Ecore_Drm_Output *drm_output = NULL, *o = NULL; + const tdm_output_mode *big_mode = NULL; + const tdm_output_mode *modes = NULL; + Ecore_Drm_Device *dev = NULL; + tdm_output *output = NULL; tdm_error err = TDM_ERROR_NONE; const Eina_List *l, *ll; int crtc_id = 0; int count = 0; + int i = 0; /* * TODO: Temporary take into account only HDMI @@ -536,7 +553,7 @@ _e_eom_hal_output_get(const char *id) } } - if (!drm_output) + if (drm_output == NULL) { EOM_ERR("ERROR: drm output was not found\n"); return NULL; @@ -550,7 +567,7 @@ _e_eom_hal_output_get(const char *id) } output = tdm_display_get_output(g_eom->dpy, crtc_id, NULL); - if (!output) + if (output == NULL) { EOM_ERR("ERROR: there is no HAL output for:%d\n", crtc_id); return NULL; @@ -579,15 +596,14 @@ _e_eom_hal_output_get(const char *id) big_mode = &modes[0]; - int i = 0; for (i = 0; i < count; i++) { - if ((modes[i].vdisplay + modes[i].hdisplay) >= (big_mode->vdisplay + big_mode->hdisplay)) + if ((modes[i].vdisplay + modes[i].hdisplay) >= + (big_mode->vdisplay + big_mode->hdisplay)) big_mode = &modes[i]; } - /*TODO: fix it*/ - if (!big_mode) + if (big_mode == NULL) { EOM_ERR("no Big mode\n"); return NULL; @@ -676,11 +692,11 @@ _e_eom_hal_layer_get(tdm_output *output, int width, int height) static void _e_eom_create_fake_buffers(int width, int height) { - tbm_surface_h buffer; tbm_surface_info_s buffer_info; + tbm_surface_h buffer = NULL; buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - if (!buffer) + if (buffer == NULL) { EOM_DBG("can not create fake_buffer\n"); goto err; @@ -704,17 +720,17 @@ err: return; } -static int +static Eina_Bool _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height) { - tbm_surface_h buffer; tbm_surface_info_s buffer_info; + tbm_surface_h buffer = NULL; /* * TODO: Add support of other formats */ buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - if (!buffer) + if (buffer == NULL) { EOM_DBG("can not create dst_buffer\n"); goto err; @@ -742,7 +758,7 @@ _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height) * TODO: Add support of other formats */ buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - if (!buffer) + if (buffer == NULL) { EOM_DBG("can not create dst_buffer\n"); goto err; @@ -765,14 +781,14 @@ _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height) eom_data->dst_buffers[1] = buffer; - return 1; + return EINA_TRUE; err: /* * Add deinitialization */ - return 0; + return EINA_FALSE; } static enum wl_eom_type @@ -792,15 +808,15 @@ _e_eom_output_name_to_eom_type(const char *output_name) return eom_type; } -static int +static Eina_Bool _e_eom_mirror_start(const char *output_name, int width, int height) { - tbm_surface_h src_buffer; tbm_surface_info_s src_buffer_info; - int ret = 0; + tbm_surface_h src_buffer = NULL; + Eina_Bool ret = EINA_FALSE; src_buffer = _e_eom_root_internal_tdm_surface_get(output_name); - if (!src_buffer ) + if (src_buffer == NULL) { EOM_ERR("ERROR: get root tdm surfcae\n"); return 0; @@ -809,28 +825,22 @@ _e_eom_mirror_start(const char *output_name, int width, int height) tbm_surface_get_info(src_buffer, &src_buffer_info ); EOM_DBG("FRAMEBUFFER TDM: %dx%d bpp:%d size:%d", - src_buffer_info.width, - src_buffer_info.height, - src_buffer_info.bpp, - src_buffer_info.size); + src_buffer_info.width, src_buffer_info.height, + src_buffer_info.bpp, src_buffer_info.size); g_eom->src_mode.w = width; g_eom->src_mode.h = height; /* TODO: free that memory */ g_eom->int_output_name = strdup(output_name); - EOM_DBG("INT SURFACE: 1\n"); - ret = _e_eom_pp_src_to_dst(src_buffer); - if (!ret ) + if (ret == EINA_FALSE) { EOM_ERR("ERROR: init pp\n"); - return 0; + return ret == EINA_FALSE; } - EOM_DBG("INT SURFACE: 2\n"); - - return 1; + return EINA_TRUE; } static tbm_surface_h @@ -846,10 +856,10 @@ _e_eom_root_internal_tdm_surface_get(const char *name) primary_output = ecore_drm_device_output_name_find(dev, name); } - if (!primary_output) + if (primary_output == NULL) { - EOM_ERR("ERROR: get primary output\n"); - return NULL; + EOM_ERR("ERROR: get primary output\n"); + return NULL; } /* I think it is more convenient than one upon, but E took first @@ -864,7 +874,7 @@ _e_eom_root_internal_tdm_surface_get(const char *name) */ fb = ecore_drm_display_output_primary_layer_fb_get(primary_output); - if (!primary_output) + if (primary_output == NULL) { EOM_ERR("ERROR: get primary frambuffer\n"); return NULL; @@ -875,14 +885,12 @@ _e_eom_root_internal_tdm_surface_get(const char *name) return (tbm_surface_h)fb->hal_buffer; } -static int +static Eina_Bool _e_eom_pp_src_to_dst( tbm_surface_h src_buffer) { - tdm_pp *pp; - tdm_info_pp pp_info; tdm_error err = TDM_ERROR_NONE; - - EOM_DBG("PP: 1\n"); + tdm_info_pp pp_info; + tdm_pp *pp = NULL; pp = tdm_display_create_pp(g_eom->dpy, &err); if (err != TDM_ERROR_NONE) @@ -891,8 +899,6 @@ _e_eom_pp_src_to_dst( tbm_surface_h src_buffer) return 0; } - EOM_DBG("PP: 2\n"); - g_eom_event_data.pp = pp; pp_info.src_config.size.h = g_eom->src_mode.w; /*1440*/ @@ -913,50 +919,42 @@ _e_eom_pp_src_to_dst( tbm_surface_h src_buffer) pp_info.sync = 0; pp_info.flags = 0; - EOM_DBG("PP: 3\n"); - err = tdm_pp_set_info(pp, &pp_info); if (err != TDM_ERROR_NONE) { EOM_ERR("ERROR: set pp info:%d\n", err); - return 0; + return EINA_FALSE; } - EOM_DBG("PP: 4\n"); - g_eom_event_data.pp_buffer = !g_eom_event_data.current_buffer; - EOM_DBG("PP: curr:%d pp:%d\n", g_eom_event_data.current_buffer, g_eom_event_data.pp_buffer); + EOM_DBG("PP: curr:%d pp:%d\n", + g_eom_event_data.current_buffer, + g_eom_event_data.pp_buffer); err = tdm_buffer_add_release_handler(g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer], _e_eom_pp_cb, &g_eom_event_data); if (err != TDM_ERROR_NONE) { EOM_ERR ("ERROR: set pp hadler:%d\n", err); - return 0; + return EINA_FALSE; } - EOM_DBG("PP: 5\n"); - - err = tdm_pp_attach(pp, src_buffer, g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer]); + err = tdm_pp_attach(pp, src_buffer, + g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer]); if (err != TDM_ERROR_NONE) { EOM_ERR("ERROR: pp attach:%d\n", err); - return 0; + return EINA_FALSE; } - - EOM_DBG("PP: 6\n"); - err = tdm_pp_commit(g_eom_event_data.pp); if (err != TDM_ERROR_NONE) { EOM_ERR("ERROR: pp commit:%d\n", err); - return 0; + return EINA_FALSE; } - EOM_DBG("PP: OK\n"); - - return 1; + return EINA_TRUE; } static int flag = 0; @@ -1003,6 +1001,7 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e g_eom->is_external_init = 1; g_eom->id = e->id; + g_eom->wl_output = wl_output; _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_ACTIVE); _e_eom_set_eom_status(WL_EOM_STATUS_CONNECTION); @@ -1013,6 +1012,7 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e { g_eom->is_external_init = 0; g_eom->is_internal_grab = 0; + g_eom->wl_output = NULL; g_eom->id = -1; _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_INACTIVE); @@ -1030,8 +1030,6 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e goto end; } - g_eom->wl_output = wl_output; - EINA_LIST_FOREACH(g_eom->eom_clients, l, resource_iterator) { if (resource_iterator) @@ -1076,12 +1074,12 @@ end: static Eina_Bool _e_eom_client_buffer_change(void *data, int type, void *event) { - E_Client *ec; + E_Comp_Wl_Buffer *external_wl_buffer = NULL; + E_EomClientBufferPtr client_buffer = NULL; E_Event_Client *ev = event; - E_Comp_Wl_Buffer *external_wl_buffer; - E_EomClientBufferPtr client_buffer; + E_Client *ec = NULL; /* - tbm_surface_h external_tbm_buffer; + tbm_surface_h external_tbm_buffer = NULL; tbm_surface_info_s surface_info; int ret; */ @@ -1159,7 +1157,7 @@ _e_eom_client_buffer_change(void *data, int type, void *event) /* TODO: Must find proper way of getting tbm_surface */ /*client_buffer = _e_eom_create_client_buffer(external_wl_buffer, external_tbm_buffer);*/ client_buffer = _e_eom_create_client_buffer(external_wl_buffer, fake_buffers.fake_buffers[0]); - if(client_buffer == NULL) + if (client_buffer == NULL) { EOM_ERR("ERROR: BUFF CHANGE: alloc client buffer"); return ECORE_CALLBACK_PASS_ON; @@ -1184,7 +1182,7 @@ _e_eom_add_client_buffer_to_list(E_EomClientBufferPtr client_buffer) static void _e_eom_client_buffers_list_free() { - E_EomClientBufferPtr *buffer; + E_EomClientBufferPtr *buffer = NULL; Eina_List *l; /* TODO: I am not sure if it is thread safe */ @@ -1230,7 +1228,7 @@ _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffe static E_EomClientBufferPtr _e_eom_get_client_buffer_from_list() { - E_EomClientBufferPtr buffer; + E_EomClientBufferPtr buffer = NULL; Eina_List *l; /* TODO: Have to describe how that list works*/ @@ -1286,11 +1284,11 @@ end: static void _e_eom_wl_request_set_attribute_cb(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, uint32_t attribute) { - int ret = 0; + Eina_Bool ret = EINA_FALSE; /* TODO: Add notifications when more prior client changes eom state */ ret = _e_eom_set_eom_attribute(attribute); - if (ret == 0) + if (ret == EINA_FALSE) { EOM_DBG("set attribute FAILED\n"); @@ -1322,7 +1320,7 @@ _e_eom_wl_request_set_attribute_cb(struct wl_client *client, struct wl_resource ret = _e_eom_mirror_start(g_eom->int_output_name, g_eom->src_mode.w, g_eom->src_mode.h); - if (!ret) + if (ret == EINA_FALSE) { EOM_ERR("ERROR: restore mirror mode after a client disconnection\n"); goto err; @@ -1342,7 +1340,7 @@ _e_eom_wl_request_get_output_info_cb(struct wl_client *client, struct wl_resourc if (g_eom->outputs) { Eina_List *l; - E_EomOutputPtr output; + E_EomOutputPtr output = NULL; EINA_LIST_FOREACH(g_eom->outputs, l, output) { @@ -1368,14 +1366,14 @@ static const struct wl_eom_interface _e_eom_wl_implementation = static void _e_eom_wl_resource_destory_cb(struct wl_resource *resource) { - struct wl_resource *resource_iterator; - Eina_List *l; - int ret; + struct wl_resource *resource_iterator = NULL; + Eina_List *l = NULL; + Eina_Bool ret; EOM_DBG("client unbind\n"); ret = _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); - if (ret != 1) + if (ret == EINA_FALSE) EOM_DBG("Restore attribute: Failed\n"); else EOM_DBG("Restore attribute: OK\n"); @@ -1392,7 +1390,7 @@ _e_eom_wl_resource_destory_cb(struct wl_resource *resource) ret = _e_eom_mirror_start(g_eom->int_output_name, g_eom->src_mode.w, g_eom->src_mode.h); - if (!ret) + if (ret == EINA_FALSE) { EOM_ERR("ERROR: restore mirror mode after a client disconnection\n"); return; @@ -1419,14 +1417,21 @@ static void _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32_t id) { enum wl_eom_type eom_type = WL_EOM_TYPE_NONE; - struct wl_resource *resource; + struct wl_resource *resource = NULL; + + if (data == NULL) + { + EOM_ERR("ERROR: data is NULL"); + return; + } + E_EomPtr eom = data; resource = wl_resource_create(client, &wl_eom_interface, MIN(version, 1), id); - if (!resource) + if (resource == NULL) { EOM_ERR("error. resource is null. (version :%d, id:%d)\n", version, id); wl_client_post_no_memory(client); @@ -1462,7 +1467,7 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32 if (g_eom->outputs) { Eina_List *l; - E_EomOutputPtr output; + E_EomOutputPtr output = NULL; EINA_LIST_FOREACH(g_eom->outputs, l, output) { @@ -1480,9 +1485,9 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32 static void _e_eom_deinit() { - Ecore_Event_Handler *h; + Ecore_Event_Handler *h = NULL; - if (!g_eom) return; + if (g_eom == NULL) return; if (g_eom->handlers) { @@ -1501,8 +1506,9 @@ _e_eom_deinit() static Eina_Bool _e_eom_output_info_get(tdm_display *dpy) { - int i, count; tdm_error ret = TDM_ERROR_NONE; + int i, count; + ret = tdm_display_get_output_count(dpy, &count); if (ret != TDM_ERROR_NONE) @@ -1522,12 +1528,12 @@ _e_eom_output_info_get(tdm_display *dpy) for (i = 0; i < count; i++) { + const tdm_output_mode *mode = NULL; + E_EomOutputPtr new_output = NULL; + unsigned int mmWidth, mmHeight; + tdm_output_conn_status status; tdm_output *output = NULL; - E_EomOutputPtr new_output; tdm_output_type type; - tdm_output_conn_status status; - unsigned int mmWidth, mmHeight; - const tdm_output_mode *mode; output = tdm_display_get_output(dpy, i, &ret); if (ret != TDM_ERROR_NONE) @@ -1536,7 +1542,7 @@ _e_eom_output_info_get(tdm_display *dpy) goto err; } - if (!output) + if (output == NULL) { EOM_ERR("tdm_display_get_output fail(no output:%d)", ret); goto err; @@ -1554,7 +1560,7 @@ _e_eom_output_info_get(tdm_display *dpy) continue; new_output = E_NEW(E_EomOutput, 1); - if (!new_output) + if (new_output == NULL) { EOM_ERR("calloc fail"); goto err; @@ -1681,7 +1687,7 @@ err: static Eina_Bool _e_eom_init() { - Eina_Bool ret = 0; + Eina_Bool ret = EINA_FALSE; EINA_SAFETY_ON_NULL_GOTO(e_comp_wl, err); -- 2.7.4 From ed885131fab86d15d279609e056fd15098c84d5d Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Tue, 10 May 2016 17:05:42 +0300 Subject: [PATCH 04/16] change error handling. move declarations to header Change-Id: I0dcc166eda8c19a7f92f209a373bb80c508131e3 Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 667 +++++++++++++++---------------------------------------- src/e_mod_main.h | 177 ++++++++++++++- 2 files changed, 353 insertions(+), 491 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 76564eb..e1cb81e 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -10,122 +10,23 @@ #include "eom-server-protocol.h" #include "Ecore_Drm.h" -#define NUM_MAIN_BUF 2 -#define NUM_ATTR 3 - -typedef struct _E_Eom E_Eom, *E_EomPtr; -typedef struct _E_Eom_Out_Mode E_EomOutMode, *E_EomOutModePtr; -typedef struct _E_Eom_Event_Data E_EomEventData, *E_EomEventDataPtr; -typedef struct _E_Eom_Output E_EomOutput, *E_EomOutputPtr; -typedef struct _E_Eom_Fake_Buffers E_EomFakeBuffers, *E_EomFakeBuffersPtr; -typedef struct _E_Eom_Client_Buffer E_EomClientBuffer, *E_EomClientBufferPtr; - - -struct _E_Eom_Out_Mode -{ - int w; - int h; -}; - -struct _E_Eom_Output -{ - unsigned int id; - eom_output_type_e type; - eom_output_mode_e mode; - unsigned int w; - unsigned int h; - unsigned int phys_width; - unsigned int phys_height; - - tdm_output_conn_status status; - unsigned int mirror_run; - eom_output_attribute_e attribute; - eom_output_attribute_state_e attribute_state; - - /* external output data */ - char *ext_output_name; - int is_external_init; - E_EomOutMode src_mode; - E_Comp_Wl_Output *wl_output; - - /* internal output data */ - char *int_output_name; - int is_internal_grab; - E_EomOutMode dst_mode; -}; - -struct _E_Eom -{ - struct wl_global *global; - Eina_List *eom_clients; - Eina_List *handlers; - - tdm_display *dpy; - tbm_bufmgr bufmgr; - int fd; - - Eina_List *outputs; - unsigned int output_count; - -#if 1 - /* eom state */ - enum wl_eom_mode eom_mode; - enum wl_eom_attribute eom_attribute; - enum wl_eom_attribute_state eom_attribute_state; - enum wl_eom_status eom_status; - - /*data related to cooperating with clients */ - int is_mirror_mode; - - /* external output data */ - char *ext_output_name; - int is_external_init; - int id; - E_EomOutMode src_mode; - E_Comp_Wl_Output *wl_output; - - /* internal output data */ - char *int_output_name; - int is_internal_grab; - E_EomOutMode dst_mode; -#endif -}; - -struct _E_Eom_Event_Data -{ - tdm_output *output; - tdm_layer *layer; - tdm_pp *pp; - - /* mirror mode data*/ - tbm_surface_h dst_buffers[NUM_MAIN_BUF]; - int current_buffer; - int pp_buffer; - - /* extended mode data */ - Eina_List *client_buffers_list; -}; - -struct _E_Eom_Client_Buffer -{ - E_Comp_Wl_Buffer *wl_buffer; - tbm_surface_h tbm_buffer; - - unsigned long stamp; -}; - -struct _E_Eom_Fake_Buffers -{ - tbm_surface_h fake_buffers[NUM_MAIN_BUF]; - int current_fake_buffer; -}; - - -static E_EomEventData g_eom_event_data; -E_EomPtr g_eom = NULL; -E_EomFakeBuffers fake_buffers; - E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "EOM Module" }; +static E_EomEventData g_eom_event_data; +static E_EomFakeBuffers fake_buffers; +static E_EomPtr g_eom = NULL; + +/* EOM Output Attributes + + +----------------+------------+----------------+-------------+ + | | normal | exclusiv_share | exclusive | + +----------------+------------+----------------+-------------+ + | normal | possible | possible | possible | + +----------------+------------+----------------+-------------+ + | exclusiv_share | impossible | possible | possible | + +----------------+------------+----------------+-------------+ + | exclusive | impossible | impossible | impossible | + +----------------+------------+----------------+-------------+ +*/ static int eom_output_attributes[NUM_ATTR][NUM_ATTR] = { {1, 1, 1}, @@ -133,34 +34,6 @@ static int eom_output_attributes[NUM_ATTR][NUM_ATTR] = {0, 0, 0}, }; -/* handle external output */ -static E_Comp_Wl_Output *_e_eom_e_comp_wl_output_get(const Eina_List *outputs, const char *id); -static Eina_Bool _e_eom_set_up_external_output(const char *output_name, int width, int height); -static tdm_output * _e_eom_hal_output_get(const char *id); -static tdm_layer * _e_eom_hal_layer_get(tdm_output *output, int width, int height); -static Eina_Bool _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height); -static enum wl_eom_type _e_eom_output_name_to_eom_type(const char *output_name); -/* handle internal output, pp */ -static Eina_Bool _e_eom_mirror_start(const char *output_name, int width, int height); -static tbm_surface_h _e_eom_root_internal_tdm_surface_get(const char *name); -static Eina_Bool _e_eom_pp_src_to_dst( tbm_surface_h src_buffer); -/* tdm handlers */ -static void _e_eom_pp_cb(tbm_surface_h surface, void *user_data); -static void _e_eom_commit_cb(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); - -/* clients buffers */ -static E_EomClientBufferPtr _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer); -static void _e_eom_add_client_buffer_to_list(E_EomClientBufferPtr client_buffer); -static void _e_eom_client_buffers_list_free(); -static E_EomClientBufferPtr _e_eom_get_client_buffer_from_list(); - - -/*eom utils functions*/ -static int _e_eom_get_time_in_mseconds(); -static void _e_eom_create_fake_buffers(int width, int height); - static inline enum wl_eom_mode _e_eom_get_eom_mode() { @@ -227,11 +100,7 @@ _e_eom_pp_cb(tbm_surface_h surface, void *user_data) tdm_error tdm_err = TDM_ERROR_NONE; E_EomEventDataPtr eom_data = NULL; - if (user_data == NULL) - { - EOM_DBG("ERROR: PP EVENT: user data is NULL\n"); - return; - } + RETURNIFTRUE(user_data == NULL, "ERROR: PP EVENT: user data is NULL"); eom_data = (E_EomEventDataPtr)user_data; @@ -240,40 +109,24 @@ _e_eom_pp_cb(tbm_surface_h surface, void *user_data) /* TODO: lock that flag??? */ /* If a client has committed its buffer stop mirror mode */ - if (g_eom->is_mirror_mode == 0) + if (g_eom->is_mirror_mode == DOWN) return; tbm_surface_h src_buffer; src_buffer = _e_eom_root_internal_tdm_surface_get(g_eom->int_output_name); - if (src_buffer == EINA_FALSE) - { - EOM_DBG("ERROR: PP EVENT: get root tdm surfcae\n"); - return; - } + RETURNIFTRUE(src_buffer == NULL, "ERROR: PP EVENT: get root tdm surface"); g_eom_event_data.pp_buffer = !g_eom_event_data.current_buffer; tdm_err = tdm_buffer_add_release_handler(g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer], _e_eom_pp_cb, &g_eom_event_data); - if (tdm_err != TDM_ERROR_NONE) - { - EOM_DBG ("ERROR: PP EVENT: set pp hadler:%d\n", tdm_err ); - return; - } + RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "ERROR: PP EVENT: set pp hadler:%d", tdm_err ); tdm_err = tdm_pp_attach(eom_data->pp, src_buffer, g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer]); - if (tdm_err != TDM_ERROR_NONE) - { - printf ("ERROR: pp attach:%d\n", tdm_err); - return; - } + RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "ERROR: pp attach:%d\n", tdm_err); - tdm_err = tdm_pp_commit(g_eom_event_data.pp); - if (tdm_err != TDM_ERROR_NONE) - { - EOM_DBG ("ERROR: PP EVENT: pp commit:%d\n", tdm_err ); - return; - } + tdm_err = tdm_pp_commit(g_eom_event_data.pp); + RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "ERROR: PP EVENT: pp commit:%d", tdm_err ); } static void @@ -285,16 +138,12 @@ _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS E_EomEventDataPtr eom_data = NULL; tdm_error err = TDM_ERROR_NONE; - if (user_data == NULL) - { - EOM_ERR("ERROR: EVENT: user_data is NULL\n"); - return; - } + RETURNIFTRUE(user_data == NULL, "ERROR: PP EVENT: user data is NULL"); eom_data = (E_EomEventDataPtr)user_data; /* TODO: Maybe better to separating that callback on to mirror and extended callbacks */ - if (g_eom->is_mirror_mode == 1) + if (g_eom->is_mirror_mode == UP) { if (eom_data->current_buffer == 1) { @@ -302,11 +151,7 @@ _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS err = tdm_layer_set_buffer(eom_data->layer, eom_data->dst_buffers[!eom_data->pp_buffer]); - if (err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: EVENT: set buffer 0\n"); - return; - } + RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: EVENT: set buffer 0 err:%d", err); } else { @@ -314,42 +159,22 @@ _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS err = tdm_layer_set_buffer(eom_data->layer, eom_data->dst_buffers[!eom_data->pp_buffer]); - if (err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: EVENT: set buffer 1\n"); - return; - } + RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: EVENT: set buffer 1 err:%d", err); } err = tdm_output_commit(eom_data->output, 0, _e_eom_commit_cb, eom_data); - if (err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: EVENT: commit\n"); - return; - } + RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: EVENT commit"); } else { client_buffer = _e_eom_get_client_buffer_from_list(); - if (client_buffer == NULL) - { - EOM_ERR("ERROR: EVENT: client buffer is NULL\n"); - return; - } + RETURNIFTRUE(client_buffer == NULL, "ERROR: EVENT: client buffer is NULL"); err = tdm_layer_set_buffer(eom_data->layer, client_buffer->tbm_buffer); - if (err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: EVENT: set buffer 1\n"); - return; - } + RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: EVENT: set buffer 1"); err = tdm_output_commit(eom_data->output, 0, _e_eom_commit_cb, eom_data); - if (err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: EVENT: commit\n"); - return; - } + RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: EVENT: commit"); } } @@ -400,35 +225,19 @@ _e_eom_set_up_external_output(const char *output_name, int width, int height) eom_data = &g_eom_event_data; hal_output = _e_eom_hal_output_get(output_name); - if (hal_output == NULL) - { - EOM_ERR("ERROR: get hal output for, (%s)\n", output_name); - goto err; - } + GOTOIFTRUE(hal_output == NULL, err, "ERROR: get hal output for, (%s)", output_name); hal_layer = _e_eom_hal_layer_get(hal_output, width, height); - if (hal_layer == NULL) - { - EOM_ERR("ERROR: get hal layer\n"); - goto err; - } + GOTOIFTRUE(hal_layer == NULL, err, "ERROR: get hal layer"); ret = _e_eom_create_output_buffers(eom_data, width, height); - if (ret == EINA_FALSE) - { - EOM_ERR("ERROR: create buffers \n"); - goto err; - } + GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: create buffers"); /* TODO: Models commited clients buffers */ _e_eom_create_fake_buffers(width, height); tdm_err = tdm_layer_get_info(hal_layer, &layer_info); - if (tdm_err != TDM_ERROR_NONE) - { - EOM_ERR ("ERROR: get layer info: %d", tdm_err); - goto err; - } + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: get layer info: %d", tdm_err); 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, @@ -439,7 +248,6 @@ _e_eom_set_up_external_output(const char *output_name, int width, int height) g_eom->dst_mode.w = width; g_eom->dst_mode.h = height; - /* TODO: free that memory */ g_eom->ext_output_name = strdup(output_name); eom_data->layer = hal_layer; @@ -447,25 +255,13 @@ _e_eom_set_up_external_output(const char *output_name, int width, int height) eom_data->current_buffer = 0; tdm_err = tdm_layer_set_buffer(hal_layer, eom_data->dst_buffers[eom_data->current_buffer]); - if (tdm_err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: set buffer on layer:%d\n", tdm_err); - goto err; - } + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: set buffer on layer:%d", tdm_err); tdm_err = tdm_output_set_dpms(hal_output, TDM_OUTPUT_DPMS_ON); - if (tdm_err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: failed set DPMS on:%d\n", tdm_err); - goto err; - } + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: failed set DPMS on:%d", tdm_err); tdm_err = tdm_output_commit(hal_output, 0, _e_eom_commit_cb, eom_data); - if (tdm_err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: commit crtc:%d\n", tdm_err); - goto err; - } + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: commit crtc:%d", tdm_err); return EINA_TRUE; @@ -553,33 +349,17 @@ _e_eom_hal_output_get(const char *id) } } - if (drm_output == NULL) - { - EOM_ERR("ERROR: drm output was not found\n"); - return NULL; - } + RETURNVALIFTRUE(drm_output == NULL, NULL, "ERROR: drm output was not found"); crtc_id = ecore_drm_output_crtc_id_get(drm_output); - if (crtc_id == 0) - { - EOM_ERR("ERROR: crtc is 0\n"); - return NULL; - } + RETURNVALIFTRUE(crtc_id == 0, NULL, "ERROR: crtc is 0\n"); output = tdm_display_get_output(g_eom->dpy, crtc_id, NULL); - if (output == NULL) - { - EOM_ERR("ERROR: there is no HAL output for:%d\n", crtc_id); - return NULL; - } + RETURNVALIFTRUE(output == NULL, NULL, "ERROR: there is no HAL output for:%d", crtc_id); int min_w, min_h, max_w, max_h, preferred_align; err = tdm_output_get_available_size(output, &min_w, &min_h, &max_w, &max_h, &preferred_align); - if (err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: Gent get geometry for hal output"); - return NULL; - } + RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "ERROR: Gent get geometry for hal output"); EOM_DBG("HAL size min:%dx%d max:%dx%d alighn:%d\n", min_w, min_h, max_w, max_h, preferred_align); @@ -588,11 +368,7 @@ _e_eom_hal_output_get(const char *id) * Force TDM to make setCrtc onto new buffer */ err = tdm_output_get_available_modes(output, &modes, &count); - if (err != TDM_ERROR_NONE) - { - EOM_ERR("Get availvable modes filed\n"); - return NULL; - } + RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "Get availvable modes filed"); big_mode = &modes[0]; @@ -603,20 +379,12 @@ _e_eom_hal_output_get(const char *id) big_mode = &modes[i]; } - if (big_mode == NULL) - { - EOM_ERR("no Big mode\n"); - return NULL; - } + RETURNVALIFTRUE(big_mode == NULL, NULL, "no Big mode\n"); EOM_DBG("BIG_MODE: %dx%d\n", big_mode->hdisplay, big_mode->vdisplay); err = tdm_output_set_mode(output, big_mode); - if (err != TDM_ERROR_NONE) - { - EOM_ERR("set Mode failed\n"); - return NULL; - } + RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "set Mode failed"); EOM_DBG("Created output: %p\n", output); return output; @@ -643,18 +411,10 @@ _e_eom_hal_layer_get(tdm_output *output, int width, int height) 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; - } + RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_output_get_layer fail(%d)\n", err); err = tdm_layer_get_capabilities(layer, &capa); - if (err != TDM_ERROR_NONE) - { - EOM_DBG ("tdm_layer_get_capabilities fail(%d)\n", err); - return NULL; - } + RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_layer_get_capabilities fail(%d)\n", err); if (capa & TDM_LAYER_CAPABILITY_PRIMARY) { @@ -678,16 +438,11 @@ _e_eom_hal_layer_get(tdm_output *output, int width, int height) layer_info.transform = TDM_TRANSFORM_NORMAL; err = tdm_layer_set_info(layer, &layer_info); - if (err != TDM_ERROR_NONE) - { - EOM_DBG ("tdm_layer_set_info fail(%d)\n", err); - return NULL; - } + RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_layer_set_info fail(%d)\n", err); return layer; } - /* TODO: Models commited clients buffers */ static void _e_eom_create_fake_buffers(int width, int height) @@ -696,11 +451,7 @@ _e_eom_create_fake_buffers(int width, int height) tbm_surface_h buffer = NULL; buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - if (buffer == NULL) - { - EOM_DBG("can not create fake_buffer\n"); - goto err; - } + GOTOIFTRUE(buffer == NULL, err, "can not create fake_buffer\n"); memset(&buffer_info, 0x0, sizeof(tbm_surface_info_s)); if (tbm_surface_map(buffer, @@ -730,11 +481,7 @@ _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height) * TODO: Add support of other formats */ buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - if (buffer == NULL) - { - EOM_DBG("can not create dst_buffer\n"); - goto err; - } + GOTOIFTRUE(buffer == NULL, err, "can not create dst_buffer 1"); /* * TODO: temp code for testing, actual convert will be in _e_eom_put_src_to_dst() @@ -758,11 +505,7 @@ _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height) * TODO: Add support of other formats */ buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - if (buffer == NULL) - { - EOM_DBG("can not create dst_buffer\n"); - goto err; - } + GOTOIFTRUE(buffer == NULL, err, "can not create dst_buffer 2"); /* * TODO: temp code for testing, actual convert will be in _e_eom_put_src_to_dst() @@ -816,11 +559,7 @@ _e_eom_mirror_start(const char *output_name, int width, int height) Eina_Bool ret = EINA_FALSE; src_buffer = _e_eom_root_internal_tdm_surface_get(output_name); - if (src_buffer == NULL) - { - EOM_ERR("ERROR: get root tdm surfcae\n"); - return 0; - } + RETURNVALIFTRUE(src_buffer == NULL, EINA_FALSE, "ERROR: get root tdm surfcae\n"); tbm_surface_get_info(src_buffer, &src_buffer_info ); @@ -830,15 +569,15 @@ _e_eom_mirror_start(const char *output_name, int width, int height) g_eom->src_mode.w = width; g_eom->src_mode.h = height; - /* TODO: free that memory */ g_eom->int_output_name = strdup(output_name); + /* TODO: if internal and external outputs are equal */ + ret = _e_eom_pp_is_needed(g_eom->src_mode.w, g_eom->src_mode.h, + g_eom->dst_mode.w, g_eom->dst_mode.h); + RETURNVALIFTRUE(ret == EINA_FALSE, EINA_TRUE, "pp is not required\n"); + ret = _e_eom_pp_src_to_dst(src_buffer); - if (ret == EINA_FALSE) - { - EOM_ERR("ERROR: init pp\n"); - return ret == EINA_FALSE; - } + RETURNVALIFTRUE(ret == EINA_FALSE, EINA_FALSE, "ERROR: init pp\n"); return EINA_TRUE; } @@ -856,29 +595,17 @@ _e_eom_root_internal_tdm_surface_get(const char *name) primary_output = ecore_drm_device_output_name_find(dev, name); } - if (primary_output == NULL) - { - EOM_ERR("ERROR: get primary output\n"); - return NULL; - } + RETURNVALIFTRUE(primary_output == NULL, NULL, "ERROR: get primary output\n"); /* I think it is more convenient than one upon, but E took first * output as primary and it can be not internal output * primary_output = ecore_drm_output_primary_get(); - if (!primary_output) - { - EOM_ERR("ERROR: get primary output\n"); - return NULL; - } + RETURNVALIFTRUE(primary_output == NULL, NULL, "ERROR: get primary output\n"); */ fb = ecore_drm_display_output_primary_layer_fb_get(primary_output); - if (primary_output == NULL) - { - EOM_ERR("ERROR: get primary frambuffer\n"); - return NULL; - } + RETURNVALIFTRUE(fb == NULL, NULL, "ERROR: get primary frambuffer\n"); /*EOM_DBG("FRAMEBUFFER ECORE_DRM: is_client:%d mode%dx%d\n", fb->from_client, fb->w, fb->h);*/ @@ -892,39 +619,43 @@ _e_eom_pp_src_to_dst( tbm_surface_h src_buffer) tdm_info_pp pp_info; tdm_pp *pp = NULL; + int calc_x; + int calc_width; + pp = tdm_display_create_pp(g_eom->dpy, &err); - if (err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: create pp:%d\n", err); - return 0; - } + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: create pp:%d\n", err); + + _e_eom_pp_calculate_new_size(&calc_x, &calc_width, + g_eom->src_mode.w, g_eom->src_mode.h, + g_eom->dst_mode.w, g_eom->dst_mode.h); + + DBG("PP INFO: src:%dx%d dst:%dx%d calc_x:%d calc_width:%d", + g_eom->src_mode.w, g_eom->src_mode.h, + g_eom->dst_mode.w, g_eom->dst_mode.h, + calc_x, calc_width); g_eom_event_data.pp = pp; - pp_info.src_config.size.h = g_eom->src_mode.w; /*1440*/ - pp_info.src_config.size.v = g_eom->src_mode.h; /*2560*/ + pp_info.src_config.size.h = g_eom->src_mode.w; + pp_info.src_config.size.v = g_eom->src_mode.h; pp_info.src_config.pos.x = 0; pp_info.src_config.pos.y = 0; - pp_info.src_config.pos.w = g_eom->src_mode.w; /*1440*/ - pp_info.src_config.pos.h = g_eom->src_mode.h; /*2560*/ + pp_info.src_config.pos.w = g_eom->src_mode.w; + pp_info.src_config.pos.h = g_eom->src_mode.h; pp_info.src_config.format = TBM_FORMAT_ARGB8888; - pp_info.dst_config.size.h = g_eom->dst_mode.w; /*1960*/ - pp_info.dst_config.size.v = g_eom->dst_mode.h; /*1080*/ - pp_info.dst_config.pos.x = 0; + pp_info.dst_config.size.h = calc_width; + pp_info.dst_config.size.v = g_eom->dst_mode.h; + pp_info.dst_config.pos.x = calc_x; pp_info.dst_config.pos.y = 0; - pp_info.dst_config.pos.w = g_eom->dst_mode.w; /*1960*/ - pp_info.dst_config.pos.h = g_eom->dst_mode.h; /*1080*/ + pp_info.dst_config.pos.w = calc_width; + pp_info.dst_config.pos.h = g_eom->dst_mode.h; pp_info.dst_config.format = TBM_FORMAT_ARGB8888; - pp_info.transform = TDM_TRANSFORM_NORMAL;/*TDM_TRANSFORM_NORMAL*/ + pp_info.transform = TDM_TRANSFORM_NORMAL; pp_info.sync = 0; pp_info.flags = 0; err = tdm_pp_set_info(pp, &pp_info); - if (err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: set pp info:%d\n", err); - return EINA_FALSE; - } + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: set pp info:%d\n", err); g_eom_event_data.pp_buffer = !g_eom_event_data.current_buffer; EOM_DBG("PP: curr:%d pp:%d\n", @@ -933,30 +664,45 @@ _e_eom_pp_src_to_dst( tbm_surface_h src_buffer) err = tdm_buffer_add_release_handler(g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer], _e_eom_pp_cb, &g_eom_event_data); - if (err != TDM_ERROR_NONE) - { - EOM_ERR ("ERROR: set pp hadler:%d\n", err); - return EINA_FALSE; - } + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: set pp hadler:%d\n", err); err = tdm_pp_attach(pp, src_buffer, g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer]); - if (err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: pp attach:%d\n", err); - return EINA_FALSE; - } + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: pp attach:%d\n", err); err = tdm_pp_commit(g_eom_event_data.pp); - if (err != TDM_ERROR_NONE) - { - EOM_ERR("ERROR: pp commit:%d\n", err); - return EINA_FALSE; - } + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: pp commit:%d\n", err); return EINA_TRUE; } +static Eina_Bool +_e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h) +{ + if (src_w != dst_w) + return EINA_TRUE; + + if (src_h != dst_h) + return EINA_TRUE; + + return EINA_FALSE; +} + +static void +_e_eom_pp_calculate_new_size(int *x, int *new_w, int src_w, int src_h, int dst_w, int dst_h) +{ + float similatiry_coeficient = 0.0; + int mean_dst_width, mean_new_width; + + similatiry_coeficient = dst_h / src_h; + *new_w = (int)similatiry_coeficient * src_w; + + mean_dst_width = dst_w / 2; + mean_new_width = *new_w / 2; + + *x = mean_dst_width - mean_new_width; +} + static int flag = 0; static Eina_Bool @@ -970,9 +716,9 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e Eina_List *l; int ret = 0; - if (!(e = event)) goto end; + if (!(e = event)) goto err; - if (!e->plug) goto end; + if (!e->plug) goto err; EOM_DBG("id:%d (x,y,w,h):(%d,%d,%d,%d) (w_mm,h_mm):(%d,%d) refresh:%d subpixel_order:%d transform:%d make:%s model:%s name:%s plug:%d\n", e->id, e->x, e->y, e->w, e->h, e->phys_width, e->phys_height, e->refresh, e->subpixel_order, e->transform, e->make, e->model, e->name, e->plug); @@ -985,21 +731,13 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e { /* Get e_comp_wl_output */ wl_output = _e_eom_e_comp_wl_output_get(e_comp_wl->outputs, buff); - if (!wl_output) - { - EOM_ERR("ERROR: there is no wl_output:(%s)\n", buff); - goto end; - } + GOTOIFTRUE(wl_output == NULL, err, "ERROR: there is no wl_output:(%s)\n", buff); /* Initialize external output */ ret = _e_eom_set_up_external_output(buff, e->w, e->h); - if (!ret) - { - EOM_ERR("ERROR: initialize external output\n"); - goto end; - } + GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: initialize external output\n"); - g_eom->is_external_init = 1; + g_eom->is_external_init = UP; g_eom->id = e->id; g_eom->wl_output = wl_output; @@ -1010,8 +748,8 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e } else { - g_eom->is_external_init = 0; - g_eom->is_internal_grab = 0; + g_eom->is_external_init = DOWN; + g_eom->is_internal_grab = DOWN; g_eom->wl_output = NULL; g_eom->id = -1; @@ -1024,11 +762,7 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e } eom_type = _e_eom_output_name_to_eom_type(buff); - if (eom_type == WL_EOM_TYPE_NONE) - { - EOM_ERR("ERROR: eom_type is NONE\n"); - goto end; - } + GOTOIFTRUE(eom_type == WL_EOM_TYPE_NONE, err, "ERROR: eom_type is NONE\n"); EINA_LIST_FOREACH(g_eom->eom_clients, l, resource_iterator) { @@ -1051,23 +785,19 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e } } } - else if (strcmp(e->name, "DSI-0") == 0 && g_eom->is_external_init && flag == 2) + else if (strcmp(e->name, "DSI-0") == 0 && g_eom->is_external_init == UP && flag == 2) { /*TODO: add support of internal and external output of same size */ ret = _e_eom_mirror_start(buff, e->w, e->h); - if (!ret) - { - EOM_ERR("ERROR: get root surfcae\n"); - goto end; - } + GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: get root surfcae\n"); - g_eom->is_internal_grab = 1; - g_eom->is_mirror_mode = 1; + g_eom->is_internal_grab = UP; + g_eom->is_mirror_mode = UP; } ++flag; -end: +err: return ECORE_CALLBACK_PASS_ON; } @@ -1078,6 +808,7 @@ _e_eom_client_buffer_change(void *data, int type, void *event) E_EomClientBufferPtr client_buffer = NULL; E_Event_Client *ev = event; E_Client *ec = NULL; + Eina_Bool ret_err; /* tbm_surface_h external_tbm_buffer = NULL; tbm_surface_info_s surface_info; @@ -1100,21 +831,18 @@ _e_eom_client_buffer_change(void *data, int type, void *event) * TODO: Make all goto same, not err, end, ret etc. */ /*We are not interested in non external clients*/ - if (e_client_is_external_output_client(ec) != EINA_TRUE) - { - EOM_ERR("ERROR: BUFF CHANGE: ec is not external\n"); - return ECORE_CALLBACK_PASS_ON; - } + ret_err = e_client_is_external_output_client(ec); + RETURNVALIFTRUE(ret_err != EINA_TRUE, + ECORE_CALLBACK_PASS_ON, + "ERROR: BUFF CHANGE: ec is not external\n"); if (ec->pixmap == NULL) return ECORE_CALLBACK_PASS_ON; external_wl_buffer = e_pixmap_resource_get(ec->pixmap); - if (external_wl_buffer == NULL) - { - EOM_ERR("ERROR:BUFF CHANGE: wl buffer is NULL\n"); - return ECORE_CALLBACK_PASS_ON; - } + RETURNVALIFTRUE(external_wl_buffer == NULL, + ECORE_CALLBACK_PASS_ON, + "ERROR:BUFF CHANGE: wl buffer is NULL\n"); EOM_DBG("BUFF CHANGE: wl_buff:%dx%d", external_wl_buffer->w, @@ -1157,16 +885,14 @@ _e_eom_client_buffer_change(void *data, int type, void *event) /* TODO: Must find proper way of getting tbm_surface */ /*client_buffer = _e_eom_create_client_buffer(external_wl_buffer, external_tbm_buffer);*/ client_buffer = _e_eom_create_client_buffer(external_wl_buffer, fake_buffers.fake_buffers[0]); - if (client_buffer == NULL) - { - EOM_ERR("ERROR: BUFF CHANGE: alloc client buffer"); - return ECORE_CALLBACK_PASS_ON; - } + RETURNVALIFTRUE(client_buffer == NULL, + ECORE_CALLBACK_PASS_ON, + "ERROR: BUFF CHANGE: alloc client buffer"); _e_eom_add_client_buffer_to_list(client_buffer); /* Stop mirror mode */ - g_eom->is_mirror_mode = 0; + g_eom->is_mirror_mode = DOWN; return ECORE_CALLBACK_PASS_ON; } @@ -1311,21 +1037,19 @@ _e_eom_wl_request_set_attribute_cb(struct wl_client *client, struct wl_resource /* If client has set WL_EOM_ATTRIBUTE_NONE, eom will be * switched to mirror mode */ - if (attribute == WL_EOM_ATTRIBUTE_NONE && g_eom->is_mirror_mode == 0) + if (attribute == WL_EOM_ATTRIBUTE_NONE && g_eom->is_mirror_mode == DOWN) { - g_eom->is_mirror_mode = 1; + g_eom->is_mirror_mode = UP; _e_eom_client_buffers_list_free(); ret = _e_eom_mirror_start(g_eom->int_output_name, g_eom->src_mode.w, g_eom->src_mode.h); - if (ret == EINA_FALSE) - { - EOM_ERR("ERROR: restore mirror mode after a client disconnection\n"); - goto err; - } - } + GOTOIFTRUE(ret == EINA_FALSE, + err, + "ERROR: restore mirror mode after a client disconnection\n"); + } } err: @@ -1381,20 +1105,17 @@ _e_eom_wl_resource_destory_cb(struct wl_resource *resource) /* If a client has been disconnected and eom has not been * restored to mirror mode, start mirror mode */ - if (g_eom->is_mirror_mode == 0) + if (g_eom->is_mirror_mode == DOWN) { - g_eom->is_mirror_mode = 1; + g_eom->is_mirror_mode = UP; _e_eom_client_buffers_list_free(); ret = _e_eom_mirror_start(g_eom->int_output_name, g_eom->src_mode.w, g_eom->src_mode.h); - if (ret == EINA_FALSE) - { - EOM_ERR("ERROR: restore mirror mode after a client disconnection\n"); - return; - } + RETURNIFTRUE(ret == EINA_FALSE, + "ERROR: restore mirror mode after a client disconnection\n"); /* Notify eom clients that eom state has been changed */ EINA_LIST_FOREACH(g_eom->eom_clients, l, resource_iterator) @@ -1419,11 +1140,7 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32 enum wl_eom_type eom_type = WL_EOM_TYPE_NONE; struct wl_resource *resource = NULL; - if (data == NULL) - { - EOM_ERR("ERROR: data is NULL"); - return; - } + RETURNIFTRUE(data == NULL, "ERROR: data is NULL"); E_EomPtr eom = data; @@ -1511,17 +1228,12 @@ _e_eom_output_info_get(tdm_display *dpy) ret = tdm_display_get_output_count(dpy, &count); - if (ret != TDM_ERROR_NONE) - { - EOM_ERR("tdm_display_get_output_count fail\n"); - return EINA_FALSE; - } - - if (count <= 1) - { - EOM_DBG("output count is 1. device doesn't support external outputs.\n"); - return EINA_FALSE; - } + RETURNVALIFTRUE(ret != TDM_ERROR_NONE, + EINA_FALSE, + "tdm_display_get_output_count fail"); + RETURNVALIFTRUE(count <= 1, + EINA_FALSE, + "output count is 1. device doesn't support external outputs.\n"); g_eom->output_count = count - 1; EOM_DBG("external output count : %d\n", g_eom->output_count); @@ -1536,35 +1248,28 @@ _e_eom_output_info_get(tdm_display *dpy) tdm_output_type type; output = tdm_display_get_output(dpy, i, &ret); - if (ret != TDM_ERROR_NONE) - { - EOM_ERR("tdm_display_get_output fail(ret:%d)", ret); - goto err; - } + GOTOIFTRUE(ret != TDM_ERROR_NONE, + err, + "tdm_display_get_output fail(ret:%d)", ret); - if (output == NULL) - { - EOM_ERR("tdm_display_get_output fail(no output:%d)", ret); - goto err; - } + GOTOIFTRUE(output == NULL, + err, + "tdm_display_get_output fail(no output:%d)", ret); ret = tdm_output_get_output_type(output, &type); - if (ret != TDM_ERROR_NONE) - { - EOM_ERR("tdm_output_get_output_type fail(%d)", ret); - goto err; - } + GOTOIFTRUE(ret != TDM_ERROR_NONE, + err, + "tdm_output_get_output_type fail(%d)", ret); + /* skip main output */ /* TODO: need more check about main display*/ if ((type == TDM_OUTPUT_TYPE_DSI) || (type == TDM_OUTPUT_TYPE_LVDS)) continue; new_output = E_NEW(E_EomOutput, 1); - if (new_output == NULL) - { - EOM_ERR("calloc fail"); - goto err; - } + GOTOIFTRUE(new_output == NULL, + err, + "calloc fail"); ret = tdm_output_get_conn_status(output, &status); if (ret != TDM_ERROR_NONE) @@ -1594,11 +1299,13 @@ _e_eom_output_info_get(tdm_display *dpy) free(new_output); goto err; } + if (mode == NULL) { new_output->w = 0; new_output->h = 0; } + else { new_output->w = mode->hdisplay; @@ -1623,8 +1330,8 @@ _e_eom_output_info_get(tdm_display *dpy) } return EINA_TRUE; -err: +err: if (g_eom->outputs) { Eina_List *l; @@ -1646,25 +1353,13 @@ _e_eom_init_internal() tdm_error ret = TDM_ERROR_NONE; g_eom->dpy = tdm_display_init(&ret); - if (ret != TDM_ERROR_NONE) - { - EOM_ERR("tdm_display_init fail\n"); - goto err; - } + GOTOIFTRUE(ret != TDM_ERROR_NONE, err, "tdm_display_init fail"); ret = tdm_display_get_fd(g_eom->dpy, &g_eom->fd); - if (ret != TDM_ERROR_NONE) - { - EOM_ERR("tdm_display_get_fd fail\n"); - goto err; - } + GOTOIFTRUE(ret != TDM_ERROR_NONE, err, "tdm_display_get_fd fail"); g_eom->bufmgr = tbm_bufmgr_init(g_eom->fd); - if (!g_eom->bufmgr) - { - EOM_ERR("tbm_bufmgr_init fail\n"); - goto err; - } + GOTOIFTRUE(g_eom->bufmgr == NULL, err, "tbm_bufmgr_init fail"); if (_e_eom_output_info_get(g_eom->dpy) != EINA_TRUE) { @@ -1703,18 +1398,14 @@ _e_eom_init() EINA_SAFETY_ON_NULL_GOTO(g_eom->global, err); ret = _e_eom_init_internal(); - if (ret == EINA_FALSE) - { - EOM_ERR("failed init_internal()"); - goto err; - } + GOTOIFTRUE(ret == EINA_FALSE, err, "failed init_internal()"); 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); E_LIST_HANDLER_APPEND(g_eom->handlers, E_EVENT_CLIENT_BUFFER_CHANGE, _e_eom_client_buffer_change, NULL); - g_eom->is_external_init = 0; - g_eom->is_internal_grab = 0; + g_eom->is_external_init = DOWN; + g_eom->is_internal_grab = DOWN; g_eom->ext_output_name = NULL; g_eom->int_output_name = NULL; diff --git a/src/e_mod_main.h b/src/e_mod_main.h index 94675fc..b004dc6 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -1,14 +1,37 @@ #ifndef E_MOD_MAIN_H #define E_MOD_MAIN_H +#include "eom-server-protocol.h" + #define CHECK_ERR(val) if (WL_KEYROUTER_ERROR_NONE != val) return; #define CHECK_ERR_VAL(val) if (WL_KEYROUTER_ERROR_NONE != val) return val; #define CHECK_NULL(val) if (!val) return; #define CHECK_NULL_VAL(val) if (!val) return val; -#define EOM_ERR(msg, ARG...) ERR("[eom module][%s:%d] "msg, __FUNCTION__, __LINE__, ##ARG) -#define EOM_WARN(msg, ARG...) WARN("[eom module][%s:%d] "msg, __FUNCTION__, __LINE__, ##ARG) -#define EOM_DBG(msg, ARG...) DBG("[eom module][%s:%d] "msg, __FUNCTION__, __LINE__, ##ARG) +#define EOM_ERR(msg, ARG...) ERR("[eom module][%s:%d] "msg"\n", __FUNCTION__, __LINE__, ##ARG) +#define EOM_WARN(msg, ARG...) WARN("[eom module][%s:%d] "msg"\n", __FUNCTION__, __LINE__, ##ARG) +#define EOM_DBG(msg, ARG...) DBG("[eom module][%s:%d] "msg"\n", __FUNCTION__, __LINE__, ##ARG) + +#define RETURNIFTRUE(statement, msg, ARG...) \ +if (statement) \ +{ \ + EOM_ERR( msg, ##ARG); \ + return; \ +} + +#define RETURNVALIFTRUE(statement, ret, msg, ARG...) \ +if (statement) \ +{ \ + EOM_ERR( msg, ##ARG); \ + return ret; \ +} + +#define GOTOIFTRUE(statement, lable, msg, ARG...) \ +if (statement) \ +{ \ + EOM_ERR( msg, ##ARG); \ + goto lable; \ +} /* E Module */ E_API extern E_Module_Api e_modapi; @@ -16,4 +39,152 @@ E_API void *e_modapi_init(E_Module *m); E_API int e_modapi_shutdown(E_Module *m); E_API int e_modapi_save(E_Module *m); +#define NUM_MAIN_BUF 2 +#define NUM_ATTR 3 + +typedef struct _E_Eom E_Eom, *E_EomPtr; +typedef struct _E_Eom_Out_Mode E_EomOutMode, *E_EomOutModePtr; +typedef struct _E_Eom_Event_Data E_EomEventData, *E_EomEventDataPtr; +typedef struct _E_Eom_Output E_EomOutput, *E_EomOutputPtr; +typedef struct _E_Eom_Fake_Buffers E_EomFakeBuffers, *E_EomFakeBuffersPtr; +typedef struct _E_Eom_Client_Buffer E_EomClientBuffer, *E_EomClientBufferPtr; + +typedef enum +{ + DOWN = 0, + UP, +} E_EomFlag; + +struct _E_Eom_Out_Mode +{ + int w; + int h; +}; + +struct _E_Eom_Output +{ + unsigned int id; + eom_output_type_e type; + eom_output_mode_e mode; + unsigned int w; + unsigned int h; + unsigned int phys_width; + unsigned int phys_height; + + tdm_output_conn_status status; + E_EomFlag mirror_run; + eom_output_attribute_e attribute; + eom_output_attribute_state_e attribute_state; + + /* external output data */ + char *ext_output_name; + E_EomFlag is_external_init; + E_EomOutMode src_mode; + E_Comp_Wl_Output *wl_output; + + /* internal output data */ + char *int_output_name; + E_EomFlag is_internal_grab; + E_EomOutMode dst_mode; +}; + +struct _E_Eom +{ + struct wl_global *global; + Eina_List *eom_clients; + Eina_List *handlers; + + tdm_display *dpy; + tbm_bufmgr bufmgr; + int fd; + + Eina_List *outputs; + unsigned int output_count; + +#if 1 + /* eom state */ + enum wl_eom_mode eom_mode; + enum wl_eom_attribute eom_attribute; + enum wl_eom_attribute_state eom_attribute_state; + enum wl_eom_status eom_status; + + /*data related to cooperating with clients */ + E_EomFlag is_mirror_mode; + + /* external output data */ + char *ext_output_name; + E_EomFlag is_external_init; + int id; + E_EomOutMode src_mode; + E_Comp_Wl_Output *wl_output; + + /* internal output data */ + char *int_output_name; + E_EomFlag is_internal_grab; + E_EomOutMode dst_mode; +#endif +}; + +struct _E_Eom_Event_Data +{ + tdm_output *output; + tdm_layer *layer; + tdm_pp *pp; + + /* mirror mode data*/ + tbm_surface_h dst_buffers[NUM_MAIN_BUF]; + int current_buffer; + int pp_buffer; + + /* extended mode data */ + Eina_List *client_buffers_list; +}; + +struct _E_Eom_Client_Buffer +{ + E_Comp_Wl_Buffer *wl_buffer; + tbm_surface_h tbm_buffer; + + unsigned long stamp; +}; + +struct _E_Eom_Fake_Buffers +{ + tbm_surface_h fake_buffers[NUM_MAIN_BUF]; + int current_fake_buffer; +}; + + +/* handle external output */ +static E_Comp_Wl_Output *_e_eom_e_comp_wl_output_get(const Eina_List *outputs, const char *id); +static Eina_Bool _e_eom_set_up_external_output(const char *output_name, int width, int height); +static tdm_output * _e_eom_hal_output_get(const char *id); +static tdm_layer * _e_eom_hal_layer_get(tdm_output *output, int width, int height); +static Eina_Bool _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height); +static enum wl_eom_type _e_eom_output_name_to_eom_type(const char *output_name); + +/* handle internal output, pp */ +static Eina_Bool _e_eom_mirror_start(const char *output_name, int width, int height); +static tbm_surface_h _e_eom_root_internal_tdm_surface_get(const char *name); +static Eina_Bool _e_eom_pp_src_to_dst( tbm_surface_h src_buffer); +static Eina_Bool _e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h); +static void _e_eom_pp_calculate_new_size(int *x, int *new_w, int src_w, int src_h, int dst_w, int dst_h); + +/* tdm handlers */ +static void _e_eom_pp_cb(tbm_surface_h surface, void *user_data); +static void _e_eom_commit_cb(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); + +/* clients buffers */ +static E_EomClientBufferPtr _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer); +static void _e_eom_add_client_buffer_to_list(E_EomClientBufferPtr client_buffer); +static void _e_eom_client_buffers_list_free(); +static E_EomClientBufferPtr _e_eom_get_client_buffer_from_list(); + +/*eom utils functions*/ +static int _e_eom_get_time_in_mseconds(); +static void _e_eom_create_fake_buffers(int width, int height); + + #endif -- 2.7.4 From bf4f7b9a6179cc958dd312f867b10190ad28c356 Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Tue, 10 May 2016 21:45:56 +0300 Subject: [PATCH 05/16] add handling of more prior client than current one Change-Id: I1b45d5f995d0351d4998304e183241fc01db29f1 Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 205 ++++++++++++++++++++++++++++++++++--------------------- src/e_mod_main.h | 9 ++- 2 files changed, 137 insertions(+), 77 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index e1cb81e..b24ef68 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -26,6 +26,9 @@ static E_EomPtr g_eom = NULL; +----------------+------------+----------------+-------------+ | exclusive | impossible | impossible | impossible | +----------------+------------+----------------+-------------+ + + possible = 1 + impossible = 0 */ static int eom_output_attributes[NUM_ATTR][NUM_ATTR] = { @@ -64,6 +67,12 @@ _e_eom_get_eom_attribute() return g_eom->eom_attribute; } +static inline void +_e_eom_set_eom_attribute_by_current_client(enum wl_eom_attribute attribute) +{ + g_eom->eom_attribute = attribute; +} + static inline Eina_Bool _e_eom_set_eom_attribute(enum wl_eom_attribute attribute) { @@ -709,7 +718,7 @@ static Eina_Bool _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { enum wl_eom_type eom_type = WL_EOM_TYPE_NONE; - struct wl_resource *resource_iterator; + struct wl_resource *iterator; E_Comp_Wl_Output *wl_output = NULL; Ecore_Drm_Event_Output *e; char buff[PATH_MAX]; @@ -764,22 +773,22 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e eom_type = _e_eom_output_name_to_eom_type(buff); GOTOIFTRUE(eom_type == WL_EOM_TYPE_NONE, err, "ERROR: eom_type is NONE\n"); - EINA_LIST_FOREACH(g_eom->eom_clients, l, resource_iterator) + EINA_LIST_FOREACH(g_eom->eom_clients, l, iterator) { - if (resource_iterator) + if (iterator) { - wl_eom_send_output_type(resource_iterator, + wl_eom_send_output_type(iterator, g_eom->id, eom_type, _e_eom_get_eom_status()); - wl_eom_send_output_attribute(resource_iterator, + wl_eom_send_output_attribute(iterator, g_eom->id, _e_eom_get_eom_attribute(), _e_eom_get_eom_attribute_state(), WL_EOM_ERROR_NONE); - wl_eom_send_output_mode(resource_iterator, + wl_eom_send_output_mode(iterator, g_eom->id, _e_eom_get_eom_mode()); } @@ -798,6 +807,11 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e ++flag; err: + _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_INACTIVE); + _e_eom_set_eom_status(WL_EOM_STATUS_DISCONNECTION); + _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); + _e_eom_set_eom_mode(WL_EOM_MODE_NONE); + return ECORE_CALLBACK_PASS_ON; } @@ -825,12 +839,8 @@ _e_eom_client_buffer_change(void *data, int type, void *event) return ECORE_CALLBACK_PASS_ON; } - /* TODO: Remove all 1, 0 etc. Write my own enume or use - * Eina_Troo etc. - * - * TODO: Make all goto same, not err, end, ret etc. - */ - /*We are not interested in non external clients*/ + /* TODO: Make all goto same, not err, end, ret etc. */ + /* We are not interested in non external clients */ ret_err = e_client_is_external_output_client(ec); RETURNVALIFTRUE(ret_err != EINA_TRUE, ECORE_CALLBACK_PASS_ON, @@ -914,18 +924,18 @@ _e_eom_client_buffers_list_free() /* TODO: I am not sure if it is thread safe */ EINA_LIST_FOREACH(g_eom_event_data.client_buffers_list, l, buffer) { - if (buffer) - { - /* I am not sure if it is necessary */ - /* tbm_surface_internal_unref(buffer->tbm_buffer); */ + if (buffer) + { + /* I am not sure if it is necessary */ + /* tbm_surface_internal_unref(buffer->tbm_buffer); */ - /* TODO: Do we need reference that buffer? */ - /*e_comp_wl_buffer_reference(buffer->tbm_buffer, NULL);*/ + /* TODO: Do we need reference that buffer? */ + /*e_comp_wl_buffer_reference(buffer->tbm_buffer, NULL);*/ - g_eom_event_data.client_buffers_list = eina_list_remove(g_eom_event_data.client_buffers_list, buffer); - free(buffer); - } - } + g_eom_event_data.client_buffers_list = eina_list_remove(g_eom_event_data.client_buffers_list, buffer); + E_FREE(buffer); + } + } } static E_EomClientBufferPtr @@ -933,7 +943,7 @@ _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffe { E_EomClientBufferPtr buffer = NULL; - buffer = malloc(sizeof(E_EomClientBuffer)); + buffer = E_NEW(E_EomClientBuffer, 1); if(buffer == NULL) return NULL; @@ -1010,49 +1020,90 @@ end: static void _e_eom_wl_request_set_attribute_cb(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, uint32_t attribute) { + enum wl_eom_error eom_error = WL_EOM_ERROR_NONE; + struct wl_resource *iterator = NULL; Eina_Bool ret = EINA_FALSE; + Eina_Bool changes = EINA_FALSE; + Eina_List *l; - /* TODO: Add notifications when more prior client changes eom state */ - ret = _e_eom_set_eom_attribute(attribute); - if (ret == EINA_FALSE) + if (resource == g_eom->current_client) { - EOM_DBG("set attribute FAILED\n"); - - wl_eom_send_output_attribute(resource, - g_eom->id, - _e_eom_get_eom_attribute(), - _e_eom_get_eom_attribute_state(), - WL_EOM_ERROR_OUTPUT_OCCUPIED); + /* Current client can set any flag it wants */ + _e_eom_set_eom_attribute_by_current_client(attribute); + changes = EINA_TRUE; } else { - EOM_DBG("set attribute OK\n"); - - wl_eom_send_output_attribute(resource, - g_eom->id, - _e_eom_get_eom_attribute(), - _e_eom_get_eom_attribute_state(), - WL_EOM_ERROR_NONE); - - /* If client has set WL_EOM_ATTRIBUTE_NONE, eom will be - * switched to mirror mode - */ - if (attribute == WL_EOM_ATTRIBUTE_NONE && g_eom->is_mirror_mode == DOWN) + ret = _e_eom_set_eom_attribute(attribute); + if (ret == EINA_FALSE) { - g_eom->is_mirror_mode = UP; + EOM_DBG("set attribute FAILED\n"); + + eom_error = WL_EOM_ERROR_OUTPUT_OCCUPIED; + goto end; + } + + changes = EINA_TRUE; + } + + EOM_DBG("set attribute OK\n"); + + /* If client has set WL_EOM_ATTRIBUTE_NONE, eom will be + * switched to mirror mode + */ + if (attribute == WL_EOM_ATTRIBUTE_NONE && g_eom->is_mirror_mode == DOWN) + { + g_eom->is_mirror_mode = UP; + ret = _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); + _e_eom_set_eom_mode(WL_EOM_MODE_MIRROR); + + _e_eom_client_buffers_list_free(); + + ret = _e_eom_mirror_start(g_eom->int_output_name, + g_eom->src_mode.w, + g_eom->src_mode.h); + GOTOIFTRUE(ret == EINA_FALSE, + end, + "ERROR: restore mirror mode after a client disconnection\n"); + + goto end; + } - _e_eom_client_buffers_list_free(); +end: + wl_eom_send_output_attribute(resource, + g_eom->id, + _e_eom_get_eom_attribute(), + _e_eom_get_eom_attribute_state(), + eom_error); - ret = _e_eom_mirror_start(g_eom->int_output_name, - g_eom->src_mode.w, - g_eom->src_mode.h); - GOTOIFTRUE(ret == EINA_FALSE, - err, - "ERROR: restore mirror mode after a client disconnection\n"); + /* Notify */ + if (changes == EINA_TRUE) + { + EINA_LIST_FOREACH(g_eom->eom_clients, l, iterator) + { + if (iterator == resource) + continue; + + if (iterator) + { + if (g_eom->is_mirror_mode == UP) + wl_eom_send_output_attribute(iterator, + g_eom->id, + _e_eom_get_eom_attribute(), + _e_eom_get_eom_attribute_state(), + WL_EOM_ERROR_NONE); + else + wl_eom_send_output_attribute(iterator, + g_eom->id, + _e_eom_get_eom_attribute(), + WL_EOM_ATTRIBUTE_STATE_LOST, + WL_EOM_ERROR_NONE); + } } + + g_eom->current_client = resource; } -err: return; } @@ -1073,6 +1124,7 @@ _e_eom_wl_request_get_output_info_cb(struct wl_client *client, struct wl_resourc EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d\n", output->id, output->type, output->mode, output->w, output->h, output->phys_width, output->phys_height, output->status); + wl_eom_send_output_info(resource, output->id, output->type, output->mode, output->w, output->h, output->phys_width, output->phys_height, output->status); } @@ -1090,45 +1142,45 @@ static const struct wl_eom_interface _e_eom_wl_implementation = static void _e_eom_wl_resource_destory_cb(struct wl_resource *resource) { - struct wl_resource *resource_iterator = NULL; + struct wl_resource *iterator = NULL; Eina_List *l = NULL; Eina_Bool ret; EOM_DBG("client unbind\n"); - ret = _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); - if (ret == EINA_FALSE) - EOM_DBG("Restore attribute: Failed\n"); - else - EOM_DBG("Restore attribute: OK\n"); + g_eom->eom_clients = eina_list_remove(g_eom->eom_clients, resource); + g_eom->current_client = NULL; - /* If a client has been disconnected and eom has not been - * restored to mirror mode, start mirror mode + /* If a client has been disconnected and mirror mode has not + * been restore, start mirror mode */ if (g_eom->is_mirror_mode == DOWN) { g_eom->is_mirror_mode = UP; + ret = _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); + _e_eom_set_eom_mode(WL_EOM_MODE_MIRROR); _e_eom_client_buffers_list_free(); ret = _e_eom_mirror_start(g_eom->int_output_name, g_eom->src_mode.w, g_eom->src_mode.h); - RETURNIFTRUE(ret == EINA_FALSE, - "ERROR: restore mirror mode after a client disconnection\n"); + GOTOIFTRUE(ret == EINA_FALSE, + end, + "ERROR: restore mirror mode after a client disconnection\n"); + } - /* Notify eom clients that eom state has been changed */ - EINA_LIST_FOREACH(g_eom->eom_clients, l, resource_iterator) +end: + /* Notify eom clients that eom state has been changed */ + EINA_LIST_FOREACH(g_eom->eom_clients, l, iterator) + { + if (iterator) { - if (resource_iterator) - { - wl_eom_send_output_attribute(resource_iterator, - g_eom->id, - _e_eom_get_eom_attribute(), - _e_eom_get_eom_attribute_state(), - WL_EOM_ERROR_NONE); - } - + wl_eom_send_output_attribute(iterator, + g_eom->id, + _e_eom_get_eom_attribute(), + _e_eom_get_eom_attribute_state(), + WL_EOM_ERROR_NONE); } } } @@ -1226,7 +1278,6 @@ _e_eom_output_info_get(tdm_display *dpy) tdm_error ret = TDM_ERROR_NONE; int i, count; - ret = tdm_display_get_output_count(dpy, &count); RETURNVALIFTRUE(ret != TDM_ERROR_NONE, EINA_FALSE, @@ -1409,6 +1460,8 @@ _e_eom_init() g_eom->ext_output_name = NULL; g_eom->int_output_name = NULL; + g_eom->current_client = NULL; + _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_NONE); _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); _e_eom_set_eom_status(WL_EOM_STATUS_NONE); diff --git a/src/e_mod_main.h b/src/e_mod_main.h index b004dc6..ea30639 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -48,6 +48,7 @@ typedef struct _E_Eom_Event_Data E_EomEventData, *E_EomEventDataPtr; typedef struct _E_Eom_Output E_EomOutput, *E_EomOutputPtr; typedef struct _E_Eom_Fake_Buffers E_EomFakeBuffers, *E_EomFakeBuffersPtr; typedef struct _E_Eom_Client_Buffer E_EomClientBuffer, *E_EomClientBufferPtr; +typedef struct _E_Eom_Client E_EomClient, *E_EomClientPtr; typedef enum { @@ -110,6 +111,7 @@ struct _E_Eom /*data related to cooperating with clients */ E_EomFlag is_mirror_mode; + struct wl_resource *current_client; /* external output data */ char *ext_output_name; @@ -148,13 +150,18 @@ struct _E_Eom_Client_Buffer unsigned long stamp; }; +struct _E_Eom_Client +{ + struct wl_resource *resource; + Eina_Bool curent; +}; + struct _E_Eom_Fake_Buffers { tbm_surface_h fake_buffers[NUM_MAIN_BUF]; int current_fake_buffer; }; - /* handle external output */ static E_Comp_Wl_Output *_e_eom_e_comp_wl_output_get(const Eina_List *outputs, const char *id); static Eina_Bool _e_eom_set_up_external_output(const char *output_name, int width, int height); -- 2.7.4 From c6a310c08407820e0c6fbf9613d7a8b55309ea12 Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Wed, 11 May 2016 10:45:29 +0300 Subject: [PATCH 06/16] unbiding of non current client Change-Id: I49677cf142f6037c95ff4016acb50c8ba849109a Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index b24ef68..b8dd84a 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -1029,8 +1029,8 @@ _e_eom_wl_request_set_attribute_cb(struct wl_client *client, struct wl_resource if (resource == g_eom->current_client) { /* Current client can set any flag it wants */ - _e_eom_set_eom_attribute_by_current_client(attribute); - changes = EINA_TRUE; + _e_eom_set_eom_attribute_by_current_client(attribute); + changes = EINA_TRUE; } else { @@ -1149,7 +1149,10 @@ _e_eom_wl_resource_destory_cb(struct wl_resource *resource) EOM_DBG("client unbind\n"); g_eom->eom_clients = eina_list_remove(g_eom->eom_clients, resource); - g_eom->current_client = NULL; + + /* If not current client has been destroyed do nothing */ + if (resource != g_eom->current_client) + goto end2; /* If a client has been disconnected and mirror mode has not * been restore, start mirror mode @@ -1183,6 +1186,9 @@ end: WL_EOM_ERROR_NONE); } } + +end2: + g_eom->current_client = NULL; } /* wl_eom global object bind function */ -- 2.7.4 From 205617013d9989f93715e275bc96d706680511c3 Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Wed, 11 May 2016 16:14:20 +0300 Subject: [PATCH 07/16] control eom with eom_state flag Change-Id: I313ce2b22ec630130a4581faf1396115276d685b Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 49 +++++++++++++++++++++++++++++++++---------------- src/e_mod_main.h | 1 + 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index b8dd84a..446457d 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -116,10 +116,14 @@ _e_eom_pp_cb(tbm_surface_h surface, void *user_data) tdm_buffer_remove_release_handler(eom_data->dst_buffers[eom_data->pp_buffer], _e_eom_pp_cb, eom_data); + /* Stop EOM */ + if (g_eom->eom_sate != UP) + return; + /* TODO: lock that flag??? */ /* If a client has committed its buffer stop mirror mode */ if (g_eom->is_mirror_mode == DOWN) - return; + return; tbm_surface_h src_buffer; src_buffer = _e_eom_root_internal_tdm_surface_get(g_eom->int_output_name); @@ -151,6 +155,10 @@ _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS eom_data = (E_EomEventDataPtr)user_data; + /* Stop EOM */ + if (g_eom->eom_sate != UP) + return; + /* TODO: Maybe better to separating that callback on to mirror and extended callbacks */ if (g_eom->is_mirror_mode == UP) { @@ -300,21 +308,24 @@ _e_eom_deinit_external_output() EOM_DBG ("EXT OUTPUT DEINIT: fail commit:%d\n", err); else EOM_DBG("EXT OUTPUT DEINIT: ok commit:%d\n", err); + } - /* TODO: do I need to do DPMS off? */ - err = tdm_output_set_dpms(g_eom_event_data.output, TDM_OUTPUT_DPMS_OFF); - if (err != TDM_ERROR_NONE) - EOM_ERR("EXT OUTPUT DEINIT: failed set DPMS off:%d\n", err); + /* TODO: do I need to do DPMS off? */ + err = tdm_output_set_dpms(g_eom_event_data.output, TDM_OUTPUT_DPMS_OFF); + if (err != TDM_ERROR_NONE) + EOM_ERR("EXT OUTPUT DEINIT: failed set DPMS off:%d\n", err); - for (i = 0; i < NUM_MAIN_BUF; i++) - { - tdm_buffer_remove_release_handler(g_eom_event_data.dst_buffers[i], - _e_eom_pp_cb, &g_eom_event_data); - if (g_eom_event_data.dst_buffers[i]) - tbm_surface_destroy(g_eom_event_data.dst_buffers[i]); - } + for (i = 0; i < NUM_MAIN_BUF; i++) + { + tdm_buffer_remove_release_handler(g_eom_event_data.dst_buffers[i], + _e_eom_pp_cb, &g_eom_event_data); + if (g_eom_event_data.dst_buffers[i]) + tbm_surface_destroy(g_eom_event_data.dst_buffers[i]); } + if (g_eom->eom_sate == DOWN) + _e_eom_client_buffers_list_free(g_eom->eom_clients); + if (g_eom->int_output_name) { free(g_eom->int_output_name); @@ -747,8 +758,9 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: initialize external output\n"); g_eom->is_external_init = UP; - g_eom->id = e->id; + g_eom->eom_sate = UP; g_eom->wl_output = wl_output; + g_eom->id = e->id; _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_ACTIVE); _e_eom_set_eom_status(WL_EOM_STATUS_CONNECTION); @@ -759,6 +771,7 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e { g_eom->is_external_init = DOWN; g_eom->is_internal_grab = DOWN; + g_eom->eom_sate = DOWN; g_eom->wl_output = NULL; g_eom->id = -1; @@ -796,7 +809,7 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e } else if (strcmp(e->name, "DSI-0") == 0 && g_eom->is_external_init == UP && flag == 2) { - /*TODO: add support of internal and external output of same size */ + /*TODO: add support of internal and external output of same size */ ret = _e_eom_mirror_start(buff, e->w, e->h); GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: get root surfcae\n"); @@ -806,7 +819,11 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e ++flag; + return ECORE_CALLBACK_PASS_ON; + err: + _e_eom_deinit_external_output(); + _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_INACTIVE); _e_eom_set_eom_status(WL_EOM_STATUS_DISCONNECTION); _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); @@ -1022,8 +1039,8 @@ _e_eom_wl_request_set_attribute_cb(struct wl_client *client, struct wl_resource { enum wl_eom_error eom_error = WL_EOM_ERROR_NONE; struct wl_resource *iterator = NULL; - Eina_Bool ret = EINA_FALSE; Eina_Bool changes = EINA_FALSE; + Eina_Bool ret = EINA_FALSE; Eina_List *l; if (resource == g_eom->current_client) @@ -1076,7 +1093,7 @@ end: _e_eom_get_eom_attribute_state(), eom_error); - /* Notify */ + /* Notify eom clients that eom state has been changed */ if (changes == EINA_TRUE) { EINA_LIST_FOREACH(g_eom->eom_clients, l, iterator) diff --git a/src/e_mod_main.h b/src/e_mod_main.h index ea30639..cc6f056 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -104,6 +104,7 @@ struct _E_Eom #if 1 /* eom state */ + E_EomFlag eom_sate; enum wl_eom_mode eom_mode; enum wl_eom_attribute eom_attribute; enum wl_eom_attribute_state eom_attribute_state; -- 2.7.4 From 7e9c76c03c69fb08f83bab9322070dae9d421bae Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Fri, 27 May 2016 15:51:53 +0300 Subject: [PATCH 08/16] adopt "use tdm udev handler for external output update" commit Change-Id: Ie88e0b52f0b8e0459c4a63508760513cb8824234 Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 535 ++++++++++++++++++++++++++++++++++++++++++++++++------- src/e_mod_main.h | 17 +- 2 files changed, 480 insertions(+), 72 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 446457d..f06e0ce 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -37,6 +37,14 @@ static int eom_output_attributes[NUM_ATTR][NUM_ATTR] = {0, 0, 0}, }; +static const char *eom_conn_types[] = +{ + "None", "VGA", "DVI-I", "DVI-D", "DVI-A", + "Composite", "S-Video", "LVDS", "Component", "DIN", + "DisplayPort", "HDMI-A", "HDMI-B", "TV", "eDP", "Virtual", + "DSI", +}; + static inline enum wl_eom_mode _e_eom_get_eom_mode() { @@ -273,12 +281,13 @@ _e_eom_set_up_external_output(const char *output_name, int width, int height) tdm_err = tdm_layer_set_buffer(hal_layer, eom_data->dst_buffers[eom_data->current_buffer]); GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: set buffer on layer:%d", tdm_err); - +/* tdm_err = tdm_output_set_dpms(hal_output, TDM_OUTPUT_DPMS_ON); GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: failed set DPMS on:%d", tdm_err); tdm_err = tdm_output_commit(hal_output, 0, _e_eom_commit_cb, eom_data); GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: commit crtc:%d", tdm_err); +*/ return EINA_TRUE; @@ -516,7 +525,7 @@ _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height) goto err; } - memset(buffer_info.planes[0].ptr, 0xFF, buffer_info.planes[0].size); + memset(buffer_info.planes[0].ptr, 0x0, buffer_info.planes[0].size); tbm_surface_unmap(buffer); eom_data->dst_buffers[0] = buffer; @@ -539,7 +548,7 @@ _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height) goto err; } - memset(buffer_info.planes[0].ptr, 0xFF, buffer_info.planes[0].size); + memset(buffer_info.planes[0].ptr, 0x0, buffer_info.planes[0].size); tbm_surface_unmap(buffer); eom_data->dst_buffers[1] = buffer; @@ -574,6 +583,7 @@ _e_eom_output_name_to_eom_type(const char *output_name) static Eina_Bool _e_eom_mirror_start(const char *output_name, int width, int height) { + /* should be changed in HWC enable environment */ tbm_surface_info_s src_buffer_info; tbm_surface_h src_buffer = NULL; Eina_Bool ret = EINA_FALSE; @@ -587,9 +597,11 @@ _e_eom_mirror_start(const char *output_name, int width, int height) src_buffer_info.width, src_buffer_info.height, src_buffer_info.bpp, src_buffer_info.size); + /* g_eom->src_mode.w = width; g_eom->src_mode.h = height; g_eom->int_output_name = strdup(output_name); + */ /* TODO: if internal and external outputs are equal */ ret = _e_eom_pp_is_needed(g_eom->src_mode.w, g_eom->src_mode.h, @@ -608,14 +620,26 @@ _e_eom_root_internal_tdm_surface_get(const char *name) Ecore_Drm_Output *primary_output = NULL; Ecore_Drm_Device *dev; const Eina_List *l; +#if 0 Ecore_Drm_Fb *fb; +#else + tdm_output *tdm_output_obj = NULL; + tbm_surface_h tbm = NULL; + tdm_error err = TDM_ERROR_NONE; + int count = 0, i = 0; +#endif EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev) { primary_output = ecore_drm_device_output_name_find(dev, name); + if (primary_output != NULL) + break; } - RETURNVALIFTRUE(primary_output == NULL, NULL, "ERROR: get primary output\n"); +#if 0 + RETURNVALIFTRUE(primary_output == NULL, NULL, + "ERROR: get primary output.(%s)\n", + name); /* I think it is more convenient than one upon, but E took first * output as primary and it can be not internal output @@ -623,36 +647,115 @@ _e_eom_root_internal_tdm_surface_get(const char *name) primary_output = ecore_drm_output_primary_get(); RETURNVALIFTRUE(primary_output == NULL, NULL, "ERROR: get primary output\n"); */ +#else + if (primary_output == NULL) + { + EOM_ERR("ERROR: get primary output.(%s)\n", name); + EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev) + { + primary_output = ecore_drm_output_primary_get(dev); + if (primary_output != NULL) + break; + } + + if (primary_output == NULL) + { + EOM_ERR("ERROR: get primary output.(%s)\n", name); + return NULL; + } + } +#endif + +#if 0 fb = ecore_drm_display_output_primary_layer_fb_get(primary_output); RETURNVALIFTRUE(fb == NULL, NULL, "ERROR: get primary frambuffer\n"); - /*EOM_DBG("FRAMEBUFFER ECORE_DRM: is_client:%d mode%dx%d\n", fb->from_client, fb->w, fb->h);*/ return (tbm_surface_h)fb->hal_buffer; +#else + tdm_output_obj = tdm_display_get_output(g_eom->dpy, 0, &err); + if (tdm_output_obj == NULL || err != TDM_ERROR_NONE) + { + EOM_ERR("tdm_display_get_output 0 fail\n"); + return NULL; + } + err = tdm_output_get_layer_count(tdm_output_obj, &count); + if (err != TDM_ERROR_NONE) + { + EOM_ERR("tdm_output_get_layer_count fail\n"); + return NULL; + } + + for (i = 0; i < count; i++) + { + tdm_layer *layer = tdm_output_get_layer(tdm_output_obj, i, NULL); + tdm_layer_capability capabilities = 0; + tdm_layer_get_capabilities(layer, &capabilities); + if (capabilities & TDM_LAYER_CAPABILITY_PRIMARY) + { + tbm = tdm_layer_get_displaying_buffer(layer, &err); + if (err != TDM_ERROR_NONE) + { + EOM_ERR("tdm_layer_get_displaying_buffer fail\n"); + return NULL; + } + break; + } + } + + return tbm; +#endif +} + +static void +_e_eom_calculate_fullsize(int src_h, int src_v, int dst_size_h, int dst_size_v, + int *dst_x, int *dst_y, int *dst_w, int *dst_h) +{ + double h_ratio, v_ratio; + + h_ratio = src_h / dst_size_h; + v_ratio = src_v / dst_size_v; + + if (h_ratio == v_ratio) + { + *dst_x = 0; + *dst_y = 0; + *dst_w = dst_size_h; + *dst_h = dst_size_v; + } + else if (h_ratio < v_ratio) + { + *dst_y = 0; + *dst_h = dst_size_v; + *dst_w = dst_size_v * src_h / src_v; + *dst_x = (dst_size_h - *dst_w) / 2; + } + else /* (h_ratio > v_ratio) */ + { + *dst_x = 0; + *dst_w = dst_size_h; + *dst_h = dst_size_h * src_h / src_v; + *dst_y = (dst_size_v - *dst_h) / 2; + } } static Eina_Bool -_e_eom_pp_src_to_dst( tbm_surface_h src_buffer) +_e_eom_pp_src_to_dst(tbm_surface_h src_buffer) { tdm_error err = TDM_ERROR_NONE; tdm_info_pp pp_info; tdm_pp *pp = NULL; - - int calc_x; - int calc_width; + int x, y, w, h; pp = tdm_display_create_pp(g_eom->dpy, &err); RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: create pp:%d\n", err); - _e_eom_pp_calculate_new_size(&calc_x, &calc_width, - g_eom->src_mode.w, g_eom->src_mode.h, - g_eom->dst_mode.w, g_eom->dst_mode.h); - - DBG("PP INFO: src:%dx%d dst:%dx%d calc_x:%d calc_width:%d", - g_eom->src_mode.w, g_eom->src_mode.h, - g_eom->dst_mode.w, g_eom->dst_mode.h, - calc_x, calc_width); + /* TO DO : consider rotation */ + _e_eom_calculate_fullsize(g_eom->src_mode.w, g_eom->src_mode.h, + g_eom->dst_mode.w, g_eom->dst_mode.h, + &x, &y, &w, &h); + EOM_DBG("x:%d, y:%d, w:%d, h:%d\n", x, y, w, h); g_eom_event_data.pp = pp; @@ -663,13 +766,16 @@ _e_eom_pp_src_to_dst( tbm_surface_h src_buffer) pp_info.src_config.pos.w = g_eom->src_mode.w; pp_info.src_config.pos.h = g_eom->src_mode.h; pp_info.src_config.format = TBM_FORMAT_ARGB8888; - pp_info.dst_config.size.h = calc_width; + + pp_info.dst_config.size.h = g_eom->dst_mode.w; pp_info.dst_config.size.v = g_eom->dst_mode.h; - pp_info.dst_config.pos.x = calc_x; - pp_info.dst_config.pos.y = 0; - pp_info.dst_config.pos.w = calc_width; - pp_info.dst_config.pos.h = g_eom->dst_mode.h; + pp_info.dst_config.pos.x = x; + pp_info.dst_config.pos.y = y; + pp_info.dst_config.pos.w = w; + pp_info.dst_config.pos.h = h; pp_info.dst_config.format = TBM_FORMAT_ARGB8888; + + /* TO DO : get rotation */ pp_info.transform = TDM_TRANSFORM_NORMAL; pp_info.sync = 0; pp_info.flags = 0; @@ -708,47 +814,39 @@ _e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h) return EINA_FALSE; } -static void -_e_eom_pp_calculate_new_size(int *x, int *new_w, int src_w, int src_h, int dst_w, int dst_h) -{ - float similatiry_coeficient = 0.0; - int mean_dst_width, mean_new_width; - - similatiry_coeficient = dst_h / src_h; - *new_w = (int)similatiry_coeficient * src_w; - - mean_dst_width = dst_w / 2; - mean_new_width = *new_w / 2; - - *x = mean_dst_width - mean_new_width; -} - -static int flag = 0; - static Eina_Bool _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { enum wl_eom_type eom_type = WL_EOM_TYPE_NONE; - struct wl_resource *iterator; E_Comp_Wl_Output *wl_output = NULL; - Ecore_Drm_Event_Output *e; + Ecore_Drm_Event_Output *e = NULL; + struct wl_resource *iterator; char buff[PATH_MAX]; Eina_List *l; int ret = 0; if (!(e = event)) goto err; - if (!e->plug) goto err; - EOM_DBG("id:%d (x,y,w,h):(%d,%d,%d,%d) (w_mm,h_mm):(%d,%d) refresh:%d subpixel_order:%d transform:%d make:%s model:%s name:%s plug:%d\n", - e->id, e->x, e->y, e->w, e->h, e->phys_width, e->phys_height, e->refresh, e->subpixel_order, e->transform, e->make, e->model, e->name, e->plug); + e->id, e->x, e->y, e->w, e->h, e->phys_width, e->phys_height, e->refresh, e->subpixel_order, e->transform, e->make, e->model, e->name, e->plug); snprintf(buff, sizeof(buff), "%s", e->name); + if (e->id == 0) /* main output */ + { + g_eom->src_mode.w = e->w; + g_eom->src_mode.h = e->h; + /* TODO: free that memory */ + if (g_eom->int_output_name == NULL) + g_eom->int_output_name = strdup(buff); + } + if (strcmp(e->name, "HDMI-A-0") == 0) { if (e->plug == 1) { + tdm_error tdm_err = TDM_ERROR_NONE; + /* Get e_comp_wl_output */ wl_output = _e_eom_e_comp_wl_output_get(e_comp_wl->outputs, buff); GOTOIFTRUE(wl_output == NULL, err, "ERROR: there is no wl_output:(%s)\n", buff); @@ -762,6 +860,16 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e g_eom->wl_output = wl_output; g_eom->id = e->id; + /* get main surface */ + ret = _e_eom_mirror_start(g_eom->int_output_name, g_eom->src_mode.w, g_eom->src_mode.h); + GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: get root surfcae\n"); + + tdm_err = tdm_output_set_dpms(g_eom_event_data.output, TDM_OUTPUT_DPMS_ON); + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: tdm_output_set_dpms on\n"); + + tdm_err = tdm_output_commit(g_eom_event_data.output, 0, _e_eom_commit_cb, &g_eom_event_data); + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: commit crtc:%d\n", tdm_err); + _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_ACTIVE); _e_eom_set_eom_status(WL_EOM_STATUS_CONNECTION); _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); @@ -807,17 +915,6 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e } } } - else if (strcmp(e->name, "DSI-0") == 0 && g_eom->is_external_init == UP && flag == 2) - { - /*TODO: add support of internal and external output of same size */ - ret = _e_eom_mirror_start(buff, e->w, e->h); - GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: get root surfcae\n"); - - g_eom->is_internal_grab = UP; - g_eom->is_mirror_mode = UP; - } - - ++flag; return ECORE_CALLBACK_PASS_ON; @@ -832,6 +929,295 @@ err: return ECORE_CALLBACK_PASS_ON; } +static const tdm_output_mode * +_e_eom_get_best_mode(tdm_output *output) +{ + tdm_error ret = TDM_ERROR_NONE; + const tdm_output_mode *modes; + const tdm_output_mode *mode = NULL; + /* unsigned int vrefresh = 0; */ + unsigned int best_value = 0; + unsigned int value; + int i, count = 0; + + ret = tdm_output_get_available_modes(output, &modes, &count); + if (ret != TDM_ERROR_NONE) + { + EOM_ERR("tdm_output_get_available_modes fail(%d)\n", ret); + return NULL; + } +#if 0 + /* kernel error */ + for (i = 0; i < count; i++) + { + value = modes[i].vdisplay + modes[i].hdisplay; + if (value > best_value) + best_value = value; + } + + for (i = 0; i < count; i++) + { + value = modes[i].vdisplay + modes[i].hdisplay; + if (value != best_value) + continue; + + if (modes[i].vrefresh > vrefresh) + { + mode = &modes[i]; + vrefresh = modes[i].vrefresh; + } + } +#else + for (i = 0; i < count; i++) + { + value = modes[i].vdisplay + modes[i].hdisplay; + if (value >= best_value) + { + best_value = value; + mode = &modes[i]; + } + } +#endif + EOM_DBG("bestmode : %s, (%dx%d) r(%d), f(%d), t(%d)", + mode->name, mode->hdisplay, mode->vdisplay, mode->vrefresh, mode->flags, mode->type); + + return mode; +} + +static int +_e_eom_get_output_position(void) +{ + tdm_output *output_main = NULL; + const tdm_output_mode *mode; + tdm_error ret = TDM_ERROR_NONE; + int x = 0; + + output_main = tdm_display_get_output(g_eom->dpy, 0, &ret); + RETURNVALIFTRUE(ret != TDM_ERROR_NONE, 0, "tdm_display_get_output main fail(ret:%d)", ret); + RETURNVALIFTRUE(output_main == NULL, 0, "tdm_display_get_output main fail(no output:%d)", ret); + + ret = tdm_output_get_mode(output_main, &mode); + RETURNVALIFTRUE(ret != TDM_ERROR_NONE, 0, "tdm_output_get_mode main fail(ret:%d)", ret); + + if (mode == NULL) + x = 0; + else + x = mode->hdisplay; + + if (g_eom->outputs) + { + Eina_List *l; + E_EomOutputPtr eom_output_tmp; + + EINA_LIST_FOREACH(g_eom->outputs, l, eom_output_tmp) + { + if (eom_output_tmp->status == TDM_OUTPUT_CONN_STATUS_CONNECTED) + x += eom_output_tmp->w; + } + } + + return x; +} + +static void +_e_eom_start_mirror(E_EomOutputPtr eom_output, int width, int height) +{ + tdm_output *output; + tdm_layer *hal_layer; + tdm_info_layer layer_info; + tdm_error tdm_err = TDM_ERROR_NONE; + E_EomEventDataPtr eom_event_data = &g_eom_event_data; + int ret = 0; + + if (eom_output->mirror_run == UP) + return; + + output = eom_output->output; + hal_layer = _e_eom_hal_layer_get(output, width, height); + GOTOIFTRUE(hal_layer == NULL, err, "ERROR: get hal layer\n"); + + ret = _e_eom_create_output_buffers(eom_event_data, width, height); + GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: create buffers \n"); + + tdm_err = tdm_layer_get_info(hal_layer, &layer_info); + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: get layer info: %d", tdm_err); + + 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); + + g_eom->dst_mode.w = width; + g_eom->dst_mode.h = height; + /* TODO: free that memory */ + /*g_eom->ext_output_name = strdup(output_name);*/ + + eom_event_data->layer = hal_layer; + eom_event_data->output = output; + eom_event_data->current_buffer = 0; + + tdm_err = tdm_layer_set_buffer(hal_layer, eom_event_data->dst_buffers[eom_event_data->current_buffer]); + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: set buffer on layer:%d\n", tdm_err); + + g_eom->is_external_init = 1; + g_eom->id = eom_output->id; + + tdm_err = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON); + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: tdm_output_set_dpms on\n"); + + /* get main surface */ + ret = _e_eom_mirror_start(g_eom->int_output_name, g_eom->src_mode.w, g_eom->src_mode.h); + GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: get root surfcae\n"); + + tdm_err = tdm_output_commit(output, 0, _e_eom_commit_cb, &g_eom_event_data); + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: commit crtc:%d\n", tdm_err); + + _e_eom_set_eom_mode(WL_EOM_MODE_MIRROR); + + eom_output->mirror_run = UP; + + return; + +err: +/* + * TODO: add deinitialization + */ + return; +} + +static void +_e_eom_stop_mirror(E_EomOutputPtr eom_output) +{ + if (eom_output->mirror_run == DOWN) + return; + + g_eom->is_external_init = 0; + g_eom->is_internal_grab = 0; + g_eom->id = -1; + + _e_eom_set_eom_status(WL_EOM_STATUS_DISCONNECTION); + _e_eom_set_eom_mode(WL_EOM_MODE_NONE); + + _e_eom_deinit_external_output(); + + eom_output->mirror_run = DOWN; +} + +static void +_e_eom_tdm_output_status_change_cb(tdm_output *output, tdm_output_change_type type, tdm_value value, void *user_data) +{ + tdm_output_type tdm_type; + tdm_error ret = TDM_ERROR_NONE; + tdm_output_conn_status status; + tdm_output_conn_status status2; + const char *maker = NULL, *model = NULL, *name = NULL; + const char *tmp_name; + char new_name[DRM_CONNECTOR_NAME_LEN]; + E_EomOutputPtr eom_output = NULL; + tdm_output_conn_status plug; + + if (type == TDM_OUTPUT_CHANGE_DPMS) + return; + + if (g_eom->outputs) + { + Eina_List *l; + E_EomOutputPtr eom_output_tmp; + + EINA_LIST_FOREACH(g_eom->outputs, l, eom_output_tmp) + { + if (eom_output_tmp->output == output) + eom_output = eom_output_tmp; + } + } + + ret = tdm_output_get_output_type(output, &tdm_type); + RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_output_type fail(%d)", ret); + + ret = tdm_output_get_model_info(output, &maker, &model, &name); + RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_model_info fail(%d)", ret); + + ret = tdm_output_get_conn_status(output, &status); + RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_conn_status fail(%d)", ret); + + status2 = value.u32; + + EOM_DBG("type(%d, %d), status(%d, %d) (%s,%s,%s)", type, tdm_type, status, status2, maker, model, name); + + if (tdm_type < ALEN(eom_conn_types)) + tmp_name = eom_conn_types[tdm_type]; + else + tmp_name = "unknown"; + snprintf(new_name, sizeof(new_name), "%s-%d", tmp_name, 0); + + plug = value.u32; + + if (plug == TDM_OUTPUT_CONN_STATUS_CONNECTED || plug == TDM_OUTPUT_CONN_STATUS_MODE_SETTED) + { + unsigned int mmWidth, mmHeight, subpixel; + const tdm_output_mode *mode; + int x = 0; + + ret = tdm_output_get_physical_size(output, &mmWidth, &mmHeight); + RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_physical_size fail(%d)", ret); + + ret = tdm_output_get_subpixel(output, &subpixel); + RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_subpixel fail(%d)", ret); + + mode = _e_eom_get_best_mode(output); + RETURNIFTRUE(mode == NULL, "_e_eom_get_best_resolution fail"); + + ret = tdm_output_set_mode(output, mode); + RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_set_mode fail(%d)", ret); + + x = _e_eom_get_output_position(); + EOM_DBG("mode: %dx%d, phy(%dx%d), pos(%d,0), refresh:%d, subpixel:%d", + mode->hdisplay, mode->vdisplay, mmWidth, mmHeight, x, mode->vrefresh, subpixel); + + if (!e_comp_wl_output_init(new_name, maker, model, x, 0, + mode->hdisplay, mode->vdisplay, + mmWidth, mmHeight, mode->vrefresh, subpixel, 0)) + { + EOM_ERR("Could not setup new output: %s", new_name); + return; + } + EOM_DBG("Setup new output: %s", new_name); + + /* update eom_output connect */ + eom_output->w = mode->hdisplay; + eom_output->h = mode->vdisplay; + eom_output->phys_width = mmWidth; + eom_output->phys_height = mmHeight; + eom_output->status = plug; + + g_eom->is_mirror_mode = UP; + g_eom->eom_sate = UP; + + /* TODO: check output mode(presentation set) and HDMI type */ + _e_eom_start_mirror(eom_output, mode->hdisplay, mode->vdisplay); + } + else /*TDM_OUTPUT_CONN_STATUS_DISCONNECTED*/ + { + if (eom_output->mirror_run == UP) + _e_eom_stop_mirror(eom_output); + + /* update eom_output disconnect */ + eom_output->w = 0; + eom_output->h = 0; + eom_output->phys_width = 0; + eom_output->phys_height = 0; + eom_output->status = plug; + + g_eom->is_mirror_mode = DOWN; + g_eom->eom_sate = DOWN; + + e_comp_wl_output_remove(new_name); + EOM_DBG("Destory output: %s", new_name); + } +} + static Eina_Bool _e_eom_client_buffer_change(void *data, int type, void *event) { @@ -839,7 +1225,7 @@ _e_eom_client_buffer_change(void *data, int type, void *event) E_EomClientBufferPtr client_buffer = NULL; E_Event_Client *ev = event; E_Client *ec = NULL; - Eina_Bool ret_err; + /* Eina_Bool ret_err; */ /* tbm_surface_h external_tbm_buffer = NULL; tbm_surface_info_s surface_info; @@ -849,6 +1235,8 @@ _e_eom_client_buffer_change(void *data, int type, void *event) EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON); EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON); + return ECORE_CALLBACK_PASS_ON; + ec = ev->ec; if (e_object_is_del(E_OBJECT(ec))) { @@ -858,10 +1246,12 @@ _e_eom_client_buffer_change(void *data, int type, void *event) /* TODO: Make all goto same, not err, end, ret etc. */ /* We are not interested in non external clients */ + /* ret_err = e_client_is_external_output_client(ec); RETURNVALIFTRUE(ret_err != EINA_TRUE, ECORE_CALLBACK_PASS_ON, "ERROR: BUFF CHANGE: ec is not external\n"); + */ if (ec->pixmap == NULL) return ECORE_CALLBACK_PASS_ON; @@ -922,6 +1312,8 @@ _e_eom_client_buffer_change(void *data, int type, void *event) g_eom->is_mirror_mode = DOWN; return ECORE_CALLBACK_PASS_ON; + + /* TODO: deinitialization */ } static void @@ -938,7 +1330,6 @@ _e_eom_client_buffers_list_free() E_EomClientBufferPtr *buffer = NULL; Eina_List *l; - /* TODO: I am not sure if it is thread safe */ EINA_LIST_FOREACH(g_eom_event_data.client_buffers_list, l, buffer) { if (buffer) @@ -984,7 +1375,6 @@ _e_eom_get_client_buffer_from_list() E_EomClientBufferPtr buffer = NULL; Eina_List *l; - /* TODO: Have to describe how that list works*/ /* There must be only one buffer */ EINA_LIST_FOREACH(g_eom_event_data.client_buffers_list, l, buffer) { @@ -1008,7 +1398,7 @@ _e_eom_get_time_in_mseconds() static Eina_Bool _e_eom_ecore_drm_activate_cb(void *data, int type EINA_UNUSED, void *event) { - /* + /* Ecore_Drm_Event_Activate *e = NULL; E_EomPtr eom = NULL; @@ -1022,15 +1412,16 @@ _e_eom_ecore_drm_activate_cb(void *data, int type EINA_UNUSED, void *event) if (e->active) { - + ; } else { - + ; } end: - */ + +*/ return ECORE_CALLBACK_PASS_ON; } @@ -1312,7 +1703,9 @@ _e_eom_output_info_get(tdm_display *dpy) g_eom->output_count = count - 1; EOM_DBG("external output count : %d\n", g_eom->output_count); - for (i = 0; i < count; i++) + /* skip main output id:0 */ + /* start from 1 */ + for (i = 1; i < count; i++) { const tdm_output_mode *mode = NULL; E_EomOutputPtr new_output = NULL; @@ -1335,11 +1728,6 @@ _e_eom_output_info_get(tdm_display *dpy) err, "tdm_output_get_output_type fail(%d)", ret); - /* skip main output */ - /* TODO: need more check about main display*/ - if ((type == TDM_OUTPUT_TYPE_DSI) || (type == TDM_OUTPUT_TYPE_LVDS)) - continue; - new_output = E_NEW(E_EomOutput, 1); GOTOIFTRUE(new_output == NULL, err, @@ -1356,6 +1744,15 @@ _e_eom_output_info_get(tdm_display *dpy) new_output->type = type; new_output->status = status; new_output->mode = EOM_OUTPUT_MODE_NONE; + new_output->output = output; + + ret = tdm_output_add_change_handler(output, _e_eom_tdm_output_status_change_cb, NULL); + if (ret != TDM_ERROR_NONE) + { + EOM_ERR("tdm_output_add_change_handler fail(%d)", ret); + free(new_output); + goto err; + } if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { @@ -1475,7 +1872,7 @@ _e_eom_init() GOTOIFTRUE(ret == EINA_FALSE, err, "failed init_internal()"); 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); + E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_OUTPUT, _e_eom_ecore_drm_output_cb, g_eom); E_LIST_HANDLER_APPEND(g_eom->handlers, E_EVENT_CLIENT_BUFFER_CHANGE, _e_eom_client_buffer_change, NULL); g_eom->is_external_init = DOWN; diff --git a/src/e_mod_main.h b/src/e_mod_main.h index cc6f056..84d5023 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -12,6 +12,8 @@ #define EOM_WARN(msg, ARG...) WARN("[eom module][%s:%d] "msg"\n", __FUNCTION__, __LINE__, ##ARG) #define EOM_DBG(msg, ARG...) DBG("[eom module][%s:%d] "msg"\n", __FUNCTION__, __LINE__, ##ARG) +#define ALEN(array) (sizeof(array) / sizeof(array)[0]) + #define RETURNIFTRUE(statement, msg, ARG...) \ if (statement) \ { \ @@ -72,6 +74,8 @@ struct _E_Eom_Output unsigned int phys_width; unsigned int phys_height; + tdm_output *output; + tdm_output_conn_status status; E_EomFlag mirror_run; eom_output_attribute_e attribute; @@ -174,9 +178,10 @@ static enum wl_eom_type _e_eom_output_name_to_eom_type(const char *output_name); /* handle internal output, pp */ static Eina_Bool _e_eom_mirror_start(const char *output_name, int width, int height); static tbm_surface_h _e_eom_root_internal_tdm_surface_get(const char *name); -static Eina_Bool _e_eom_pp_src_to_dst( tbm_surface_h src_buffer); +static Eina_Bool _e_eom_pp_src_to_dst(tbm_surface_h src_buffer); static Eina_Bool _e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h); -static void _e_eom_pp_calculate_new_size(int *x, int *new_w, int src_w, int src_h, int dst_w, int dst_h); +static void _e_eom_calculate_fullsize(int src_h, int src_v, int dst_size_h, int dst_size_v, + int *dst_x, int *dst_y, int *dst_w, int *dst_h); /* tdm handlers */ static void _e_eom_pp_cb(tbm_surface_h surface, void *user_data); @@ -184,7 +189,13 @@ static void _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequen unsigned int tv_sec EINA_UNUSED, unsigned int tv_usec EINA_UNUSED, void *user_data); -/* clients buffers */ +/* handle clients buffers + * The work flow is very simple, when a client does commit we take a client's + * buffer and add it to list. During page flip we show that buffer. When a + * new client's buffer has been send we destroy previous buffer and add new + * one to the list. And so on + * We created that list for future possible extending + */ static E_EomClientBufferPtr _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer); static void _e_eom_add_client_buffer_to_list(E_EomClientBufferPtr client_buffer); static void _e_eom_client_buffers_list_free(); -- 2.7.4 From dce0e530d738119609663071dcb63261ebb5026d Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Mon, 30 May 2016 16:28:54 +0300 Subject: [PATCH 09/16] remove pointless functional Change-Id: Idd8c7c620c76f022c67e9420ffbb4a0ee935667f Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 271 ++++--------------------------------------------------- src/e_mod_main.h | 5 +- 2 files changed, 18 insertions(+), 258 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index f06e0ce..858cb28 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -203,101 +203,6 @@ _e_eom_commit_cb(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS } } -static E_Comp_Wl_Output * -_e_eom_e_comp_wl_output_get(const Eina_List *outputs, const char *id) -{ - E_Comp_Wl_Output *output = NULL, *o = NULL; - const Eina_List *l; - int loc = 0; - - if (id == NULL) - return NULL; - - EINA_LIST_FOREACH(outputs, l, o) - { - char *temp_id = NULL; - temp_id = strchr(o->id, '/'); - - if (temp_id == NULL) - { - if (strcmp(o->id, id) == 0) - output = o; - } - else - { - loc = temp_id - o->id; - - if (strncmp(o->id, id, loc) == 0) - output = o; - } - } - - if (!output) - return NULL; - return output; -} - -static Eina_Bool -_e_eom_set_up_external_output(const char *output_name, int width, int height) -{ - tdm_error tdm_err = TDM_ERROR_NONE; - E_EomEventDataPtr eom_data = NULL; - tdm_output *hal_output = NULL; - tdm_layer *hal_layer = NULL; - Eina_Bool ret = EINA_FALSE; - tdm_info_layer layer_info; - - eom_data = &g_eom_event_data; - - hal_output = _e_eom_hal_output_get(output_name); - GOTOIFTRUE(hal_output == NULL, err, "ERROR: get hal output for, (%s)", output_name); - - hal_layer = _e_eom_hal_layer_get(hal_output, width, height); - GOTOIFTRUE(hal_layer == NULL, err, "ERROR: get hal layer"); - - ret = _e_eom_create_output_buffers(eom_data, width, height); - GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: create buffers"); - - /* TODO: Models commited clients buffers */ - _e_eom_create_fake_buffers(width, height); - - tdm_err = tdm_layer_get_info(hal_layer, &layer_info); - GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: get layer info: %d", tdm_err); - - 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); - - g_eom->dst_mode.w = width; - g_eom->dst_mode.h = height; - g_eom->ext_output_name = strdup(output_name); - - eom_data->layer = hal_layer; - eom_data->output = hal_output; - eom_data->current_buffer = 0; - - tdm_err = tdm_layer_set_buffer(hal_layer, eom_data->dst_buffers[eom_data->current_buffer]); - GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: set buffer on layer:%d", tdm_err); -/* - tdm_err = tdm_output_set_dpms(hal_output, TDM_OUTPUT_DPMS_ON); - GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: failed set DPMS on:%d", tdm_err); - - tdm_err = tdm_output_commit(hal_output, 0, _e_eom_commit_cb, eom_data); - GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: commit crtc:%d", tdm_err); -*/ - - return EINA_TRUE; - -err: -/* - * TODO: add deinitialization - */ - return EINA_FALSE; -} - static void _e_eom_deinit_external_output() { @@ -351,73 +256,6 @@ _e_eom_deinit_external_output() g_eom->wl_output = NULL; } -static tdm_output * -_e_eom_hal_output_get(const char *id) -{ - Ecore_Drm_Output *drm_output = NULL, *o = NULL; - const tdm_output_mode *big_mode = NULL; - const tdm_output_mode *modes = NULL; - Ecore_Drm_Device *dev = NULL; - tdm_output *output = NULL; - tdm_error err = TDM_ERROR_NONE; - const Eina_List *l, *ll; - int crtc_id = 0; - int count = 0; - int i = 0; - - /* - * TODO: Temporary take into account only HDMI - */ - EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev) - { -/* EINA_LIST_FOREACH(dev->external_outputs, ll, o)*/ - EINA_LIST_FOREACH(dev->outputs, ll, o) - { - if ((ecore_drm_output_name_get(o)) && (strcmp(id, ecore_drm_output_name_get(o)) == 0)) - drm_output = o; - } - } - - RETURNVALIFTRUE(drm_output == NULL, NULL, "ERROR: drm output was not found"); - - crtc_id = ecore_drm_output_crtc_id_get(drm_output); - RETURNVALIFTRUE(crtc_id == 0, NULL, "ERROR: crtc is 0\n"); - - output = tdm_display_get_output(g_eom->dpy, crtc_id, NULL); - RETURNVALIFTRUE(output == NULL, NULL, "ERROR: there is no HAL output for:%d", crtc_id); - - int min_w, min_h, max_w, max_h, preferred_align; - err = tdm_output_get_available_size(output, &min_w, &min_h, &max_w, &max_h, &preferred_align); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "ERROR: Gent get geometry for hal output"); - - EOM_DBG("HAL size min:%dx%d max:%dx%d alighn:%d\n", - min_w, min_h, max_w, max_h, preferred_align); - - /* - * Force TDM to make setCrtc onto new buffer - */ - err = tdm_output_get_available_modes(output, &modes, &count); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "Get availvable modes filed"); - - big_mode = &modes[0]; - - for (i = 0; i < count; i++) - { - if ((modes[i].vdisplay + modes[i].hdisplay) >= - (big_mode->vdisplay + big_mode->hdisplay)) - big_mode = &modes[i]; - } - - RETURNVALIFTRUE(big_mode == NULL, NULL, "no Big mode\n"); - - EOM_DBG("BIG_MODE: %dx%d\n", big_mode->hdisplay, big_mode->vdisplay); - - err = tdm_output_set_mode(output, big_mode); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "set Mode failed"); - - EOM_DBG("Created output: %p\n", output); - return output; -} static tdm_layer * _e_eom_hal_layer_get(tdm_output *output, int width, int height) @@ -473,6 +311,7 @@ _e_eom_hal_layer_get(tdm_output *output, int width, int height) } /* TODO: Models commited clients buffers */ +/* static void _e_eom_create_fake_buffers(int width, int height) { @@ -499,6 +338,7 @@ _e_eom_create_fake_buffers(int width, int height) err: return; } +*/ static Eina_Bool _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height) @@ -817,15 +657,10 @@ _e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h) static Eina_Bool _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { - enum wl_eom_type eom_type = WL_EOM_TYPE_NONE; - E_Comp_Wl_Output *wl_output = NULL; Ecore_Drm_Event_Output *e = NULL; - struct wl_resource *iterator; char buff[PATH_MAX]; - Eina_List *l; - int ret = 0; - if (!(e = event)) goto err; + if (!(e = event)) return ECORE_CALLBACK_PASS_ON;; EOM_DBG("id:%d (x,y,w,h):(%d,%d,%d,%d) (w_mm,h_mm):(%d,%d) refresh:%d subpixel_order:%d transform:%d make:%s model:%s name:%s plug:%d\n", e->id, e->x, e->y, e->w, e->h, e->phys_width, e->phys_height, e->refresh, e->subpixel_order, e->transform, e->make, e->model, e->name, e->plug); @@ -834,99 +669,27 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e if (e->id == 0) /* main output */ { - g_eom->src_mode.w = e->w; - g_eom->src_mode.h = e->h; - /* TODO: free that memory */ - if (g_eom->int_output_name == NULL) - g_eom->int_output_name = strdup(buff); - } - - if (strcmp(e->name, "HDMI-A-0") == 0) - { - if (e->plug == 1) - { - tdm_error tdm_err = TDM_ERROR_NONE; - - /* Get e_comp_wl_output */ - wl_output = _e_eom_e_comp_wl_output_get(e_comp_wl->outputs, buff); - GOTOIFTRUE(wl_output == NULL, err, "ERROR: there is no wl_output:(%s)\n", buff); - - /* Initialize external output */ - ret = _e_eom_set_up_external_output(buff, e->w, e->h); - GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: initialize external output\n"); - - g_eom->is_external_init = UP; - g_eom->eom_sate = UP; - g_eom->wl_output = wl_output; - g_eom->id = e->id; - - /* get main surface */ - ret = _e_eom_mirror_start(g_eom->int_output_name, g_eom->src_mode.w, g_eom->src_mode.h); - GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: get root surfcae\n"); - - tdm_err = tdm_output_set_dpms(g_eom_event_data.output, TDM_OUTPUT_DPMS_ON); - GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: tdm_output_set_dpms on\n"); - - tdm_err = tdm_output_commit(g_eom_event_data.output, 0, _e_eom_commit_cb, &g_eom_event_data); - GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: commit crtc:%d\n", tdm_err); - - _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_ACTIVE); - _e_eom_set_eom_status(WL_EOM_STATUS_CONNECTION); - _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); - _e_eom_set_eom_mode(WL_EOM_MODE_MIRROR); - } - else - { - g_eom->is_external_init = DOWN; - g_eom->is_internal_grab = DOWN; - g_eom->eom_sate = DOWN; - g_eom->wl_output = NULL; - g_eom->id = -1; - - _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_INACTIVE); - _e_eom_set_eom_status(WL_EOM_STATUS_DISCONNECTION); - _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); - _e_eom_set_eom_mode(WL_EOM_MODE_NONE); - - _e_eom_deinit_external_output(); - } - - eom_type = _e_eom_output_name_to_eom_type(buff); - GOTOIFTRUE(eom_type == WL_EOM_TYPE_NONE, err, "ERROR: eom_type is NONE\n"); - - EINA_LIST_FOREACH(g_eom->eom_clients, l, iterator) + if (e->plug == 1) { - if (iterator) - { - wl_eom_send_output_type(iterator, - g_eom->id, - eom_type, - _e_eom_get_eom_status()); + g_eom->src_mode.w = e->w; + g_eom->src_mode.h = e->h; + if (g_eom->int_output_name == NULL) + g_eom->int_output_name = strdup(buff); - wl_eom_send_output_attribute(iterator, - g_eom->id, - _e_eom_get_eom_attribute(), - _e_eom_get_eom_attribute_state(), - WL_EOM_ERROR_NONE); + g_eom->eom_sate = UP; + } + else + { + g_eom->src_mode.w = -1; + g_eom->src_mode.h = -1; + if (g_eom->int_output_name) + free(g_eom->int_output_name); - wl_eom_send_output_mode(iterator, - g_eom->id, - _e_eom_get_eom_mode()); - } + g_eom->eom_sate = DOWN; } } return ECORE_CALLBACK_PASS_ON; - -err: - _e_eom_deinit_external_output(); - - _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_INACTIVE); - _e_eom_set_eom_status(WL_EOM_STATUS_DISCONNECTION); - _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); - _e_eom_set_eom_mode(WL_EOM_MODE_NONE); - - return ECORE_CALLBACK_PASS_ON; } static const tdm_output_mode * diff --git a/src/e_mod_main.h b/src/e_mod_main.h index 84d5023..a1dfe95 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -168,9 +168,6 @@ struct _E_Eom_Fake_Buffers }; /* handle external output */ -static E_Comp_Wl_Output *_e_eom_e_comp_wl_output_get(const Eina_List *outputs, const char *id); -static Eina_Bool _e_eom_set_up_external_output(const char *output_name, int width, int height); -static tdm_output * _e_eom_hal_output_get(const char *id); static tdm_layer * _e_eom_hal_layer_get(tdm_output *output, int width, int height); static Eina_Bool _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height); static enum wl_eom_type _e_eom_output_name_to_eom_type(const char *output_name); @@ -203,7 +200,7 @@ static E_EomClientBufferPtr _e_eom_get_client_buffer_from_list(); /*eom utils functions*/ static int _e_eom_get_time_in_mseconds(); -static void _e_eom_create_fake_buffers(int width, int height); +/*static void _e_eom_create_fake_buffers(int width, int height);*/ #endif -- 2.7.4 From a2743ee50fe84d235aaf96e2ccae9968a6ae5624 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Thu, 9 Jun 2016 19:12:46 +0900 Subject: [PATCH 10/16] change output status check condition Change-Id: I3f02a0afa423d56fc155a4e2f842dce0cb245fc5 --- src/e_mod_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 858cb28..54203d5 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -774,7 +774,7 @@ _e_eom_get_output_position(void) EINA_LIST_FOREACH(g_eom->outputs, l, eom_output_tmp) { - if (eom_output_tmp->status == TDM_OUTPUT_CONN_STATUS_CONNECTED) + if (eom_output_tmp->status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) x += eom_output_tmp->w; } } @@ -917,7 +917,7 @@ _e_eom_tdm_output_status_change_cb(tdm_output *output, tdm_output_change_type ty plug = value.u32; - if (plug == TDM_OUTPUT_CONN_STATUS_CONNECTED || plug == TDM_OUTPUT_CONN_STATUS_MODE_SETTED) + if (plug == TDM_OUTPUT_CONN_STATUS_CONNECTED) { unsigned int mmWidth, mmHeight, subpixel; const tdm_output_mode *mode; @@ -961,7 +961,7 @@ _e_eom_tdm_output_status_change_cb(tdm_output *output, tdm_output_change_type ty /* TODO: check output mode(presentation set) and HDMI type */ _e_eom_start_mirror(eom_output, mode->hdisplay, mode->vdisplay); } - else /*TDM_OUTPUT_CONN_STATUS_DISCONNECTED*/ + else if (plug == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { if (eom_output->mirror_run == UP) _e_eom_stop_mirror(eom_output); -- 2.7.4 From 008b374b63981921fd9424dd448cbe51bfc5eab7 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Fri, 17 Jun 2016 14:55:56 +0900 Subject: [PATCH 11/16] erase useless file Change-Id: I5c65e84b46aec4d9bcffce7135e2e8a9d6f5db51 --- packaging/e-mod-tizen-eom.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/packaging/e-mod-tizen-eom.spec b/packaging/e-mod-tizen-eom.spec index e0b15fa..bb162a4 100644 --- a/packaging/e-mod-tizen-eom.spec +++ b/packaging/e-mod-tizen-eom.spec @@ -60,6 +60,7 @@ make install DESTDIR=%{buildroot} # clear useless textual files find %{buildroot}%{_libdir}/enlightenment/modules/%{name} -name *.la | xargs rm +find %{buildroot}%{_libdir}/enlightenment/modules/%{name} -name *.a | xargs rm %files %defattr(-,root,root,-) -- 2.7.4 From d9ec829ec40906aec488fd40476374393ca8c48f Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Fri, 10 Jun 2016 11:07:35 +0300 Subject: [PATCH 12/16] basic implementation of multi output supprot. consideration of review remarks The commit is a carcass multi output support and extended mode will be implemented over. It is big and messy commit which represent itself as squash of commits which were not accepted. To fit requirements and review remarks next improvements have been bringed in: 1: code style following 2: none E Module API have been removed 3: EOM protocol does not send output name anymore 4: using none accepted Enlightenment API have been removed from EOM 5: Review remarks have been considered and corrected Change-Id: I4f3a5de25512ca4f948ac0dcbc912152da545801 Signed-off-by: Roman Peresipkyn --- configure.ac | 2 +- packaging/e-mod-tizen-eom.spec | 1 + protocol/eom-client-protocol.h | 30 +- protocol/eom-protocol.c | 1 + protocol/eom-server-protocol.h | 14 +- src/e_mod_main.c | 2353 +++++++++++++++++++++------------------- src/e_mod_main.h | 184 ++-- 7 files changed, 1365 insertions(+), 1220 deletions(-) diff --git a/configure.ac b/configure.ac index 37a7a06..56d3d27 100644 --- a/configure.ac +++ b/configure.ac @@ -35,7 +35,7 @@ fi PKG_CHECK_MODULES(WAYLAND_SCANNER, wayland-scanner) PKG_CHECK_MODULES(WAYLAND, [wayland-server]) -PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment, elementary, eom]) +PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment, elementary, eom, wayland-tbm-server]) dnl ======================================================================== # checks for wayland only argument diff --git a/packaging/e-mod-tizen-eom.spec b/packaging/e-mod-tizen-eom.spec index bb162a4..d0b941d 100644 --- a/packaging/e-mod-tizen-eom.spec +++ b/packaging/e-mod-tizen-eom.spec @@ -19,6 +19,7 @@ BuildRequires: pkgconfig(x11) %if %{with wayland} BuildRequires: pkgconfig(wayland-server) BuildRequires: pkgconfig(libtbm) +BuildRequires: pkgconfig(wayland-tbm-server) %endif BuildRequires: pkgconfig(dlog) %if "%{?profile}" == "common" diff --git a/protocol/eom-client-protocol.h b/protocol/eom-client-protocol.h index d38e84a..9a26b78 100644 --- a/protocol/eom-client-protocol.h +++ b/protocol/eom-client-protocol.h @@ -145,6 +145,8 @@ enum wl_eom_attribute_state { /** * wl_eom - an interface to get the information of the external outputs + * @output_count: (none) + * @output_info: (none) * @output_type: (none) * @output_mode: (none) * @output_attribute: (none) @@ -157,8 +159,8 @@ struct wl_eom_listener { * @count: (none) */ void (*output_count)(void *data, - struct wl_eom *wl_eom, - uint32_t count); + struct wl_eom *wl_eom, + uint32_t count); /** * output_info - (none) * @output_id: (none) @@ -171,16 +173,15 @@ struct wl_eom_listener { * @connection: (none) */ void (*output_info)(void *data, - struct wl_eom *wl_eom, - uint32_t output_id, - uint32_t type, - uint32_t mode, - uint32_t w, - uint32_t h, - uint32_t w_mm, - uint32_t h_mm, - uint32_t connection); - + struct wl_eom *wl_eom, + uint32_t output_id, + uint32_t type, + uint32_t mode, + uint32_t w, + uint32_t h, + uint32_t w_mm, + uint32_t h_mm, + uint32_t connection); /** * output_type - (none) * @output_id: (none) @@ -225,9 +226,10 @@ wl_eom_add_listener(struct wl_eom *wl_eom, } #define WL_EOM_SET_ATTRIBUTE 0 -#define WL_EOM_GET_INFO 1 +#define WL_EOM_GET_OUTPUT_INFO 1 #define WL_EOM_SET_ATTRIBUTE_SINCE_VERSION 1 +#define WL_EOM_GET_OUTPUT_INFO_SINCE_VERSION 1 static inline void wl_eom_set_user_data(struct wl_eom *wl_eom, void *user_data) @@ -264,7 +266,7 @@ static inline void wl_eom_get_output_info(struct wl_eom *wl_eom, uint32_t output_id) { wl_proxy_marshal((struct wl_proxy *) wl_eom, - WL_EOM_GET_INFO, output_id); + WL_EOM_GET_OUTPUT_INFO, output_id); } #ifdef __cplusplus diff --git a/protocol/eom-protocol.c b/protocol/eom-protocol.c index ed56ef6..0568c61 100644 --- a/protocol/eom-protocol.c +++ b/protocol/eom-protocol.c @@ -11,6 +11,7 @@ static const struct wl_interface *types[] = { NULL, NULL, NULL, + NULL, }; static const struct wl_message wl_eom_requests[] = { diff --git a/protocol/eom-server-protocol.h b/protocol/eom-server-protocol.h index 8ee0777..8c0e929 100644 --- a/protocol/eom-server-protocol.h +++ b/protocol/eom-server-protocol.h @@ -146,6 +146,7 @@ enum wl_eom_attribute_state { /** * wl_eom - an interface to get the information of the external outputs * @set_attribute: (none) + * @get_output_info: (none) * * ***** TODO ****** */ @@ -164,8 +165,8 @@ struct wl_eom_interface { * @output_id: (none) */ void (*get_output_info)(struct wl_client *client, - struct wl_resource *resource, - uint32_t output_id); + struct wl_resource *resource, + uint32_t output_id); }; #define WL_EOM_OUTPUT_COUNT 0 @@ -174,19 +175,20 @@ struct wl_eom_interface { #define WL_EOM_OUTPUT_MODE 3 #define WL_EOM_OUTPUT_ATTRIBUTE 4 +#define WL_EOM_OUTPUT_COUNT_SINCE_VERSION 1 +#define WL_EOM_OUTPUT_INFO_SINCE_VERSION 1 #define WL_EOM_OUTPUT_TYPE_SINCE_VERSION 1 #define WL_EOM_OUTPUT_MODE_SINCE_VERSION 1 #define WL_EOM_OUTPUT_ATTRIBUTE_SINCE_VERSION 1 static inline void -wl_eom_send_output_count(struct wl_resource *resource_, uint32_t output_id, uint32_t count) +wl_eom_send_output_count(struct wl_resource *resource_, uint32_t count) { - wl_resource_post_event(resource_, WL_EOM_OUTPUT_COUNT, output_id, count); + wl_resource_post_event(resource_, WL_EOM_OUTPUT_COUNT, count); } static inline void -wl_eom_send_output_info(struct wl_resource *resource_, uint32_t output_id, uint32_t type, uint32_t mode, - uint32_t w, uint32_t h, uint32_t w_mm, uint32_t h_mm, uint32_t connection) +wl_eom_send_output_info(struct wl_resource *resource_, uint32_t output_id, uint32_t type, uint32_t mode, uint32_t w, uint32_t h, uint32_t w_mm, uint32_t h_mm, uint32_t connection) { wl_resource_post_event(resource_, WL_EOM_OUTPUT_INFO, output_id, type, mode, w, h, w_mm, h_mm, connection); } diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 54203d5..06807e0 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -9,12 +9,17 @@ #include "e_mod_main.h" #include "eom-server-protocol.h" #include "Ecore_Drm.h" +#include E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "EOM Module" }; -static E_EomEventData g_eom_event_data; -static E_EomFakeBuffers fake_buffers; static E_EomPtr g_eom = NULL; +static const struct wl_eom_interface _e_eom_wl_implementation = +{ + _e_eom_cb_wl_request_set_attribute, + _e_eom_cb_wl_request_get_output_info +}; + /* EOM Output Attributes +----------------+------------+----------------+-------------+ @@ -45,655 +50,959 @@ static const char *eom_conn_types[] = "DSI", }; -static inline enum wl_eom_mode -_e_eom_get_eom_mode() +////////////////////////////////////////////////////////////////////////////////////////////////////// + +static inline eom_output_mode_e +_e_eom_output_state_get_mode(E_EomOutputPtr output) { - return g_eom->eom_mode; + if (output == NULL) + return EOM_OUTPUT_MODE_NONE; + return output->mode; } static inline void -_e_eom_set_eom_mode(enum wl_eom_mode mode) +_e_eom_output_state_set_mode(E_EomOutputPtr output, eom_output_mode_e mode) { - g_eom->eom_mode = mode; + if (output == NULL) + return; + output->mode = mode; } -static inline enum wl_eom_attribute_state -_e_eom_get_eom_attribute_state() +static inline eom_output_attribute_e +_e_eom_output_state_get_attribute_state(E_EomOutputPtr output) { - return g_eom->eom_attribute_state; + if (output == NULL) + return EOM_OUTPUT_ATTRIBUTE_STATE_NONE; + return output->attribute_state; } static inline void -_e_eom_set_eom_attribute_state(enum wl_eom_attribute_state attribute_state) +_e_eom_output_attribute_state_set(E_EomOutputPtr output, eom_output_attribute_e attribute_state) { - g_eom->eom_attribute_state = attribute_state; + if (output == NULL) + return; + output->attribute_state = attribute_state; } -static inline enum wl_eom_attribute -_e_eom_get_eom_attribute() +static inline eom_output_attribute_e +_e_eom_output_state_get_attribute(E_EomOutputPtr output) { - return g_eom->eom_attribute; + if (output == NULL) + return EOM_OUTPUT_ATTRIBUTE_NONE; + return output->attribute; } static inline void -_e_eom_set_eom_attribute_by_current_client(enum wl_eom_attribute attribute) +_e_eom_output_state_set_force_attribute(E_EomOutputPtr output, eom_output_attribute_e attribute) { - g_eom->eom_attribute = attribute; + if (output == NULL) + return; + output->attribute = attribute; } static inline Eina_Bool -_e_eom_set_eom_attribute(enum wl_eom_attribute attribute) +_e_eom_output_state_set_attribute(E_EomOutputPtr output, eom_output_attribute_e attribute) { - if (attribute == WL_EOM_ATTRIBUTE_NONE || g_eom->eom_attribute == WL_EOM_ATTRIBUTE_NONE) + if (output == NULL) + return EINA_FALSE; + + if (attribute == EOM_OUTPUT_ATTRIBUTE_NONE || output->attribute == EOM_OUTPUT_ATTRIBUTE_NONE) { - g_eom->eom_attribute = attribute; + output->attribute = attribute; return EINA_TRUE; } - if (eom_output_attributes[g_eom->eom_attribute - 1][attribute - 1] == 1) + if (eom_output_attributes[output->attribute - 1][attribute - 1] == 1) { - g_eom->eom_attribute = attribute; + output->attribute = attribute; return EINA_TRUE; } return EINA_FALSE; } -static inline enum wl_eom_status -_e_eom_get_eom_status() +static inline tdm_output_conn_status +_e_eom_output_state_get_status(E_EomOutputPtr output) { - return g_eom->eom_status; + if (output == NULL) + return TDM_OUTPUT_CONN_STATUS_DISCONNECTED; + return output->status; } static inline void -_e_eom_set_eom_status(enum wl_eom_status status) +_e_eom_output_state_set_status(E_EomOutputPtr output, tdm_output_conn_status status) { - g_eom->eom_status = status; + if (output == NULL) + return; + output->status = status; } static void -_e_eom_pp_cb(tbm_surface_h surface, void *user_data) +_e_eom_cb_wl_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) { - tdm_error tdm_err = TDM_ERROR_NONE; - E_EomEventDataPtr eom_data = NULL; + struct wl_resource *resource = NULL; + E_EomClientPtr new_client = NULL; - RETURNIFTRUE(user_data == NULL, "ERROR: PP EVENT: user data is NULL"); + RETURNIFTRUE(data == NULL, "ERROR: data is NULL"); - eom_data = (E_EomEventDataPtr)user_data; + E_EomPtr eom = data; - tdm_buffer_remove_release_handler(eom_data->dst_buffers[eom_data->pp_buffer], - _e_eom_pp_cb, eom_data); + resource = wl_resource_create(client, + &wl_eom_interface, + MIN(version, 1), + id); + if (resource == NULL) + { + EOM_ERR("error. resource is null. (version :%d, id:%d)\n", version, id); + wl_client_post_no_memory(client); + return; + } - /* Stop EOM */ - if (g_eom->eom_sate != UP) - return; + wl_resource_set_implementation(resource, + &_e_eom_wl_implementation, + eom, + _e_eom_cb_wl_resource_destory); - /* TODO: lock that flag??? */ - /* If a client has committed its buffer stop mirror mode */ - if (g_eom->is_mirror_mode == DOWN) - return; + EOM_DBG("send - output count : %d\n", g_eom->output_count); - tbm_surface_h src_buffer; - src_buffer = _e_eom_root_internal_tdm_surface_get(g_eom->int_output_name); - RETURNIFTRUE(src_buffer == NULL, "ERROR: PP EVENT: get root tdm surface"); + wl_eom_send_output_count(resource, g_eom->output_count); - g_eom_event_data.pp_buffer = !g_eom_event_data.current_buffer; + if (g_eom->outputs) + { + Eina_List *l; + E_EomOutputPtr output = NULL; - tdm_err = tdm_buffer_add_release_handler(g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer], - _e_eom_pp_cb, &g_eom_event_data); - RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "ERROR: PP EVENT: set pp hadler:%d", tdm_err ); + EINA_LIST_FOREACH(g_eom->outputs, l, output) + { + EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d\n", + output->id, output->type, output->mode, output->width, output->height, + output->phys_width, output->phys_height, output->status); + wl_eom_send_output_info(resource, output->id, output->type, output->mode, output->width, output->height, + output->phys_width, output->phys_height, output->status); - tdm_err = tdm_pp_attach(eom_data->pp, src_buffer, g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer]); - RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "ERROR: pp attach:%d\n", tdm_err); + wl_eom_send_output_attribute(resource, + output->id, + _e_eom_output_state_get_attribute(output), + _e_eom_output_state_get_attribute_state(output), + EOM_ERROR_NONE); + } + } - tdm_err = tdm_pp_commit(g_eom_event_data.pp); - RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "ERROR: PP EVENT: pp commit:%d", tdm_err ); + new_client = E_NEW(E_EomClient, 1); + if (new_client == NULL) + { + EOM_ERR("allocate new client"); + /*TODO: should resource be deleted?*/ + return; + } + + new_client->resource = resource; + new_client->current = EINA_FALSE; + new_client->output_id = -1; + new_client->buffers = NULL; + + g_eom->clients = eina_list_append(g_eom->clients, new_client); } static void -_e_eom_commit_cb(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) +_e_eom_cb_wl_resource_destory(struct wl_resource *resource) { - E_EomClientBufferPtr client_buffer = NULL; - E_EomEventDataPtr eom_data = NULL; - tdm_error err = TDM_ERROR_NONE; - - RETURNIFTRUE(user_data == NULL, "ERROR: PP EVENT: user data is NULL"); - - eom_data = (E_EomEventDataPtr)user_data; + E_EomClientPtr client = NULL, iterator = NULL; + E_EomOutputPtr output = NULL; + Eina_List *l = NULL; + Eina_Bool ret; - /* Stop EOM */ - if (g_eom->eom_sate != UP) - return; + EOM_DBG("client unbind\n"); - /* TODO: Maybe better to separating that callback on to mirror and extended callbacks */ - if (g_eom->is_mirror_mode == UP) - { - if (eom_data->current_buffer == 1) - { - eom_data->current_buffer = 0; - - err = tdm_layer_set_buffer(eom_data->layer, - eom_data->dst_buffers[!eom_data->pp_buffer]); - RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: EVENT: set buffer 0 err:%d", err); - } - else - { - eom_data->current_buffer = 1; - - err = tdm_layer_set_buffer(eom_data->layer, - eom_data->dst_buffers[!eom_data->pp_buffer]); - RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: EVENT: set buffer 1 err:%d", err); - } - - err = tdm_output_commit(eom_data->output, 0, _e_eom_commit_cb, eom_data); - RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: EVENT commit"); - } - else - { - client_buffer = _e_eom_get_client_buffer_from_list(); - RETURNIFTRUE(client_buffer == NULL, "ERROR: EVENT: client buffer is NULL"); + client = _e_eom_client_get_by_resource(resource); + RETURNIFTRUE(client == NULL, "destroy client: client is NULL"); - err = tdm_layer_set_buffer(eom_data->layer, client_buffer->tbm_buffer); - RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: EVENT: set buffer 1"); + g_eom->clients = eina_list_remove(g_eom->clients, client); - err = tdm_output_commit(eom_data->output, 0, _e_eom_commit_cb, eom_data); - RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: EVENT: commit"); - } -} + /* If it is not current client do nothing */ + GOTOIFTRUE(client->current == EINA_FALSE, end2, ""); -static void -_e_eom_deinit_external_output() -{ - tdm_error err = TDM_ERROR_NONE; - int i = 0; + output = _e_eom_output_get_by_id(client->output_id); + GOTOIFTRUE(output == NULL, end2, "destroy client: client is NULL"); - if (g_eom_event_data.layer) - { - err = tdm_layer_unset_buffer(g_eom_event_data.layer); - if (err != TDM_ERROR_NONE) - EOM_DBG("EXT OUTPUT DEINIT: fail unset buffer:%d\n", err); - else - EOM_DBG("EXT OUTPUT DEINIT: ok unset buffer:%d\n", err); + _e_eom_client_free_buffers(client); - err = tdm_output_commit(g_eom_event_data.output, 0, NULL, &g_eom_event_data); - if (err != TDM_ERROR_NONE) - EOM_DBG ("EXT OUTPUT DEINIT: fail commit:%d\n", err); - else - EOM_DBG("EXT OUTPUT DEINIT: ok commit:%d\n", err); - } + _e_eom_output_state_set_mode(output, EOM_OUTPUT_MODE_MIRROR); + ret = _e_eom_output_state_set_attribute(output, EOM_OUTPUT_ATTRIBUTE_NONE); + (void)ret; - /* TODO: do I need to do DPMS off? */ - err = tdm_output_set_dpms(g_eom_event_data.output, TDM_OUTPUT_DPMS_OFF); - if (err != TDM_ERROR_NONE) - EOM_ERR("EXT OUTPUT DEINIT: failed set DPMS off:%d\n", err); + /* TODO: process case when output is not connected */ + if (output->state == NONE) + goto end; - for (i = 0; i < NUM_MAIN_BUF; i++) + /* If a client has been disconnected and mirror mode has not + * been restored, start mirror mode + */ + if (output->state != MIRROR) { - tdm_buffer_remove_release_handler(g_eom_event_data.dst_buffers[i], - _e_eom_pp_cb, &g_eom_event_data); - if (g_eom_event_data.dst_buffers[i]) - tbm_surface_destroy(g_eom_event_data.dst_buffers[i]); - } + output->state = MIRROR; - if (g_eom->eom_sate == DOWN) - _e_eom_client_buffers_list_free(g_eom->eom_clients); + ret = _e_eom_output_start_pp(output); + GOTOIFTRUE(ret == EINA_FALSE, end, + "ERROR: restore mirror mode after a client disconnection\n"); + } - if (g_eom->int_output_name) +end: + /* Notify eom clients which are binded to a concrete output that the + * state and mode of the output has been changed */ + EINA_LIST_FOREACH(g_eom->clients, l, iterator) { - free(g_eom->int_output_name); - g_eom->int_output_name = NULL; + if (iterator && iterator->output_id == output->id) + { + wl_eom_send_output_attribute(iterator->resource, + output->id, + _e_eom_output_state_get_attribute(output), + _e_eom_output_state_get_attribute_state(output), + EOM_OUTPUT_MODE_NONE); + + wl_eom_send_output_mode(iterator->resource, + output->id, + _e_eom_output_state_get_mode(output)); + } } - if (g_eom->ext_output_name) - { - free(g_eom->ext_output_name); - g_eom->ext_output_name = NULL; - } - - if (g_eom->wl_output) - g_eom->wl_output = NULL; +end2: + free(client); } - -static tdm_layer * -_e_eom_hal_layer_get(tdm_output *output, int width, int height) +static Eina_Bool +_e_eom_cb_ecore_drm_output(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { - int i = 0; - int count = 0; - tdm_layer *layer = NULL; - tdm_error err = TDM_ERROR_NONE; - tdm_layer_capability capa; - tdm_info_layer layer_info; + Ecore_Drm_Event_Output *e = NULL; + char buff[PATH_MAX]; + + if (!(e = event)) return ECORE_CALLBACK_PASS_ON;; + EOM_DBG("id:%d (x,y,w,h):(%d,%d,%d,%d) (w_mm,h_mm):(%d,%d) refresh:%d subpixel_order:%d transform:%d make:%s model:%s name:%s plug:%d\n", + e->id, e->x, e->y, e->w, e->h, e->phys_width, e->phys_height, e->refresh, e->subpixel_order, e->transform, e->make, e->model, e->name, e->plug); - 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; - } + snprintf(buff, sizeof(buff), "%s", e->name); - for (i = 0; i < count; i++) + /* main output */ + if (e->id == 0) { - layer = (tdm_layer *)tdm_output_get_layer(output, i, &err); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_output_get_layer fail(%d)\n", err); - - err = tdm_layer_get_capabilities(layer, &capa); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_layer_get_capabilities fail(%d)\n", err); + if (e->plug == 1) + { + g_eom->width = e->w; + g_eom->height = e->h; + if (g_eom->main_output_name == NULL) + g_eom->main_output_name = strdup(buff); - if (capa & TDM_LAYER_CAPABILITY_PRIMARY) + g_eom->main_output_state = UP; + } + else { - EOM_DBG("TDM_LAYER_CAPABILITY_PRIMARY layer found : %d\n", i); - break; + g_eom->width = -1; + g_eom->height = -1; + if (g_eom->main_output_name) + free(g_eom->main_output_name); + + g_eom->main_output_state = DOWN; } } - memset(&layer_info, 0x0, sizeof(tdm_info_layer)); - layer_info.src_config.size.h = width; - layer_info.src_config.size.v = height; - layer_info.src_config.pos.x = 0; - layer_info.src_config.pos.y = 0; - layer_info.src_config.pos.w = width; - layer_info.src_config.pos.h = height; - layer_info.src_config.format = TBM_FORMAT_ARGB8888; - layer_info.dst_pos.x = 0; - layer_info.dst_pos.y = 0; - layer_info.dst_pos.w = width; - layer_info.dst_pos.h = height; - layer_info.transform = TDM_TRANSFORM_NORMAL; - - err = tdm_layer_set_info(layer, &layer_info); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_layer_set_info fail(%d)\n", err); - - return layer; + return ECORE_CALLBACK_PASS_ON; } -/* TODO: Models commited clients buffers */ -/* -static void -_e_eom_create_fake_buffers(int width, int height) +static Eina_Bool +_e_eom_cb_ecore_drm_activate(void *data, int type EINA_UNUSED, void *event) { - tbm_surface_info_s buffer_info; - tbm_surface_h buffer = NULL; + /* + Ecore_Drm_Event_Activate *e = NULL; + E_EomPtr eom = NULL; - buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - GOTOIFTRUE(buffer == NULL, err, "can not create fake_buffer\n"); + EOM_DBG("_e_eom_cb_ecore_drm_activate called\n"); - 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) + if ((!event) || (!data)) goto end; + e = event; + eom = data; + + EOM_DBG("e->active:%d\n", e->active); + + if (e->active) { - EOM_DBG("can not mmap fake_buffer\n"); - goto err; + ; + } + else + { + ; } - memset(buffer_info.planes[0].ptr, 0xFF, buffer_info.planes[0].size); - tbm_surface_unmap(buffer); - - fake_buffers.fake_buffers[0] = buffer; +end: -err: - return; -} */ + return ECORE_CALLBACK_PASS_ON; +} static Eina_Bool -_e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height) +_e_eom_cb_client_buffer_change(void *data, int type, void *event) { - tbm_surface_info_s buffer_info; - tbm_surface_h buffer = NULL; - - /* - * TODO: Add support of other formats - */ - buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - GOTOIFTRUE(buffer == NULL, err, "can not create dst_buffer 1"); + E_Comp_Wl_Buffer *external_wl_buffer = NULL; + E_EomClientBufferPtr client_buffer = NULL; + E_EomClientPtr client = NULL; + E_EomOutputPtr output = NULL; + E_Event_Client *ev = event; + E_Client *ec = NULL; + const char *output_name = NULL; + tbm_surface_h external_tbm_buffer = NULL; +/* + tbm_surface_info_s surface_info; + int ret; +*/ - /* - * TODO: temp code for testing, actual convert will be in _e_eom_put_src_to_dst() - */ + EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON); + EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON); - 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) + ec = ev->ec; + if (e_object_is_del(E_OBJECT(ec))) { - EOM_DBG("can not mmap buffer\n"); - goto err; + EOM_ERR("ERROR: BUFF CHANGE: ec objects is del\n"); + return ECORE_CALLBACK_PASS_ON; } - memset(buffer_info.planes[0].ptr, 0x0, buffer_info.planes[0].size); - tbm_surface_unmap(buffer); + /* TODO: implemente new client's buffers hooking mechanism */ + return ECORE_CALLBACK_PASS_ON; - eom_data->dst_buffers[0] = buffer; + output = _e_eom_output_get_by_name(output_name); + RETURNVALIFTRUE(output == NULL, + ECORE_CALLBACK_PASS_ON, + "ERROR:BUFF CHANGE: eom_output is NULL\n"); - /* - * TODO: Add support of other formats - */ - buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - GOTOIFTRUE(buffer == NULL, err, "can not create dst_buffer 2"); + if (ec->pixmap == NULL) + return ECORE_CALLBACK_PASS_ON; - /* - * TODO: temp code for testing, actual convert will be in _e_eom_put_src_to_dst() - */ - memset(&buffer_info, 0x00, sizeof(tbm_surface_info_s)); - if (tbm_surface_map(buffer, - TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, - &buffer_info) != TBM_SURFACE_ERROR_NONE) + external_wl_buffer = e_pixmap_resource_get(ec->pixmap); + RETURNVALIFTRUE(external_wl_buffer == NULL, + ECORE_CALLBACK_PASS_ON, + "ERROR:BUFF CHANGE: wl buffer is NULL\n"); +/* + EOM_DBG("BUFF CHANGE: wl_buff:%dx%d type:%d", + external_wl_buffer->w, + external_wl_buffer->h, + external_wl_buffer->type); +*/ + + /* TODO: support buffers smaller then output resolution */ + if (external_wl_buffer->w != output->width || + external_wl_buffer->h != output->height ) { - EOM_DBG("can not mmap buffer\n"); - goto err; + EOM_ERR("BUFF CHANGE: ERROR: tbm_buffer does not fit output's resolution"); + return ECORE_CALLBACK_PASS_ON; } - memset(buffer_info.planes[0].ptr, 0x0, buffer_info.planes[0].size); - tbm_surface_unmap(buffer); - - eom_data->dst_buffers[1] = buffer; + /* TODO: support different external_wl_buffer->type */ - return EINA_TRUE; + if (external_wl_buffer->resource == NULL) + { + EOM_ERR("ERROR: BUFF CHANGE: resource is NULL\n"); + return ECORE_CALLBACK_PASS_ON; + } -err: + external_tbm_buffer = wayland_tbm_server_get_surface( + e_comp->wl_comp_data->tbm.server, + external_wl_buffer->resource); + if (external_tbm_buffer == NULL) + { + EOM_ERR("ERROR: BUFF CHANGE: client tbm buffer is NULL\n"); + return ECORE_CALLBACK_PASS_ON; + } -/* - * Add deinitialization - */ - return EINA_FALSE; -} + EOM_DBG("BUFF CHANGE: tbm_buffer %p", external_tbm_buffer); -static enum wl_eom_type -_e_eom_output_name_to_eom_type(const char *output_name) -{ - enum wl_eom_type eom_type; +#if 0 + _e_eom_util_draw(external_tbm_buffer); +#endif - if (output_name == NULL) - return WL_EOM_TYPE_NONE; + /* mmap that buffer to get width and height for test's sake */ + /* + memset(&surface_info, 0, sizeof(tbm_surface_info_s)); + ret = tbm_surface_map(external_tbm_buffer, TBM_SURF_OPTION_READ | + TBM_SURF_OPTION_WRITE, &surface_info); + if (ret != TBM_SURFACE_ERROR_NONE) + { + EOM_ERR("BUFF CHANGE: failed mmap buffer: %d", ret); + return ECORE_CALLBACK_PASS_ON; + } - /* TODO: Add other external outputs */ - if (strcmp(output_name, "HDMI-A-0") == 0) - eom_type = WL_EOM_TYPE_HDMIA; - else - eom_type = WL_EOM_TYPE_NONE; + EOM_DBG("BUFF CHANGE: tbm_buffer: %dx%d", surface_info.width, surface_info.height); - return eom_type; + tbm_surface_unmap(external_tbm_buffer); + */ + + client_buffer = _e_eom_util_create_client_buffer(external_wl_buffer, external_tbm_buffer); + /* client_buffer = _e_eom_util_create_client_buffer(external_wl_buffer, output->fake_buffer); */ + RETURNVALIFTRUE(client_buffer == NULL, + ECORE_CALLBACK_PASS_ON, + "ERROR: BUFF CHANGE: alloc client buffer"); + + /* TODO: What if not current client has committed a buffer */ + client = _e_eom_client_current_by_id_get(output->id); + if (client == NULL) + { + EOM_ERR("ERROR: BUFF CHANGE: current client is NULL"); + E_FREE(client_buffer); + return ECORE_CALLBACK_PASS_ON; + } + + _e_eom_client_add_buffer(client, client_buffer); + + output->state = PRESENTATION; + + return ECORE_CALLBACK_PASS_ON; } -static Eina_Bool -_e_eom_mirror_start(const char *output_name, int width, int height) +static void +_e_eom_cb_pp(tbm_surface_h surface, void *user_data) { - /* should be changed in HWC enable environment */ - tbm_surface_info_s src_buffer_info; - tbm_surface_h src_buffer = NULL; - Eina_Bool ret = EINA_FALSE; + tdm_error tdm_err = TDM_ERROR_NONE; + E_EomOutputPtr eom_output = NULL; - src_buffer = _e_eom_root_internal_tdm_surface_get(output_name); - RETURNVALIFTRUE(src_buffer == NULL, EINA_FALSE, "ERROR: get root tdm surfcae\n"); + eom_output = (E_EomOutputPtr)user_data; + RETURNIFTRUE(user_data == NULL, "ERROR: PP EVENT: user data is NULL"); - tbm_surface_get_info(src_buffer, &src_buffer_info ); + tdm_buffer_remove_release_handler(eom_output->dst_buffers[eom_output->pp_buffer], + _e_eom_cb_pp, eom_output); - EOM_DBG("FRAMEBUFFER TDM: %dx%d bpp:%d size:%d", - src_buffer_info.width, src_buffer_info.height, - src_buffer_info.bpp, src_buffer_info.size); + /* TODO: lock these flags??? */ + if (g_eom->main_output_state == DOWN) + return; - /* - g_eom->src_mode.w = width; - g_eom->src_mode.h = height; - g_eom->int_output_name = strdup(output_name); - */ + /* If a client has committed its buffer stop mirror mode */ + if (eom_output->state != MIRROR) + return; - /* TODO: if internal and external outputs are equal */ - ret = _e_eom_pp_is_needed(g_eom->src_mode.w, g_eom->src_mode.h, - g_eom->dst_mode.w, g_eom->dst_mode.h); - RETURNVALIFTRUE(ret == EINA_FALSE, EINA_TRUE, "pp is not required\n"); + tbm_surface_h src_buffer; + src_buffer = _e_eom_util_get_output_surface(g_eom->main_output_name); + RETURNIFTRUE(src_buffer == NULL, "ERROR: PP EVENT: get root tdm surface"); - ret = _e_eom_pp_src_to_dst(src_buffer); - RETURNVALIFTRUE(ret == EINA_FALSE, EINA_FALSE, "ERROR: init pp\n"); + /*TODO: rewrite the mirror mode buffer's switching */ + eom_output->pp_buffer ^= 1; - return EINA_TRUE; + tdm_err = tdm_buffer_add_release_handler(eom_output->dst_buffers[eom_output->pp_buffer], + _e_eom_cb_pp, eom_output); + RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "ERROR: PP EVENT: set pp hadler:%d", tdm_err ); + + tdm_err = tdm_pp_attach(eom_output->pp, src_buffer, eom_output->dst_buffers[eom_output->pp_buffer]); + RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "ERROR: pp attach:%d\n", tdm_err); + + tdm_err = tdm_pp_commit(eom_output->pp); + RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "ERROR: PP EVENT: pp commit:%d", tdm_err ); } -static tbm_surface_h -_e_eom_root_internal_tdm_surface_get(const char *name) +static void +_e_eom_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) { - Ecore_Drm_Output *primary_output = NULL; - Ecore_Drm_Device *dev; - const Eina_List *l; -#if 0 - Ecore_Drm_Fb *fb; -#else - tdm_output *tdm_output_obj = NULL; - tbm_surface_h tbm = NULL; + E_EomClientBufferPtr client_buffer = NULL; + E_EomOutputPtr eom_output = NULL; + E_EomClientPtr eom_client = NULL; tdm_error err = TDM_ERROR_NONE; - int count = 0, i = 0; -#endif - EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev) + eom_output = (E_EomOutputPtr)user_data; + RETURNIFTRUE(user_data == NULL, "ERROR: COMMIT EVENT: user data is NULL"); + + if (g_eom->main_output_state == DOWN) + return; + + /* TODO: Maybe better to separating that callback on to mirror and extended callbacks */ + if (eom_output->state == MIRROR) { - primary_output = ecore_drm_device_output_name_find(dev, name); - if (primary_output != NULL) - break; + /*TODO: rewrite the mirror mode buffer's switching */ + eom_output->current_buffer ^= 1; + err = tdm_layer_set_buffer(eom_output->layer, + eom_output->dst_buffers[eom_output->current_buffer]); + + RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: COMMIT EVENT: MIRROR: set buffer 0 err:%d", err); + + err = tdm_output_commit(eom_output->output, 0, _e_eom_cb_commit, eom_output); + RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: COMMIT EVENT: MIRROR: commit"); } + else if (eom_output->state == PRESENTATION) + { + eom_client = _e_eom_client_current_by_id_get(eom_output->id); -#if 0 - RETURNVALIFTRUE(primary_output == NULL, NULL, - "ERROR: get primary output.(%s)\n", - name); - - /* I think it is more convenient than one upon, but E took first - * output as primary and it can be not internal output - * - primary_output = ecore_drm_output_primary_get(); - RETURNVALIFTRUE(primary_output == NULL, NULL, "ERROR: get primary output\n"); - */ -#else + client_buffer = _e_eom_client_get_buffer(eom_client); + RETURNIFTRUE(client_buffer == NULL, "ERROR: COMMIT EVENT: PRESENTATION: client buffer is NULL"); - if (primary_output == NULL) + err = tdm_layer_set_buffer(eom_output->layer, client_buffer->tbm_buffer); + RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: COMMIT EVENT: PRESENTATION: set client buffer"); + + err = tdm_output_commit(eom_output->output, 0, _e_eom_cb_commit, eom_output); + RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: COMMIT EVENT: PRESENTATION: commit"); + } +} + +static void +_e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type type, tdm_value value, void *user_data) +{ + tdm_output_type tdm_type; + tdm_error ret = TDM_ERROR_NONE; + tdm_output_conn_status status; + tdm_output_conn_status status2; + const char *maker = NULL, *model = NULL, *name = NULL; + const char *tmp_name; + char new_name[DRM_CONNECTOR_NAME_LEN]; + E_EomOutputPtr eom_output = NULL; + tdm_output_conn_status plug; + E_EomClientPtr iterator = NULL; + Eina_List *l; + + if (type == TDM_OUTPUT_CHANGE_DPMS || g_eom->main_output_state == DOWN) + return; + + if (g_eom->outputs) { - EOM_ERR("ERROR: get primary output.(%s)\n", name); - EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev) - { - primary_output = ecore_drm_output_primary_get(dev); - if (primary_output != NULL) - break; - } + Eina_List *l; + E_EomOutputPtr eom_output_tmp; - if (primary_output == NULL) + EINA_LIST_FOREACH(g_eom->outputs, l, eom_output_tmp) { - EOM_ERR("ERROR: get primary output.(%s)\n", name); - return NULL; + if (eom_output_tmp->output == output) + eom_output = eom_output_tmp; } } -#endif -#if 0 - fb = ecore_drm_display_output_primary_layer_fb_get(primary_output); - RETURNVALIFTRUE(fb == NULL, NULL, "ERROR: get primary frambuffer\n"); - /*EOM_DBG("FRAMEBUFFER ECORE_DRM: is_client:%d mode%dx%d\n", fb->from_client, fb->w, fb->h);*/ + ret = tdm_output_get_output_type(output, &tdm_type); + RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_output_type fail(%d)", ret); - return (tbm_surface_h)fb->hal_buffer; -#else - tdm_output_obj = tdm_display_get_output(g_eom->dpy, 0, &err); - if (tdm_output_obj == NULL || err != TDM_ERROR_NONE) + ret = tdm_output_get_model_info(output, &maker, &model, &name); + RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_model_info fail(%d)", ret); + + ret = tdm_output_get_conn_status(output, &status); + RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_conn_status fail(%d)", ret); + + status2 = value.u32; + + EOM_DBG("id (%d), type(%d, %d), status(%d, %d) (%s,%s,%s)", eom_output->id, type, tdm_type, status, status2, maker, model, name); + + if (tdm_type < ALEN(eom_conn_types)) + tmp_name = eom_conn_types[tdm_type]; + else + tmp_name = "unknown"; + /*TODO: What if there will more then one output of same type. + *e.g. "HDMI and HDMI" "LVDS and LVDS"*/ + snprintf(new_name, sizeof(new_name), "%s-%d", tmp_name, 0); + + plug = value.u32; + + if (plug == TDM_OUTPUT_CONN_STATUS_CONNECTED || plug == TDM_OUTPUT_CONN_STATUS_MODE_SETTED) { - EOM_ERR("tdm_display_get_output 0 fail\n"); - return NULL; + unsigned int mmWidth, mmHeight, subpixel; + const tdm_output_mode *mode; + int x = 0; + + ret = tdm_output_get_physical_size(output, &mmWidth, &mmHeight); + RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_physical_size fail(%d)", ret); + + ret = tdm_output_get_subpixel(output, &subpixel); + RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_subpixel fail(%d)", ret); + + mode = _e_eom_output_get_best_mode(output); + RETURNIFTRUE(mode == NULL, "_e_eom_get_best_resolution fail"); + + ret = tdm_output_set_mode(output, mode); + RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_set_mode fail(%d)", ret); + + x = _e_eom_output_get_position(); + EOM_DBG("mode: %dx%d, phy(%dx%d), pos(%d,0), refresh:%d, subpixel:%d", + mode->hdisplay, mode->vdisplay, mmWidth, mmHeight, x, mode->vrefresh, subpixel); + + /* model is substituted with new_name. + * It used to bind wl_output with eom_output in libeom. */ + if (!e_comp_wl_output_init(new_name, maker, new_name, x, 0, + mode->hdisplay, mode->vdisplay, + mmWidth, mmHeight, mode->vrefresh, subpixel, 0)) + { + EOM_ERR("Could not setup new output: %s", new_name); + return; + } + EOM_DBG("Setup new output: %s", new_name); + + /* update eom_output connect */ + eom_output->width = mode->hdisplay; + eom_output->height = mode->vdisplay; + eom_output->phys_width = mmWidth; + eom_output->phys_height = mmHeight; + eom_output->status = plug; + eom_output->name = eina_stringshare_add(new_name); + eom_output->type = (eom_output_type_e)tdm_type; + + /* Create fake buffer */ + eom_output->fake_buffer = _e_eom_util_create_fake_buffer(eom_output->width, eom_output->height); + + /* TODO: check output mode(presentation set) and HDMI type */ + _e_eom_output_start_mirror(eom_output, mode->hdisplay, mode->vdisplay); + + /* If there were previously connected clients to the output - notify them */ + EINA_LIST_FOREACH(g_eom->clients, l, iterator) + { + if (iterator) + { + EOM_DBG("Send MIRROR ON notification to clients"); + + wl_eom_send_output_info(iterator->resource, eom_output->id, + eom_output->type, eom_output->mode, + eom_output->width, eom_output->height, + eom_output->phys_width, eom_output->phys_height, + eom_output->status); + + wl_eom_send_output_attribute(iterator->resource, + eom_output->id, + _e_eom_output_state_get_attribute(eom_output), + _e_eom_output_state_get_attribute_state(eom_output), + EOM_ERROR_NONE); + } + } } - err = tdm_output_get_layer_count(tdm_output_obj, &count); - if (err != TDM_ERROR_NONE) + else /*TDM_OUTPUT_CONN_STATUS_DISCONNECTED*/ { - EOM_ERR("tdm_output_get_layer_count fail\n"); - return NULL; - } + if (eom_output->state == MIRROR) + _e_eom_output_stop_mirror(eom_output); - for (i = 0; i < count; i++) - { - tdm_layer *layer = tdm_output_get_layer(tdm_output_obj, i, NULL); - tdm_layer_capability capabilities = 0; - tdm_layer_get_capabilities(layer, &capabilities); - if (capabilities & TDM_LAYER_CAPABILITY_PRIMARY) + /* update eom_output disconnect */ + eom_output->width = 0; + eom_output->height = 0; + eom_output->phys_width = 0; + eom_output->phys_height = 0; + eom_output->status = plug; + + /* If there were previously connected clients to the output - notify them */ + EINA_LIST_FOREACH(g_eom->clients, l, iterator) { - tbm = tdm_layer_get_displaying_buffer(layer, &err); - if (err != TDM_ERROR_NONE) + if (iterator) { - EOM_ERR("tdm_layer_get_displaying_buffer fail\n"); - return NULL; + EOM_DBG("Send MIRROR OFF notification to clients"); + + wl_eom_send_output_info(iterator->resource, eom_output->id, + eom_output->type, eom_output->mode, + eom_output->width, eom_output->height, + eom_output->phys_width, eom_output->phys_height, + eom_output->status); + + wl_eom_send_output_attribute(iterator->resource, + eom_output->id, + _e_eom_output_state_get_attribute(eom_output), + EOM_OUTPUT_ATTRIBUTE_STATE_LOST, + EOM_ERROR_NONE); } - break; - } - } + } - return tbm; -#endif + if (eom_output->fake_buffer) + tbm_surface_destroy(eom_output->fake_buffer); + + e_comp_wl_output_remove(new_name); + EOM_DBG("Destory output: %s", new_name); + eina_stringshare_del(eom_output->name); + } } static void -_e_eom_calculate_fullsize(int src_h, int src_v, int dst_size_h, int dst_size_v, - int *dst_x, int *dst_y, int *dst_w, int *dst_h) +_e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, uint32_t attribute) { - double h_ratio, v_ratio; + eom_error_e eom_error = EOM_ERROR_NONE; + E_EomClientPtr eom_client = NULL, iterator = NULL; + E_EomOutputPtr eom_output = NULL; + Eina_Bool changes = EINA_FALSE; + Eina_Bool mode_change = EINA_FALSE; + Eina_Bool ret = EINA_FALSE; + Eina_List *l; - h_ratio = src_h / dst_size_h; - v_ratio = src_v / dst_size_v; + eom_client = _e_eom_client_get_by_resource(resource); + RETURNIFTRUE(eom_client == NULL, "client is NULL"); - if (h_ratio == v_ratio) + /* Bind the client with a concrete output */ + if (eom_client->output_id == -1) + eom_client->output_id = output_id; + + eom_output = _e_eom_output_get_by_id(output_id); + GOTOIFTRUE(eom_output == NULL, no_output, "output is NULL"); + + if (eom_client->current == EINA_TRUE && eom_output->id == eom_client->output_id) { - *dst_x = 0; - *dst_y = 0; - *dst_w = dst_size_h; - *dst_h = dst_size_v; + /* Current client can set any flag it wants */ + _e_eom_output_state_set_force_attribute(eom_output, attribute); + changes = EINA_TRUE; } - else if (h_ratio < v_ratio) + else { - *dst_y = 0; - *dst_h = dst_size_v; - *dst_w = dst_size_v * src_h / src_v; - *dst_x = (dst_size_h - *dst_w) / 2; + ret = _e_eom_output_state_set_attribute(eom_output, attribute); + if (ret == EINA_FALSE) + { + EOM_DBG("set attribute FAILED\n"); + + eom_error = EOM_ERROR_INVALID_PARAMETER; + goto end; + } + + eom_client->output_id = output_id; + changes = EINA_TRUE; } - else /* (h_ratio > v_ratio) */ + + EOM_DBG("set attribute OK\n"); + + /* If client has set EOM_OUTPUT_ATTRIBUTE_NONE, eom will be + * switched to mirror mode + */ + if (attribute == EOM_OUTPUT_ATTRIBUTE_NONE && eom_output->state != MIRROR) { - *dst_x = 0; - *dst_w = dst_size_h; - *dst_h = dst_size_h * src_h / src_v; - *dst_y = (dst_size_v - *dst_h) / 2; - } -} + eom_output->state = MIRROR; + eom_client->current = EINA_FALSE; -static Eina_Bool -_e_eom_pp_src_to_dst(tbm_surface_h src_buffer) -{ - tdm_error err = TDM_ERROR_NONE; - tdm_info_pp pp_info; - tdm_pp *pp = NULL; - int x, y, w, h; + _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_ATTRIBUTE_NONE); + mode_change = EINA_TRUE; - pp = tdm_display_create_pp(g_eom->dpy, &err); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: create pp:%d\n", err); + ret = _e_eom_output_state_set_attribute(eom_output, EOM_OUTPUT_ATTRIBUTE_NONE); + (void)ret; - /* TO DO : consider rotation */ - _e_eom_calculate_fullsize(g_eom->src_mode.w, g_eom->src_mode.h, - g_eom->dst_mode.w, g_eom->dst_mode.h, - &x, &y, &w, &h); - EOM_DBG("x:%d, y:%d, w:%d, h:%d\n", x, y, w, h); + _e_eom_client_free_buffers(eom_client); - g_eom_event_data.pp = pp; + if (eom_output->status == 0) + { + EOM_DBG("ATTRIBUTE: output:%d is disconnected", output_id); + goto end; + } - pp_info.src_config.size.h = g_eom->src_mode.w; - pp_info.src_config.size.v = g_eom->src_mode.h; - pp_info.src_config.pos.x = 0; - pp_info.src_config.pos.y = 0; - pp_info.src_config.pos.w = g_eom->src_mode.w; - pp_info.src_config.pos.h = g_eom->src_mode.h; - pp_info.src_config.format = TBM_FORMAT_ARGB8888; + ret = _e_eom_output_start_pp(eom_output); + GOTOIFTRUE(ret == EINA_FALSE, end, + "ERROR: restore mirror mode after a client disconnection\n"); + goto end; + } - pp_info.dst_config.size.h = g_eom->dst_mode.w; - pp_info.dst_config.size.v = g_eom->dst_mode.h; - pp_info.dst_config.pos.x = x; - pp_info.dst_config.pos.y = y; - pp_info.dst_config.pos.w = w; - pp_info.dst_config.pos.h = h; - pp_info.dst_config.format = TBM_FORMAT_ARGB8888; +end: + wl_eom_send_output_attribute(eom_client->resource, + eom_output->id, + _e_eom_output_state_get_attribute(eom_output), + _e_eom_output_state_get_attribute_state(eom_output), + eom_error); - /* TO DO : get rotation */ - pp_info.transform = TDM_TRANSFORM_NORMAL; - pp_info.sync = 0; - pp_info.flags = 0; + /* Notify eom clients that eom state has been changed */ + if (changes == EINA_TRUE) + { + EINA_LIST_FOREACH(g_eom->clients, l, iterator) + { + if (iterator && iterator->resource == resource) + continue; - err = tdm_pp_set_info(pp, &pp_info); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: set pp info:%d\n", err); + if (iterator && iterator->output_id == eom_output->id) + { + iterator->current = 0; + + if (eom_output->state == MIRROR) + { + wl_eom_send_output_attribute(iterator->resource, + eom_output->id, + _e_eom_output_state_get_attribute(eom_output), + _e_eom_output_state_get_attribute_state(eom_output), + EOM_ERROR_NONE); + } + else + { + wl_eom_send_output_attribute(iterator->resource, + eom_output->id, + _e_eom_output_state_get_attribute(eom_output), + EOM_OUTPUT_ATTRIBUTE_STATE_LOST, + EOM_ERROR_NONE); + } + + if (mode_change == EINA_TRUE) + { + wl_eom_send_output_mode(iterator->resource, + eom_output->id, + _e_eom_output_state_get_mode(eom_output)); + } + } + } - g_eom_event_data.pp_buffer = !g_eom_event_data.current_buffer; - EOM_DBG("PP: curr:%d pp:%d\n", - g_eom_event_data.current_buffer, - g_eom_event_data.pp_buffer); + eom_client->current= EINA_TRUE; + } - err = tdm_buffer_add_release_handler(g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer], - _e_eom_pp_cb, &g_eom_event_data); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: set pp hadler:%d\n", err); + return; - err = tdm_pp_attach(pp, src_buffer, - g_eom_event_data.dst_buffers[g_eom_event_data.pp_buffer]); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: pp attach:%d\n", err); + /* Get here if EOM does not have output with output_id is */ +no_output: - err = tdm_pp_commit(g_eom_event_data.pp); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: pp commit:%d\n", err); + wl_eom_send_output_attribute(eom_client->resource, + output_id, + EOM_OUTPUT_ATTRIBUTE_NONE, + EOM_OUTPUT_ATTRIBUTE_STATE_NONE, + EOM_ERROR_NO_SUCH_DEVICE); - return EINA_TRUE; + wl_eom_send_output_mode(eom_client->resource, + output_id, + EOM_OUTPUT_MODE_NONE); + + wl_eom_send_output_type(eom_client->resource, + output_id, + EOM_OUTPUT_ATTRIBUTE_STATE_NONE, + TDM_OUTPUT_CONN_STATUS_DISCONNECTED); + return; } -static Eina_Bool -_e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h) +static void +_e_eom_cb_wl_request_get_output_info(struct wl_client *client, struct wl_resource *resource, uint32_t output_id) { - if (src_w != dst_w) - return EINA_TRUE; + EOM_DBG("output:%d\n", output_id); - if (src_h != dst_h) - return EINA_TRUE; + if (g_eom->outputs) + { + Eina_List *l; + E_EomOutputPtr output = NULL; - return EINA_FALSE; + EINA_LIST_FOREACH(g_eom->outputs, l, output) + { + if (output->id == output_id) + { + EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d\n", + output->id, output->type, output->mode, output->width, output->height, + output->phys_width, output->phys_height, output->status); + + wl_eom_send_output_info(resource, output->id, output->type, output->mode, output->width, output->height, + output->phys_width, output->phys_height, output->status); + } + } + } } static Eina_Bool -_e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +_e_eom_output_init(tdm_display *dpy) { - Ecore_Drm_Event_Output *e = NULL; - char buff[PATH_MAX]; - - if (!(e = event)) return ECORE_CALLBACK_PASS_ON;; + tdm_error ret = TDM_ERROR_NONE; + int i, count; - EOM_DBG("id:%d (x,y,w,h):(%d,%d,%d,%d) (w_mm,h_mm):(%d,%d) refresh:%d subpixel_order:%d transform:%d make:%s model:%s name:%s plug:%d\n", - e->id, e->x, e->y, e->w, e->h, e->phys_width, e->phys_height, e->refresh, e->subpixel_order, e->transform, e->make, e->model, e->name, e->plug); + ret = tdm_display_get_output_count(dpy, &count); + RETURNVALIFTRUE(ret != TDM_ERROR_NONE, + EINA_FALSE, + "tdm_display_get_output_count fail"); + RETURNVALIFTRUE(count <= 1, + EINA_FALSE, + "output count is 1. device doesn't support external outputs.\n"); - snprintf(buff, sizeof(buff), "%s", e->name); + g_eom->output_count = count - 1; + EOM_DBG("external output count : %d\n", g_eom->output_count); - if (e->id == 0) /* main output */ + /* skip main output id:0 */ + /* start from 1 */ + for (i = 1; i < count; i++) { - if (e->plug == 1) + const tdm_output_mode *mode = NULL; + E_EomOutputPtr new_output = NULL; + unsigned int mmWidth, mmHeight; + tdm_output_conn_status status; + tdm_output *output = NULL; + tdm_output_type type; + + output = tdm_display_get_output(dpy, i, &ret); + GOTOIFTRUE(ret != TDM_ERROR_NONE, + err, + "tdm_display_get_output fail(ret:%d)", ret); + + GOTOIFTRUE(output == NULL, + err, + "tdm_display_get_output fail(no output:%d)", ret); + + ret = tdm_output_get_output_type(output, &type); + GOTOIFTRUE(ret != TDM_ERROR_NONE, + err, + "tdm_output_get_output_type fail(%d)", ret); + + new_output = E_NEW(E_EomOutput, 1); + GOTOIFTRUE(new_output == NULL, + err, + "calloc fail"); + + ret = tdm_output_get_conn_status(output, &status); + if (ret != TDM_ERROR_NONE) + { + EOM_ERR("tdm_output_get_conn_status fail(%d)", ret); + free(new_output); + goto err; + } + new_output->id = i; + new_output->type = type; + new_output->status = status; + new_output->mode = EOM_OUTPUT_MODE_NONE; + new_output->output = output; + + ret = tdm_output_add_change_handler(output, _e_eom_cb_tdm_output_status_change, NULL); + if (ret != TDM_ERROR_NONE) { - g_eom->src_mode.w = e->w; - g_eom->src_mode.h = e->h; - if (g_eom->int_output_name == NULL) - g_eom->int_output_name = strdup(buff); + EOM_ERR("tdm_output_add_change_handler fail(%d)", ret); + free(new_output); + goto err; + } - g_eom->eom_sate = UP; + if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) + { + EOM_DBG("create(%d)output, type:%d, status:%d", + new_output->id, new_output->type, new_output->status); + g_eom->outputs = eina_list_append(g_eom->outputs, new_output); + continue; } + new_output->status = TDM_OUTPUT_CONN_STATUS_CONNECTED; + + ret = tdm_output_get_mode(output, &mode); + if (ret != TDM_ERROR_NONE) + { + EOM_ERR("tdm_output_get_mode fail(%d)", ret); + free(new_output); + goto err; + } + + if (mode == NULL) + { + new_output->width = 0; + new_output->height = 0; + } + else { - g_eom->src_mode.w = -1; - g_eom->src_mode.h = -1; - if (g_eom->int_output_name) - free(g_eom->int_output_name); + new_output->width = mode->hdisplay; + new_output->height = mode->vdisplay; + } - g_eom->eom_sate = DOWN; + ret = tdm_output_get_physical_size(output, &mmWidth, &mmHeight); + if (ret != TDM_ERROR_NONE) + { + EOM_ERR("tdm_output_get_conn_status fail(%d)", ret); + free(new_output); + goto err; } + new_output->phys_width = mmWidth; + new_output->phys_height = mmHeight; + + EOM_DBG("create(%d)output, type:%d, status:%d, w:%d, h:%d, mm_w:%d, mm_h:%d", + new_output->id, new_output->type, new_output->status, + new_output->width, new_output->height, new_output->phys_width, new_output->phys_height); + + g_eom->outputs = eina_list_append(g_eom->outputs, new_output); } - return ECORE_CALLBACK_PASS_ON; + return EINA_TRUE; + +err: + if (g_eom->outputs) + { + Eina_List *l; + E_EomOutputPtr output; + + EINA_LIST_FOREACH(g_eom->outputs, l, output) + { + free(output); + } + eina_list_free(g_eom->outputs); + } + + return EINA_FALSE; } static const tdm_output_mode * -_e_eom_get_best_mode(tdm_output *output) +_e_eom_output_get_best_mode(tdm_output *output) { tdm_error ret = TDM_ERROR_NONE; const tdm_output_mode *modes; @@ -703,34 +1012,13 @@ _e_eom_get_best_mode(tdm_output *output) unsigned int value; int i, count = 0; - ret = tdm_output_get_available_modes(output, &modes, &count); - if (ret != TDM_ERROR_NONE) - { - EOM_ERR("tdm_output_get_available_modes fail(%d)\n", ret); - return NULL; - } -#if 0 - /* kernel error */ - for (i = 0; i < count; i++) - { - value = modes[i].vdisplay + modes[i].hdisplay; - if (value > best_value) - best_value = value; - } - - for (i = 0; i < count; i++) - { - value = modes[i].vdisplay + modes[i].hdisplay; - if (value != best_value) - continue; - - if (modes[i].vrefresh > vrefresh) - { - mode = &modes[i]; - vrefresh = modes[i].vrefresh; - } + ret = tdm_output_get_available_modes(output, &modes, &count); + if (ret != TDM_ERROR_NONE) + { + EOM_ERR("tdm_output_get_available_modes fail(%d)\n", ret); + return NULL; } -#else + for (i = 0; i < count; i++) { value = modes[i].vdisplay + modes[i].hdisplay; @@ -740,7 +1028,7 @@ _e_eom_get_best_mode(tdm_output *output) mode = &modes[i]; } } -#endif + EOM_DBG("bestmode : %s, (%dx%d) r(%d), f(%d), t(%d)", mode->name, mode->hdisplay, mode->vdisplay, mode->vrefresh, mode->flags, mode->type); @@ -748,7 +1036,7 @@ _e_eom_get_best_mode(tdm_output *output) } static int -_e_eom_get_output_position(void) +_e_eom_output_get_position(void) { tdm_output *output_main = NULL; const tdm_output_mode *mode; @@ -775,7 +1063,7 @@ _e_eom_get_output_position(void) EINA_LIST_FOREACH(g_eom->outputs, l, eom_output_tmp) { if (eom_output_tmp->status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) - x += eom_output_tmp->w; + x += eom_output_tmp->width; } } @@ -783,23 +1071,22 @@ _e_eom_get_output_position(void) } static void -_e_eom_start_mirror(E_EomOutputPtr eom_output, int width, int height) +_e_eom_output_start_mirror(E_EomOutputPtr eom_output, int width, int height) { tdm_output *output; tdm_layer *hal_layer; tdm_info_layer layer_info; tdm_error tdm_err = TDM_ERROR_NONE; - E_EomEventDataPtr eom_event_data = &g_eom_event_data; int ret = 0; - if (eom_output->mirror_run == UP) + if (eom_output->state == MIRROR) return; output = eom_output->output; - hal_layer = _e_eom_hal_layer_get(output, width, height); + hal_layer = _e_eom_output_get_layer(output, width, height); GOTOIFTRUE(hal_layer == NULL, err, "ERROR: get hal layer\n"); - ret = _e_eom_create_output_buffers(eom_event_data, width, height); + ret = _e_eom_util_create_buffers(eom_output, width, height); GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: create buffers \n"); tdm_err = tdm_layer_get_info(hal_layer, &layer_info); @@ -812,34 +1099,26 @@ _e_eom_start_mirror(E_EomOutputPtr eom_output, int width, int height) layer_info.dst_pos.x, layer_info.dst_pos.y, layer_info.dst_pos.w, layer_info.dst_pos.h); - g_eom->dst_mode.w = width; - g_eom->dst_mode.h = height; - /* TODO: free that memory */ - /*g_eom->ext_output_name = strdup(output_name);*/ + eom_output->layer = hal_layer; + eom_output->output = output; + eom_output->current_buffer = 0; - eom_event_data->layer = hal_layer; - eom_event_data->output = output; - eom_event_data->current_buffer = 0; - - tdm_err = tdm_layer_set_buffer(hal_layer, eom_event_data->dst_buffers[eom_event_data->current_buffer]); + tdm_err = tdm_layer_set_buffer(hal_layer, eom_output->dst_buffers[eom_output->current_buffer]); GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: set buffer on layer:%d\n", tdm_err); - g_eom->is_external_init = 1; - g_eom->id = eom_output->id; - tdm_err = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON); GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: tdm_output_set_dpms on\n"); /* get main surface */ - ret = _e_eom_mirror_start(g_eom->int_output_name, g_eom->src_mode.w, g_eom->src_mode.h); + ret = _e_eom_output_start_pp(eom_output); GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: get root surfcae\n"); - tdm_err = tdm_output_commit(output, 0, _e_eom_commit_cb, &g_eom_event_data); + tdm_err = tdm_output_commit(output, 0, _e_eom_cb_commit, eom_output); GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: commit crtc:%d\n", tdm_err); - _e_eom_set_eom_mode(WL_EOM_MODE_MIRROR); - - eom_output->mirror_run = UP; + _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_MODE_MIRROR); + _e_eom_output_state_set_attribute(eom_output, EOM_OUTPUT_ATTRIBUTE_NONE); + eom_output->state = MIRROR; return; @@ -851,266 +1130,347 @@ err: } static void -_e_eom_stop_mirror(E_EomOutputPtr eom_output) +_e_eom_output_stop_mirror(E_EomOutputPtr eom_output) { - if (eom_output->mirror_run == DOWN) + if (eom_output->state == NONE) return; - g_eom->is_external_init = 0; - g_eom->is_internal_grab = 0; - g_eom->id = -1; - - _e_eom_set_eom_status(WL_EOM_STATUS_DISCONNECTION); - _e_eom_set_eom_mode(WL_EOM_MODE_NONE); + _e_eom_output_state_set_status(eom_output, TDM_OUTPUT_CONN_STATUS_DISCONNECTED); + _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_MODE_NONE); + _e_eom_output_state_set_attribute(eom_output, EOM_OUTPUT_ATTRIBUTE_NONE); - _e_eom_deinit_external_output(); + _e_eom_output_deinit(eom_output); - eom_output->mirror_run = DOWN; + eom_output->state = NONE; } static void -_e_eom_tdm_output_status_change_cb(tdm_output *output, tdm_output_change_type type, tdm_value value, void *user_data) +_e_eom_output_deinit(E_EomOutputPtr eom_output) { - tdm_output_type tdm_type; - tdm_error ret = TDM_ERROR_NONE; - tdm_output_conn_status status; - tdm_output_conn_status status2; - const char *maker = NULL, *model = NULL, *name = NULL; - const char *tmp_name; - char new_name[DRM_CONNECTOR_NAME_LEN]; - E_EomOutputPtr eom_output = NULL; - tdm_output_conn_status plug; - - if (type == TDM_OUTPUT_CHANGE_DPMS) - return; + tdm_error err = TDM_ERROR_NONE; + E_EomClientPtr iterator = NULL; + Eina_List *l; + int i = 0; - if (g_eom->outputs) + if (eom_output->layer) { - Eina_List *l; - E_EomOutputPtr eom_output_tmp; + err = tdm_layer_unset_buffer(eom_output->layer); + if (err != TDM_ERROR_NONE) + EOM_DBG("EXT OUTPUT DEINIT: fail unset buffer:%d\n", err); + else + EOM_DBG("EXT OUTPUT DEINIT: ok unset buffer:%d\n", err); - EINA_LIST_FOREACH(g_eom->outputs, l, eom_output_tmp) - { - if (eom_output_tmp->output == output) - eom_output = eom_output_tmp; - } - } + err = tdm_output_commit(eom_output->output, 0, NULL, eom_output); + if (err != TDM_ERROR_NONE) + EOM_DBG ("EXT OUTPUT DEINIT: fail commit:%d\n", err); + else + EOM_DBG("EXT OUTPUT DEINIT: ok commit:%d\n", err); + } - ret = tdm_output_get_output_type(output, &tdm_type); - RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_output_type fail(%d)", ret); + /* TODO: do I need to do DPMS off? */ - ret = tdm_output_get_model_info(output, &maker, &model, &name); - RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_model_info fail(%d)", ret); + err = tdm_output_set_dpms(eom_output->output, TDM_OUTPUT_DPMS_OFF); + if (err != TDM_ERROR_NONE) + EOM_ERR("EXT OUTPUT DEINIT: failed set DPMS off:%d\n", err); - ret = tdm_output_get_conn_status(output, &status); - RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_conn_status fail(%d)", ret); + for (i = 0; i < NUM_MAIN_BUF; i++) + { + tdm_buffer_remove_release_handler(eom_output->dst_buffers[i], + _e_eom_cb_pp, eom_output); - status2 = value.u32; + if (eom_output->dst_buffers[i]) + tbm_surface_destroy(eom_output->dst_buffers[i]); + } - EOM_DBG("type(%d, %d), status(%d, %d) (%s,%s,%s)", type, tdm_type, status, status2, maker, model, name); + /*TODO: what is that for?*/ + if (g_eom->main_output_state == DOWN) + EINA_LIST_FOREACH(g_eom->clients, l, iterator) + { + if (iterator && iterator->output_id == eom_output->id) + _e_eom_client_free_buffers(iterator); + } +} - if (tdm_type < ALEN(eom_conn_types)) - tmp_name = eom_conn_types[tdm_type]; - else - tmp_name = "unknown"; - snprintf(new_name, sizeof(new_name), "%s-%d", tmp_name, 0); +static tdm_layer * +_e_eom_output_get_layer(tdm_output *output, int width, int height) +{ + int i = 0; + int count = 0; + tdm_layer *layer = NULL; + tdm_error err = TDM_ERROR_NONE; + tdm_layer_capability capa; + tdm_info_layer layer_info; - plug = value.u32; + 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; + } - if (plug == TDM_OUTPUT_CONN_STATUS_CONNECTED) + for (i = 0; i < count; i++) { - unsigned int mmWidth, mmHeight, subpixel; - const tdm_output_mode *mode; - int x = 0; + layer = (tdm_layer *)tdm_output_get_layer(output, i, &err); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_output_get_layer fail(%d)\n", err); - ret = tdm_output_get_physical_size(output, &mmWidth, &mmHeight); - RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_physical_size fail(%d)", ret); + err = tdm_layer_get_capabilities(layer, &capa); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_layer_get_capabilities fail(%d)\n", err); - ret = tdm_output_get_subpixel(output, &subpixel); - RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_get_subpixel fail(%d)", ret); + if (capa & TDM_LAYER_CAPABILITY_PRIMARY) + { + EOM_DBG("TDM_LAYER_CAPABILITY_PRIMARY layer found : %d\n", i); + break; + } + } - mode = _e_eom_get_best_mode(output); - RETURNIFTRUE(mode == NULL, "_e_eom_get_best_resolution fail"); + memset(&layer_info, 0x0, sizeof(tdm_info_layer)); + layer_info.src_config.size.h = width; + layer_info.src_config.size.v = height; + layer_info.src_config.pos.x = 0; + layer_info.src_config.pos.y = 0; + layer_info.src_config.pos.w = width; + layer_info.src_config.pos.h = height; + layer_info.src_config.format = TBM_FORMAT_ARGB8888; + layer_info.dst_pos.x = 0; + layer_info.dst_pos.y = 0; + layer_info.dst_pos.w = width; + layer_info.dst_pos.h = height; + layer_info.transform = TDM_TRANSFORM_NORMAL; - ret = tdm_output_set_mode(output, mode); - RETURNIFTRUE(ret != TDM_ERROR_NONE, "tdm_output_set_mode fail(%d)", ret); + err = tdm_layer_set_info(layer, &layer_info); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_layer_set_info fail(%d)\n", err); - x = _e_eom_get_output_position(); - EOM_DBG("mode: %dx%d, phy(%dx%d), pos(%d,0), refresh:%d, subpixel:%d", - mode->hdisplay, mode->vdisplay, mmWidth, mmHeight, x, mode->vrefresh, subpixel); + return layer; +} - if (!e_comp_wl_output_init(new_name, maker, model, x, 0, - mode->hdisplay, mode->vdisplay, - mmWidth, mmHeight, mode->vrefresh, subpixel, 0)) - { - EOM_ERR("Could not setup new output: %s", new_name); - return; - } - EOM_DBG("Setup new output: %s", new_name); +static E_EomOutputPtr +_e_eom_output_get_by_id(int id) +{ + Eina_List *l; + E_EomOutputPtr output; - /* update eom_output connect */ - eom_output->w = mode->hdisplay; - eom_output->h = mode->vdisplay; - eom_output->phys_width = mmWidth; - eom_output->phys_height = mmHeight; - eom_output->status = plug; + EINA_LIST_FOREACH(g_eom->outputs, l, output) + { + if (output && output->id == id) + return output; + } - g_eom->is_mirror_mode = UP; - g_eom->eom_sate = UP; + return NULL; +} - /* TODO: check output mode(presentation set) and HDMI type */ - _e_eom_start_mirror(eom_output, mode->hdisplay, mode->vdisplay); - } - else if (plug == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) +static E_EomOutputPtr +_e_eom_output_get_by_name(const char *name) +{ + Eina_List *l; + E_EomOutputPtr output; + + EINA_LIST_FOREACH(g_eom->outputs, l, output) { - if (eom_output->mirror_run == UP) - _e_eom_stop_mirror(eom_output); + if (output && strcmp(output->name, name) == 0) + return output; + } - /* update eom_output disconnect */ - eom_output->w = 0; - eom_output->h = 0; - eom_output->phys_width = 0; - eom_output->phys_height = 0; - eom_output->status = plug; + return NULL; +} + +static Eina_Bool +_e_eom_output_start_pp(E_EomOutputPtr eom_output) +{ + /* should be changed in HWC enable environment */ + tbm_surface_info_s src_buffer_info; + tbm_surface_h src_buffer = NULL; + Eina_Bool ret = EINA_FALSE; - g_eom->is_mirror_mode = DOWN; - g_eom->eom_sate = DOWN; + src_buffer = _e_eom_util_get_output_surface(g_eom->main_output_name); + RETURNVALIFTRUE(src_buffer == NULL, EINA_FALSE, "ERROR: get root tdm surfcae\n"); - e_comp_wl_output_remove(new_name); - EOM_DBG("Destory output: %s", new_name); - } + tbm_surface_get_info(src_buffer, &src_buffer_info); + + EOM_DBG("FRAMEBUFFER TDM: %dx%d bpp:%d size:%d", + src_buffer_info.width, src_buffer_info.height, + src_buffer_info.bpp, src_buffer_info.size); + + /* TODO: if internal and external outputs are equal */ + ret = _e_eom_pp_is_needed(g_eom->width, g_eom->height, + eom_output->width, eom_output->height); + RETURNVALIFTRUE(ret == EINA_FALSE, EINA_TRUE, "pp is not required\n"); + + ret = _e_eom_pp_init(eom_output, src_buffer); + RETURNVALIFTRUE(ret == EINA_FALSE, EINA_FALSE, "ERROR: init pp\n"); + + return EINA_TRUE; } static Eina_Bool -_e_eom_client_buffer_change(void *data, int type, void *event) +_e_eom_pp_init(E_EomOutputPtr eom_output, tbm_surface_h src_buffer) { - E_Comp_Wl_Buffer *external_wl_buffer = NULL; - E_EomClientBufferPtr client_buffer = NULL; - E_Event_Client *ev = event; - E_Client *ec = NULL; - /* Eina_Bool ret_err; */ - /* - tbm_surface_h external_tbm_buffer = NULL; - tbm_surface_info_s surface_info; - int ret; - */ + tdm_error err = TDM_ERROR_NONE; + tdm_info_pp pp_info; + tdm_pp *pp = NULL; + int x, y, w, h; - EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON); - EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON); + pp = tdm_display_create_pp(g_eom->dpy, &err); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: create pp:%d\n", err); - return ECORE_CALLBACK_PASS_ON; + eom_output->pp = pp; - ec = ev->ec; - if (e_object_is_del(E_OBJECT(ec))) - { - EOM_ERR("ERROR: BUFF CHANGE: ec objects is del\n"); - return ECORE_CALLBACK_PASS_ON; - } + /* TO DO : consider rotation */ + _e_eom_util_calculate_fullsize(g_eom->width, g_eom->height, + eom_output->width, eom_output->height, + &x, &y, &w, &h); + EOM_DBG("x:%d, y:%d, w:%d, h:%d\n", x, y, w, h); - /* TODO: Make all goto same, not err, end, ret etc. */ - /* We are not interested in non external clients */ - /* - ret_err = e_client_is_external_output_client(ec); - RETURNVALIFTRUE(ret_err != EINA_TRUE, - ECORE_CALLBACK_PASS_ON, - "ERROR: BUFF CHANGE: ec is not external\n"); - */ + pp_info.src_config.size.h = g_eom->width; + pp_info.src_config.size.v = g_eom->height; + pp_info.src_config.pos.x = 0; + pp_info.src_config.pos.y = 0; + pp_info.src_config.pos.w = g_eom->width; + pp_info.src_config.pos.h = g_eom->height; + pp_info.src_config.format = TBM_FORMAT_ARGB8888; - if (ec->pixmap == NULL) - return ECORE_CALLBACK_PASS_ON; + pp_info.dst_config.size.h = eom_output->width; + pp_info.dst_config.size.v = eom_output->height; + pp_info.dst_config.pos.x = x; + pp_info.dst_config.pos.y = y; + pp_info.dst_config.pos.w = w; + pp_info.dst_config.pos.h = h; + pp_info.dst_config.format = TBM_FORMAT_ARGB8888; - external_wl_buffer = e_pixmap_resource_get(ec->pixmap); - RETURNVALIFTRUE(external_wl_buffer == NULL, - ECORE_CALLBACK_PASS_ON, - "ERROR:BUFF CHANGE: wl buffer is NULL\n"); + /* TO DO : get rotation */ + pp_info.transform = TDM_TRANSFORM_NORMAL; + pp_info.sync = 0; + pp_info.flags = 0; - EOM_DBG("BUFF CHANGE: wl_buff:%dx%d", - external_wl_buffer->w, - external_wl_buffer->h); + err = tdm_pp_set_info(pp, &pp_info); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: set pp info:%d\n", err); - if (external_wl_buffer->w == 1 && external_wl_buffer->h == 1) - { - EOM_ERR("ERROR:BUFF CHANGE: skip first 1x1 client buffer\n"); - return ECORE_CALLBACK_PASS_ON; - } + eom_output->pp_buffer = !eom_output->current_buffer; + EOM_DBG("PP: curr:%d pp:%d\n", + eom_output->current_buffer, + eom_output->pp_buffer); - /*TODO: wayland_tbm_server_get_surface is implicit declarated */ - /*external_tbm_buffer = wayland_tbm_server_get_surface(NULL, - external_wl_buffer->resource); - if (external_tbm_buffer == NULL) - { - EOM_ERR("ERROR: BUFF CHANGE: client tbm buffer is NULL\n"); - return ECORE_CALLBACK_PASS_ON; - } + err = tdm_buffer_add_release_handler(eom_output->dst_buffers[eom_output->pp_buffer], + _e_eom_cb_pp, eom_output); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: set pp hadler:%d\n", err); - EOM_DBG("BUFF CHANGE: tbm_buffer %p", external_tbm_buffer); - */ + err = tdm_pp_attach(pp, src_buffer, + eom_output->dst_buffers[eom_output->pp_buffer]); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: pp attach:%d\n", err); + + err = tdm_pp_commit(eom_output->pp); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: pp commit:%d\n", err); + + return EINA_TRUE; +} + +static Eina_Bool +_e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h) +{ + if (src_w != dst_w) + return EINA_TRUE; + + if (src_h != dst_h) + return EINA_TRUE; + + return EINA_FALSE; +} + +static tbm_surface_h +_e_eom_util_create_fake_buffer(int width, int height) +{ + tbm_surface_info_s buffer_info; + tbm_surface_h buffer = NULL; - /* mmap that buffer to get width and height for test's sake */ - /* - memset(&surface_info, 0, sizeof(tbm_surface_info_s)); - ret = tbm_surface_map(external_tbm_buffer, TBM_SURF_OPTION_READ | - TBM_SURF_OPTION_WRITE, &surface_info); - if (ret != TBM_SURFACE_ERROR_NONE) + buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); + GOTOIFTRUE(buffer == NULL, err, "can not create fake_buffer\n"); + + 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_ERR("BUFF CHANGE: failed mmap buffer: %d", ret); - //return ECORE_CALLBACK_PASS_ON; + EOM_DBG("can not mmap fake_buffer\n"); + goto err; } - EOM_DBG("BUFF CHANGE: tbm_buffer: %dx%d", surface_info.width, surface_info.height); + memset(buffer_info.planes[0].ptr, 0xFF, buffer_info.planes[0].size); + tbm_surface_unmap(buffer); - tbm_surface_unmap(external_tbm_buffer); - */ + return buffer; +err: - /* TODO: Must find proper way of getting tbm_surface */ - /*client_buffer = _e_eom_create_client_buffer(external_wl_buffer, external_tbm_buffer);*/ - client_buffer = _e_eom_create_client_buffer(external_wl_buffer, fake_buffers.fake_buffers[0]); - RETURNVALIFTRUE(client_buffer == NULL, - ECORE_CALLBACK_PASS_ON, - "ERROR: BUFF CHANGE: alloc client buffer"); + if (buffer) + tbm_surface_destroy(buffer); - _e_eom_add_client_buffer_to_list(client_buffer); + /* TODO: check if the fake buffer is NULL along the code */ + return NULL; +} - /* Stop mirror mode */ - g_eom->is_mirror_mode = DOWN; +static Eina_Bool +_e_eom_util_create_buffers(E_EomOutputPtr eom_output, int width, int height) +{ + tbm_surface_info_s buffer_info; + tbm_surface_h buffer = NULL; + int i = 0; - return ECORE_CALLBACK_PASS_ON; + /* + * TODO: Add support of other formats + */ + buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); + GOTOIFTRUE(buffer == NULL, err, "can not create dst_buffer 1"); - /* TODO: deinitialization */ -} + /* + * 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"); + goto err; + } -static void -_e_eom_add_client_buffer_to_list(E_EomClientBufferPtr client_buffer) -{ - _e_eom_client_buffers_list_free(); + memset(buffer_info.planes[0].ptr, 0x0, buffer_info.planes[0].size); + tbm_surface_unmap(buffer); - g_eom_event_data.client_buffers_list = eina_list_append(g_eom_event_data.client_buffers_list, client_buffer); -} + eom_output->dst_buffers[0] = buffer; -static void -_e_eom_client_buffers_list_free() -{ - E_EomClientBufferPtr *buffer = NULL; - Eina_List *l; + /* + * TODO: Add support of other formats + */ + buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); + GOTOIFTRUE(buffer == NULL, err, "can not create dst_buffer 2"); - EINA_LIST_FOREACH(g_eom_event_data.client_buffers_list, l, buffer) + /* + * TODO: temp code for testing, actual convert will be in _e_eom_put_src_to_dst() + */ + memset(&buffer_info, 0x00, sizeof(tbm_surface_info_s)); + if (tbm_surface_map(buffer, + TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, + &buffer_info) != TBM_SURFACE_ERROR_NONE) { - if (buffer) - { - /* I am not sure if it is necessary */ - /* tbm_surface_internal_unref(buffer->tbm_buffer); */ + EOM_DBG("can not mmap buffer\n"); + goto err; + } - /* TODO: Do we need reference that buffer? */ - /*e_comp_wl_buffer_reference(buffer->tbm_buffer, NULL);*/ + memset(buffer_info.planes[0].ptr, 0x0, buffer_info.planes[0].size); + tbm_surface_unmap(buffer); - g_eom_event_data.client_buffers_list = eina_list_remove(g_eom_event_data.client_buffers_list, buffer); - E_FREE(buffer); - } - } + eom_output->dst_buffers[1] = buffer; + + return EINA_TRUE; + +err: + for (i = 0; i < NUM_MAIN_BUF; i++) + if (eom_output->dst_buffers[i]) + tbm_surface_destroy(eom_output->dst_buffers[i]); + + return EINA_FALSE; } static E_EomClientBufferPtr -_e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer) +_e_eom_util_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer) { E_EomClientBufferPtr buffer = NULL; @@ -1121,463 +1481,268 @@ _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffe buffer->wl_buffer = wl_buffer; buffer->tbm_buffer = tbm_buffer; /* TODO: It is not used right now */ - buffer->stamp = _e_eom_get_time_in_mseconds(); + buffer->stamp = _e_eom_util_get_stamp(); /* I am not sure if it is necessary */ - /* tbm_surface_internal_ref(tbm_buffer); */ + tbm_surface_internal_ref(tbm_buffer); /* TODO: Do we need reference that buffer? */ - /*e_comp_wl_buffer_reference(buffer->tbm_buffer, NULL);*/ + /* e_comp_wl_buffer_reference(buffer->tbm_buffer, NULL);*/ return buffer; } -static E_EomClientBufferPtr -_e_eom_get_client_buffer_from_list() -{ - E_EomClientBufferPtr buffer = NULL; - Eina_List *l; - - /* There must be only one buffer */ - EINA_LIST_FOREACH(g_eom_event_data.client_buffers_list, l, buffer) - { - if (buffer) - return buffer; - } - - return NULL; -} - -static int -_e_eom_get_time_in_mseconds() -{ - struct timespec tp; - - clock_gettime(CLOCK_MONOTONIC, &tp); - - return ((tp.tv_sec * 1000) + (tp.tv_nsec / 1000)); -} - -static Eina_Bool -_e_eom_ecore_drm_activate_cb(void *data, int type EINA_UNUSED, void *event) +static tbm_surface_h +_e_eom_util_get_output_surface(const char *name) { - /* - Ecore_Drm_Event_Activate *e = NULL; - E_EomPtr eom = NULL; - - EOM_DBG("_e_eom_ecore_drm_activate_cb called\n"); - - if ((!event) || (!data)) goto end; - e = event; - eom = data; - - EOM_DBG("e->active:%d\n", e->active); + Ecore_Drm_Output *primary_output = NULL; + Ecore_Drm_Device *dev; + const Eina_List *l; + tdm_output *tdm_output_obj = NULL; + tbm_surface_h tbm = NULL; + tdm_error err = TDM_ERROR_NONE; + int count = 0, i = 0; - if (e->active) - { - ; - } - else + EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev) { - ; + primary_output = ecore_drm_device_output_name_find(dev, name); + if (primary_output != NULL) + break; } -end: - -*/ - return ECORE_CALLBACK_PASS_ON; -} - -static void -_e_eom_wl_request_set_attribute_cb(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, uint32_t attribute) -{ - enum wl_eom_error eom_error = WL_EOM_ERROR_NONE; - struct wl_resource *iterator = NULL; - Eina_Bool changes = EINA_FALSE; - Eina_Bool ret = EINA_FALSE; - Eina_List *l; - - if (resource == g_eom->current_client) - { - /* Current client can set any flag it wants */ - _e_eom_set_eom_attribute_by_current_client(attribute); - changes = EINA_TRUE; - } - else + if (primary_output == NULL) { - ret = _e_eom_set_eom_attribute(attribute); - if (ret == EINA_FALSE) + EOM_ERR("ERROR: get primary output.(%s)\n", name); + EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev) { - EOM_DBG("set attribute FAILED\n"); - - eom_error = WL_EOM_ERROR_OUTPUT_OCCUPIED; - goto end; + primary_output = ecore_drm_output_primary_get(dev); + if (primary_output != NULL) + break; } - changes = EINA_TRUE; + if (primary_output == NULL) + { + EOM_ERR("ERROR: get primary output.(%s)\n", name); + return NULL; + } } - EOM_DBG("set attribute OK\n"); - - /* If client has set WL_EOM_ATTRIBUTE_NONE, eom will be - * switched to mirror mode - */ - if (attribute == WL_EOM_ATTRIBUTE_NONE && g_eom->is_mirror_mode == DOWN) + tdm_output_obj = tdm_display_get_output(g_eom->dpy, 0, &err); + if (tdm_output_obj == NULL || err != TDM_ERROR_NONE) { - g_eom->is_mirror_mode = UP; - ret = _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); - _e_eom_set_eom_mode(WL_EOM_MODE_MIRROR); - - _e_eom_client_buffers_list_free(); - - ret = _e_eom_mirror_start(g_eom->int_output_name, - g_eom->src_mode.w, - g_eom->src_mode.h); - GOTOIFTRUE(ret == EINA_FALSE, - end, - "ERROR: restore mirror mode after a client disconnection\n"); - - goto end; + EOM_ERR("tdm_display_get_output 0 fail\n"); + return NULL; + } + err = tdm_output_get_layer_count(tdm_output_obj, &count); + if (err != TDM_ERROR_NONE) + { + EOM_ERR("tdm_output_get_layer_count fail\n"); + return NULL; } -end: - wl_eom_send_output_attribute(resource, - g_eom->id, - _e_eom_get_eom_attribute(), - _e_eom_get_eom_attribute_state(), - eom_error); - - /* Notify eom clients that eom state has been changed */ - if (changes == EINA_TRUE) + for (i = 0; i < count; i++) { - EINA_LIST_FOREACH(g_eom->eom_clients, l, iterator) + tdm_layer *layer = tdm_output_get_layer(tdm_output_obj, i, NULL); + tdm_layer_capability capabilities = 0; + tdm_layer_get_capabilities(layer, &capabilities); + if (capabilities & TDM_LAYER_CAPABILITY_PRIMARY) { - if (iterator == resource) - continue; - - if (iterator) + tbm = tdm_layer_get_displaying_buffer(layer, &err); + if (err != TDM_ERROR_NONE) { - if (g_eom->is_mirror_mode == UP) - wl_eom_send_output_attribute(iterator, - g_eom->id, - _e_eom_get_eom_attribute(), - _e_eom_get_eom_attribute_state(), - WL_EOM_ERROR_NONE); - else - wl_eom_send_output_attribute(iterator, - g_eom->id, - _e_eom_get_eom_attribute(), - WL_EOM_ATTRIBUTE_STATE_LOST, - WL_EOM_ERROR_NONE); + EOM_ERR("tdm_layer_get_displaying_buffer fail\n"); + return NULL; } - } - - g_eom->current_client = resource; + break; + } } - return; + return tbm; } static void -_e_eom_wl_request_get_output_info_cb(struct wl_client *client, struct wl_resource *resource, uint32_t output_id) +_e_eom_util_calculate_fullsize(int src_h, int src_v, int dst_size_h, int dst_size_v, + int *dst_x, int *dst_y, int *dst_w, int *dst_h) { - EOM_DBG("output:%d\n", output_id); - - if (g_eom->outputs) - { - Eina_List *l; - E_EomOutputPtr output = NULL; + double h_ratio, v_ratio; - EINA_LIST_FOREACH(g_eom->outputs, l, output) - { - if (output->id == output_id) - { - EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d\n", - output->id, output->type, output->mode, output->w, output->h, - output->phys_width, output->phys_height, output->status); + h_ratio = src_h / dst_size_h; + v_ratio = src_v / dst_size_v; - wl_eom_send_output_info(resource, output->id, output->type, output->mode, output->w, output->h, - output->phys_width, output->phys_height, output->status); - } - } + if (h_ratio == v_ratio) + { + *dst_x = 0; + *dst_y = 0; + *dst_w = dst_size_h; + *dst_h = dst_size_v; + } + else if (h_ratio < v_ratio) + { + *dst_y = 0; + *dst_h = dst_size_v; + *dst_w = dst_size_v * src_h / src_v; + *dst_x = (dst_size_h - *dst_w) / 2; + } + else /* (h_ratio > v_ratio) */ + { + *dst_x = 0; + *dst_w = dst_size_h; + *dst_h = dst_size_h * src_h / src_v; + *dst_y = (dst_size_v - *dst_h) / 2; } } -static const struct wl_eom_interface _e_eom_wl_implementation = -{ - _e_eom_wl_request_set_attribute_cb, - _e_eom_wl_request_get_output_info_cb -}; - -/* wl_eom global object destroy function */ -static void -_e_eom_wl_resource_destory_cb(struct wl_resource *resource) +static int +_e_eom_util_get_stamp() { - struct wl_resource *iterator = NULL; - Eina_List *l = NULL; - Eina_Bool ret; + struct timespec tp; - EOM_DBG("client unbind\n"); + clock_gettime(CLOCK_MONOTONIC, &tp); - g_eom->eom_clients = eina_list_remove(g_eom->eom_clients, resource); + return ((tp.tv_sec * 1000) + (tp.tv_nsec / 1000)); +} - /* If not current client has been destroyed do nothing */ - if (resource != g_eom->current_client) - goto end2; +#if 0 +static void +_e_eom_util_draw(tbm_surface_h surface) +{ + int i = 0, j = 0; - /* If a client has been disconnected and mirror mode has not - * been restore, start mirror mode - */ - if (g_eom->is_mirror_mode == DOWN) - { - g_eom->is_mirror_mode = UP; - ret = _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); - _e_eom_set_eom_mode(WL_EOM_MODE_MIRROR); + tbm_bo bo = tbm_surface_internal_get_bo(surface, 0); + RETURNIFTRUE(bo == NULL, "bo is NULL"); - _e_eom_client_buffers_list_free(); + unsigned int *mm = (unsigned int *)tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE).ptr; + RETURNIFTRUE(mm == NULL, "mm is NULL"); - ret = _e_eom_mirror_start(g_eom->int_output_name, - g_eom->src_mode.w, - g_eom->src_mode.h); - GOTOIFTRUE(ret == EINA_FALSE, - end, - "ERROR: restore mirror mode after a client disconnection\n"); - } + unsigned char r = 0; + unsigned char g = 255; + unsigned char b = 0; + unsigned char a = 0; -end: - /* Notify eom clients that eom state has been changed */ - EINA_LIST_FOREACH(g_eom->eom_clients, l, iterator) - { - if (iterator) - { - wl_eom_send_output_attribute(iterator, - g_eom->id, - _e_eom_get_eom_attribute(), - _e_eom_get_eom_attribute_state(), - WL_EOM_ERROR_NONE); - } - } + int w = (int)tbm_surface_get_width(surface); + int h = (int)tbm_surface_get_height(surface); -end2: - g_eom->current_client = NULL; + for (i = 0; i < w; i++) + for (j = 0; j < h/2; j++) + { + mm[i*w + j] = r << 24 | g << 16 | b << 8 | a; + } } +#endif -/* wl_eom global object bind function */ static void -_e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32_t id) +_e_eom_client_add_buffer(E_EomClientPtr client, E_EomClientBufferPtr buffer) { - enum wl_eom_type eom_type = WL_EOM_TYPE_NONE; - struct wl_resource *resource = NULL; + _e_eom_client_free_buffers(client); - RETURNIFTRUE(data == NULL, "ERROR: data is NULL"); + client->buffers = eina_list_append(client->buffers, buffer); +} - E_EomPtr eom = data; +static void +_e_eom_client_free_buffers(E_EomClientPtr client) +{ + E_EomClientBufferPtr buffer = NULL; + Eina_List *l; - resource = wl_resource_create(client, - &wl_eom_interface, - MIN(version, 1), - id); - if (resource == NULL) + EINA_LIST_FOREACH(client->buffers, l, buffer) { - 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, - eom, - _e_eom_wl_resource_destory_cb); - - eom_type = _e_eom_output_name_to_eom_type(g_eom->ext_output_name); - - wl_eom_send_output_type(resource, - eom->id, - eom_type, - _e_eom_get_eom_status()); - - wl_eom_send_output_attribute(resource, - eom->id, - _e_eom_get_eom_attribute(), - _e_eom_get_eom_attribute_state(), - WL_EOM_ERROR_NONE); - - wl_eom_send_output_mode(resource, - eom->id, - _e_eom_get_eom_mode()); - - EOM_DBG("send - output count : %d\n", g_eom->output_count); - wl_eom_send_output_count(resource, - g_eom->output_count); + if (buffer) + { + /* I am not sure if it is necessary */ + if (buffer->tbm_buffer) + tbm_surface_internal_unref(buffer->tbm_buffer); - if (g_eom->outputs) - { - Eina_List *l; - E_EomOutputPtr output = NULL; + /* TODO: Do we need reference that buffer? */ + /* e_comp_wl_buffer_reference(buffer->tbm_buffer, NULL); */ - EINA_LIST_FOREACH(g_eom->outputs, l, output) - { - EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d\n", - output->id, output->type, output->mode, output->w, output->h, - output->phys_width, output->phys_height, output->status); - wl_eom_send_output_info(resource, output->id, output->type, output->mode, output->w, output->h, - output->phys_width, output->phys_height, output->status); + client->buffers = eina_list_remove(client->buffers, buffer); + E_FREE(buffer); } } - - g_eom->eom_clients = eina_list_append(g_eom->eom_clients, resource); } -static void -_e_eom_deinit() +static E_EomClientBufferPtr +_e_eom_client_get_buffer(E_EomClientPtr client) { - Ecore_Event_Handler *h = NULL; - - if (g_eom == NULL) return; + E_EomClientBufferPtr buffer = NULL; + Eina_List *l; - if (g_eom->handlers) + /* There must be only one buffer */ + EINA_LIST_FOREACH(client->buffers, l, buffer) { - EINA_LIST_FREE(g_eom->handlers, h) - ecore_event_handler_del(h); + if (buffer) + return buffer; } - if (g_eom->dpy) tdm_display_deinit(g_eom->dpy); - if (g_eom->bufmgr) tbm_bufmgr_deinit(g_eom->bufmgr); - - if (g_eom->global) wl_global_destroy(g_eom->global); - - E_FREE(g_eom); + return NULL; } -static Eina_Bool -_e_eom_output_info_get(tdm_display *dpy) +static E_EomClientPtr +_e_eom_client_get_by_resource(struct wl_resource *resource) { - tdm_error ret = TDM_ERROR_NONE; - int i, count; - - ret = tdm_display_get_output_count(dpy, &count); - RETURNVALIFTRUE(ret != TDM_ERROR_NONE, - EINA_FALSE, - "tdm_display_get_output_count fail"); - RETURNVALIFTRUE(count <= 1, - EINA_FALSE, - "output count is 1. device doesn't support external outputs.\n"); - - g_eom->output_count = count - 1; - EOM_DBG("external output count : %d\n", g_eom->output_count); + Eina_List *l; + E_EomClientPtr client; - /* skip main output id:0 */ - /* start from 1 */ - for (i = 1; i < count; i++) + EINA_LIST_FOREACH(g_eom->clients, l, client) { - const tdm_output_mode *mode = NULL; - E_EomOutputPtr new_output = NULL; - unsigned int mmWidth, mmHeight; - tdm_output_conn_status status; - tdm_output *output = NULL; - tdm_output_type type; + if (client && client->resource == resource) + return client; + } - output = tdm_display_get_output(dpy, i, &ret); - GOTOIFTRUE(ret != TDM_ERROR_NONE, - err, - "tdm_display_get_output fail(ret:%d)", ret); + return NULL; +} - GOTOIFTRUE(output == NULL, - err, - "tdm_display_get_output fail(no output:%d)", ret); +static E_EomClientPtr +_e_eom_client_current_by_id_get(int id) +{ + Eina_List *l; + E_EomClientPtr client; - ret = tdm_output_get_output_type(output, &type); - GOTOIFTRUE(ret != TDM_ERROR_NONE, - err, - "tdm_output_get_output_type fail(%d)", ret); + EINA_LIST_FOREACH(g_eom->clients, l, client) + { + if (client && + client->current == EINA_TRUE && + client->output_id == id) + return client; + } - new_output = E_NEW(E_EomOutput, 1); - GOTOIFTRUE(new_output == NULL, - err, - "calloc fail"); + return NULL; +} - ret = tdm_output_get_conn_status(output, &status); - if (ret != TDM_ERROR_NONE) - { - EOM_ERR("tdm_output_get_conn_status fail(%d)", ret); - free(new_output); - goto err; - } - new_output->id = i; - new_output->type = type; - new_output->status = status; - new_output->mode = EOM_OUTPUT_MODE_NONE; - new_output->output = output; +static Eina_Bool +_e_eom_init() +{ + Eina_Bool ret = EINA_FALSE; - ret = tdm_output_add_change_handler(output, _e_eom_tdm_output_status_change_cb, NULL); - if (ret != TDM_ERROR_NONE) - { - EOM_ERR("tdm_output_add_change_handler fail(%d)", ret); - free(new_output); - goto err; - } + EINA_SAFETY_ON_NULL_GOTO(e_comp_wl, err); - if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) - { - EOM_DBG("create(%d)output, type:%d, status:%d", - new_output->id, new_output->type, new_output->status); - g_eom->outputs = eina_list_append(g_eom->outputs, new_output); - continue; - } - new_output->status = TDM_OUTPUT_CONN_STATUS_CONNECTED; + g_eom = E_NEW(E_Eom, 1); + EINA_SAFETY_ON_NULL_RETURN_VAL(g_eom, EINA_FALSE); - ret = tdm_output_get_mode(output, &mode); - if (ret != TDM_ERROR_NONE) - { - EOM_ERR("tdm_output_get_mode fail(%d)", ret); - free(new_output); - goto err; - } + g_eom->global = wl_global_create(e_comp_wl->wl.disp, + &wl_eom_interface, + 1, + g_eom, + _e_eom_cb_wl_bind); - if (mode == NULL) - { - new_output->w = 0; - new_output->h = 0; - } + uint32_t id = wl_display_get_serial(e_comp_wl->wl.disp); + EOM_DBG("eom name: %d", id); - else - { - new_output->w = mode->hdisplay; - new_output->h = mode->vdisplay; - } + EINA_SAFETY_ON_NULL_GOTO(g_eom->global, err); - ret = tdm_output_get_physical_size(output, &mmWidth, &mmHeight); - if (ret != TDM_ERROR_NONE) - { - EOM_ERR("tdm_output_get_conn_status fail(%d)", ret); - free(new_output); - goto err; - } - new_output->phys_width = mmWidth; - new_output->phys_height = mmHeight; + ret = _e_eom_init_internal(); + GOTOIFTRUE(ret == EINA_FALSE, err, "failed init_internal()"); - EOM_DBG("create(%d)output, type:%d, status:%d, w:%d, h:%d, mm_w:%d, mm_h:%d", - new_output->id, new_output->type, new_output->status, - new_output->w, new_output->h, new_output->phys_width, new_output->phys_height); + E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_ACTIVATE, _e_eom_cb_ecore_drm_activate, g_eom); + E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_OUTPUT, _e_eom_cb_ecore_drm_output, g_eom); + E_LIST_HANDLER_APPEND(g_eom->handlers, E_EVENT_CLIENT_BUFFER_CHANGE, _e_eom_cb_client_buffer_change, NULL); - g_eom->outputs = eina_list_append(g_eom->outputs, new_output); - } + g_eom->main_output_name = NULL; return EINA_TRUE; err: - if (g_eom->outputs) - { - Eina_List *l; - E_EomOutputPtr output; - - EINA_LIST_FOREACH(g_eom->outputs, l, output) - { - free(output); - } - eina_list_free(g_eom->outputs); - } - + _e_eom_deinit(); return EINA_FALSE; } @@ -1595,9 +1760,9 @@ _e_eom_init_internal() g_eom->bufmgr = tbm_bufmgr_init(g_eom->fd); GOTOIFTRUE(g_eom->bufmgr == NULL, err, "tbm_bufmgr_init fail"); - if (_e_eom_output_info_get(g_eom->dpy) != EINA_TRUE) + if (_e_eom_output_init(g_eom->dpy) != EINA_TRUE) { - EOM_ERR("_e_eom_output_info_get fail\n"); + EOM_ERR("_e_eom_output_init fail\n"); goto err; } @@ -1613,48 +1778,25 @@ err: return EINA_FALSE; } -static Eina_Bool -_e_eom_init() +static void +_e_eom_deinit() { - Eina_Bool ret = EINA_FALSE; - - 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); - - g_eom->global = wl_global_create(e_comp_wl->wl.disp, - &wl_eom_interface, - 1, - g_eom, - _e_eom_wl_bind_cb); - - EINA_SAFETY_ON_NULL_GOTO(g_eom->global, err); - - ret = _e_eom_init_internal(); - GOTOIFTRUE(ret == EINA_FALSE, err, "failed init_internal()"); - - 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); - E_LIST_HANDLER_APPEND(g_eom->handlers, E_EVENT_CLIENT_BUFFER_CHANGE, _e_eom_client_buffer_change, NULL); + Ecore_Event_Handler *h = NULL; - g_eom->is_external_init = DOWN; - g_eom->is_internal_grab = DOWN; - g_eom->ext_output_name = NULL; - g_eom->int_output_name = NULL; + if (g_eom == NULL) return; - g_eom->current_client = NULL; + if (g_eom->handlers) + { + EINA_LIST_FREE(g_eom->handlers, h) + ecore_event_handler_del(h); + } - _e_eom_set_eom_attribute_state(WL_EOM_ATTRIBUTE_STATE_NONE); - _e_eom_set_eom_attribute(WL_EOM_ATTRIBUTE_NONE); - _e_eom_set_eom_status(WL_EOM_STATUS_NONE); - _e_eom_set_eom_mode(WL_EOM_MODE_NONE); + if (g_eom->dpy) tdm_display_deinit(g_eom->dpy); + if (g_eom->bufmgr) tbm_bufmgr_deinit(g_eom->bufmgr); - return EINA_TRUE; + if (g_eom->global) wl_global_destroy(g_eom->global); -err: - _e_eom_deinit(); - return EINA_FALSE; + E_FREE(g_eom); } E_API void * @@ -1676,3 +1818,4 @@ e_modapi_save(E_Module *m EINA_UNUSED) /* Save something to be kept */ return 1; } + diff --git a/src/e_mod_main.h b/src/e_mod_main.h index a1dfe95..6e56ca7 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -46,9 +46,7 @@ E_API int e_modapi_save(E_Module *m); typedef struct _E_Eom E_Eom, *E_EomPtr; typedef struct _E_Eom_Out_Mode E_EomOutMode, *E_EomOutModePtr; -typedef struct _E_Eom_Event_Data E_EomEventData, *E_EomEventDataPtr; typedef struct _E_Eom_Output E_EomOutput, *E_EomOutputPtr; -typedef struct _E_Eom_Fake_Buffers E_EomFakeBuffers, *E_EomFakeBuffersPtr; typedef struct _E_Eom_Client_Buffer E_EomClientBuffer, *E_EomClientBufferPtr; typedef struct _E_Eom_Client E_EomClient, *E_EomClientPtr; @@ -58,6 +56,13 @@ typedef enum UP, } E_EomFlag; +typedef enum +{ + NONE = 0, + MIRROR, + PRESENTATION, +} E_EomOutputState; + struct _E_Eom_Out_Mode { int w; @@ -69,82 +74,65 @@ struct _E_Eom_Output unsigned int id; eom_output_type_e type; eom_output_mode_e mode; - unsigned int w; - unsigned int h; + unsigned int width; + unsigned int height; unsigned int phys_width; unsigned int phys_height; + const char *name; + tdm_output *output; + tdm_layer *layer; + tdm_pp *pp; + E_EomOutputState state; tdm_output_conn_status status; - E_EomFlag mirror_run; eom_output_attribute_e attribute; eom_output_attribute_state_e attribute_state; /* external output data */ - char *ext_output_name; - E_EomFlag is_external_init; - E_EomOutMode src_mode; E_Comp_Wl_Output *wl_output; - /* internal output data */ - char *int_output_name; - E_EomFlag is_internal_grab; - E_EomOutMode dst_mode; + /* mirror mode data */ + tbm_surface_h dst_buffers[NUM_MAIN_BUF]; + int current_buffer; + int pp_buffer; + + tbm_surface_h fake_buffer; }; struct _E_Eom { struct wl_global *global; - Eina_List *eom_clients; - Eina_List *handlers; tdm_display *dpy; tbm_bufmgr bufmgr; int fd; + /* Internal output data */ + E_EomFlag main_output_state; + char *main_output_name; + int width; + int height; + + Eina_List *clients; + Eina_List *handlers; Eina_List *outputs; unsigned int output_count; - -#if 1 - /* eom state */ - E_EomFlag eom_sate; - enum wl_eom_mode eom_mode; - enum wl_eom_attribute eom_attribute; - enum wl_eom_attribute_state eom_attribute_state; - enum wl_eom_status eom_status; - - /*data related to cooperating with clients */ - E_EomFlag is_mirror_mode; - struct wl_resource *current_client; - - /* external output data */ - char *ext_output_name; - E_EomFlag is_external_init; - int id; - E_EomOutMode src_mode; - E_Comp_Wl_Output *wl_output; - - /* internal output data */ - char *int_output_name; - E_EomFlag is_internal_grab; - E_EomOutMode dst_mode; -#endif }; -struct _E_Eom_Event_Data +struct _E_Eom_Client { - tdm_output *output; - tdm_layer *layer; - tdm_pp *pp; + struct wl_resource *resource; + Eina_Bool current; - /* mirror mode data*/ - tbm_surface_h dst_buffers[NUM_MAIN_BUF]; - int current_buffer; - int pp_buffer; + /* Output a client related to */ + int output_id; - /* extended mode data */ - Eina_List *client_buffers_list; + /*TODO: As I understand there are cannot be more than one client buffer on + *server side, but for future extendabilty store it in the list */ + /*Client's buffers */ + Eina_List *buffers; }; struct _E_Eom_Client_Buffer @@ -155,52 +143,60 @@ struct _E_Eom_Client_Buffer unsigned long stamp; }; -struct _E_Eom_Client -{ - struct wl_resource *resource; - Eina_Bool curent; -}; - -struct _E_Eom_Fake_Buffers -{ - tbm_surface_h fake_buffers[NUM_MAIN_BUF]; - int current_fake_buffer; -}; - -/* handle external output */ -static tdm_layer * _e_eom_hal_layer_get(tdm_output *output, int width, int height); -static Eina_Bool _e_eom_create_output_buffers(E_EomEventDataPtr eom_data, int width, int height); -static enum wl_eom_type _e_eom_output_name_to_eom_type(const char *output_name); - -/* handle internal output, pp */ -static Eina_Bool _e_eom_mirror_start(const char *output_name, int width, int height); -static tbm_surface_h _e_eom_root_internal_tdm_surface_get(const char *name); -static Eina_Bool _e_eom_pp_src_to_dst(tbm_surface_h src_buffer); +static Eina_Bool _e_eom_init(); +static Eina_Bool _e_eom_init_internal(); +static void _e_eom_deinit(); + +static void _e_eom_cb_wl_request_set_attribute(struct wl_client *client, + struct wl_resource *resource, + uint32_t output_id, + uint32_t attribute); +static void _e_eom_cb_wl_request_get_output_info(struct wl_client *client, + struct wl_resource *resource, + uint32_t output_id); +static void _e_eom_cb_wl_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id); +static void _e_eom_cb_wl_resource_destory(struct wl_resource *resource); +static Eina_Bool _e_eom_cb_ecore_drm_output(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); +static Eina_Bool _e_eom_cb_ecore_drm_activate(void *data, int type EINA_UNUSED, void *event); +static Eina_Bool _e_eom_cb_client_buffer_change(void *data, int type, void *event); +static void _e_eom_cb_pp(tbm_surface_h surface, void *user_data); +static void _e_eom_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); +static void _e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type type, + tdm_value value, void *user_data); + +static Eina_Bool _e_eom_output_init(tdm_display *dpy); +static const tdm_output_mode *_e_eom_output_get_best_mode(tdm_output *output); +static int _e_eom_output_get_position(void); +static void _e_eom_output_start_mirror(E_EomOutputPtr eom_output, int width, int height); +static void _e_eom_output_stop_mirror(E_EomOutputPtr eom_output); +static void _e_eom_output_deinit(E_EomOutputPtr eom_output); +static tdm_layer *_e_eom_output_get_layer(tdm_output *output, int width, int height); +static E_EomOutputPtr _e_eom_output_get_by_id(int id); +static E_EomOutputPtr _e_eom_output_get_by_name(const char *name); +static Eina_Bool _e_eom_output_start_pp(E_EomOutputPtr eom_output); + +static Eina_Bool _e_eom_pp_init(E_EomOutputPtr eom_output, tbm_surface_h src_buffer); static Eina_Bool _e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h); -static void _e_eom_calculate_fullsize(int src_h, int src_v, int dst_size_h, int dst_size_v, - int *dst_x, int *dst_y, int *dst_w, int *dst_h); - -/* tdm handlers */ -static void _e_eom_pp_cb(tbm_surface_h surface, void *user_data); -static void _e_eom_commit_cb(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); - -/* handle clients buffers - * The work flow is very simple, when a client does commit we take a client's - * buffer and add it to list. During page flip we show that buffer. When a - * new client's buffer has been send we destroy previous buffer and add new - * one to the list. And so on - * We created that list for future possible extending - */ -static E_EomClientBufferPtr _e_eom_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer); -static void _e_eom_add_client_buffer_to_list(E_EomClientBufferPtr client_buffer); -static void _e_eom_client_buffers_list_free(); -static E_EomClientBufferPtr _e_eom_get_client_buffer_from_list(); - -/*eom utils functions*/ -static int _e_eom_get_time_in_mseconds(); -/*static void _e_eom_create_fake_buffers(int width, int height);*/ +static Eina_Bool _e_eom_util_create_buffers(E_EomOutputPtr eom_output, int width, int height); +static E_EomClientBufferPtr _e_eom_util_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, + tbm_surface_h tbm_buffer); +static tbm_surface_h _e_eom_util_create_fake_buffer(int width, int height); +static void _e_eom_util_calculate_fullsize(int src_h, int src_v, int dst_size_h, int dst_size_v, + int *dst_x, int *dst_y, int *dst_w, int *dst_h); +static tbm_surface_h _e_eom_util_get_output_surface(const char *name); +static int _e_eom_util_get_stamp(); +#if 0 +static void _e_eom_util_draw(tbm_surface_h surface); +#endif + +static void _e_eom_client_add_buffer(E_EomClientPtr client, E_EomClientBufferPtr buffer); +static void _e_eom_client_free_buffers(E_EomClientPtr client); +static E_EomClientBufferPtr _e_eom_client_get_buffer(E_EomClientPtr client); +static E_EomClientPtr _e_eom_client_get_by_resource(struct wl_resource *resource); +static E_EomClientPtr _e_eom_client_current_by_id_get(int id); #endif + -- 2.7.4 From 613e101b019b52940064bf45ee07cefcc6328ce0 Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Wed, 6 Jul 2016 17:15:21 +0300 Subject: [PATCH 13/16] working extended mode The commit consists of next improvemtns 1: Extending of EOM protocol by which clients set its windows using wl_eom_set_xdg_window and wl_eom_set_shell_window 2: Fixed substitution of clients in case of Presentetion to Presentation scenario 3: Refactor of _e_eom_util_create_fake_buffer function 4: Clean unnecessary code Change-Id: I7181121b0890a5f240a94b35c84a5d4687b215e3 Signed-off-by: Roman Peresipkyn --- protocol/eom-client-protocol.h | 22 ++- protocol/eom-protocol.c | 10 +- protocol/eom-server-protocol.h | 22 +++ protocol/eom.xml | 10 ++ src/e_mod_main.c | 322 ++++++++++++++++++++++------------------- src/e_mod_main.h | 24 ++- 6 files changed, 250 insertions(+), 160 deletions(-) diff --git a/protocol/eom-client-protocol.h b/protocol/eom-client-protocol.h index 9a26b78..7172c5f 100644 --- a/protocol/eom-client-protocol.h +++ b/protocol/eom-client-protocol.h @@ -13,6 +13,8 @@ struct wl_client; struct wl_resource; struct wl_eom; +struct wl_shell_surface; +struct xdg_surface; extern const struct wl_interface wl_eom_interface; @@ -226,9 +228,13 @@ wl_eom_add_listener(struct wl_eom *wl_eom, } #define WL_EOM_SET_ATTRIBUTE 0 -#define WL_EOM_GET_OUTPUT_INFO 1 +#define WL_EOM_SET_XDG_WINDOW 1 +#define WL_EOM_SET_SHELL_WINDOW 2 +#define WL_EOM_GET_OUTPUT_INFO 3 #define WL_EOM_SET_ATTRIBUTE_SINCE_VERSION 1 +#define WL_EOM_SET_XDG_WINDOW_SINCE_VERSION 1 +#define WL_EOM_SET_SHELL_WINDOW_SINCE_VERSION 1 #define WL_EOM_GET_OUTPUT_INFO_SINCE_VERSION 1 static inline void @@ -263,6 +269,20 @@ wl_eom_set_attribute(struct wl_eom *wl_eom, uint32_t output_id, uint32_t attribu } static inline void +wl_eom_set_xdg_window(struct wl_eom *wl_eom, uint32_t output_id, struct xdg_surface *surface) +{ + wl_proxy_marshal((struct wl_proxy *) wl_eom, + WL_EOM_SET_XDG_WINDOW, output_id, surface); +} + +static inline void +wl_eom_set_shell_window(struct wl_eom *wl_eom, uint32_t output_id, struct wl_shell_surface *surface) +{ + wl_proxy_marshal((struct wl_proxy *) wl_eom, + WL_EOM_SET_SHELL_WINDOW, output_id, surface); +} + +static inline void wl_eom_get_output_info(struct wl_eom *wl_eom, uint32_t output_id) { wl_proxy_marshal((struct wl_proxy *) wl_eom, diff --git a/protocol/eom-protocol.c b/protocol/eom-protocol.c index 0568c61..3db1593 100644 --- a/protocol/eom-protocol.c +++ b/protocol/eom-protocol.c @@ -2,6 +2,8 @@ #include #include "wayland-util.h" +extern const struct wl_interface wl_shell_surface_interface; +extern const struct wl_interface xdg_surface_interface; static const struct wl_interface *types[] = { NULL, @@ -12,10 +14,16 @@ static const struct wl_interface *types[] = { NULL, NULL, NULL, + NULL, + &xdg_surface_interface, + NULL, + &wl_shell_surface_interface, }; static const struct wl_message wl_eom_requests[] = { { "set_attribute", "uu", types + 0 }, + { "set_xdg_window", "uo", types + 8 }, + { "set_shell_window", "uo", types + 10 }, { "get_output_info", "u", types + 0 }, }; @@ -29,7 +37,7 @@ static const struct wl_message wl_eom_events[] = { WL_EXPORT const struct wl_interface wl_eom_interface = { "wl_eom", 1, - 2, wl_eom_requests, + 4, wl_eom_requests, 5, wl_eom_events, }; diff --git a/protocol/eom-server-protocol.h b/protocol/eom-server-protocol.h index 8c0e929..58400a7 100644 --- a/protocol/eom-server-protocol.h +++ b/protocol/eom-server-protocol.h @@ -13,6 +13,8 @@ struct wl_client; struct wl_resource; struct wl_eom; +struct wl_shell_surface; +struct xdg_surface; extern const struct wl_interface wl_eom_interface; @@ -146,6 +148,8 @@ enum wl_eom_attribute_state { /** * wl_eom - an interface to get the information of the external outputs * @set_attribute: (none) + * @set_xdg_window: (none) + * @set_shell_window: (none) * @get_output_info: (none) * * ***** TODO ****** @@ -161,6 +165,24 @@ struct wl_eom_interface { uint32_t output_id, uint32_t attribute); /** + * set_xdg_window - (none) + * @output_id: (none) + * @surface: (none) + */ + void (*set_xdg_window)(struct wl_client *client, + struct wl_resource *resource, + uint32_t output_id, + struct wl_resource *surface); + /** + * set_shell_window - (none) + * @output_id: (none) + * @surface: (none) + */ + void (*set_shell_window)(struct wl_client *client, + struct wl_resource *resource, + uint32_t output_id, + struct wl_resource *surface); + /** * get_output_info - (none) * @output_id: (none) */ diff --git a/protocol/eom.xml b/protocol/eom.xml index 32fff54..699d499 100644 --- a/protocol/eom.xml +++ b/protocol/eom.xml @@ -77,6 +77,16 @@ + + + + + + + + + + diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 06807e0..23b944d 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -17,6 +17,8 @@ static E_EomPtr g_eom = NULL; static const struct wl_eom_interface _e_eom_wl_implementation = { _e_eom_cb_wl_request_set_attribute, + _e_eom_cb_wl_request_set_xdg_window, + _e_eom_cb_wl_request_set_shell_window, _e_eom_cb_wl_request_get_output_info }; @@ -189,16 +191,12 @@ _e_eom_cb_wl_bind(struct wl_client *client, void *data, uint32_t version, uint32 } new_client = E_NEW(E_EomClient, 1); - if (new_client == NULL) - { - EOM_ERR("allocate new client"); - /*TODO: should resource be deleted?*/ - return; - } + RETURNIFTRUE(new_client == NULL, "ERROR: allocate new client") new_client->resource = resource; new_client->current = EINA_FALSE; new_client->output_id = -1; + new_client->ec = NULL; new_client->buffers = NULL; g_eom->clients = eina_list_append(g_eom->clients, new_client); @@ -344,11 +342,10 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) { E_Comp_Wl_Buffer *external_wl_buffer = NULL; E_EomClientBufferPtr client_buffer = NULL; - E_EomClientPtr client = NULL; - E_EomOutputPtr output = NULL; + E_EomClientPtr eom_client = NULL; + E_EomOutputPtr eom_output = NULL; E_Event_Client *ev = event; E_Client *ec = NULL; - const char *output_name = NULL; tbm_surface_h external_tbm_buffer = NULL; /* tbm_surface_info_s surface_info; @@ -359,17 +356,21 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON); ec = ev->ec; - if (e_object_is_del(E_OBJECT(ec))) - { - EOM_ERR("ERROR: BUFF CHANGE: ec objects is del\n"); - return ECORE_CALLBACK_PASS_ON; - } + RETURNVALIFTRUE(e_object_is_del(E_OBJECT(ec)), + ECORE_CALLBACK_PASS_ON, + "ERROR: BUFF CHANGE: ec objects is del\n"); - /* TODO: implemente new client's buffers hooking mechanism */ - return ECORE_CALLBACK_PASS_ON; + eom_client = _e_eom_client_get_current_by_ec(ec); + if (eom_client== NULL) + return ECORE_CALLBACK_PASS_ON; +/* + RETURNVALIFTRUE(eom_client == NULL, + ECORE_CALLBACK_PASS_ON, + "ERROR: BUFF CHANGE: current client is NULL"); +*/ - output = _e_eom_output_get_by_name(output_name); - RETURNVALIFTRUE(output == NULL, + eom_output = _e_eom_output_get_by_id(eom_client->output_id); + RETURNVALIFTRUE(eom_output == NULL, ECORE_CALLBACK_PASS_ON, "ERROR:BUFF CHANGE: eom_output is NULL\n"); @@ -380,6 +381,10 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) RETURNVALIFTRUE(external_wl_buffer == NULL, ECORE_CALLBACK_PASS_ON, "ERROR:BUFF CHANGE: wl buffer is NULL\n"); + RETURNVALIFTRUE(external_wl_buffer->resource == NULL, + ECORE_CALLBACK_PASS_ON, + "ERROR: BUFF CHANGE: resource is NULL\n"); + /* EOM_DBG("BUFF CHANGE: wl_buff:%dx%d type:%d", external_wl_buffer->w, @@ -388,8 +393,8 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) */ /* TODO: support buffers smaller then output resolution */ - if (external_wl_buffer->w != output->width || - external_wl_buffer->h != output->height ) + if (external_wl_buffer->w != eom_output->width || + external_wl_buffer->h != eom_output->height ) { EOM_ERR("BUFF CHANGE: ERROR: tbm_buffer does not fit output's resolution"); return ECORE_CALLBACK_PASS_ON; @@ -397,20 +402,12 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) /* TODO: support different external_wl_buffer->type */ - if (external_wl_buffer->resource == NULL) - { - EOM_ERR("ERROR: BUFF CHANGE: resource is NULL\n"); - return ECORE_CALLBACK_PASS_ON; - } - external_tbm_buffer = wayland_tbm_server_get_surface( e_comp->wl_comp_data->tbm.server, external_wl_buffer->resource); - if (external_tbm_buffer == NULL) - { - EOM_ERR("ERROR: BUFF CHANGE: client tbm buffer is NULL\n"); - return ECORE_CALLBACK_PASS_ON; - } + RETURNVALIFTRUE(external_tbm_buffer == NULL, + ECORE_CALLBACK_PASS_ON, + "ERROR: BUFF CHANGE: client tbm buffer is NULL\n"); EOM_DBG("BUFF CHANGE: tbm_buffer %p", external_tbm_buffer); @@ -435,23 +432,13 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) */ client_buffer = _e_eom_util_create_client_buffer(external_wl_buffer, external_tbm_buffer); - /* client_buffer = _e_eom_util_create_client_buffer(external_wl_buffer, output->fake_buffer); */ RETURNVALIFTRUE(client_buffer == NULL, ECORE_CALLBACK_PASS_ON, "ERROR: BUFF CHANGE: alloc client buffer"); - /* TODO: What if not current client has committed a buffer */ - client = _e_eom_client_current_by_id_get(output->id); - if (client == NULL) - { - EOM_ERR("ERROR: BUFF CHANGE: current client is NULL"); - E_FREE(client_buffer); - return ECORE_CALLBACK_PASS_ON; - } - - _e_eom_client_add_buffer(client, client_buffer); + _e_eom_client_add_buffer(eom_client, client_buffer); - output->state = PRESENTATION; + eom_output->state = PRESENTATION; return ECORE_CALLBACK_PASS_ON; } @@ -503,6 +490,7 @@ _e_eom_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS E_EomOutputPtr eom_output = NULL; E_EomClientPtr eom_client = NULL; tdm_error err = TDM_ERROR_NONE; + tbm_surface_h external_buffer = NULL; eom_output = (E_EomOutputPtr)user_data; RETURNIFTRUE(user_data == NULL, "ERROR: COMMIT EVENT: user data is NULL"); @@ -525,12 +513,18 @@ _e_eom_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS } else if (eom_output->state == PRESENTATION) { - eom_client = _e_eom_client_current_by_id_get(eom_output->id); + eom_client = _e_eom_client_get_current_by_id(eom_output->id); client_buffer = _e_eom_client_get_buffer(eom_client); - RETURNIFTRUE(client_buffer == NULL, "ERROR: COMMIT EVENT: PRESENTATION: client buffer is NULL"); + if (client_buffer == NULL) + { + external_buffer = eom_output->dummy_buffer; + EOM_DBG("COMMIT EVENT: PRESENTATION: dummy buffer was substitute"); + } + else + external_buffer = client_buffer->tbm_buffer; - err = tdm_layer_set_buffer(eom_output->layer, client_buffer->tbm_buffer); + err = tdm_layer_set_buffer(eom_output->layer, external_buffer); RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: COMMIT EVENT: PRESENTATION: set client buffer"); err = tdm_output_commit(eom_output->output, 0, _e_eom_cb_commit, eom_output); @@ -633,9 +627,6 @@ _e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type ty eom_output->name = eina_stringshare_add(new_name); eom_output->type = (eom_output_type_e)tdm_type; - /* Create fake buffer */ - eom_output->fake_buffer = _e_eom_util_create_fake_buffer(eom_output->width, eom_output->height); - /* TODO: check output mode(presentation set) and HDMI type */ _e_eom_output_start_mirror(eom_output, mode->hdisplay, mode->vdisplay); @@ -693,9 +684,6 @@ _e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type ty } } - if (eom_output->fake_buffer) - tbm_surface_destroy(eom_output->fake_buffer); - e_comp_wl_output_remove(new_name); EOM_DBG("Destory output: %s", new_name); eina_stringshare_del(eom_output->name); @@ -844,6 +832,50 @@ no_output: return; } +/* TODO: It uses xdg_surface. Add support of shell_surface */ +/* TODO: I think there must be implemented an event for client which signals if set window was successful */ +static void +_e_eom_cb_wl_request_set_xdg_window(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, struct wl_resource *surface) +{ + E_Client *ec = NULL; + + if (resource == NULL || output_id <= 0 || surface == NULL) + return; + + EOM_DBG("SET XDG WINDOW: output id:%d resource:%p surface:%p", + output_id, resource, surface); + + if (!(ec = wl_resource_get_user_data(surface))) + { + wl_resource_post_error(surface,WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + + _e_eom_window_set_internal(resource, output_id, ec); +} + +static void +_e_eom_cb_wl_request_set_shell_window(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, struct wl_resource *surface) +{ + E_Client *ec = NULL; + + if (resource == NULL || output_id <= 0 || surface == NULL) + return; + + EOM_DBG("SET SHELL WINDOW: output id:%d resource:%p surface:%p", + output_id, resource, surface); + + if (!(ec = wl_resource_get_user_data(surface))) + { + wl_resource_post_error(surface,WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + + _e_eom_window_set_internal(resource, output_id, ec); +} + static void _e_eom_cb_wl_request_get_output_info(struct wl_client *client, struct wl_resource *resource, uint32_t output_id) { @@ -959,7 +991,6 @@ _e_eom_output_init(tdm_display *dpy) new_output->width = 0; new_output->height = 0; } - else { new_output->width = mode->hdisplay; @@ -1086,7 +1117,7 @@ _e_eom_output_start_mirror(E_EomOutputPtr eom_output, int width, int height) hal_layer = _e_eom_output_get_layer(output, width, height); GOTOIFTRUE(hal_layer == NULL, err, "ERROR: get hal layer\n"); - ret = _e_eom_util_create_buffers(eom_output, width, height); + ret = _e_eom_output_create_buffers(eom_output, width, height); GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: create buffers \n"); tdm_err = tdm_layer_get_info(hal_layer, &layer_info); @@ -1258,21 +1289,6 @@ _e_eom_output_get_by_id(int id) return NULL; } -static E_EomOutputPtr -_e_eom_output_get_by_name(const char *name) -{ - Eina_List *l; - E_EomOutputPtr output; - - EINA_LIST_FOREACH(g_eom->outputs, l, output) - { - if (output && strcmp(output->name, name) == 0) - return output; - } - - return NULL; -} - static Eina_Bool _e_eom_output_start_pp(E_EomOutputPtr eom_output) { @@ -1302,6 +1318,64 @@ _e_eom_output_start_pp(E_EomOutputPtr eom_output) } static Eina_Bool +_e_eom_output_create_buffers(E_EomOutputPtr eom_output, int width, int height) +{ + int i = 0; + + /* TODO: Add support for other formats */ + for (i = 0; i < NUM_MAIN_BUF; i++) + { + eom_output->dst_buffers[i] = _e_eom_util_create_buffer(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); + GOTOIFTRUE(eom_output->dst_buffers[i] == NULL, err, "ERROR: create dst buffer"); + } + + eom_output->dummy_buffer = _e_eom_util_create_buffer(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); + GOTOIFTRUE(eom_output->dummy_buffer == NULL, err, "ERROR: create dummy buffer"); + + return EINA_TRUE; + +err: + for (i = 0; i < NUM_MAIN_BUF; i++) + if (eom_output->dst_buffers[i]) + tbm_surface_destroy(eom_output->dst_buffers[i]); + + return EINA_FALSE; +} + +static void +_e_eom_window_set_internal(struct wl_resource *resource, int output_id, E_Client *ec) +{ + E_EomOutputPtr eom_output = NULL; + E_EomClientPtr eom_client = NULL; + E_Comp_Client_Data *cdata = NULL; + + if (resource == NULL || output_id <= 0 || ec == NULL) + return; + + cdata = ec->comp_data; + RETURNIFTRUE(cdata == NULL, "ERROR: cdata is NULL"); + RETURNIFTRUE(cdata->shell.configure_send == NULL, "ERROR: cdata->shell.configure_send is NULL"); + + eom_client = _e_eom_client_get_by_resource(resource); + RETURNIFTRUE(eom_client == NULL, "ERROR: client is NULL"); + + RETURNIFTRUE(eom_client->current == EINA_FALSE, "ERROR: not current client is going to set its window"); + + eom_output = _e_eom_output_get_by_id(output_id); + RETURNIFTRUE(eom_output == NULL, "ERROR: EOM output is NULL"); + + cdata->shell.configure_send(ec->comp_data->shell.surface, 0, eom_output->width, eom_output->height); + + /* Hide the window from e compositing + * TODO: It is not work find other solution + */ + e_comp_object_redirected_set(ec->frame, 0); + + /* ec is used in buffer_change callback for distinguishing external ec and its buffers */ + eom_client->ec = ec; +} + +static Eina_Bool _e_eom_pp_init(E_EomOutputPtr eom_output, tbm_surface_h src_buffer) { tdm_error err = TDM_ERROR_NONE; @@ -1314,11 +1388,12 @@ _e_eom_pp_init(E_EomOutputPtr eom_output, tbm_surface_h src_buffer) eom_output->pp = pp; - /* TO DO : consider rotation */ + /* TODO : consider rotation */ _e_eom_util_calculate_fullsize(g_eom->width, g_eom->height, eom_output->width, eom_output->height, &x, &y, &w, &h); - EOM_DBG("x:%d, y:%d, w:%d, h:%d\n", x, y, w, h); + + EOM_DBG("PP calculation: x:%d, y:%d, w:%d, h:%d\n", x, y, w, h); pp_info.src_config.size.h = g_eom->width; pp_info.src_config.size.v = g_eom->height; @@ -1345,10 +1420,6 @@ _e_eom_pp_init(E_EomOutputPtr eom_output, tbm_surface_h src_buffer) RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: set pp info:%d\n", err); eom_output->pp_buffer = !eom_output->current_buffer; - EOM_DBG("PP: curr:%d pp:%d\n", - eom_output->current_buffer, - eom_output->pp_buffer); - err = tdm_buffer_add_release_handler(eom_output->dst_buffers[eom_output->pp_buffer], _e_eom_cb_pp, eom_output); RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: set pp hadler:%d\n", err); @@ -1376,97 +1447,27 @@ _e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h) } static tbm_surface_h -_e_eom_util_create_fake_buffer(int width, int height) +_e_eom_util_create_buffer(int width, int height, int format, int flags) { tbm_surface_info_s buffer_info; tbm_surface_h buffer = NULL; - buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - GOTOIFTRUE(buffer == NULL, err, "can not create fake_buffer\n"); + buffer = tbm_surface_internal_create_with_flags(width, height, format, flags); + RETURNVALIFTRUE(buffer == NULL, NULL, "ERROR: create buffer"); 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 fake_buffer\n"); - goto err; - } - - memset(buffer_info.planes[0].ptr, 0xFF, buffer_info.planes[0].size); - tbm_surface_unmap(buffer); - - return buffer; -err: - - if (buffer) - tbm_surface_destroy(buffer); - - /* TODO: check if the fake buffer is NULL along the code */ - return NULL; -} - -static Eina_Bool -_e_eom_util_create_buffers(E_EomOutputPtr eom_output, int width, int height) -{ - tbm_surface_info_s buffer_info; - tbm_surface_h buffer = NULL; - int i = 0; - - /* - * TODO: Add support of other formats - */ - buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - GOTOIFTRUE(buffer == NULL, err, "can not create dst_buffer 1"); - - /* - * 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"); - goto err; - } - - memset(buffer_info.planes[0].ptr, 0x0, buffer_info.planes[0].size); - tbm_surface_unmap(buffer); - - eom_output->dst_buffers[0] = buffer; - - /* - * TODO: Add support of other formats - */ - buffer = tbm_surface_internal_create_with_flags(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - GOTOIFTRUE(buffer == NULL, err, "can not create dst_buffer 2"); - - /* - * TODO: temp code for testing, actual convert will be in _e_eom_put_src_to_dst() - */ - memset(&buffer_info, 0x00, 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"); - goto err; + EOM_DBG("ERROR: map buffer"); + return NULL; } memset(buffer_info.planes[0].ptr, 0x0, buffer_info.planes[0].size); tbm_surface_unmap(buffer); - eom_output->dst_buffers[1] = buffer; - - return EINA_TRUE; - -err: - for (i = 0; i < NUM_MAIN_BUF; i++) - if (eom_output->dst_buffers[i]) - tbm_surface_destroy(eom_output->dst_buffers[i]); - - return EINA_FALSE; + return buffer; } static E_EomClientBufferPtr @@ -1693,7 +1694,7 @@ _e_eom_client_get_by_resource(struct wl_resource *resource) } static E_EomClientPtr -_e_eom_client_current_by_id_get(int id) +_e_eom_client_get_current_by_id(int id) { Eina_List *l; E_EomClientPtr client; @@ -1709,6 +1710,23 @@ _e_eom_client_current_by_id_get(int id) return NULL; } +static E_EomClientPtr +_e_eom_client_get_current_by_ec(E_Client *ec) +{ + Eina_List *l; + E_EomClientPtr client; + + EINA_LIST_FOREACH(g_eom->clients, l, client) + { + if (client && + client->current == EINA_TRUE && + client->ec == ec) + return client; + } + + return NULL; +} + static Eina_Bool _e_eom_init() { diff --git a/src/e_mod_main.h b/src/e_mod_main.h index 6e56ca7..e2eef74 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -98,7 +98,7 @@ struct _E_Eom_Output int current_buffer; int pp_buffer; - tbm_surface_h fake_buffer; + tbm_surface_h dummy_buffer; }; struct _E_Eom @@ -126,8 +126,10 @@ struct _E_Eom_Client struct wl_resource *resource; Eina_Bool current; - /* Output a client related to */ + /* EOM output the client related to */ int output_id; + /* E_Client the client related to */ + E_Client *ec; /*TODO: As I understand there are cannot be more than one client buffer on *server side, but for future extendabilty store it in the list */ @@ -151,6 +153,14 @@ static void _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, uint32_t attribute); +static void _e_eom_cb_wl_request_set_xdg_window(struct wl_client *client, + struct wl_resource *resource, + uint32_t output_id, + struct wl_resource *surface); +static void _e_eom_cb_wl_request_set_shell_window(struct wl_client *client, + struct wl_resource *resource, + uint32_t output_id, + struct wl_resource *surface); static void _e_eom_cb_wl_request_get_output_info(struct wl_client *client, struct wl_resource *resource, uint32_t output_id); @@ -174,16 +184,17 @@ static void _e_eom_output_stop_mirror(E_EomOutputPtr eom_output); static void _e_eom_output_deinit(E_EomOutputPtr eom_output); static tdm_layer *_e_eom_output_get_layer(tdm_output *output, int width, int height); static E_EomOutputPtr _e_eom_output_get_by_id(int id); -static E_EomOutputPtr _e_eom_output_get_by_name(const char *name); static Eina_Bool _e_eom_output_start_pp(E_EomOutputPtr eom_output); +static Eina_Bool _e_eom_output_create_buffers(E_EomOutputPtr eom_output, int width, int height); + +static void _e_eom_window_set_internal(struct wl_resource *resource, int output_id, E_Client *ec); static Eina_Bool _e_eom_pp_init(E_EomOutputPtr eom_output, tbm_surface_h src_buffer); static Eina_Bool _e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h); -static Eina_Bool _e_eom_util_create_buffers(E_EomOutputPtr eom_output, int width, int height); +static tbm_surface_h _e_eom_util_create_buffer(int width, int height, int format, int flags); static E_EomClientBufferPtr _e_eom_util_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer); -static tbm_surface_h _e_eom_util_create_fake_buffer(int width, int height); static void _e_eom_util_calculate_fullsize(int src_h, int src_v, int dst_size_h, int dst_size_v, int *dst_x, int *dst_y, int *dst_w, int *dst_h); static tbm_surface_h _e_eom_util_get_output_surface(const char *name); @@ -196,7 +207,8 @@ static void _e_eom_client_add_buffer(E_EomClientPtr client, E_EomClientBufferPtr static void _e_eom_client_free_buffers(E_EomClientPtr client); static E_EomClientBufferPtr _e_eom_client_get_buffer(E_EomClientPtr client); static E_EomClientPtr _e_eom_client_get_by_resource(struct wl_resource *resource); -static E_EomClientPtr _e_eom_client_current_by_id_get(int id); +static E_EomClientPtr _e_eom_client_get_current_by_id(int id); +static E_EomClientPtr _e_eom_client_get_current_by_ec(E_Client *ec); #endif -- 2.7.4 From 5333552fcc041b9ea6d686eb81d3e23d257ca7f0 Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Wed, 6 Jul 2016 18:33:26 +0300 Subject: [PATCH 14/16] refactor _e_eom_output_start_mirror and _e_eom_output_get_layer functions Change-Id: Ica30dbf2bb44d08a00c01ed5d356fff4426389e1 Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 36 ++++++++++++++++++------------------ src/e_mod_main.h | 4 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 23b944d..b96a58e 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -628,7 +628,7 @@ _e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type ty eom_output->type = (eom_output_type_e)tdm_type; /* TODO: check output mode(presentation set) and HDMI type */ - _e_eom_output_start_mirror(eom_output, mode->hdisplay, mode->vdisplay); + _e_eom_output_start_mirror(eom_output); /* If there were previously connected clients to the output - notify them */ EINA_LIST_FOREACH(g_eom->clients, l, iterator) @@ -1102,9 +1102,8 @@ _e_eom_output_get_position(void) } static void -_e_eom_output_start_mirror(E_EomOutputPtr eom_output, int width, int height) +_e_eom_output_start_mirror(E_EomOutputPtr eom_output) { - tdm_output *output; tdm_layer *hal_layer; tdm_info_layer layer_info; tdm_error tdm_err = TDM_ERROR_NONE; @@ -1113,11 +1112,10 @@ _e_eom_output_start_mirror(E_EomOutputPtr eom_output, int width, int height) if (eom_output->state == MIRROR) return; - output = eom_output->output; - hal_layer = _e_eom_output_get_layer(output, width, height); + hal_layer = _e_eom_output_get_layer(eom_output); GOTOIFTRUE(hal_layer == NULL, err, "ERROR: get hal layer\n"); - ret = _e_eom_output_create_buffers(eom_output, width, height); + ret = _e_eom_output_create_buffers(eom_output, eom_output->width, eom_output->height); GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: create buffers \n"); tdm_err = tdm_layer_get_info(hal_layer, &layer_info); @@ -1131,20 +1129,19 @@ _e_eom_output_start_mirror(E_EomOutputPtr eom_output, int width, int height) layer_info.dst_pos.w, layer_info.dst_pos.h); eom_output->layer = hal_layer; - eom_output->output = output; eom_output->current_buffer = 0; tdm_err = tdm_layer_set_buffer(hal_layer, eom_output->dst_buffers[eom_output->current_buffer]); GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: set buffer on layer:%d\n", tdm_err); - tdm_err = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON); + tdm_err = tdm_output_set_dpms(eom_output->output, TDM_OUTPUT_DPMS_ON); GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: tdm_output_set_dpms on\n"); /* get main surface */ ret = _e_eom_output_start_pp(eom_output); GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: get root surfcae\n"); - tdm_err = tdm_output_commit(output, 0, _e_eom_cb_commit, eom_output); + tdm_err = tdm_output_commit(eom_output->output, 0, _e_eom_cb_commit, eom_output); GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: commit crtc:%d\n", tdm_err); _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_MODE_MIRROR); @@ -1223,7 +1220,7 @@ _e_eom_output_deinit(E_EomOutputPtr eom_output) } static tdm_layer * -_e_eom_output_get_layer(tdm_output *output, int width, int height) +_e_eom_output_get_layer(E_EomOutputPtr eom_output) { int i = 0; int count = 0; @@ -1232,7 +1229,10 @@ _e_eom_output_get_layer(tdm_output *output, int width, int height) tdm_layer_capability capa; tdm_info_layer layer_info; - err = tdm_output_get_layer_count(output, &count); + RETURNVALIFTRUE(eom_output == NULL, NULL, "ERROR: eom_output is NULL"); + RETURNVALIFTRUE(eom_output->output == NULL, NULL, "ERROR: eom_output->output is NULL"); + + err = tdm_output_get_layer_count(eom_output->output, &count); if (err != TDM_ERROR_NONE) { EOM_DBG ("tdm_output_get_layer_count fail(%d)\n", err); @@ -1241,7 +1241,7 @@ _e_eom_output_get_layer(tdm_output *output, int width, int height) for (i = 0; i < count; i++) { - layer = (tdm_layer *)tdm_output_get_layer(output, i, &err); + layer = (tdm_layer *)tdm_output_get_layer(eom_output->output, i, &err); RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_output_get_layer fail(%d)\n", err); err = tdm_layer_get_capabilities(layer, &capa); @@ -1255,17 +1255,17 @@ _e_eom_output_get_layer(tdm_output *output, int width, int height) } memset(&layer_info, 0x0, sizeof(tdm_info_layer)); - layer_info.src_config.size.h = width; - layer_info.src_config.size.v = height; + layer_info.src_config.size.h = eom_output->width; + layer_info.src_config.size.v = eom_output->height; layer_info.src_config.pos.x = 0; layer_info.src_config.pos.y = 0; - layer_info.src_config.pos.w = width; - layer_info.src_config.pos.h = height; + layer_info.src_config.pos.w = eom_output->width; + layer_info.src_config.pos.h = eom_output->height; layer_info.src_config.format = TBM_FORMAT_ARGB8888; layer_info.dst_pos.x = 0; layer_info.dst_pos.y = 0; - layer_info.dst_pos.w = width; - layer_info.dst_pos.h = height; + layer_info.dst_pos.w = eom_output->width; + layer_info.dst_pos.h = eom_output->height; layer_info.transform = TDM_TRANSFORM_NORMAL; err = tdm_layer_set_info(layer, &layer_info); diff --git a/src/e_mod_main.h b/src/e_mod_main.h index e2eef74..b041517 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -179,10 +179,10 @@ static void _e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_ch static Eina_Bool _e_eom_output_init(tdm_display *dpy); static const tdm_output_mode *_e_eom_output_get_best_mode(tdm_output *output); static int _e_eom_output_get_position(void); -static void _e_eom_output_start_mirror(E_EomOutputPtr eom_output, int width, int height); +static void _e_eom_output_start_mirror(E_EomOutputPtr eom_output); static void _e_eom_output_stop_mirror(E_EomOutputPtr eom_output); static void _e_eom_output_deinit(E_EomOutputPtr eom_output); -static tdm_layer *_e_eom_output_get_layer(tdm_output *output, int width, int height); +static tdm_layer *_e_eom_output_get_layer(E_EomOutputPtr eom_output); static E_EomOutputPtr _e_eom_output_get_by_id(int id); static Eina_Bool _e_eom_output_start_pp(E_EomOutputPtr eom_output); static Eina_Bool _e_eom_output_create_buffers(E_EomOutputPtr eom_output, int width, int height); -- 2.7.4 From a59dd79c241afbd637c42d00bac4c64f509eec2d Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Thu, 7 Jul 2016 14:17:56 +0300 Subject: [PATCH 15/16] turn on/off EOM's debug by EOM_SERVER_DBG environment variable. improved debug output Change-Id: I56c50b5ef0cd4a5ccf22e66eae9d2fb64634a6f6 Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 209 +++++++++++++++++++++++++++++-------------------------- src/e_mod_main.h | 22 ++++-- 2 files changed, 129 insertions(+), 102 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index b96a58e..24bb7d8 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -13,6 +13,7 @@ E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "EOM Module" }; static E_EomPtr g_eom = NULL; +Eina_Bool eom_server_debug_on = EINA_FALSE; static const struct wl_eom_interface _e_eom_wl_implementation = { @@ -145,7 +146,7 @@ _e_eom_cb_wl_bind(struct wl_client *client, void *data, uint32_t version, uint32 struct wl_resource *resource = NULL; E_EomClientPtr new_client = NULL; - RETURNIFTRUE(data == NULL, "ERROR: data is NULL"); + RETURNIFTRUE(data == NULL, "data is NULL"); E_EomPtr eom = data; @@ -155,7 +156,7 @@ _e_eom_cb_wl_bind(struct wl_client *client, void *data, uint32_t version, uint32 id); if (resource == NULL) { - EOM_ERR("error. resource is null. (version :%d, id:%d)\n", version, id); + EOM_ERR("resource is null. (version :%d, id:%d)", version, id); wl_client_post_no_memory(client); return; } @@ -165,7 +166,7 @@ _e_eom_cb_wl_bind(struct wl_client *client, void *data, uint32_t version, uint32 eom, _e_eom_cb_wl_resource_destory); - EOM_DBG("send - output count : %d\n", g_eom->output_count); + EOM_DBG("send - output count : %d", g_eom->output_count); wl_eom_send_output_count(resource, g_eom->output_count); @@ -176,7 +177,7 @@ _e_eom_cb_wl_bind(struct wl_client *client, void *data, uint32_t version, uint32 EINA_LIST_FOREACH(g_eom->outputs, l, output) { - EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d\n", + EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d", output->id, output->type, output->mode, output->width, output->height, output->phys_width, output->phys_height, output->status); wl_eom_send_output_info(resource, output->id, output->type, output->mode, output->width, output->height, @@ -191,7 +192,7 @@ _e_eom_cb_wl_bind(struct wl_client *client, void *data, uint32_t version, uint32 } new_client = E_NEW(E_EomClient, 1); - RETURNIFTRUE(new_client == NULL, "ERROR: allocate new client") + RETURNIFTRUE(new_client == NULL, "Allocate new client") new_client->resource = resource; new_client->current = EINA_FALSE; @@ -210,18 +211,19 @@ _e_eom_cb_wl_resource_destory(struct wl_resource *resource) Eina_List *l = NULL; Eina_Bool ret; - EOM_DBG("client unbind\n"); + EOM_DBG("client unbind"); client = _e_eom_client_get_by_resource(resource); - RETURNIFTRUE(client == NULL, "destroy client: client is NULL"); + RETURNIFTRUE(client == NULL, "eom client is NULL"); g_eom->clients = eina_list_remove(g_eom->clients, client); /* If it is not current client do nothing */ - GOTOIFTRUE(client->current == EINA_FALSE, end2, ""); + if (client->current == EINA_FALSE) + goto end2; output = _e_eom_output_get_by_id(client->output_id); - GOTOIFTRUE(output == NULL, end2, "destroy client: client is NULL"); + GOTOIFTRUE(output == NULL, end2, "output is NULL"); _e_eom_client_free_buffers(client); @@ -242,7 +244,7 @@ _e_eom_cb_wl_resource_destory(struct wl_resource *resource) ret = _e_eom_output_start_pp(output); GOTOIFTRUE(ret == EINA_FALSE, end, - "ERROR: restore mirror mode after a client disconnection\n"); + "Restore mirror mode after a client disconnection"); } end: @@ -276,7 +278,7 @@ _e_eom_cb_ecore_drm_output(void *data EINA_UNUSED, int type EINA_UNUSED, void *e if (!(e = event)) return ECORE_CALLBACK_PASS_ON;; - EOM_DBG("id:%d (x,y,w,h):(%d,%d,%d,%d) (w_mm,h_mm):(%d,%d) refresh:%d subpixel_order:%d transform:%d make:%s model:%s name:%s plug:%d\n", + EOM_DBG("id:%d (x,y,w,h):(%d,%d,%d,%d) (w_mm,h_mm):(%d,%d) refresh:%d subpixel_order:%d transform:%d make:%s model:%s name:%s plug:%d", e->id, e->x, e->y, e->w, e->h, e->phys_width, e->phys_height, e->refresh, e->subpixel_order, e->transform, e->make, e->model, e->name, e->plug); snprintf(buff, sizeof(buff), "%s", e->name); @@ -314,13 +316,13 @@ _e_eom_cb_ecore_drm_activate(void *data, int type EINA_UNUSED, void *event) Ecore_Drm_Event_Activate *e = NULL; E_EomPtr eom = NULL; - EOM_DBG("_e_eom_cb_ecore_drm_activate called\n"); + EOM_DBG("_e_eom_cb_ecore_drm_activate called"); if ((!event) || (!data)) goto end; e = event; eom = data; - EOM_DBG("e->active:%d\n", e->active); + EOM_DBG("e->active:%d", e->active); if (e->active) { @@ -358,7 +360,7 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) ec = ev->ec; RETURNVALIFTRUE(e_object_is_del(E_OBJECT(ec)), ECORE_CALLBACK_PASS_ON, - "ERROR: BUFF CHANGE: ec objects is del\n"); + "ec objects is del"); eom_client = _e_eom_client_get_current_by_ec(ec); if (eom_client== NULL) @@ -366,13 +368,13 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) /* RETURNVALIFTRUE(eom_client == NULL, ECORE_CALLBACK_PASS_ON, - "ERROR: BUFF CHANGE: current client is NULL"); + "Current client is NULL"); */ eom_output = _e_eom_output_get_by_id(eom_client->output_id); RETURNVALIFTRUE(eom_output == NULL, ECORE_CALLBACK_PASS_ON, - "ERROR:BUFF CHANGE: eom_output is NULL\n"); + "eom_output is NULL"); if (ec->pixmap == NULL) return ECORE_CALLBACK_PASS_ON; @@ -380,13 +382,13 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) external_wl_buffer = e_pixmap_resource_get(ec->pixmap); RETURNVALIFTRUE(external_wl_buffer == NULL, ECORE_CALLBACK_PASS_ON, - "ERROR:BUFF CHANGE: wl buffer is NULL\n"); + "wl buffer is NULL"); RETURNVALIFTRUE(external_wl_buffer->resource == NULL, ECORE_CALLBACK_PASS_ON, - "ERROR: BUFF CHANGE: resource is NULL\n"); + "resource is NULL"); /* - EOM_DBG("BUFF CHANGE: wl_buff:%dx%d type:%d", + EOM_DBG(" wl_buff:%dx%d type:%d", external_wl_buffer->w, external_wl_buffer->h, external_wl_buffer->type); @@ -396,7 +398,7 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) if (external_wl_buffer->w != eom_output->width || external_wl_buffer->h != eom_output->height ) { - EOM_ERR("BUFF CHANGE: ERROR: tbm_buffer does not fit output's resolution"); + EOM_ERR("tbm_buffer does not fit output's resolution"); return ECORE_CALLBACK_PASS_ON; } @@ -407,9 +409,9 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) external_wl_buffer->resource); RETURNVALIFTRUE(external_tbm_buffer == NULL, ECORE_CALLBACK_PASS_ON, - "ERROR: BUFF CHANGE: client tbm buffer is NULL\n"); + "Client tbm buffer is NULL"); - EOM_DBG("BUFF CHANGE: tbm_buffer %p", external_tbm_buffer); + EOM_DBG("tbm_buffer %p", external_tbm_buffer); #if 0 _e_eom_util_draw(external_tbm_buffer); @@ -422,11 +424,11 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) TBM_SURF_OPTION_WRITE, &surface_info); if (ret != TBM_SURFACE_ERROR_NONE) { - EOM_ERR("BUFF CHANGE: failed mmap buffer: %d", ret); + EOM_ERR("mmap buffer: %d", ret); return ECORE_CALLBACK_PASS_ON; } - EOM_DBG("BUFF CHANGE: tbm_buffer: %dx%d", surface_info.width, surface_info.height); + EOM_DBG("tbm_buffer: %dx%d", surface_info.width, surface_info.height); tbm_surface_unmap(external_tbm_buffer); */ @@ -434,7 +436,7 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) client_buffer = _e_eom_util_create_client_buffer(external_wl_buffer, external_tbm_buffer); RETURNVALIFTRUE(client_buffer == NULL, ECORE_CALLBACK_PASS_ON, - "ERROR: BUFF CHANGE: alloc client buffer"); + "Alloc client buffer"); _e_eom_client_add_buffer(eom_client, client_buffer); @@ -450,7 +452,7 @@ _e_eom_cb_pp(tbm_surface_h surface, void *user_data) E_EomOutputPtr eom_output = NULL; eom_output = (E_EomOutputPtr)user_data; - RETURNIFTRUE(user_data == NULL, "ERROR: PP EVENT: user data is NULL"); + RETURNIFTRUE(user_data == NULL, "pp event: user data is NULL"); tdm_buffer_remove_release_handler(eom_output->dst_buffers[eom_output->pp_buffer], _e_eom_cb_pp, eom_output); @@ -465,20 +467,20 @@ _e_eom_cb_pp(tbm_surface_h surface, void *user_data) tbm_surface_h src_buffer; src_buffer = _e_eom_util_get_output_surface(g_eom->main_output_name); - RETURNIFTRUE(src_buffer == NULL, "ERROR: PP EVENT: get root tdm surface"); + RETURNIFTRUE(src_buffer == NULL, "pp event: get root tdm surface"); /*TODO: rewrite the mirror mode buffer's switching */ eom_output->pp_buffer ^= 1; tdm_err = tdm_buffer_add_release_handler(eom_output->dst_buffers[eom_output->pp_buffer], _e_eom_cb_pp, eom_output); - RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "ERROR: PP EVENT: set pp hadler:%d", tdm_err ); + RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "pp event: set pp hadler:%d", tdm_err ); tdm_err = tdm_pp_attach(eom_output->pp, src_buffer, eom_output->dst_buffers[eom_output->pp_buffer]); - RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "ERROR: pp attach:%d\n", tdm_err); + RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "pp attach:%d", tdm_err); tdm_err = tdm_pp_commit(eom_output->pp); - RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "ERROR: PP EVENT: pp commit:%d", tdm_err ); + RETURNIFTRUE(tdm_err != TDM_ERROR_NONE, "pp event: commit:%d", tdm_err ); } static void @@ -493,7 +495,7 @@ _e_eom_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS tbm_surface_h external_buffer = NULL; eom_output = (E_EomOutputPtr)user_data; - RETURNIFTRUE(user_data == NULL, "ERROR: COMMIT EVENT: user data is NULL"); + RETURNIFTRUE(user_data == NULL, "commit event: user data is NULL"); if (g_eom->main_output_state == DOWN) return; @@ -506,10 +508,10 @@ _e_eom_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS err = tdm_layer_set_buffer(eom_output->layer, eom_output->dst_buffers[eom_output->current_buffer]); - RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: COMMIT EVENT: MIRROR: set buffer 0 err:%d", err); + RETURNIFTRUE(err != TDM_ERROR_NONE, "commit event: mirror: set buffer 0 err:%d", err); err = tdm_output_commit(eom_output->output, 0, _e_eom_cb_commit, eom_output); - RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: COMMIT EVENT: MIRROR: commit"); + RETURNIFTRUE(err != TDM_ERROR_NONE, "commit event: mirror: commit"); } else if (eom_output->state == PRESENTATION) { @@ -519,16 +521,16 @@ _e_eom_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS if (client_buffer == NULL) { external_buffer = eom_output->dummy_buffer; - EOM_DBG("COMMIT EVENT: PRESENTATION: dummy buffer was substitute"); + EOM_DBG("dummy buffer was substitute"); } else external_buffer = client_buffer->tbm_buffer; err = tdm_layer_set_buffer(eom_output->layer, external_buffer); - RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: COMMIT EVENT: PRESENTATION: set client buffer"); + RETURNIFTRUE(err != TDM_ERROR_NONE, "commit event: presentation: set client buffer"); err = tdm_output_commit(eom_output->output, 0, _e_eom_cb_commit, eom_output); - RETURNIFTRUE(err != TDM_ERROR_NONE, "ERROR: COMMIT EVENT: PRESENTATION: commit"); + RETURNIFTRUE(err != TDM_ERROR_NONE, "commit event: presentation: commit"); } } @@ -702,14 +704,14 @@ _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource Eina_List *l; eom_client = _e_eom_client_get_by_resource(resource); - RETURNIFTRUE(eom_client == NULL, "client is NULL"); + RETURNIFTRUE(eom_client == NULL, "eom_client is NULL"); /* Bind the client with a concrete output */ if (eom_client->output_id == -1) eom_client->output_id = output_id; eom_output = _e_eom_output_get_by_id(output_id); - GOTOIFTRUE(eom_output == NULL, no_output, "output is NULL"); + GOTOIFTRUE(eom_output == NULL, no_output, "eom_output is NULL"); if (eom_client->current == EINA_TRUE && eom_output->id == eom_client->output_id) { @@ -722,7 +724,7 @@ _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource ret = _e_eom_output_state_set_attribute(eom_output, attribute); if (ret == EINA_FALSE) { - EOM_DBG("set attribute FAILED\n"); + EOM_DBG("set attribute FAILED"); eom_error = EOM_ERROR_INVALID_PARAMETER; goto end; @@ -732,7 +734,7 @@ _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource changes = EINA_TRUE; } - EOM_DBG("set attribute OK\n"); + EOM_DBG("set attribute OK"); /* If client has set EOM_OUTPUT_ATTRIBUTE_NONE, eom will be * switched to mirror mode @@ -752,13 +754,13 @@ _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource if (eom_output->status == 0) { - EOM_DBG("ATTRIBUTE: output:%d is disconnected", output_id); + EOM_DBG("output:%d is disconnected", output_id); goto end; } ret = _e_eom_output_start_pp(eom_output); GOTOIFTRUE(ret == EINA_FALSE, end, - "ERROR: restore mirror mode after a client disconnection\n"); + "Restore mirror mode after a client disconnection"); goto end; } @@ -842,7 +844,7 @@ _e_eom_cb_wl_request_set_xdg_window(struct wl_client *client, struct wl_resource if (resource == NULL || output_id <= 0 || surface == NULL) return; - EOM_DBG("SET XDG WINDOW: output id:%d resource:%p surface:%p", + EOM_DBG(" 11111111 output id:%d resource:%p surface:%p", output_id, resource, surface); if (!(ec = wl_resource_get_user_data(surface))) @@ -863,7 +865,7 @@ _e_eom_cb_wl_request_set_shell_window(struct wl_client *client, struct wl_resour if (resource == NULL || output_id <= 0 || surface == NULL) return; - EOM_DBG("SET SHELL WINDOW: output id:%d resource:%p surface:%p", + EOM_DBG("output id:%d resource:%p surface:%p", output_id, resource, surface); if (!(ec = wl_resource_get_user_data(surface))) @@ -879,7 +881,7 @@ _e_eom_cb_wl_request_set_shell_window(struct wl_client *client, struct wl_resour static void _e_eom_cb_wl_request_get_output_info(struct wl_client *client, struct wl_resource *resource, uint32_t output_id) { - EOM_DBG("output:%d\n", output_id); + EOM_DBG("output:%d", output_id); if (g_eom->outputs) { @@ -890,7 +892,7 @@ _e_eom_cb_wl_request_get_output_info(struct wl_client *client, struct wl_resourc { if (output->id == output_id) { - EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d\n", + EOM_DBG("send - id : %d, type : %d, mode : %d, w : %d, h : %d, w_mm : %d, h_mm : %d, conn : %d", output->id, output->type, output->mode, output->width, output->height, output->phys_width, output->phys_height, output->status); @@ -913,10 +915,10 @@ _e_eom_output_init(tdm_display *dpy) "tdm_display_get_output_count fail"); RETURNVALIFTRUE(count <= 1, EINA_FALSE, - "output count is 1. device doesn't support external outputs.\n"); + "output count is 1. device doesn't support external outputs."); g_eom->output_count = count - 1; - EOM_DBG("external output count : %d\n", g_eom->output_count); + EOM_DBG("external output count : %d", g_eom->output_count); /* skip main output id:0 */ /* start from 1 */ @@ -1046,7 +1048,7 @@ _e_eom_output_get_best_mode(tdm_output *output) ret = tdm_output_get_available_modes(output, &modes, &count); if (ret != TDM_ERROR_NONE) { - EOM_ERR("tdm_output_get_available_modes fail(%d)\n", ret); + EOM_ERR("tdm_output_get_available_modes fail(%d)", ret); return NULL; } @@ -1113,15 +1115,15 @@ _e_eom_output_start_mirror(E_EomOutputPtr eom_output) return; hal_layer = _e_eom_output_get_layer(eom_output); - GOTOIFTRUE(hal_layer == NULL, err, "ERROR: get hal layer\n"); + GOTOIFTRUE(hal_layer == NULL, err, "Get hal layer"); ret = _e_eom_output_create_buffers(eom_output, eom_output->width, eom_output->height); - GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: create buffers \n"); + GOTOIFTRUE(ret == EINA_FALSE, err, "Create buffers "); tdm_err = tdm_layer_get_info(hal_layer, &layer_info); - GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: get layer info: %d", tdm_err); + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "Get layer info: %d", tdm_err); - EOM_DBG("LAYER INFO: %dx%d, pos (x:%d, y:%d, w:%d, h:%d, dpos (x:%d, y:%d, w:%d, h:%d))", + 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, @@ -1132,17 +1134,17 @@ _e_eom_output_start_mirror(E_EomOutputPtr eom_output) eom_output->current_buffer = 0; tdm_err = tdm_layer_set_buffer(hal_layer, eom_output->dst_buffers[eom_output->current_buffer]); - GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: set buffer on layer:%d\n", tdm_err); + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "Set buffer on layer:%d", tdm_err); tdm_err = tdm_output_set_dpms(eom_output->output, TDM_OUTPUT_DPMS_ON); - GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: tdm_output_set_dpms on\n"); + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "tdm_output_set_dpms on"); /* get main surface */ ret = _e_eom_output_start_pp(eom_output); - GOTOIFTRUE(ret == EINA_FALSE, err, "ERROR: get root surfcae\n"); + GOTOIFTRUE(ret == EINA_FALSE, err, "Get root surfcae"); tdm_err = tdm_output_commit(eom_output->output, 0, _e_eom_cb_commit, eom_output); - GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "ERROR: commit crtc:%d\n", tdm_err); + GOTOIFTRUE(tdm_err != TDM_ERROR_NONE, err, "Commit crtc:%d", tdm_err); _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_MODE_MIRROR); _e_eom_output_state_set_attribute(eom_output, EOM_OUTPUT_ATTRIBUTE_NONE); @@ -1184,22 +1186,18 @@ _e_eom_output_deinit(E_EomOutputPtr eom_output) { err = tdm_layer_unset_buffer(eom_output->layer); if (err != TDM_ERROR_NONE) - EOM_DBG("EXT OUTPUT DEINIT: fail unset buffer:%d\n", err); - else - EOM_DBG("EXT OUTPUT DEINIT: ok unset buffer:%d\n", err); + EOM_DBG("fail unset buffer:%d", err); err = tdm_output_commit(eom_output->output, 0, NULL, eom_output); if (err != TDM_ERROR_NONE) - EOM_DBG ("EXT OUTPUT DEINIT: fail commit:%d\n", err); - else - EOM_DBG("EXT OUTPUT DEINIT: ok commit:%d\n", err); + EOM_DBG ("fail commit:%d", err); } /* TODO: do I need to do DPMS off? */ err = tdm_output_set_dpms(eom_output->output, TDM_OUTPUT_DPMS_OFF); if (err != TDM_ERROR_NONE) - EOM_ERR("EXT OUTPUT DEINIT: failed set DPMS off:%d\n", err); + EOM_ERR("set DPMS off:%d", err); for (i = 0; i < NUM_MAIN_BUF; i++) { @@ -1210,7 +1208,6 @@ _e_eom_output_deinit(E_EomOutputPtr eom_output) tbm_surface_destroy(eom_output->dst_buffers[i]); } - /*TODO: what is that for?*/ if (g_eom->main_output_state == DOWN) EINA_LIST_FOREACH(g_eom->clients, l, iterator) { @@ -1229,27 +1226,27 @@ _e_eom_output_get_layer(E_EomOutputPtr eom_output) tdm_layer_capability capa; tdm_info_layer layer_info; - RETURNVALIFTRUE(eom_output == NULL, NULL, "ERROR: eom_output is NULL"); - RETURNVALIFTRUE(eom_output->output == NULL, NULL, "ERROR: eom_output->output is NULL"); + RETURNVALIFTRUE(eom_output == NULL, NULL, "eom_output is NULL"); + RETURNVALIFTRUE(eom_output->output == NULL, NULL, "eom_output->output is NULL"); err = tdm_output_get_layer_count(eom_output->output, &count); if (err != TDM_ERROR_NONE) { - EOM_DBG ("tdm_output_get_layer_count fail(%d)\n", err); + EOM_DBG ("tdm_output_get_layer_count fail(%d)", err); return NULL; } for (i = 0; i < count; i++) { layer = (tdm_layer *)tdm_output_get_layer(eom_output->output, i, &err); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_output_get_layer fail(%d)\n", err); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_output_get_layer fail(%d)", err); err = tdm_layer_get_capabilities(layer, &capa); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_layer_get_capabilities fail(%d)\n", err); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_layer_get_capabilities fail(%d)", err); if (capa & TDM_LAYER_CAPABILITY_PRIMARY) { - EOM_DBG("TDM_LAYER_CAPABILITY_PRIMARY layer found : %d\n", i); + EOM_DBG("TDM_LAYER_CAPABILITY_PRIMARY layer found : %d", i); break; } } @@ -1269,7 +1266,7 @@ _e_eom_output_get_layer(E_EomOutputPtr eom_output) layer_info.transform = TDM_TRANSFORM_NORMAL; err = tdm_layer_set_info(layer, &layer_info); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_layer_set_info fail(%d)\n", err); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, NULL, "tdm_layer_set_info fail(%d)", err); return layer; } @@ -1298,21 +1295,21 @@ _e_eom_output_start_pp(E_EomOutputPtr eom_output) Eina_Bool ret = EINA_FALSE; src_buffer = _e_eom_util_get_output_surface(g_eom->main_output_name); - RETURNVALIFTRUE(src_buffer == NULL, EINA_FALSE, "ERROR: get root tdm surfcae\n"); + RETURNVALIFTRUE(src_buffer == NULL, EINA_FALSE, "Get root tdm surfcae"); tbm_surface_get_info(src_buffer, &src_buffer_info); - EOM_DBG("FRAMEBUFFER TDM: %dx%d bpp:%d size:%d", + EOM_DBG("main output info: %dx%d bpp:%d size:%d", src_buffer_info.width, src_buffer_info.height, src_buffer_info.bpp, src_buffer_info.size); /* TODO: if internal and external outputs are equal */ ret = _e_eom_pp_is_needed(g_eom->width, g_eom->height, eom_output->width, eom_output->height); - RETURNVALIFTRUE(ret == EINA_FALSE, EINA_TRUE, "pp is not required\n"); + RETURNVALIFTRUE(ret == EINA_FALSE, EINA_TRUE, "pp is not required"); ret = _e_eom_pp_init(eom_output, src_buffer); - RETURNVALIFTRUE(ret == EINA_FALSE, EINA_FALSE, "ERROR: init pp\n"); + RETURNVALIFTRUE(ret == EINA_FALSE, EINA_FALSE, "Init pp"); return EINA_TRUE; } @@ -1326,11 +1323,11 @@ _e_eom_output_create_buffers(E_EomOutputPtr eom_output, int width, int height) for (i = 0; i < NUM_MAIN_BUF; i++) { eom_output->dst_buffers[i] = _e_eom_util_create_buffer(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - GOTOIFTRUE(eom_output->dst_buffers[i] == NULL, err, "ERROR: create dst buffer"); + GOTOIFTRUE(eom_output->dst_buffers[i] == NULL, err, "Create dst buffer"); } eom_output->dummy_buffer = _e_eom_util_create_buffer(width, height, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - GOTOIFTRUE(eom_output->dummy_buffer == NULL, err, "ERROR: create dummy buffer"); + GOTOIFTRUE(eom_output->dummy_buffer == NULL, err, "Create dummy buffer"); return EINA_TRUE; @@ -1353,16 +1350,16 @@ _e_eom_window_set_internal(struct wl_resource *resource, int output_id, E_Client return; cdata = ec->comp_data; - RETURNIFTRUE(cdata == NULL, "ERROR: cdata is NULL"); - RETURNIFTRUE(cdata->shell.configure_send == NULL, "ERROR: cdata->shell.configure_send is NULL"); + RETURNIFTRUE(cdata == NULL, "cdata is NULL"); + RETURNIFTRUE(cdata->shell.configure_send == NULL, " cdata->shell.configure_send is NULL"); eom_client = _e_eom_client_get_by_resource(resource); - RETURNIFTRUE(eom_client == NULL, "ERROR: client is NULL"); + RETURNIFTRUE(eom_client == NULL, "eom_client is NULL"); - RETURNIFTRUE(eom_client->current == EINA_FALSE, "ERROR: not current client is going to set its window"); + RETURNIFTRUE(eom_client->current == EINA_FALSE, " not current client is going to set its window"); eom_output = _e_eom_output_get_by_id(output_id); - RETURNIFTRUE(eom_output == NULL, "ERROR: EOM output is NULL"); + RETURNIFTRUE(eom_output == NULL, "eom_output is NULL"); cdata->shell.configure_send(ec->comp_data->shell.surface, 0, eom_output->width, eom_output->height); @@ -1384,7 +1381,7 @@ _e_eom_pp_init(E_EomOutputPtr eom_output, tbm_surface_h src_buffer) int x, y, w, h; pp = tdm_display_create_pp(g_eom->dpy, &err); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: create pp:%d\n", err); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "Create pp:%d", err); eom_output->pp = pp; @@ -1393,7 +1390,7 @@ _e_eom_pp_init(E_EomOutputPtr eom_output, tbm_surface_h src_buffer) eom_output->width, eom_output->height, &x, &y, &w, &h); - EOM_DBG("PP calculation: x:%d, y:%d, w:%d, h:%d\n", x, y, w, h); + EOM_DBG("PP calculation: x:%d, y:%d, w:%d, h:%d", x, y, w, h); pp_info.src_config.size.h = g_eom->width; pp_info.src_config.size.v = g_eom->height; @@ -1417,19 +1414,19 @@ _e_eom_pp_init(E_EomOutputPtr eom_output, tbm_surface_h src_buffer) pp_info.flags = 0; err = tdm_pp_set_info(pp, &pp_info); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: set pp info:%d\n", err); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "Set pp info:%d", err); eom_output->pp_buffer = !eom_output->current_buffer; err = tdm_buffer_add_release_handler(eom_output->dst_buffers[eom_output->pp_buffer], _e_eom_cb_pp, eom_output); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: set pp hadler:%d\n", err); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "Set pp handler:%d", err); err = tdm_pp_attach(pp, src_buffer, eom_output->dst_buffers[eom_output->pp_buffer]); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: pp attach:%d\n", err); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "pp attach:%d", err); err = tdm_pp_commit(eom_output->pp); - RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "ERROR: pp commit:%d\n", err); + RETURNVALIFTRUE(err != TDM_ERROR_NONE, EINA_FALSE, "pp commit:%d", err); return EINA_TRUE; } @@ -1446,6 +1443,20 @@ _e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h) return EINA_FALSE; } +static void +_e_eom_util_get_debug_env() +{ + char *env = getenv("EOM_SERVER_DEBUG"); + + /* TODO: DLOG */ + if (env) + eom_server_debug_on =(atoi(env)) > 0 ? EINA_TRUE : EINA_FALSE; + else + eom_server_debug_on = EINA_FALSE; + + EOM_INF("EOM_SERVER_DEBUG = %s", eom_server_debug_on > 0 ? "ON" : "OFF"); +} + static tbm_surface_h _e_eom_util_create_buffer(int width, int height, int format, int flags) { @@ -1453,14 +1464,14 @@ _e_eom_util_create_buffer(int width, int height, int format, int flags) tbm_surface_h buffer = NULL; buffer = tbm_surface_internal_create_with_flags(width, height, format, flags); - RETURNVALIFTRUE(buffer == NULL, NULL, "ERROR: create buffer"); + RETURNVALIFTRUE(buffer == NULL, NULL, "Create buffer"); 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("ERROR: map buffer"); + EOM_ERR("map buffer"); return NULL; } @@ -1513,7 +1524,7 @@ _e_eom_util_get_output_surface(const char *name) if (primary_output == NULL) { - EOM_ERR("ERROR: get primary output.(%s)\n", name); + EOM_ERR("Get primary output.(%s)", name); EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev) { primary_output = ecore_drm_output_primary_get(dev); @@ -1523,7 +1534,7 @@ _e_eom_util_get_output_surface(const char *name) if (primary_output == NULL) { - EOM_ERR("ERROR: get primary output.(%s)\n", name); + EOM_ERR("Get primary output.(%s)", name); return NULL; } } @@ -1531,13 +1542,13 @@ _e_eom_util_get_output_surface(const char *name) tdm_output_obj = tdm_display_get_output(g_eom->dpy, 0, &err); if (tdm_output_obj == NULL || err != TDM_ERROR_NONE) { - EOM_ERR("tdm_display_get_output 0 fail\n"); + EOM_ERR("tdm_display_get_output 0 fail"); return NULL; } err = tdm_output_get_layer_count(tdm_output_obj, &count); if (err != TDM_ERROR_NONE) { - EOM_ERR("tdm_output_get_layer_count fail\n"); + EOM_ERR("tdm_output_get_layer_count fail"); return NULL; } @@ -1551,7 +1562,7 @@ _e_eom_util_get_output_surface(const char *name) tbm = tdm_layer_get_displaying_buffer(layer, &err); if (err != TDM_ERROR_NONE) { - EOM_ERR("tdm_layer_get_displaying_buffer fail\n"); + EOM_ERR("tdm_layer_get_displaying_buffer fail"); return NULL; } break; @@ -1732,6 +1743,8 @@ _e_eom_init() { Eina_Bool ret = EINA_FALSE; + _e_eom_util_get_debug_env(); + EINA_SAFETY_ON_NULL_GOTO(e_comp_wl, err); g_eom = E_NEW(E_Eom, 1); @@ -1749,7 +1762,7 @@ _e_eom_init() EINA_SAFETY_ON_NULL_GOTO(g_eom->global, err); ret = _e_eom_init_internal(); - GOTOIFTRUE(ret == EINA_FALSE, err, "failed init_internal()"); + GOTOIFTRUE(ret == EINA_FALSE, err, "init_internal() failed"); E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_ACTIVATE, _e_eom_cb_ecore_drm_activate, g_eom); E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_OUTPUT, _e_eom_cb_ecore_drm_output, g_eom); @@ -1780,7 +1793,7 @@ _e_eom_init_internal() if (_e_eom_output_init(g_eom->dpy) != EINA_TRUE) { - EOM_ERR("_e_eom_output_init fail\n"); + EOM_ERR("_e_eom_output_init fail"); goto err; } diff --git a/src/e_mod_main.h b/src/e_mod_main.h index b041517..7b0ff9a 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -3,16 +3,29 @@ #include "eom-server-protocol.h" +extern Eina_Bool eom_server_debug_on; + +#define ALEN(array) (sizeof(array) / sizeof(array)[0]) + #define CHECK_ERR(val) if (WL_KEYROUTER_ERROR_NONE != val) return; #define CHECK_ERR_VAL(val) if (WL_KEYROUTER_ERROR_NONE != val) return val; #define CHECK_NULL(val) if (!val) return; #define CHECK_NULL_VAL(val) if (!val) return val; -#define EOM_ERR(msg, ARG...) ERR("[eom module][%s:%d] "msg"\n", __FUNCTION__, __LINE__, ##ARG) -#define EOM_WARN(msg, ARG...) WARN("[eom module][%s:%d] "msg"\n", __FUNCTION__, __LINE__, ##ARG) -#define EOM_DBG(msg, ARG...) DBG("[eom module][%s:%d] "msg"\n", __FUNCTION__, __LINE__, ##ARG) +#define EOM_INF(msg, ARG...) INF("[eom module][%s:%d] " msg "\n", __FUNCTION__, __LINE__, ##ARG) +#define EOM_ERR(msg, ARG...) ERR("[eom module][%s:%d] ERR: " msg "\n", __FUNCTION__, __LINE__, ##ARG) -#define ALEN(array) (sizeof(array) / sizeof(array)[0]) +#define EOM_DBG(msg, ARG...) \ +{ \ + if (eom_server_debug_on) \ + DBG("[eom module][%s:%d] DBG: " msg "\n", __FUNCTION__, __LINE__, ##ARG); \ +} + +#define EOM_WARN(msg, ARG...) \ +{ \ + if (eom_server_debug_on) \ + WARN("[eom module][%s:%d] WARN: " msg "\n", __FUNCTION__, __LINE__, ##ARG); \ +} #define RETURNIFTRUE(statement, msg, ARG...) \ if (statement) \ @@ -192,6 +205,7 @@ static void _e_eom_window_set_internal(struct wl_resource *resource, int output_ static Eina_Bool _e_eom_pp_init(E_EomOutputPtr eom_output, tbm_surface_h src_buffer); static Eina_Bool _e_eom_pp_is_needed(int src_w, int src_h, int dst_w, int dst_h); +static void _e_eom_util_get_debug_env(); static tbm_surface_h _e_eom_util_create_buffer(int width, int height, int format, int flags); static E_EomClientBufferPtr _e_eom_util_create_client_buffer(E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer); -- 2.7.4 From 10d2bd88562ef212f725b78b7641143b2282a04e Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Fri, 8 Jul 2016 19:33:55 +0300 Subject: [PATCH 16/16] hide external window from Enlightenment's compositting Change-Id: Ie66d91d58a1ad5e368da8407e5cd6c385d1e605a --- src/e_mod_main.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++------- src/e_mod_main.h | 14 ++++++++-- 2 files changed, 84 insertions(+), 12 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 24bb7d8..8cf9ad0 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -388,7 +388,7 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) "resource is NULL"); /* - EOM_DBG(" wl_buff:%dx%d type:%d", + EOM_DBG("wl_buff:%dx%d type:%d", external_wl_buffer->w, external_wl_buffer->h, external_wl_buffer->type); @@ -844,7 +844,7 @@ _e_eom_cb_wl_request_set_xdg_window(struct wl_client *client, struct wl_resource if (resource == NULL || output_id <= 0 || surface == NULL) return; - EOM_DBG(" 11111111 output id:%d resource:%p surface:%p", + EOM_DBG("set xdg output id:%d resource:%p surface:%p", output_id, resource, surface); if (!(ec = wl_resource_get_user_data(surface))) @@ -865,7 +865,7 @@ _e_eom_cb_wl_request_set_shell_window(struct wl_client *client, struct wl_resour if (resource == NULL || output_id <= 0 || surface == NULL) return; - EOM_DBG("output id:%d resource:%p surface:%p", + EOM_DBG("set shell output id:%d resource:%p surface:%p", output_id, resource, surface); if (!(ec = wl_resource_get_user_data(surface))) @@ -904,6 +904,34 @@ _e_eom_cb_wl_request_get_output_info(struct wl_client *client, struct wl_resourc } static Eina_Bool +_e_eom_cb_comp_object_redirected(void *data, E_Client *ec) +{ + E_EomCompObjectInterceptHookData *hook_data; + + EOM_DBG("_e_eom_cb_comp_object_redirected"); + + RETURNVALIFTRUE(data == NULL, EINA_TRUE, "data is NULL"); + + hook_data = (E_EomCompObjectInterceptHookData* )data; + + RETURNVALIFTRUE(hook_data->ec == NULL, EINA_TRUE, "hook_data->ec is NULL"); + RETURNVALIFTRUE(hook_data->hook == NULL, EINA_TRUE, "hook_data->hook is NULL"); + RETURNVALIFTRUE(hook_data->ec != ec, EINA_TRUE, "hook_data->ec != ec"); + + /* Hide the window from Enlightenment main screen */ + e_comp_object_redirected_set(ec->frame, EINA_FALSE); + + e_comp_object_intercept_hook_del(hook_data->hook); + + g_eom->comp_object_intercept_hooks = eina_list_remove(g_eom->comp_object_intercept_hooks, + hook_data); + + free(hook_data); + + return EINA_TRUE; +} + +static Eina_Bool _e_eom_output_init(tdm_display *dpy) { tdm_error ret = TDM_ERROR_NONE; @@ -1345,28 +1373,31 @@ _e_eom_window_set_internal(struct wl_resource *resource, int output_id, E_Client E_EomOutputPtr eom_output = NULL; E_EomClientPtr eom_client = NULL; E_Comp_Client_Data *cdata = NULL; + Eina_Bool ret = EINA_FALSE; if (resource == NULL || output_id <= 0 || ec == NULL) return; cdata = ec->comp_data; RETURNIFTRUE(cdata == NULL, "cdata is NULL"); - RETURNIFTRUE(cdata->shell.configure_send == NULL, " cdata->shell.configure_send is NULL"); + RETURNIFTRUE(cdata->shell.configure_send == NULL, "cdata->shell.configure_send is NULL"); eom_client = _e_eom_client_get_by_resource(resource); RETURNIFTRUE(eom_client == NULL, "eom_client is NULL"); - RETURNIFTRUE(eom_client->current == EINA_FALSE, " not current client is going to set its window"); + RETURNIFTRUE(eom_client->current == EINA_FALSE, "not current client is going to set its window"); eom_output = _e_eom_output_get_by_id(output_id); RETURNIFTRUE(eom_output == NULL, "eom_output is NULL"); - cdata->shell.configure_send(ec->comp_data->shell.surface, 0, eom_output->width, eom_output->height); + ret = _e_eom_util_add_comp_object_redirected_hook(ec); + RETURNIFTRUE(ret != EINA_TRUE, "Set redirect comp hook failed"); - /* Hide the window from e compositing - * TODO: It is not work find other solution - */ - e_comp_object_redirected_set(ec->frame, 0); + EOM_DBG("e_comp_object_redirected_set (ec->frame:%p)\n", ec->frame); + + /* Send reconfigure event to a client which will resize its window to + * external output resolution in respond */ + cdata->shell.configure_send(ec->comp_data->shell.surface, 0, eom_output->width, eom_output->height); /* ec is used in buffer_change callback for distinguishing external ec and its buffers */ eom_client->ec = ec; @@ -1472,6 +1503,7 @@ _e_eom_util_create_buffer(int width, int height, int format, int flags) &buffer_info) != TBM_SURFACE_ERROR_NONE) { EOM_ERR("map buffer"); + tbm_surface_destroy(buffer); return NULL; } @@ -1604,6 +1636,36 @@ _e_eom_util_calculate_fullsize(int src_h, int src_v, int dst_size_h, int dst_siz } } +static Eina_Bool +_e_eom_util_add_comp_object_redirected_hook(E_Client *ec) +{ + E_EomCompObjectInterceptHookData *hook_data = NULL; + E_Comp_Object_Intercept_Hook *hook = NULL; + + hook_data = E_NEW(E_EomCompObjectInterceptHookData, 1); + GOTOIFTRUE(hook_data == NULL, err, "hook_data = NULL"); + + hook_data->ec = ec; + + hook = e_comp_object_intercept_hook_add(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, + _e_eom_cb_comp_object_redirected, + hook_data); + GOTOIFTRUE(hook == NULL, err, "hook = NULL"); + + hook_data->hook = hook; + + g_eom->comp_object_intercept_hooks = eina_list_append(g_eom->comp_object_intercept_hooks, + hook_data); + + EOM_DBG("_e_eom_redirected_hook have been added"); + return EINA_TRUE; + +err: + if (hook_data) + free(hook_data); + return EINA_FALSE; +} + static int _e_eom_util_get_stamp() { diff --git a/src/e_mod_main.h b/src/e_mod_main.h index 7b0ff9a..7ebb457 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -62,6 +62,7 @@ typedef struct _E_Eom_Out_Mode E_EomOutMode, *E_EomOutModePtr; typedef struct _E_Eom_Output E_EomOutput, *E_EomOutputPtr; typedef struct _E_Eom_Client_Buffer E_EomClientBuffer, *E_EomClientBufferPtr; typedef struct _E_Eom_Client E_EomClient, *E_EomClientPtr; +typedef struct _E_Eom_Comp_Object_Intercept_Hook_Data E_EomCompObjectInterceptHookData; typedef enum { @@ -128,10 +129,11 @@ struct _E_Eom int width; int height; + unsigned int output_count; + Eina_List *outputs; Eina_List *clients; Eina_List *handlers; - Eina_List *outputs; - unsigned int output_count; + Eina_List *comp_object_intercept_hooks; }; struct _E_Eom_Client @@ -158,6 +160,12 @@ struct _E_Eom_Client_Buffer unsigned long stamp; }; +struct _E_Eom_Comp_Object_Intercept_Hook_Data +{ + E_Client *ec; + E_Comp_Object_Intercept_Hook *hook; +}; + static Eina_Bool _e_eom_init(); static Eina_Bool _e_eom_init_internal(); static void _e_eom_deinit(); @@ -188,6 +196,7 @@ static void _e_eom_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequen void *user_data); static void _e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type type, tdm_value value, void *user_data); +static Eina_Bool _e_eom_cb_comp_object_redirected(void *data, E_Client *ec); static Eina_Bool _e_eom_output_init(tdm_display *dpy); static const tdm_output_mode *_e_eom_output_get_best_mode(tdm_output *output); @@ -212,6 +221,7 @@ static E_EomClientBufferPtr _e_eom_util_create_client_buffer(E_Comp_Wl_Buffer *w static void _e_eom_util_calculate_fullsize(int src_h, int src_v, int dst_size_h, int dst_size_v, int *dst_x, int *dst_y, int *dst_w, int *dst_h); static tbm_surface_h _e_eom_util_get_output_surface(const char *name); +static Eina_Bool _e_eom_util_add_comp_object_redirected_hook(E_Client *ec); static int _e_eom_util_get_stamp(); #if 0 static void _e_eom_util_draw(tbm_surface_h surface); -- 2.7.4