From: SooChan Lim Date: Thu, 13 Jun 2024 02:27:56 +0000 (+0900) Subject: e_display: add e_display X-Git-Tag: accepted/tizen/unified/20240703.154731~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1eed5a48b949b102be62a01bb65e73b029d98857;p=platform%2Fupstream%2Fenlightenment.git e_display: add e_display e_display initialize the Display and the Outputs in Enlightenemnt. It initialize the tdm display and tdm output at start of the Enlightenment. Change-Id: I8146130cdcd8b3670089b80787229292a300eaec --- diff --git a/src/bin/Makefile.mk b/src/bin/Makefile.mk index b7f117b..bcefbc0 100644 --- a/src/bin/Makefile.mk +++ b/src/bin/Makefile.mk @@ -235,6 +235,7 @@ src/bin/compmgr/e_comp_canvas.c \ src/bin/compmgr/e_comp_object.c \ src/bin/compmgr/e_egl_sync.c \ src/bin/compmgr/e_alpha_mask_rect.c \ +src/bin/displaymgr/e_display.c \ src/bin/displaymgr/e_output.c \ src/bin/displaymgr/e_scale.c \ src/bin/displaymgr/e_plane_renderer.c \ diff --git a/src/bin/displaymgr/e_display.c b/src/bin/displaymgr/e_display.c new file mode 100644 index 0000000..f333781 --- /dev/null +++ b/src/bin/displaymgr/e_display.c @@ -0,0 +1,915 @@ +#include "e_display_intern.h" +#include "e_hwc_intern.h" +#include "e_hwc_windows_intern.h" +#include "e_hwc_planes_intern.h" +#include "e_utils_intern.h" +#include "e_scale_intern.h" +#include "e_comp_screen_intern.h" +#include "e_comp_intern.h" + +#include +#include +#include + +#define NUM_SW_FORMAT (sizeof(sw_formats) / sizeof(sw_formats[0])) + +typedef struct _E_Display E_Display; + +struct _E_Display +{ + tdm_display *tdisplay; + int fd; + + void *gdevice; + int gdevice_fd; + + Eina_Bool pp_enabled; + Eina_List *available_pp_formats; + + Ecore_Fd_Handler *hdlr; + + int num_outputs; + Eina_List *outputs; // available screens +}; + +static E_Display *g_display = NULL; // global e_display + +static tbm_format sw_formats[] = { + TBM_FORMAT_ARGB8888, + TBM_FORMAT_XRGB8888, + TBM_FORMAT_YUV420, + TBM_FORMAT_YVU420, +}; + +static char * +_e_display_dpms_to_string(E_OUTPUT_DPMS dpms) +{ + switch (dpms) + { + case E_OUTPUT_DPMS_ON: + return "DPMS_ON"; + break; + case E_OUTPUT_DPMS_STANDBY: + return "DPMS_STANDBY"; + break; + case E_OUTPUT_DPMS_SUSPEND: + return "DPMS_SUSPEND"; + break; + case E_OUTPUT_DPMS_OFF: + return "DPMS_OFF"; + break; + default: + return "Unknown"; + } +} + +static tdm_layer * +_e_display_video_tdm_layer_get(tdm_output *output) +{ + int i, count = 0; +#ifdef CHECKING_PRIMARY_ZPOS + int primary_idx = 0, primary_zpos = 0; + tdm_layer *primary_layer; +#endif + + EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL); + + tdm_output_get_layer_count(output, &count); + for (i = 0; i < count; i++) + { + tdm_layer *layer = tdm_output_get_layer(output, i, NULL); + tdm_layer_capability capabilities = 0; + EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL); + + tdm_layer_get_capabilities(layer, &capabilities); + if (capabilities & TDM_LAYER_CAPABILITY_VIDEO) + return layer; + } + +#ifdef CHECKING_PRIMARY_ZPOS + tdm_output_get_primary_index(output, &primary_idx); + primary_layer = tdm_output_get_layer(output, primary_idx, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(primary_layer, NULL); + tdm_layer_get_zpos(primary_layer, &primary_zpos); +#endif + + for (i = 0; i < count; i++) + { + tdm_layer *layer = tdm_output_get_layer(output, i, NULL); + tdm_layer_capability capabilities = 0; + EINA_SAFETY_ON_NULL_RETURN_VAL(layer, NULL); + + tdm_layer_get_capabilities(layer, &capabilities); + if (capabilities & TDM_LAYER_CAPABILITY_OVERLAY) + { +#ifdef CHECKING_PRIMARY_ZPOS + int zpos = 0; + tdm_layer_get_zpos(layer, &zpos); + if (zpos >= primary_zpos) continue; +#endif + return layer; + } + } + + return NULL; +} + +static E_Output * +_e_display_eoutput_get_by_toutput(tdm_output *output) +{ + Eina_List *l; + E_Output *eo; + + EINA_LIST_FOREACH(e_display_outputs_get(), l, eo) + if (eo->toutput == output) + return eo; + + return NULL; +} + +static char * +_layer_cap_to_str(tdm_layer_capability caps, tdm_layer_capability cap) +{ + if (caps & cap) + { + if (cap == TDM_LAYER_CAPABILITY_CURSOR) return "cursor "; + else if (cap == TDM_LAYER_CAPABILITY_PRIMARY) return "primary "; + else if (cap == TDM_LAYER_CAPABILITY_OVERLAY) return "overlay "; + else if (cap == TDM_LAYER_CAPABILITY_GRAPHIC) return "graphics "; + else if (cap == TDM_LAYER_CAPABILITY_VIDEO) return "video "; + else if (cap == TDM_LAYER_CAPABILITY_TRANSFORM) return "transform "; + else if (cap == TDM_LAYER_CAPABILITY_RESEVED_MEMORY) return "reserved_memory "; + else if (cap == TDM_LAYER_CAPABILITY_NO_CROP) return "no_crop "; + else return "unkown"; + } + return ""; +} + +static void +_display_output_mode_change_cb(tdm_output *toutput, unsigned int index, void *user_data) +{ + E_Display *display = user_data; + E_Output *output = NULL; + Eina_Bool find = EINA_FALSE; + int count, num; + E_Output_Mode *set_emode = NULL, *current_emode = NULL; + E_Output_Mode *emode = NULL; + Eina_List *modelist = NULL, *l, *ll; + + EINA_SAFETY_ON_NULL_RETURN(display); + + EINA_LIST_FOREACH_SAFE(display->outputs, l, ll, output) + { + if (output->toutput == toutput) + { + find = EINA_TRUE; + break; + } + } + EINA_SAFETY_ON_FALSE_RETURN(find == EINA_TRUE); + + current_emode = e_output_current_mode_get(output); + EINA_SAFETY_ON_NULL_RETURN(current_emode); + + modelist = e_output_mode_list_get(output); + if (modelist) + { + num = eina_list_count(modelist); + EINA_SAFETY_ON_FALSE_RETURN(index < num); + + count = 0; + EINA_LIST_FOREACH(modelist, l, emode) + { + if (count == index) + { + set_emode = emode; + break; + } + count++; + } + + if (set_emode) + { + EINA_SAFETY_ON_TRUE_RETURN(current_emode == set_emode); + + ELOGF("COMP_SCREEN","request mode change(%d) (%dx%d, %lf) -> (%dx%d, %lf)\n", + NULL, index, current_emode->w, current_emode->h, current_emode->refresh, + set_emode->w, set_emode->h, set_emode->refresh); + + e_output_external_mode_change(output, set_emode); + } + } +} + +static void +_display_output_destroy_cb(tdm_output *toutput, void *user_data) +{ + E_Display *display = user_data; + E_Output *output = NULL; + Eina_List *l, *ll; + + EINA_SAFETY_ON_NULL_RETURN(display); + + tdm_output_remove_destroy_handler(toutput, _display_output_destroy_cb, display); + + EINA_LIST_FOREACH_SAFE(display->outputs, l, ll, output) + { + if (output->toutput == toutput) + { + display->num_outputs--; + display->outputs = eina_list_remove_list(display->outputs, l); + e_output_del(output); + } + } +} + +static void +_e_display_cb_output_created(tdm_display *dpy, tdm_output *toutput, void *user_data) +{ + E_Display *display = user_data; + E_Output *output = NULL; + tdm_error ret = TDM_ERROR_NONE; + + EINA_SAFETY_ON_NULL_RETURN(display); + + TRACE_DS_BEGIN(OUTPUT:NEW); + output = e_output_new1(display->num_outputs); + EINA_SAFETY_ON_NULL_GOTO(output, fail); + if (output->toutput != toutput) goto fail; + TRACE_DS_END(); + + TRACE_DS_BEGIN(OUTPUT:UPDATE); + if (!e_output_update(output)) + { + ERR("fail to e_output_update."); + e_output_del(output); + goto fail; + } + TRACE_DS_END(); + + /* todo : add tdm_output_add_mode_change_request_handler()*/ + ret = tdm_output_add_mode_change_request_handler(toutput, _display_output_mode_change_cb, display); + if (ret != TDM_ERROR_NONE) + { + ERR("fail to add output mode change handler."); + e_output_del(output); + return; + } + + ret = tdm_output_add_destroy_handler(toutput, _display_output_destroy_cb, display); + if (ret != TDM_ERROR_NONE) + { + ERR("fail to add output destroy handler."); + e_output_del(output); + return; + } + + display->outputs = eina_list_append(display->outputs, output); + display->num_outputs++; + + return; + +fail: + TRACE_DS_END(); +} + +static Eina_Bool +_display_fake_output_set(E_Display *display) +{ + E_Output *primary_output = NULL; + + EINA_SAFETY_ON_NULL_RETURN_VAL(display, EINA_FALSE); + + primary_output = e_display_primary_output_get(); + EINA_SAFETY_ON_NULL_RETURN_VAL(primary_output, EINA_FALSE); + + if (!e_output_hwc_setup(primary_output)) + { + ERR("fail to e_output_hwc_setup."); + return EINA_FALSE; + } + + if (!e_output_fake_config_set(primary_output, 2, 1)) + { + ERR("Fail to set the fake output config!"); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static void +_display_deinit_outputs(E_Display *display) +{ + E_Output *output; + Eina_List *l, *ll; + + tdm_display_remove_output_create_handler(display->tdisplay, _e_display_cb_output_created, display); + + // free up e_outputs + EINA_LIST_FOREACH_SAFE(display->outputs, l, ll, output) + { + display->outputs = eina_list_remove_list(display->outputs, l); + e_output_del(output); + } + + e_hwc_ecore_evas_deinit(); + e_hwc_deinit(); + e_hwc_windows_deinit(); + e_hwc_planes_deinit(); + + e_output_shutdown(); +} + +static Eina_Bool +_e_display_init_outputs(E_Display *display) +{ + E_Output *output = NULL; + E_Output_Mode *mode = NULL; + tdm_display *tdisplay = display->tdisplay; + int num_outputs; + int i; + Eina_Bool scale_updated = EINA_FALSE; + Eina_Bool connection_check = EINA_FALSE; + tdm_error err = TDM_ERROR_NONE; + char bootmode[32]; + int ret; + + /* init e_output */ + if (!e_output_init()) + { + ERR("fail to e_output_init."); + return EINA_FALSE; + } + + /* get the num of outputs */ + err = tdm_display_get_output_count(tdisplay, &num_outputs); + if ((err != TDM_ERROR_NONE) || + (num_outputs < 1)) + { + ERR("fail to get tdm_display_get_output_count\n"); + return EINA_FALSE; + } + display->num_outputs = num_outputs; + + ELOGF("COMP_SCREEN","num_outputs = %i", NULL, display->num_outputs); + + if (!e_hwc_init()) + { + ERR("e_hwc_init failed"); + goto fail; + } + + if (!e_hwc_planes_init()) + { + ERR("e_hwc_planes_init failed"); + goto fail; + } + + if (!e_hwc_windows_init()) + { + ERR("e_hwc_windows_init failed"); + goto fail; + } + + for (i = 0; i < num_outputs; i++) + { + e_main_ts_begin("\tE_Output New"); + output = e_output_new1(i); + if (!output) + { + e_main_ts_end("\tE_Output New Failed"); + goto fail; + } + + e_main_ts_begin("\tE_Output Update"); + if (!e_output_update(output)) + { + e_main_ts_end("\tE_Output Update Failed"); + ERR("fail to e_output_update."); + goto fail; + } + e_main_ts_end("\tE_Output Update Done"); + + display->outputs = eina_list_append(display->outputs, output); + + if (!e_output_connected(output)) continue; + + connection_check = EINA_TRUE; + + /* setting with the best mode and enable the output */ + e_main_ts_begin("\tE_Output Find Best Mode"); + mode = e_output_best_mode_find(output); + if (!mode) + { + e_main_ts_end("\tE_Output Find Best Mode Failed"); + ERR("fail to get best mode."); + goto fail; + } + e_main_ts_end("\tE_Output Find Best Mode Done"); + + e_main_ts_begin("\tE_Output Mode Apply"); + if (!e_output_mode_apply(output, mode)) + { + e_main_ts_end("\tE_Output Mode Apply Failed"); + ERR("fail to e_output_mode_apply."); + goto fail; + } + e_main_ts_end("\tE_Output Mode Apply Done"); + + e_main_ts_begin("\tE_Output Set DPMS ON"); + ret = device_board_get_boot_mode(bootmode, sizeof(bootmode)); + if (!ret && !e_util_strcmp(bootmode, "silent")) + { + INF("silent reboot. do not set dpms"); + } + else + { + if (!e_output_dpms_set(output, E_OUTPUT_DPMS_ON)) + { + e_main_ts_end("\tE_Output Set DPMS ON Failed"); + ERR("fail to e_output_dpms."); + goto fail; + } + } + + e_main_ts_end("\tE_Output Set DPMS ON Done"); + + e_main_ts_begin("\tE_Output Hwc Setup"); + if (!e_output_hwc_setup(output)) + { + e_main_ts_end("\tE_Output Hwc Setup Failed"); + ERR("fail to e_output_hwc_setup."); + goto fail; + } + e_main_ts_end("\tE_Output Hwc Setup Done"); + + /* update e_scale with first available output size */ + if ((e_config->scale.for_tdm) && (!scale_updated)) + { + double target_inch; + int dpi; + + target_inch = (round((sqrt(output->info.size.w * output->info.size.w + output->info.size.h * output->info.size.h) / 25.4) * 10) / 10); + dpi = (round((sqrt(mode->w * mode->w + mode->h * mode->h) / target_inch) * 10) / 10); + + e_scale_manual_update(dpi); + scale_updated = EINA_TRUE; + } + } + + //TODO: if there is no output connected, make the fake output which is connected. + if (!connection_check) + { + if (!_display_fake_output_set(display)) + goto fail; + } + + // FIXME: donot call e_comp_screen function at e_display. move this function to other plane, need refactoring + e_comp_screen_size_update(e_comp->e_comp_screen); + + e_main_ts_begin("\tE_Hwc Ecore_Evas Init"); + if (!e_hwc_ecore_evas_init()) + { + e_main_ts_end("\ttE_Hwc Ecore_Evas Init Failed"); + ERR("fail to e_hwc_ecore_evas_init"); + goto fail; + } + e_main_ts_end("\tE_Hwc Ecore_Evas Init Done"); + + if (tdm_display_add_output_create_handler(tdisplay, _e_display_cb_output_created, display)) + goto fail; + + return EINA_TRUE; + +fail: + _display_deinit_outputs(display); + + return EINA_FALSE; +} + +static Eina_Bool +_e_display_cb_tdm_display_interrupt(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED) +{ + E_Display *display; + tdm_error ret; + + if (!(display = data)) return ECORE_CALLBACK_RENEW; + + ret = tdm_display_handle_events(display->tdisplay); + if (ret != TDM_ERROR_NONE) + ERR("tdm_display_handle_events failed"); + + return ECORE_CALLBACK_RENEW; +} + +EINTERN Eina_Bool +e_display_init(void) +{ + E_Display *display; + tdm_display_capability capabilities; + const tbm_format *pp_formats; + tdm_error error = TDM_ERROR_NONE; + int count, i; + int fd; + + if (g_display) return EINA_TRUE; + + display = E_NEW(E_Display, 1); + EINA_SAFETY_ON_NULL_RETURN_VAL(display, EINA_FALSE); + + g_display = display; + + display->tdisplay = tdm_display_init(&error); + if (!display->tdisplay) + { + ERR("fail to tdm_display_init"); + goto fail; + } + + display->gdevice_fd = -1; + display->fd = -1; + + tdm_display_get_fd(display->tdisplay, &fd); + if (fd < 0) + { + ERR("fail to get tdm_display fd"); + goto fail; + } + + display->fd = dup(fd); + + error = tdm_display_get_capabilities(display->tdisplay, &capabilities); + if (error != TDM_ERROR_NONE) + { + ERR("tdm get_capabilities failed"); + goto fail; + } + + /* check the pp_support */ + if (capabilities & TDM_DISPLAY_CAPABILITY_PP) + { + error = tdm_display_get_pp_available_formats(display->tdisplay, + &pp_formats, &count); + if (error != TDM_ERROR_NONE) + ERR("fail to get available pp formats"); + else + { + display->pp_enabled = EINA_TRUE; + for (i = 0 ; i < count ; i++) + { + display->available_pp_formats = + eina_list_append(display->available_pp_formats, + &pp_formats[i]); + } + } + } + + display->hdlr = ecore_main_fd_handler_add(display->fd, ECORE_FD_READ, + _e_display_cb_tdm_display_interrupt, display, NULL, NULL); + + if (e_comp_socket_init("tdm-socket")) + PRCTL("[Winsys] change permission and create sym link for %s", "tdm-socket"); + + if (!_e_display_init_outputs(display)) + { + ERR("tdm get_capabilities failed"); + goto fail; + } + + return EINA_TRUE; + +fail: + if (display->hdlr) ecore_main_fd_handler_del(display->hdlr); + if (display->fd >= 0) close(display->fd); + if (display->tdisplay) tdm_display_deinit(display->tdisplay); + + E_FREE(display); + g_display = NULL; + + return EINA_FALSE; +} + + +EINTERN void +e_display_shutdown(void) +{ + Eina_List *l, *ll; + tbm_format *formats; + + if (!g_display) return; + + _display_deinit_outputs(g_display); + + if (g_display->pp_enabled) + { + EINA_LIST_FOREACH_SAFE(g_display->available_pp_formats, l, ll, formats) + { + if (!formats) continue; + g_display->available_pp_formats = eina_list_remove(g_display->available_pp_formats, l); + } + } + if (g_display->gdevice) gbm_device_destroy(g_display->gdevice); + if (g_display->gdevice_fd >= 0) close(g_display->gdevice_fd); + if (g_display->fd >= 0) close(g_display->fd); + if (g_display->hdlr) ecore_main_fd_handler_del(g_display->hdlr); + if (g_display->tdisplay) tdm_display_deinit(g_display->tdisplay); + + E_FREE(g_display); + g_display = NULL; +} + + +EINTERN E_Output * +e_display_primary_output_get(void) +{ + E_Output *output = NULL, *o; + const Eina_List *l; + + EINA_SAFETY_ON_NULL_RETURN_VAL(g_display, NULL); + + EINA_LIST_FOREACH(g_display->outputs, l, o) + { + unsigned int pipe = 0; + tdm_error error; + + error = tdm_output_get_pipe(o->toutput, &pipe); + if (error != TDM_ERROR_NONE || pipe != 0) + continue; + + output = o; + break; + } + + if (!output) + { + ERR("couldn't find the primary output"); + return NULL; + } + + return output; +} + +EINTERN void * +e_display_tdm_display_get(void) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(g_display, NULL); + + return (void *)g_display->tdisplay; +} + +EINTERN void * +e_display_gbm_device_get(void) +{ + int fd; + + EINA_SAFETY_ON_NULL_RETURN_VAL(g_display, NULL); + + if (g_display->gdevice) return g_display->gdevice; + + fd = tbm_drm_helper_get_master_fd(); + EINA_SAFETY_ON_FALSE_RETURN_VAL(fd >= 0, NULL); + + g_display->gdevice = gbm_create_device(fd); + if (!g_display->gdevice) + { + ERR("fail to create gbm device"); + close(fd); + return NULL; + } + + g_display->gdevice_fd = fd; + + return g_display->gdevice; +} + +EINTERN Eina_List * +e_display_outputs_get(void) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(g_display, NULL); + + return g_display->outputs; +} + +EINTERN int +e_display_num_outputs_get(void) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(g_display, -1); + + return g_display->num_outputs; +} + +EINTERN Eina_Bool +e_display_pp_support(void) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(g_display, EINA_TRUE); + + return g_display->pp_enabled; +} + +EINTERN Eina_Bool +e_display_available_video_formats_get(const tbm_format **formats, int *count) +{ + E_Output *output; + tdm_output *toutput; + tdm_layer *layer; + tdm_error error; + + *count = 0; + + if (e_display_pp_support()) + { + error = tdm_display_get_pp_available_formats(g_display->tdisplay, formats, count); + if (error == TDM_ERROR_NONE) + return EINA_TRUE; + } + + /* get the first output */ + toutput = tdm_display_get_output(g_display->tdisplay, 0, NULL); + if (!toutput) + return EINA_FALSE; + + output = _e_display_eoutput_get_by_toutput(toutput); + if (!output) + return EINA_FALSE; + + if (e_hwc_policy_get(output->hwc) != E_HWC_POLICY_WINDOWS) + { + /* get the first suitable layer */ + layer = _e_display_video_tdm_layer_get(toutput); + if (layer) + { + tdm_layer_get_available_formats(layer, formats, count); + } + else + { + *formats = sw_formats; + *count = NUM_SW_FORMAT; + } + } + else + { + error = tdm_hwc_get_video_supported_formats(output->hwc->thwc, formats, count); + if (error != TDM_ERROR_NONE) + { + *formats = sw_formats; + *count = NUM_SW_FORMAT; + } + } + + return EINA_TRUE; +} + + +EINTERN Eina_List * +e_display_pp_available_formats_get(void) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(g_display, EINA_FALSE); + + if (!g_display->pp_enabled) + { + ERR("pp does not support."); + return NULL; + } + + return g_display->available_pp_formats; +} + +EINTERN void +e_display_pp_available_size_get(int *minw, int *minh, int *maxw, int *maxh, int *align) +{ + EINA_SAFETY_ON_NULL_RETURN(g_display); + + tdm_display_get_pp_available_size(g_display->tdisplay, + minw, minh, maxw, maxh, align); +} + +EINTERN void +e_display_hwc_info_debug(void) +{ + EINA_SAFETY_ON_NULL_RETURN(g_display); + + E_Display *display = g_display; + E_Output *output = NULL; + E_Plane *plane = NULL; + Eina_List *l_o, *ll_o; + Eina_List *l_l, *ll_l; + tdm_output_conn_status conn_status; + int output_idx = 0; + tdm_layer_capability layer_capabilities; + char layer_cap[4096] = {0, }; + int i; + const tdm_prop *tprops; + int count; + + INF("HWC: HWC Information =========================================================="); + EINA_LIST_FOREACH_SAFE(display->outputs, l_o, ll_o, output) + { + tdm_error err = TDM_ERROR_NONE; + + if (!output) continue; + + if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES) + { + err = tdm_output_get_conn_status(output->toutput, &conn_status); + if (err != TDM_ERROR_NONE) continue; + if (conn_status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) continue; + + INF("HWC: HWC Output(%d):(x, y, w, h)=(%d, %d, %d, %d) Information.", + ++output_idx, + output->config.geom.x, output->config.geom.y, output->config.geom.w, output->config.geom.h); + INF("HWC: num_layers=%d", output->plane_count); + EINA_LIST_FOREACH_SAFE(output->planes, l_l, ll_l, plane) + { + if (!plane) continue; + /* FIXME: hwc extension doesn't provide thing like layer */ + tdm_layer_get_capabilities(plane->tlayer, &layer_capabilities); + snprintf(layer_cap, sizeof(layer_cap), "%s%s%s%s%s%s%s%s", + _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_CURSOR), + _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_PRIMARY), + _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_OVERLAY), + _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_GRAPHIC), + _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_VIDEO), + _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_TRANSFORM), + _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_RESEVED_MEMORY), + _layer_cap_to_str(layer_capabilities, TDM_LAYER_CAPABILITY_NO_CROP)); + INF("HWC: index=%d zpos=%d ec=%p %s", + plane->index, plane->zpos, + plane->ec?plane->ec:NULL, + layer_cap); + } + } + else + { + /* TODO: construct debug info for outputs managed by the hwc-wins */ + INF("HWC: HWC Output(%d) managed by hwc-wins.", ++output_idx); + + if (!e_hwc_windows_get_available_properties(output->hwc, &tprops, &count)) + { + ERR("e_hwc_windows_get_video_available_properties failed"); + return; + } + INF(">>>>>>>> Available UI props : count = %d", count); + for (i = 0; i < count; i++) + INF(" [%d] %s, %u", i, tprops[i].name, tprops[i].id); + + if (!e_hwc_windows_get_video_available_properties(output->hwc, &tprops, &count)) + { + ERR("e_hwc_windows_get_video_available_properties failed"); + return; + } + INF(">>>>>>>> Available VIDEO props : count = %d", count); + for (i = 0; i < count; i++) + INF(" [%d] %s, %u", i, tprops[i].name, tprops[i].id); + } + } + INF("HWC: ========================================================================="); +} + +EINTERN void +e_display_debug_info_get(Eldbus_Message_Iter *iter) +{ + Eldbus_Message_Iter *line_array; + E_Output *output = NULL; + E_Hwc *hwc = NULL; + Eina_List *l; + char info_str[1024]; + + eldbus_message_iter_arguments_append(iter, "as", &line_array); + + eldbus_message_iter_basic_append(line_array, 's', + "==========================================================================================="); + eldbus_message_iter_basic_append(line_array, 's', + " idx id status dpms ( x , y ) ( w x h ) "); + eldbus_message_iter_basic_append(line_array, 's', + "==========================================================================================="); + + +#ifdef E_DISPLAY + EINA_LIST_FOREACH(e_display_outputs_get(), l, output) +#else + E_Comp_Screen *e_comp_screen = NULL; + e_comp_screen = e_comp->e_comp_screen; + EINA_LIST_FOREACH(e_comp_screen->outputs, l, output) +#endif + { + if (!output) continue; + hwc = output->hwc; + if (!output->hwc) continue; + if (e_hwc_policy_get(hwc) == E_HWC_POLICY_NONE) continue; + + snprintf(info_str, sizeof(info_str), "%2d %12s %15s %10s (%5d , %5d) (%5d x %5d)", + output->index, output->id, + output->info.connected ? "connected" : "disconnected", + _e_display_dpms_to_string(output->dpms), + output->config.geom.x, output->config.geom.y, + output->config.geom.w, output->config.geom.h); + + eldbus_message_iter_basic_append(line_array, 's', info_str); + } + + eldbus_message_iter_basic_append(line_array, 's', + "==========================================================================================="); + + eldbus_message_iter_container_close(iter, line_array); +} diff --git a/src/bin/displaymgr/e_display_intern.h b/src/bin/displaymgr/e_display_intern.h new file mode 100644 index 0000000..4245322 --- /dev/null +++ b/src/bin/displaymgr/e_display_intern.h @@ -0,0 +1,27 @@ +#ifndef E_DISPLAY_INTERN_H +#define E_DISPLAY_INTERN_H + +#include "e_intern.h" +#include "e_output_intern.h" + +#include + +EINTERN Eina_Bool e_display_init(void); +EINTERN void e_display_shutdown(void); + +EINTERN E_Output *e_display_primary_output_get(void); +EINTERN void *e_display_tdm_display_get(void); +EINTERN void *e_display_gbm_device_get(void); +EINTERN Eina_List *e_display_outputs_get(void); +EINTERN int e_display_num_outputs_get(void); + +EINTERN Eina_Bool e_display_available_video_formats_get(const tbm_format **formats, int *count); + +EINTERN Eina_Bool e_display_pp_support(void); +EINTERN Eina_List *e_display_pp_available_formats_get(void); +EINTERN void e_display_pp_available_size_get(int *minw, int *minh, int *maxw, int *maxh, int *align); + +EINTERN void e_display_hwc_info_debug(void); +EINTERN void e_display_debug_info_get(Eldbus_Message_Iter *iter); + +#endif