From dce0e530d738119609663071dcb63261ebb5026d Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Mon, 30 May 2016 16:28:54 +0300 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 06/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 07/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 08/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 From 4e8ee6517f90d82e57a577d14fe829de0b4d06d0 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Tue, 12 Jul 2016 17:26:54 +0900 Subject: [PATCH 09/16] disable hwc redering of external outputs Change-Id: I2bc0e2e9bd8eba459842fb0b59aff9e87f740051 Signed-off-by: Junkyeong Kim --- configure.ac | 19 +++++++++++++++++++ src/e_mod_main.c | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/configure.ac b/configure.ac index 56d3d27..b1cc3a2 100644 --- a/configure.ac +++ b/configure.ac @@ -51,6 +51,25 @@ if test "x${have_wayland_only}" != "xno"; then AC_DEFINE_UNQUOTED([HAVE_WAYLAND_ONLY],[1],[enable wayland-only version of enlightenment]) fi +have_hwc=no +AC_ARG_ENABLE([hwc], + AS_HELP_STRING([--enable-hwc],[enable hwc @<:@default=enabled@:>@]), + [e_cv_want_hwc=$enableval], + [e_cv_want_hwc=yes]) +AC_MSG_CHECKING([whether HWC support is enabled]) +AC_MSG_RESULT([${e_cv_want_hwc}]) + +if test "x$e_cv_want_hwc" != "xno";then + PKG_CHECK_MODULES([HWC], [gbm], + [ + have_hwc=yes + AC_DEFINE_UNQUOTED([HAVE_HWC],[1],[enable hwc support]) + ]) +else + have_hwc=no +fi +AM_CONDITIONAL([HAVE_HWC], [test "x${have_hwc}" = "xyes"]) + dnl ======================================================================== # checks for wayland only argument dnl ======================================================================== diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 8cf9ad0..67ac261 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -999,6 +999,10 @@ _e_eom_output_init(tdm_display *dpy) goto err; } +#ifdef HAVE_HWC + e_comp_hwc_disable_output_hwc_rendering(i, 0); +#endif + if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { EOM_DBG("create(%d)output, type:%d, status:%d", -- 2.7.4 From 2344cff4a3387debd377fff3b0aa3913b0e09fec Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Wed, 13 Jul 2016 17:36:57 +0900 Subject: [PATCH 10/16] change tdm udev callback plug checking condition Change-Id: I8367811e45f8ff8307439540e403594b9349ad16 Signed-off-by: Junkyeong Kim --- src/e_mod_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 67ac261..b6ae4bb 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -587,7 +587,7 @@ _e_eom_cb_tdm_output_status_change(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; @@ -653,7 +653,7 @@ _e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type ty } } } - else /*TDM_OUTPUT_CONN_STATUS_DISCONNECTED*/ + else if (plug == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { if (eom_output->state == MIRROR) _e_eom_output_stop_mirror(eom_output); -- 2.7.4 From f41a01602d917bef7ae1961deb9ede966479c257 Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Thu, 14 Jul 2016 14:50:50 +0300 Subject: [PATCH 11/16] forbid enlightenment reconfigure eom client's resolution Since Enlightenment client has reconfigured its window to fit external output resolution and Enlightenment no nothing about external outputs Enlightenment sees that client's resolution differs form main screen resolution. Therefore, Enlightenment is trying to resize it back to main screen resolution. It uses timer for that purpose. To forbid it just delte the timer Change-Id: Ieaee40e7a20bfeb162bdd8e35ee466f56d943035 Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index b6ae4bb..4d7a1dd 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -388,12 +388,29 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) "resource is NULL"); /* - EOM_DBG("wl_buff:%dx%d type:%d", - external_wl_buffer->w, - external_wl_buffer->h, - external_wl_buffer->type); + EOM_DBG("wl_buff:%p type:%d %dx%d ", + external_wl_buffer, + external_wl_buffer->type, + external_wl_buffer->w, + external_wl_buffer->h, + ); */ + /* Since Enlightenment client has reconfigured its window to fit + * external output resolution and Enlightenment no nothing about + * external outputs Enlightenment sees that client's resolution + * differs form main screen resolution. Therefore, Enlightenment + * is trying to resize it back to main screen resolution. It uses + * timer for that purpose. To forbid it just delte the timer */ + + /* TODO: it works but maybe there is better solution exists ? + * Also I do not know how it affects on performance */ + if (ec->map_timer) + { + EOM_DBG("delete map_timer"); + E_FREE_FUNC(ec->map_timer, ecore_timer_del); + } + /* TODO: support buffers smaller then output resolution */ if (external_wl_buffer->w != eom_output->width || external_wl_buffer->h != eom_output->height ) -- 2.7.4 From 468fc9e6c79e0dc007834a875dbc572062f4d7e6 Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Thu, 21 Jul 2016 11:17:37 +0300 Subject: [PATCH 12/16] using queue for client's buffers syncronization changes: 1. added queue of buffers syncronization. 2. added possibility of substitution client buffers with dummy one by defining DRAW_DUMMY. 3. added possibility of dumping client buffers by defining DUMP_PRESENTATION. Change-Id: I4f221ba4cc8e876f4f4a8e4f51ccbdc9067a29fd Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 269 ++++++++++++++++++++++++++++++++++++++++++------------- src/e_mod_main.h | 43 ++++++++- 2 files changed, 245 insertions(+), 67 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 4d7a1dd..6cbea65 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -15,6 +15,10 @@ 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; +#ifdef DUMP_PRESENTATION +static int dump = 0; +#endif + static const struct wl_eom_interface _e_eom_wl_implementation = { _e_eom_cb_wl_request_set_attribute, @@ -198,7 +202,9 @@ _e_eom_cb_wl_bind(struct wl_client *client, void *data, uint32_t version, uint32 new_client->current = EINA_FALSE; new_client->output_id = -1; new_client->ec = NULL; - new_client->buffers = NULL; + new_client->buffers_show = NULL; + new_client->buffers_del = NULL; + new_client->first_buffer = EINA_TRUE; g_eom->clients = eina_list_append(g_eom->clients, new_client); } @@ -225,12 +231,12 @@ _e_eom_cb_wl_resource_destory(struct wl_resource *resource) output = _e_eom_output_get_by_id(client->output_id); GOTOIFTRUE(output == NULL, end2, "output is NULL"); - _e_eom_client_free_buffers(client); - _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; + _e_eom_client_free_buffers(client); + /* TODO: process case when output is not connected */ if (output->state == NONE) goto end; @@ -276,7 +282,7 @@ _e_eom_cb_ecore_drm_output(void *data EINA_UNUSED, int type EINA_UNUSED, void *e Ecore_Drm_Event_Output *e = NULL; char buff[PATH_MAX]; - if (!(e = event)) return ECORE_CALLBACK_PASS_ON;; + 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", 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); @@ -428,34 +434,20 @@ _e_eom_cb_client_buffer_change(void *data, int type, void *event) ECORE_CALLBACK_PASS_ON, "Client tbm buffer is NULL"); - EOM_DBG("tbm_buffer %p", external_tbm_buffer); + /* EOM_DBG("tbm_buffer %p", external_tbm_buffer); */ #if 0 _e_eom_util_draw(external_tbm_buffer); #endif - /* 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("mmap buffer: %d", ret); - return ECORE_CALLBACK_PASS_ON; - } - - EOM_DBG("tbm_buffer: %dx%d", surface_info.width, surface_info.height); - - tbm_surface_unmap(external_tbm_buffer); - */ - - client_buffer = _e_eom_util_create_client_buffer(external_wl_buffer, external_tbm_buffer); + EOM_DBG("BUFF_CHANGE >>>>>>>>>>"); + client_buffer = _e_eom_util_create_client_buffer(eom_client, external_wl_buffer, external_tbm_buffer); RETURNVALIFTRUE(client_buffer == NULL, ECORE_CALLBACK_PASS_ON, "Alloc client buffer"); _e_eom_client_add_buffer(eom_client, client_buffer); + EOM_DBG("BUFF_CHANGE <<<<<<<<<<"); eom_output->state = PRESENTATION; @@ -528,26 +520,50 @@ _e_eom_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS 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, "commit event: mirror: commit"); + RETURNIFTRUE(err != TDM_ERROR_NONE, "commit event: mirror: commit err:%d", err); } else if (eom_output->state == PRESENTATION) { eom_client = _e_eom_client_get_current_by_id(eom_output->id); + EOM_DBG("COMMIT +++++++++++++++>"); + client_buffer = _e_eom_client_get_buffer(eom_client); if (client_buffer == NULL) { external_buffer = eom_output->dummy_buffer; - EOM_DBG("dummy buffer was substitute"); + EOM_DBG("substitute dummy buffer"); } else external_buffer = client_buffer->tbm_buffer; +#ifdef DRAW_DUMMY + EOM_DBG("COMMIT draw and set dummy"); + + _e_eom_util_draw(eom_output->dummy_buffer); + external_buffer = eom_output->dummy_buffer; +#endif + +#ifdef DUMP_PRESENTATION + if (dump < 29) + { + tbm_surface_internal_dump_buffer(external_buffer, "kyky"); + dump++; + } + else + { + tbm_surface_internal_dump_end(); + EOM_DBG("dump end"); + } +#endif + err = tdm_layer_set_buffer(eom_output->layer, external_buffer); - RETURNIFTRUE(err != TDM_ERROR_NONE, "commit event: presentation: set client buffer"); + RETURNIFTRUE(err != TDM_ERROR_NONE, "commit event: presentation: set buffer"); err = tdm_output_commit(eom_output->output, 0, _e_eom_cb_commit, eom_output); - RETURNIFTRUE(err != TDM_ERROR_NONE, "commit event: presentation: commit"); + RETURNIFTRUE(err != TDM_ERROR_NONE, "commit event: presentation: commit err:%d", err); + + EOM_DBG("COMMIT <+++++++++++++++"); } } @@ -926,7 +942,6 @@ _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; @@ -1535,24 +1550,35 @@ _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) +_e_eom_util_create_client_buffer(E_EomClientPtr client, E_Comp_Wl_Buffer *wl_buffer, tbm_surface_h tbm_buffer) { E_EomClientBufferPtr buffer = NULL; buffer = E_NEW(E_EomClientBuffer, 1); - if(buffer == NULL) - return NULL; + RETURNVALIFTRUE(buffer == NULL, NULL, "Allocate new client buffer") + + /* TODO: Internal and External frame rate are same */ + + /* Forbid E sending 'wl_buffer_send_release' event to external clients */ + wl_buffer->busy++; buffer->wl_buffer = wl_buffer; buffer->tbm_buffer = tbm_buffer; - /* TODO: It is not used right now */ - buffer->stamp = _e_eom_util_get_stamp(); - /* I am not sure if it is necessary */ - tbm_surface_internal_ref(tbm_buffer); + EOM_DBG("new client buffer wl:%p tbm:%p", + buffer->wl_buffer, buffer->tbm_buffer); + +#ifdef DUMP_PRESENTATION + if (dump == 0) + { + EOM_DBG("dump start"); + tbm_surface_internal_dump_start("/A", wl_buffer->w, wl_buffer->h, 30); + } +#endif - /* TODO: Do we need reference that buffer? */ - /* e_comp_wl_buffer_reference(buffer->tbm_buffer, NULL);*/ +#if 0 + buffer->stamp = _e_eom_util_get_stamp(); +#endif return buffer; } @@ -1687,6 +1713,7 @@ err: return EINA_FALSE; } +#if 0 static int _e_eom_util_get_stamp() { @@ -1696,41 +1723,52 @@ _e_eom_util_get_stamp() return ((tp.tv_sec * 1000) + (tp.tv_nsec / 1000)); } +#endif + +#ifdef DRAW_DUMMY + +int square_x = 0; +int square_w = 200; -#if 0 static void _e_eom_util_draw(tbm_surface_h surface) { + unsigned char rw = 0, gw = 0, bw = 0, aw = 0; + unsigned char r = 255, g = 255, b = 255, a = 0; + + unsigned int *mm = NULL; int i = 0, j = 0; + int w = (int)tbm_surface_get_width(surface); + int h = (int)tbm_surface_get_height(surface); + tbm_bo bo = tbm_surface_internal_get_bo(surface, 0); RETURNIFTRUE(bo == NULL, "bo is NULL"); - unsigned int *mm = (unsigned int *)tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE).ptr; + mm = (unsigned int *)tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE).ptr; RETURNIFTRUE(mm == NULL, "mm is NULL"); - unsigned char r = 0; - unsigned char g = 255; - unsigned char b = 0; - unsigned char a = 0; - - int w = (int)tbm_surface_get_width(surface); - int h = (int)tbm_surface_get_height(surface); - - for (i = 0; i < w; i++) - for (j = 0; j < h/2; j++) + for (i = 0; i < h; i++) + for (j = 0; j < w; j++) { - mm[i*w + j] = r << 24 | g << 16 | b << 8 | a; + if (j > square_x && j < square_x + square_w) + mm[i*w + j] = r << 24 | g << 16 | b << 8 | a; + else + mm[i*w + j] = rw << 24 | gw << 16 | bw << 8 | aw; } + + square_x += 1; + if (square_x + square_w> w) + square_x = 0; + + tbm_bo_unmap(bo); } #endif static void _e_eom_client_add_buffer(E_EomClientPtr client, E_EomClientBufferPtr buffer) { - _e_eom_client_free_buffers(client); - - client->buffers = eina_list_append(client->buffers, buffer); + client->buffers_show = eina_list_append(client->buffers_show, buffer); } static void @@ -1739,18 +1777,38 @@ _e_eom_client_free_buffers(E_EomClientPtr client) E_EomClientBufferPtr buffer = NULL; Eina_List *l; - EINA_LIST_FOREACH(client->buffers, l, buffer) + EINA_LIST_FOREACH(client->buffers_show, l, buffer) + { + if (buffer) + { + client->buffers_show = eina_list_remove(client->buffers_show, buffer); + + /* TODO: not sure if it is necessary */ + if (buffer->tbm_buffer && client->first_buffer == EINA_FALSE) + tbm_surface_internal_unref(buffer->tbm_buffer); + + /* TODO: not sure if it is necessary */ + if (buffer->wl_buffer) + buffer->wl_buffer->busy--; + + E_FREE(buffer); + } + } + + EINA_LIST_FOREACH(client->buffers_del, l, buffer) { if (buffer) { - /* I am not sure if it is necessary */ + client->buffers_del= eina_list_remove(client->buffers_del, buffer); + + /* TODO: not sure if it is necessary */ if (buffer->tbm_buffer) tbm_surface_internal_unref(buffer->tbm_buffer); - /* TODO: Do we need reference that buffer? */ - /* e_comp_wl_buffer_reference(buffer->tbm_buffer, NULL); */ + /* TODO: not sure if it is necessary */ + if (buffer->wl_buffer) + buffer->wl_buffer->busy--; - client->buffers = eina_list_remove(client->buffers, buffer); E_FREE(buffer); } } @@ -1759,17 +1817,102 @@ _e_eom_client_free_buffers(E_EomClientPtr client) static E_EomClientBufferPtr _e_eom_client_get_buffer(E_EomClientPtr client) { - E_EomClientBufferPtr buffer = NULL; + E_EomClientBufferPtr show_buffer = NULL; + E_EomClientBufferPtr prev_buffer = NULL; + E_EomClientBufferPtr del_buffer = NULL; Eina_List *l; - /* There must be only one buffer */ - EINA_LIST_FOREACH(client->buffers, l, buffer) + /* TODO: is it possible that a client has only one buffet to draw too? */ + RETURNVALIFTRUE(eina_list_count(client->buffers_show) == 0, NULL, + "eom client (%p) do not have buffers to be shown", client); + + /* If there is only one buffer we have slow client, just return the buffer */ + if (eina_list_count(client->buffers_show) == 1) { - if (buffer) - return buffer; + show_buffer = eina_list_nth(client->buffers_show, 0); + RETURNVALIFTRUE(show_buffer == NULL, NULL, + "eom client (%p) buffer is NULL", client); + + EOM_DBG("one wl:%p tbm:%p", show_buffer->wl_buffer, show_buffer->tbm_buffer); + + return show_buffer; } - return NULL; + if (client->first_buffer == EINA_TRUE) + { + show_buffer= eina_list_nth(client->buffers_show, 0); + RETURNVALIFTRUE(show_buffer == NULL, NULL, "eom client (%p) first buffer is NULL", client); + + EOM_DBG("first wl:%p tbm:%p", show_buffer->wl_buffer, show_buffer->tbm_buffer); + + /* I am not sure if it is necessary */ + EOM_DBG("ref first"); + tbm_surface_internal_ref(show_buffer->tbm_buffer); + + client->first_buffer = EINA_FALSE; + return show_buffer; + } + + EINA_LIST_FOREACH(client->buffers_del, l, del_buffer) + { + if (del_buffer) + { + client->buffers_del = eina_list_remove(client->buffers_del, del_buffer); + + if (del_buffer->wl_buffer) + { + del_buffer->wl_buffer->busy--; + EOM_DBG("wl_buffer:%p busy:%d", del_buffer->wl_buffer, del_buffer->wl_buffer->busy); + if (del_buffer->wl_buffer->busy == 0) + { + if (del_buffer->wl_buffer->type != E_COMP_WL_BUFFER_TYPE_TBM) + { + if (!wl_resource_get_client(del_buffer->wl_buffer->resource)) + { + EOM_DBG("wl_buffer->resource is NULL"); + return NULL; + } + + wl_buffer_send_release(del_buffer->wl_buffer->resource); + } + } + } + + EOM_DBG("del wl:%p tbm:%p", del_buffer->wl_buffer, del_buffer->tbm_buffer); + + if (del_buffer->tbm_buffer) + { + EOM_DBG("before old unref"); + tbm_surface_internal_unref(del_buffer->tbm_buffer); + } + + /* TODO: should wl_buffer and tbm_surface be deleted here? */ + E_FREE(del_buffer); + } + } + + /* TODO: case of 2 or n buffers */ + prev_buffer = eina_list_nth(client->buffers_show, 0); + RETURNVALIFTRUE(prev_buffer == NULL, NULL, "eom client (%p) old_buffer is NULL", client); + + EOM_DBG("old wl:%p tbm:%p", prev_buffer->wl_buffer, prev_buffer->tbm_buffer); + + client->buffers_show = eina_list_remove(client->buffers_show, prev_buffer); + client->buffers_del = eina_list_append(client->buffers_del, prev_buffer); + + /* Take next buffer to be shown on external output */ + show_buffer = eina_list_nth(client->buffers_show, 0); + RETURNVALIFTRUE(show_buffer == NULL, NULL, "eom client (%p) next buffer is NULL", client); + + EOM_DBG("show wl:%p tbm:%p", show_buffer->wl_buffer, show_buffer->tbm_buffer); + + if (show_buffer->tbm_buffer) + { + EOM_DBG("show ref"); + tbm_surface_internal_ref(show_buffer->tbm_buffer); + } + + return show_buffer; } static E_EomClientPtr diff --git a/src/e_mod_main.h b/src/e_mod_main.h index 7ebb457..d718aea 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -3,6 +3,14 @@ #include "eom-server-protocol.h" +#if 0 + #define DRAW_DUMMY +#endif + +#if 0 + #define DUMP_PRESENTATION +#endif + extern Eina_Bool eom_server_debug_on; #define ALEN(array) (sizeof(array) / sizeof(array)[0]) @@ -50,8 +58,29 @@ if (statement) \ /* E Module */ E_API extern E_Module_Api e_modapi; + +/** + * @brief Called when Enlightenment is going to load the module + * @param[in] m structure which defines Enlightenment module + * @see e_modapi_shutdown() + * @see e_modapi_save() + */ E_API void *e_modapi_init(E_Module *m); + +/** + * @brief Called when Enlightenment is going to unload the module + * @param[in] m structure which defines Enlightenment module + * @see e_modapi_init() + * @see e_modapi_save() + */ E_API int e_modapi_shutdown(E_Module *m); + +/** + * @brief Called when Enlightenment is going to save some info in the module + * @param[in] m structure which defines Enlightenment module + * @see e_modapi_init() + * @see e_modapi_shutdown() + */ E_API int e_modapi_save(E_Module *m); #define NUM_MAIN_BUF 2 @@ -109,6 +138,7 @@ struct _E_Eom_Output /* mirror mode data */ tbm_surface_h dst_buffers[NUM_MAIN_BUF]; + tbm_surface_h src_buffer; int current_buffer; int pp_buffer; @@ -149,7 +179,9 @@ struct _E_Eom_Client /*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; + Eina_List *buffers_show; + Eina_List *buffers_del; + Eina_Bool first_buffer; }; struct _E_Eom_Client_Buffer @@ -216,14 +248,17 @@ 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); +static E_EomClientBufferPtr _e_eom_util_create_client_buffer(E_EomClientPtr client, + E_Comp_Wl_Buffer *wl_buffer, + tbm_surface_h tbm_buffer); 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 int _e_eom_util_get_stamp(); +#endif +#ifdef DRAW_DUMMY static void _e_eom_util_draw(tbm_surface_h surface); #endif -- 2.7.4 From 8f3774e99bad1a7e7ca9ac4ebbc3b6ae175acbd8 Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Wed, 27 Jul 2016 20:48:07 +0300 Subject: [PATCH 13/16] rework set_attribute fucntion changes: 1. If new client set attribute successfully send lost notification only to curren client 2. If current client has set NONE attribute start mirror mode and notify all clients about that changes 3. clean code Change-Id: I331690a97ae1c121eca6e33678e75d186fb8b366 Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 119 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 66 insertions(+), 53 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 6cbea65..5d193ad 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -57,8 +57,6 @@ static const char *eom_conn_types[] = "DSI", }; -////////////////////////////////////////////////////////////////////////////////////////////////////// - static inline eom_output_mode_e _e_eom_output_state_get_mode(E_EomOutputPtr output) { @@ -729,10 +727,9 @@ static void _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource *resource, uint32_t output_id, uint32_t attribute) { eom_error_e eom_error = EOM_ERROR_NONE; - E_EomClientPtr eom_client = NULL, iterator = NULL; + E_EomClientPtr eom_client = NULL, current_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; @@ -740,12 +737,13 @@ _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource 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_client->output_id = output_id; eom_output = _e_eom_output_get_by_id(output_id); GOTOIFTRUE(eom_output == NULL, no_output, "eom_output is NULL"); + EOM_DBG("Set attribute:%d", attribute); + if (eom_client->current == EINA_TRUE && eom_output->id == eom_client->output_id) { /* Current client can set any flag it wants */ @@ -754,6 +752,7 @@ _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource } else { + /* A client is trying to set new attribute */ ret = _e_eom_output_state_set_attribute(eom_output, attribute); if (ret == EINA_FALSE) { @@ -763,23 +762,25 @@ _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource goto end; } - eom_client->output_id = output_id; changes = EINA_TRUE; } + /* If there was no new changes applied do nothing */ + if (changes == EINA_FALSE) + { + EOM_DBG("no new changes"); + return; + } + EOM_DBG("set attribute OK"); - /* If client has set EOM_OUTPUT_ATTRIBUTE_NONE, eom will be - * switched to mirror mode - */ + /* If client has set EOM_OUTPUT_ATTRIBUTE_NONE switching to mirror mode */ if (attribute == EOM_OUTPUT_ATTRIBUTE_NONE && eom_output->state != MIRROR) { eom_output->state = MIRROR; eom_client->current = EINA_FALSE; _e_eom_output_state_set_mode(eom_output, EOM_OUTPUT_ATTRIBUTE_NONE); - mode_change = EINA_TRUE; - ret = _e_eom_output_state_set_attribute(eom_output, EOM_OUTPUT_ATTRIBUTE_NONE); (void)ret; @@ -793,63 +794,75 @@ _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource ret = _e_eom_output_start_pp(eom_output); GOTOIFTRUE(ret == EINA_FALSE, end, - "Restore mirror mode after a client disconnection"); - goto end; + "Restore mirror mode after disconnection of the client"); + + /* If mirror mode has been ran notify all clients about that */ + EOM_DBG("client set NONE attribute send new info to previous current client"); + EINA_LIST_FOREACH(g_eom->clients, l, iterator) + { + if (iterator->output_id == output_id) + { + 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); + + wl_eom_send_output_mode(iterator->resource, + eom_output->id, + _e_eom_output_state_get_mode(eom_output)); + } + } + + return; } end: + /* If client was not able to set attribute then send LOST event + * to it and return */ + /* TODO: I think it is bad to send LOST event in that case + * Client must process eom_errors */ + if (eom_error == EOM_ERROR_INVALID_PARAMETER) + { + EOM_DBG("client failed to set attribute"); + + wl_eom_send_output_attribute(eom_client->resource, + eom_output->id, + _e_eom_output_state_get_attribute(eom_output), + EOM_OUTPUT_ATTRIBUTE_STATE_LOST, + eom_error); + return; + } + + /* Send changes to the caller-client */ 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); - /* Notify eom clients that eom state has been changed */ - if (changes == EINA_TRUE) + /* Send changes to previous current client */ + if (eom_client->current == EINA_FALSE && + (current_eom_client = _e_eom_client_get_current_by_id(eom_output->id))) { - EINA_LIST_FOREACH(g_eom->clients, l, iterator) - { - if (iterator && iterator->resource == resource) - continue; - - 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); - } + current_eom_client->current = EINA_FALSE; - if (mode_change == EINA_TRUE) - { - wl_eom_send_output_mode(iterator->resource, - eom_output->id, - _e_eom_output_state_get_mode(eom_output)); - } - } - } + EOM_DBG("client failed to set attribute"); - eom_client->current= EINA_TRUE; + wl_eom_send_output_attribute(current_eom_client->resource, + eom_output->id, + _e_eom_output_state_get_attribute(eom_output), + EOM_OUTPUT_ATTRIBUTE_STATE_LOST, + EOM_ERROR_NONE); } + /* Set the client as current client of the eom_output */ + eom_client->current= EINA_TRUE; + return; - /* Get here if EOM does not have output with output_id is */ + /* Get here if EOM does not have output referred by output_id */ no_output: - wl_eom_send_output_attribute(eom_client->resource, output_id, EOM_OUTPUT_ATTRIBUTE_NONE, @@ -1882,7 +1895,7 @@ _e_eom_client_get_buffer(E_EomClientPtr client) if (del_buffer->tbm_buffer) { - EOM_DBG("before old unref"); + EOM_DBG("del unref"); tbm_surface_internal_unref(del_buffer->tbm_buffer); } -- 2.7.4 From ea762c2596025c232ca7e534cab714f4be4ce1b0 Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Thu, 28 Jul 2016 18:00:55 +0300 Subject: [PATCH 14/16] Send status of setting window to clietnt Change-Id: Ic78d25499c6231e9d68671a3c05a77b24657b1e2 --- protocol/eom-client-protocol.h | 10 ++++++++++ protocol/eom-protocol.c | 3 ++- protocol/eom-server-protocol.h | 8 ++++++++ protocol/eom.xml | 5 +++++ src/e_mod_main.c | 7 +++++-- 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/protocol/eom-client-protocol.h b/protocol/eom-client-protocol.h index 7172c5f..1fcd29d 100644 --- a/protocol/eom-client-protocol.h +++ b/protocol/eom-client-protocol.h @@ -152,6 +152,7 @@ enum wl_eom_attribute_state { * @output_type: (none) * @output_mode: (none) * @output_attribute: (none) + * @output_set_window: (none) * * ***** TODO ****** */ @@ -217,6 +218,15 @@ struct wl_eom_listener { uint32_t attribute, uint32_t attribute_state, uint32_t error); + /** + * output_set_window - (none) + * @output_id: (none) + * @error: (none) + */ + void (*output_set_window)(void *data, + struct wl_eom *wl_eom, + uint32_t output_id, + uint32_t error); }; static inline int diff --git a/protocol/eom-protocol.c b/protocol/eom-protocol.c index 3db1593..c032027 100644 --- a/protocol/eom-protocol.c +++ b/protocol/eom-protocol.c @@ -33,11 +33,12 @@ static const struct wl_message wl_eom_events[] = { { "output_type", "uuu", types + 0 }, { "output_mode", "uu", types + 0 }, { "output_attribute", "uuuu", types + 0 }, + { "output_set_window", "uu", types + 0 }, }; WL_EXPORT const struct wl_interface wl_eom_interface = { "wl_eom", 1, 4, wl_eom_requests, - 5, wl_eom_events, + 6, wl_eom_events, }; diff --git a/protocol/eom-server-protocol.h b/protocol/eom-server-protocol.h index 58400a7..333d0cd 100644 --- a/protocol/eom-server-protocol.h +++ b/protocol/eom-server-protocol.h @@ -196,12 +196,14 @@ struct wl_eom_interface { #define WL_EOM_OUTPUT_TYPE 2 #define WL_EOM_OUTPUT_MODE 3 #define WL_EOM_OUTPUT_ATTRIBUTE 4 +#define WL_EOM_OUTPUT_SET_WINDOW 5 #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 +#define WL_EOM_OUTPUT_SET_WINDOW_SINCE_VERSION 1 static inline void wl_eom_send_output_count(struct wl_resource *resource_, uint32_t count) @@ -233,6 +235,12 @@ wl_eom_send_output_attribute(struct wl_resource *resource_, uint32_t output_id, wl_resource_post_event(resource_, WL_EOM_OUTPUT_ATTRIBUTE, output_id, attribute, attribute_state, error); } +static inline void +wl_eom_send_output_set_window(struct wl_resource *resource_, uint32_t output_id, uint32_t error) +{ + wl_resource_post_event(resource_, WL_EOM_OUTPUT_SET_WINDOW, output_id, error); +} + #ifdef __cplusplus } #endif diff --git a/protocol/eom.xml b/protocol/eom.xml index 699d499..ff50650 100644 --- a/protocol/eom.xml +++ b/protocol/eom.xml @@ -124,6 +124,11 @@ + + + + + diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 5d193ad..37aa0e2 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -1434,8 +1434,6 @@ _e_eom_window_set_internal(struct wl_resource *resource, int output_id, E_Client 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"); - eom_output = _e_eom_output_get_by_id(output_id); RETURNIFTRUE(eom_output == NULL, "eom_output is NULL"); @@ -1450,6 +1448,11 @@ _e_eom_window_set_internal(struct wl_resource *resource, int output_id, E_Client /* ec is used in buffer_change callback for distinguishing external ec and its buffers */ eom_client->ec = ec; + + if (eom_client->current == EINA_TRUE) + wl_eom_send_output_set_window(resource, eom_output->id, WL_EOM_ERROR_NONE); + else + wl_eom_send_output_set_window(resource, eom_output->id, WL_EOM_ERROR_OUTPUT_OCCUPIED); } static Eina_Bool -- 2.7.4 From b4ab8bfcdc2aa65c6b9ba0d1e1efcc1052906274 Mon Sep 17 00:00:00 2001 From: Roman Peresipkyn Date: Wed, 3 Aug 2016 13:44:10 +0300 Subject: [PATCH 15/16] fixing. Add measuring of fps. Add doxygen documentation Change-Id: I235e8421c067b9a79066c37a8c7a5c9dfe834959 Signed-off-by: Roman Peresipkyn --- src/e_mod_main.c | 88 +++++++++++++++++++++++++++++++++++--------------------- src/e_mod_main.h | 43 ++++++++++++++------------- 2 files changed, 76 insertions(+), 55 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 37aa0e2..5565a80 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -11,14 +11,14 @@ #include "Ecore_Drm.h" #include +#ifdef FRAMES + #include +#endif + 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; -#ifdef DUMP_PRESENTATION -static int dump = 0; -#endif - static const struct wl_eom_interface _e_eom_wl_implementation = { _e_eom_cb_wl_request_set_attribute, @@ -543,16 +543,17 @@ _e_eom_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS #endif #ifdef DUMP_PRESENTATION - if (dump < 29) - { - tbm_surface_internal_dump_buffer(external_buffer, "kyky"); - dump++; - } - else - { - tbm_surface_internal_dump_end(); - EOM_DBG("dump end"); - } + if (eom_output->dump_do) + { + tbm_surface_internal_dump_buffer(external_buffer, "eom_buffer"); + eom_output->dump_count++; + + if (eom_output->dump_count > DUMP_NUM) + { + tbm_surface_internal_dump_end(); + eom_output->dump_do = EINA_FALSE; + } + } #endif err = tdm_layer_set_buffer(eom_output->layer, external_buffer); @@ -563,6 +564,10 @@ _e_eom_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS EOM_DBG("COMMIT <+++++++++++++++"); } + +#ifdef FRAMES + _e_eom_util_check_frames(eom_output); +#endif } static void @@ -659,7 +664,13 @@ _e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type ty eom_output->status = plug; eom_output->name = eina_stringshare_add(new_name); eom_output->type = (eom_output_type_e)tdm_type; +#ifdef DUMP_PRESENTATION + eom_output->dump_do = EINA_TRUE; + eom_output->dump_count = 1; + EOM_DBG("dump init"); + tbm_surface_internal_dump_start("/eom_buffers", eom_output->width, eom_output->height, DUMP_NUM); +#endif /* TODO: check output mode(presentation set) and HDMI type */ _e_eom_output_start_mirror(eom_output); @@ -729,7 +740,6 @@ _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource eom_error_e eom_error = EOM_ERROR_NONE; E_EomClientPtr eom_client = NULL, current_eom_client = NULL, iterator = NULL; E_EomOutputPtr eom_output = NULL; - Eina_Bool changes = EINA_FALSE; Eina_Bool ret = EINA_FALSE; Eina_List *l; @@ -748,7 +758,6 @@ _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource { /* Current client can set any flag it wants */ _e_eom_output_state_set_force_attribute(eom_output, attribute); - changes = EINA_TRUE; } else { @@ -761,15 +770,6 @@ _e_eom_cb_wl_request_set_attribute(struct wl_client *client, struct wl_resource eom_error = EOM_ERROR_INVALID_PARAMETER; goto end; } - - changes = EINA_TRUE; - } - - /* If there was no new changes applied do nothing */ - if (changes == EINA_FALSE) - { - EOM_DBG("no new changes"); - return; } EOM_DBG("set attribute OK"); @@ -1584,14 +1584,6 @@ _e_eom_util_create_client_buffer(E_EomClientPtr client, E_Comp_Wl_Buffer *wl_buf EOM_DBG("new client buffer wl:%p tbm:%p", buffer->wl_buffer, buffer->tbm_buffer); -#ifdef DUMP_PRESENTATION - if (dump == 0) - { - EOM_DBG("dump start"); - tbm_surface_internal_dump_start("/A", wl_buffer->w, wl_buffer->h, 30); - } -#endif - #if 0 buffer->stamp = _e_eom_util_get_stamp(); #endif @@ -1780,6 +1772,36 @@ _e_eom_util_draw(tbm_surface_h surface) tbm_bo_unmap(bo); } #endif +#ifdef FRAMES +static void _e_eom_util_check_frames(E_EomOutputPtr eom_output) +{ + int res = 0; + static int first = 1; + + eom_output->num_frames += 1; + res = gettimeofday(&eom_output->curr, NULL); + if (res) + { + EOM_ERR("gettimeofday"); + return; + } + + if (eom_output->curr.tv_sec > eom_output->prev.tv_sec && !first) + { + EOM_DBG("FPS:%d", eom_output->num_frames); + + eom_output->num_frames = 0; + eom_output->prev.tv_sec = eom_output->curr.tv_sec; + eom_output->prev.tv_usec = eom_output->curr.tv_usec; + } + else + { + eom_output->prev.tv_sec = eom_output->curr.tv_sec; + eom_output->prev.tv_usec = eom_output->curr.tv_usec; + first = 0; + } +} +#endif static void _e_eom_client_add_buffer(E_EomClientPtr client, E_EomClientBufferPtr buffer) diff --git a/src/e_mod_main.h b/src/e_mod_main.h index d718aea..365b914 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -9,6 +9,12 @@ #if 0 #define DUMP_PRESENTATION + #define DUMP_NUM 30 +#endif + +#if 0 + #define FRAMES + #include #endif extern Eina_Bool eom_server_debug_on; @@ -58,29 +64,8 @@ if (statement) \ /* E Module */ E_API extern E_Module_Api e_modapi; - -/** - * @brief Called when Enlightenment is going to load the module - * @param[in] m structure which defines Enlightenment module - * @see e_modapi_shutdown() - * @see e_modapi_save() - */ E_API void *e_modapi_init(E_Module *m); - -/** - * @brief Called when Enlightenment is going to unload the module - * @param[in] m structure which defines Enlightenment module - * @see e_modapi_init() - * @see e_modapi_save() - */ E_API int e_modapi_shutdown(E_Module *m); - -/** - * @brief Called when Enlightenment is going to save some info in the module - * @param[in] m structure which defines Enlightenment module - * @see e_modapi_init() - * @see e_modapi_shutdown() - */ E_API int e_modapi_save(E_Module *m); #define NUM_MAIN_BUF 2 @@ -143,6 +128,18 @@ struct _E_Eom_Output int pp_buffer; tbm_surface_h dummy_buffer; + +#ifdef DUMP_PRESENTATION + Eina_Bool dump_do; + int dump_count; +#endif +#ifdef FRAMES + /* for testing purposes */ + struct timeval prev; + struct timeval curr; + + int num_frames; +#endif }; struct _E_Eom @@ -261,7 +258,9 @@ static int _e_eom_util_get_stamp(); #ifdef DRAW_DUMMY static void _e_eom_util_draw(tbm_surface_h surface); #endif - +#ifdef FRAMES +static void _e_eom_util_check_frames(E_EomOutputPtr eom_output); +#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); -- 2.7.4 From 0b305c9f3c49692af09018785504823039944d97 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Fri, 5 Aug 2016 15:33:04 +0900 Subject: [PATCH 16/16] enable mirror showing when booting with hdmi connection Change-Id: Icbc52fcb794636eb787efe36f277a2317053e1d4 Signed-off-by: Junkyeong Kim --- src/e_mod_main.c | 250 +++++++++++++++++++++++++++++++++++++------------------ src/e_mod_main.h | 4 + 2 files changed, 174 insertions(+), 80 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 5565a80..e7fac6c 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -275,6 +275,77 @@ end2: } static Eina_Bool +_e_eom_check_boot_connection(void *data) +{ + if (g_eom->check_first_boot != 0) + { + g_eom->timer = NULL; + return ECORE_CALLBACK_CANCEL; + } + + g_eom->check_first_boot = 1; + + if (g_eom->outputs) + { + Eina_List *l; + E_EomOutputPtr eom_output; + + EINA_LIST_FOREACH(g_eom->outputs, l, eom_output) + { + tdm_output *output; + const char *tmp_name; + char new_name[DRM_CONNECTOR_NAME_LEN]; + tdm_output_type tdm_type; + tdm_error ret = TDM_ERROR_NONE; + tdm_output_conn_status status; + + if (eom_output->id == 0) + continue; + + output = eom_output->output; + if (output == NULL) + { + EOM_ERR("output is null fail"); + continue; + } + + ret = tdm_output_get_conn_status(output, &status); + if (ret != TDM_ERROR_NONE) + { + EOM_ERR("tdm_output_get_conn_status fail(%d)", ret); + continue; + } + + if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) + continue; + + ret = tdm_output_get_output_type(output, &tdm_type); + if (ret != TDM_ERROR_NONE) + { + EOM_ERR("tdm_output_get_output_type fail(%d)", ret); + continue; + } + + 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); + + eom_output->type = (eom_output_type_e)tdm_type; + eom_output->name = eina_stringshare_add(new_name); + eom_output->status = status; + + _e_eom_output_connected(eom_output); + } + } + g_eom->timer = NULL; + return ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool _e_eom_cb_ecore_drm_output(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { Ecore_Drm_Event_Output *e = NULL; @@ -298,6 +369,13 @@ _e_eom_cb_ecore_drm_output(void *data EINA_UNUSED, int type EINA_UNUSED, void *e g_eom->main_output_name = strdup(buff); g_eom->main_output_state = UP; + + if (g_eom->check_first_boot == 0) + { + if (g_eom->timer) + ecore_timer_del(g_eom->timer); + g_eom->timer = ecore_timer_add(EOM_CONNECT_CHECK_TIMEOUT, _e_eom_check_boot_connection, NULL); + } } else { @@ -570,20 +648,99 @@ _e_eom_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUS #endif } +static int +_e_eom_output_connected(E_EomOutputPtr eom_output) +{ + tdm_output *output; + tdm_error ret = TDM_ERROR_NONE; + const char *maker = NULL, *model = NULL, *name = NULL; + unsigned int mmWidth, mmHeight, subpixel; + const tdm_output_mode *mode; + int x = 0; + E_EomClientPtr iterator = NULL; + Eina_List *l; + + output = eom_output->output; + + ret = tdm_output_get_model_info(output, &maker, &model, &name); + RETURNVALIFTRUE(ret != TDM_ERROR_NONE, -1, "tdm_output_get_model_info fail(%d)", ret); + + ret = tdm_output_get_physical_size(output, &mmWidth, &mmHeight); + RETURNVALIFTRUE(ret != TDM_ERROR_NONE, -1, "tdm_output_get_physical_size fail(%d)", ret); + + ret = tdm_output_get_subpixel(output, &subpixel); + RETURNVALIFTRUE(ret != TDM_ERROR_NONE, -1, "tdm_output_get_subpixel fail(%d)", ret); + + mode = _e_eom_output_get_best_mode(output); + RETURNVALIFTRUE(mode == NULL, -1, "_e_eom_get_best_resolution fail"); + + ret = tdm_output_set_mode(output, mode); + RETURNVALIFTRUE(ret != TDM_ERROR_NONE, -1, "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); + + if (!e_comp_wl_output_init(eom_output->name, maker, eom_output->name, x, 0, + mode->hdisplay, mode->vdisplay, + mmWidth, mmHeight, mode->vrefresh, subpixel, 0)) + { + EOM_ERR("Could not setup new output: %s", eom_output->name); + return -1; + } + EOM_DBG("Setup new output: %s", eom_output->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; +#ifdef DUMP_PRESENTATION + eom_output->dump_do = EINA_TRUE; + eom_output->dump_count = 1; + + EOM_DBG("dump init"); + tbm_surface_internal_dump_start("/eom_buffers", eom_output->width, eom_output->height, DUMP_NUM); +#endif + /* TODO: check output mode(presentation set) and HDMI type */ + _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) + { + 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); + } + } + + return 0; +} + 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; + + g_eom->check_first_boot = 1; if (type == TDM_OUTPUT_CHANGE_DPMS || g_eom->main_output_state == DOWN) return; @@ -603,15 +760,12 @@ _e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type ty 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; + plug = 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); + EOM_DBG("id (%d), type(%d, %d), status(%d, %d)", eom_output->id, type, tdm_type, status, plug); if (tdm_type < ALEN(eom_conn_types)) tmp_name = eom_conn_types[tdm_type]; @@ -621,82 +775,19 @@ _e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type ty *e.g. "HDMI and HDMI" "LVDS and LVDS"*/ snprintf(new_name, sizeof(new_name), "%s-%d", tmp_name, 0); - plug = value.u32; + eom_output->type = (eom_output_type_e)tdm_type; + eom_output->name = eina_stringshare_add(new_name); + eom_output->status = plug; if (plug == TDM_OUTPUT_CONN_STATUS_CONNECTED) { - 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; -#ifdef DUMP_PRESENTATION - eom_output->dump_do = EINA_TRUE; - eom_output->dump_count = 1; - - EOM_DBG("dump init"); - tbm_surface_internal_dump_start("/eom_buffers", eom_output->width, eom_output->height, DUMP_NUM); -#endif - /* TODO: check output mode(presentation set) and HDMI type */ - _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) - { - 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); - } - } + _e_eom_output_connected(eom_output); } else if (plug == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { + E_EomClientPtr iterator = NULL; + Eina_List *l; + if (eom_output->state == MIRROR) _e_eom_output_stop_mirror(eom_output); @@ -705,7 +796,6 @@ _e_eom_cb_tdm_output_status_change(tdm_output *output, tdm_output_change_type ty 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) diff --git a/src/e_mod_main.h b/src/e_mod_main.h index 365b914..b24a5b8 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -70,6 +70,7 @@ E_API int e_modapi_save(E_Module *m); #define NUM_MAIN_BUF 2 #define NUM_ATTR 3 +#define EOM_CONNECT_CHECK_TIMEOUT 7.0 typedef struct _E_Eom E_Eom, *E_EomPtr; typedef struct _E_Eom_Out_Mode E_EomOutMode, *E_EomOutModePtr; @@ -155,6 +156,8 @@ struct _E_Eom char *main_output_name; int width; int height; + char check_first_boot; + Ecore_Timer *timer; unsigned int output_count; Eina_List *outputs; @@ -252,6 +255,7 @@ static void _e_eom_util_calculate_fullsize(int src_h, int src_v, int dst_size_h, 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_output_connected(E_EomOutputPtr eom_output); #if 0 static int _e_eom_util_get_stamp(); #endif -- 2.7.4