e_hwc: Support creating ecore_evas of gl compositor with gbm 71/262471/4 accepted/tizen/unified/20210906.123631 submit/tizen/20210906.041608
authorChangyeon Lee <cyeon.lee@samsung.com>
Wed, 11 Aug 2021 10:46:40 +0000 (19:46 +0900)
committerchangyeon lee <cyeon.lee@samsung.com>
Mon, 6 Sep 2021 01:50:18 +0000 (01:50 +0000)
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
src/bin/e_comp.h
src/bin/e_comp_cfdata.c
src/bin/e_comp_cfdata.h
src/bin/e_comp_screen.c
src/bin/e_comp_screen.h
src/bin/e_hwc.c

index b6c3219c17bf1d05da617135beb31cce3b1766ac..133649d40431014428dc5ba5623b94e056c723e0 100644 (file)
@@ -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())
index d47cd0c82a5afffff876767525407d06af98eff2..980b3466d4a518a963e8cd6099d39ec9928e7ba2 100644 (file)
@@ -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.
 
index 714eeb80aef64c7b18fbfd42ecc5c713d3521bf2..d1c456f525ddc7a960d93ecd2b0c73eb8874e55b 100644 (file)
@@ -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
index 9d6f8ef8a08233fb8f2dafb3f258de2cfeab2e98..af2f2b7637ad11b3ad1d96065c929b031d6e9e9f 100644 (file)
@@ -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;
index 411577d57148453b6a88992bed6f0af585b58b17..3580eda7e3f00c1b57b9cf9fba9f92fdff38dbec 100644 (file)
@@ -2,6 +2,8 @@
 #include "Eeze.h"
 #include <tizen-extension-server-protocol.h>
 #include <device/booting-internal.h>
+#include <tbm_drm_helper.h>
+#include <gbm.h>
 
 #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)
 {
index 8236d30637dc86ae0da1745d30458043254c1bbd..3e57e5717f759178e45ea2cdcf92ed48aa1e3f4b 100644 (file)
@@ -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*/
index 6db5a5bcb13350fceafdcae590ea887b3a2fe10e..bb6e8b412a278166b593969c51e275fedaca5a88 100644 (file)
@@ -1,6 +1,7 @@
 #include "e.h"
 #include "services/e_service_quickpanel.h"
 #include <Evas_GL.h>
+#include <gbm.h>
 
 #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)