From f7c84aa523a1e5bee307863fc206be9a8c41a78f Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Wed, 11 Aug 2021 19:46:40 +0900 Subject: [PATCH] e_hwc: Support creating ecore_evas of gl compositor with gbm this patch is for ddk which only support libgbm. e20 try to creating ecore_evas of gl compositor with gbm device and gbm_surface. if hwc_prefer_gbm config is set, e20 prefer creating ecore_evas with gbm to tbm. Change-Id: Ia02fbeaff13928138fa3f1675d2eb47c783337d1 --- src/bin/e_comp.c | 1 + src/bin/e_comp.h | 1 + src/bin/e_comp_cfdata.c | 2 + src/bin/e_comp_cfdata.h | 1 + src/bin/e_comp_screen.c | 22 ++++++++ src/bin/e_comp_screen.h | 2 + src/bin/e_hwc.c | 117 +++++++++++++++++++++++++++++++++++++--- 7 files changed, 139 insertions(+), 7 deletions(-) diff --git a/src/bin/e_comp.c b/src/bin/e_comp.c index b6c3219c17..133649d404 100644 --- a/src/bin/e_comp.c +++ b/src/bin/e_comp.c @@ -438,6 +438,7 @@ e_comp_init(void) e_comp->hwc = EINA_TRUE; // activate hwc policy on the primary output if (conf->avoid_afill) e_comp->avoid_afill = EINA_TRUE; + if (conf->hwc_prefer_gbm) e_comp->hwc_prefer_gbm = EINA_TRUE; e_main_ts_begin("\tE_Comp_Screen Init"); if (!e_comp_screen_init()) diff --git a/src/bin/e_comp.h b/src/bin/e_comp.h index d47cd0c82a..980b3466d4 100644 --- a/src/bin/e_comp.h +++ b/src/bin/e_comp.h @@ -166,6 +166,7 @@ struct _E_Comp Eina_Bool hwc_use_detach; Eina_Bool hwc_ignore_primary; Eina_Bool hwc_send_redraw_request; + Eina_Bool hwc_prefer_gbm; Eina_Bool use_native_type_buffer : 1; // use native buffer type Eina_Bool avoid_afill; // avoid to fill the alpha channel as 0xff. that means filling 0x00. diff --git a/src/bin/e_comp_cfdata.c b/src/bin/e_comp_cfdata.c index 714eeb80ae..d1c456f525 100644 --- a/src/bin/e_comp_cfdata.c +++ b/src/bin/e_comp_cfdata.c @@ -63,6 +63,7 @@ e_comp_cfdata_edd_init(E_Config_DD **conf_edd, E_Config_DD **match_edd) E_CONFIG_VAL(D, T, hwc_ignore_primary, UCHAR); E_CONFIG_VAL(D, T, hwc_use_detach, UCHAR); E_CONFIG_VAL(D, T, hwc_send_redraw_request, UCHAR); + E_CONFIG_VAL(D, T, hwc_prefer_gbm, UCHAR); E_CONFIG_VAL(D, T, use_native_type_buffer, UCHAR); E_CONFIG_VAL(D, T, nofade, UCHAR); E_CONFIG_VAL(D, T, smooth_windows, UCHAR); @@ -140,6 +141,7 @@ e_comp_cfdata_config_new(void) cfg->hwc_ignore_primary = 0; cfg->hwc_use_detach = 0; cfg->hwc_send_redraw_request = 0; + cfg->hwc_prefer_gbm = 0; cfg->use_native_type_buffer = 0; // 1 if use_native(wl_buffer), 0 if use_tbm(tbm_surface) cfg->nofade = 0; cfg->smooth_windows = 0; // 1 if gl, 0 if not diff --git a/src/bin/e_comp_cfdata.h b/src/bin/e_comp_cfdata.h index 9d6f8ef8a0..af2f2b7637 100644 --- a/src/bin/e_comp_cfdata.h +++ b/src/bin/e_comp_cfdata.h @@ -40,6 +40,7 @@ struct _E_Comp_Config unsigned char hwc_ignore_primary; // 0: none, 1: hwc use plane has lowest zpos and support rgb to default ui layer unsigned char hwc_use_detach; // 0: hwc use dequeue protocol, 1: hwc use detach request when synchronize scanout buffer unsigned char hwc_send_redraw_request; // 0: none, 1: send redraw request to client when client need to redraw for hwc + unsigned char hwc_prefer_gbm; //0: prefer creating ecore_evas with tbm, 1: prefer creating ecore_evas with gbm unsigned char use_native_type_buffer; // 0: use the tbm_buffer(tbm_surface), 1: use the native_buffer(wl_buffer) unsigned char smooth_windows; unsigned char nofade; diff --git a/src/bin/e_comp_screen.c b/src/bin/e_comp_screen.c index 411577d571..3580eda7e3 100644 --- a/src/bin/e_comp_screen.c +++ b/src/bin/e_comp_screen.c @@ -2,6 +2,8 @@ #include "Eeze.h" #include #include +#include +#include #define PATH "/org/enlightenment/wm" #define IFACE "org.enlightenment.wm.screen_rotation" @@ -502,6 +504,8 @@ _e_comp_screen_del(E_Comp_Screen *e_comp_screen) e_comp_screen->available_pp_formats = eina_list_remove(e_comp_screen->available_pp_formats, l); } } + + if (e_comp_screen->gdevice) gbm_device_destroy(e_comp_screen->gdevice); if (e_comp_screen->bufmgr) tbm_bufmgr_deinit(e_comp_screen->bufmgr); if (e_comp_screen->fd >= 0) close(e_comp_screen->fd); if (e_comp_screen->hdlr) ecore_main_fd_handler_del(e_comp_screen->hdlr); @@ -1655,6 +1659,24 @@ e_comp_screen_available_video_formats_get(const tbm_format **formats, int *count return EINA_TRUE; } +EINTERN void * +e_comp_screen_gbm_device_get(E_Comp_Screen *e_comp_screen) +{ + int fd; + + EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen, NULL); + + if (e_comp_screen->gdevice) return e_comp_screen->gdevice; + + fd = tbm_drm_helper_get_master_fd(); + EINA_SAFETY_ON_FALSE_RETURN_VAL(fd >= 0, NULL); + + e_comp_screen->gdevice = gbm_create_device(fd); + EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen->gdevice, NULL); + + return e_comp_screen->gdevice; +} + EINTERN void e_comp_screen_debug_info_get(Eldbus_Message_Iter *iter) { diff --git a/src/bin/e_comp_screen.h b/src/bin/e_comp_screen.h index 8236d30637..3e57e5717f 100644 --- a/src/bin/e_comp_screen.h +++ b/src/bin/e_comp_screen.h @@ -67,6 +67,8 @@ EINTERN Eina_Bool e_comp_screen_pp_support(void); EINTERN Eina_List * e_comp_screen_pp_available_formats_get(void); E_API Eina_Bool e_comp_screen_available_video_formats_get(const tbm_format **formats, int *count); +EINTERN void * e_comp_screen_gbm_device_get(E_Comp_Screen *e_comp_screen); + EINTERN void e_comp_screen_debug_info_get(Eldbus_Message_Iter *iter); #endif /*E_COMP_SCREEN_H*/ diff --git a/src/bin/e_hwc.c b/src/bin/e_hwc.c index 6db5a5bcb1..bb6e8b412a 100644 --- a/src/bin/e_hwc.c +++ b/src/bin/e_hwc.c @@ -1,6 +1,7 @@ #include "e.h" #include "services/e_service_quickpanel.h" #include +#include #define EHERR(f, hwc, x...) \ do \ @@ -230,6 +231,105 @@ _e_hwc_tbm_surface_queue_free(void *data, void *tqueue) hwc->target_buffer_queue = NULL; } +static void * +_e_hwc_gbm_surface_alloc(void *data, int w, int h) +{ + E_Hwc *hwc = (E_Hwc *)data; + E_Output *output = hwc->output; + struct gbm_device *gdevice; + struct gbm_surface *gsurface; + int format = GBM_FORMAT_ABGR8888; + + if (output->tdm_hwc) + { + EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, NULL); + + gdevice = e_comp_screen_gbm_device_get(e_comp->e_comp_screen); + EINA_SAFETY_ON_NULL_RETURN_VAL(gdevice, NULL); + + gsurface = gbm_surface_create(gdevice, w, h, + format, + GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + EINA_SAFETY_ON_NULL_RETURN_VAL(gsurface, NULL); + } + else + { + EHERR("only tdm hwc support gbm_surface", hwc); + return (void *) NULL; + } + + hwc->gsurface = gsurface; + + EHINF("The gbm_surface(%p, %dx%d) fmt(%c%c%c%c)is created.", hwc, gsurface, w, h, FOURCC_STR(format)); + + return (void *)gsurface; +} + +static void +_e_hwc_gbm_surface_free(void *data, void *gsurface) +{ + E_Hwc *hwc = (E_Hwc *)data; + + EHINF("The gbm_surface(%p) is destroyed.", NULL, gsurface); + + gbm_surface_destroy(gsurface); + hwc->gsurface = NULL; +} + +static Ecore_Evas * +_e_hwc_ecore_evas_tbm_alloc(E_Hwc *hwc, int src_w, int src_h) +{ + Ecore_Evas *ee; + + if (e_comp->avoid_afill) + { + ee = ecore_evas_tbm_allocfunc_new("gl_tbm_ES", src_w, src_h, + _e_hwc_tbm_surface_queue_alloc, + _e_hwc_tbm_surface_queue_free, + (void *)hwc); + } + else + { + ee = ecore_evas_tbm_allocfunc_new("gl_tbm", src_w, src_h, + _e_hwc_tbm_surface_queue_alloc, + _e_hwc_tbm_surface_queue_free, + (void *)hwc); + } + + EHINF("ecore_evas engine:gl_tbm ee:%p avoid_afill:%d", hwc, ee, e_comp->avoid_afill); + + return ee; +} + +static Ecore_Evas * +_e_hwc_ecore_evas_gbm_alloc(E_Hwc *hwc, int src_w, int src_h) +{ + Ecore_Evas *ee; + struct gbm_device *gdevice; + + gdevice = e_comp_screen_gbm_device_get(e_comp->e_comp_screen); + if (!gdevice) return NULL; + + if (e_comp->avoid_afill) + { + ee = ecore_evas_tbm_native_allocfunc_new("gl_tbm_ES", gdevice, src_w, src_h, + _e_hwc_gbm_surface_alloc, + _e_hwc_gbm_surface_free, + (void *)hwc); + } + else + { + ee = ecore_evas_tbm_native_allocfunc_new("gl_tbm", gdevice, src_w, src_h, + _e_hwc_gbm_surface_alloc, + _e_hwc_gbm_surface_free, + (void *)hwc); + } + + EHINF("ecore_evas engine:gl_tbm with gbm ee:%p avaoid_afill:%d", hwc, ee, e_comp->avoid_afill); + + return ee; +} + static void _e_hwc_ee_deinit(E_Hwc *hwc) { @@ -307,18 +407,21 @@ _e_hwc_ee_init(E_Hwc* hwc) if ((e_comp_gl_get()) && (e_comp_config_get()->engine == E_COMP_ENGINE_GL)) { - e_main_ts_begin("\tEE_GL_DRM New"); - if (e_comp->avoid_afill) + e_main_ts_begin("\tEE_GL_TBM New"); + if (e_comp->hwc_prefer_gbm) { - ee = ecore_evas_tbm_allocfunc_new("gl_tbm_ES", scr_w, scr_h, _e_hwc_tbm_surface_queue_alloc, _e_hwc_tbm_surface_queue_free, (void *)hwc); - EHINF("ecore_evas engine:gl_tbm_ES avoid_afill:%d", hwc, e_comp->avoid_afill); + ee = _e_hwc_ecore_evas_gbm_alloc(hwc, scr_w, scr_h); + if (!ee) + ee = _e_hwc_ecore_evas_tbm_alloc(hwc, scr_w, scr_h); } else { - ee = ecore_evas_tbm_allocfunc_new("gl_tbm", scr_w, scr_h, _e_hwc_tbm_surface_queue_alloc, _e_hwc_tbm_surface_queue_free, (void *)hwc); - EHINF("ecore_evas engine:gl_tbm avoid_afill:%d", hwc, e_comp->avoid_afill); + ee = _e_hwc_ecore_evas_tbm_alloc(hwc, scr_w, scr_h); + if (!ee) + ee = _e_hwc_ecore_evas_gbm_alloc(hwc, scr_w, scr_h); } - snprintf(buf, sizeof(buf), "\tEE_GL_DRM New Done %p %dx%d", ee, scr_w, scr_h); + + snprintf(buf, sizeof(buf), "\tEE_GL_TBM New Done %p %dx%d", ee, scr_w, scr_h); e_main_ts_end(buf); if (!ee) -- 2.34.1