e_comp_canvas: move ecore_evas to e_comp_canvas
authorSooChan Lim <sc1.lim@samsung.com>
Fri, 6 Dec 2024 08:12:42 +0000 (17:12 +0900)
committerJunseok Kim <juns.kim@samsung.com>
Fri, 13 Dec 2024 05:15:51 +0000 (14:15 +0900)
Change-Id: I31361988cf103c78b079e2a23a46df2953fbc9b5

src/bin/compmgr/e_comp.c
src/bin/compmgr/e_comp_canvas.c
src/bin/compmgr/e_comp_canvas_intern.h
src/bin/displaymgr/e_display.c
src/bin/displaymgr/e_display_intern.h
src/bin/e_comp_screen.c
src/bin/e_comp_screen_intern.h
src/include/e_comp_screen.h

index abaa4bd234f828b573f57f7e20f090d7ab29877b..ff235f2dd0017f931fb5792aa14918c1b9105408 100644 (file)
@@ -228,7 +228,7 @@ _e_comp_free(E_Comp *c)
 
    e_comp_canvas_clear();
 
-   ecore_evas_free(c->ee);
+//   ecore_evas_free(c->ee);
    eina_stringshare_del(c->name);
 
    if (c->render_animator) ecore_animator_del(c->render_animator);
index 4b0a22dc06885fe04690d075e2b36ce08e2fc203..d2a62fcc4b2676a403be4e6dfe55bd245f220e0c 100644 (file)
 #include "e_view_intern.h"
 #include "e_view_rect.h"
 #include "e_view_edje_intern.h"
+#include "e_display_intern.h"
+#include "e_hwc_windows_intern.h"
+
+#include <gbm.h>
 
 static Eina_List *handlers;
 static Eina_Bool _ev_freeze = EINA_FALSE;
@@ -49,20 +53,257 @@ _e_comp_canvas_prerender(Ecore_Evas *ee EINA_UNUSED)
      cb();
 }
 
+static void
+_e_hwc_tbm_surface_queue_free(void *data, void *tqueue)
+{
+   E_Comp_Screen *e_comp_screen = (E_Comp_Screen *)data;
+
+   ELOGF("Comp_Canvas", "The tbm_surface(%p) is destroyed.", NULL,
+         e_comp_screen->tqueue);
+
+   e_display_tbm_buffer_queue_destroy(e_comp_screen->tqueue);
+}
+
+static void *
+_e_hwc_tbm_surface_queue_alloc(void *data, int w, int h)
+{
+   E_Comp_Screen *e_comp_screen = (E_Comp_Screen *)data;
+
+   e_comp_screen->tqueue =
+         e_display_tbm_buffer_queue_create(e_comp_screen->w, e_comp_screen->h);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen->tqueue, NULL);
+
+   ELOGF("Comp_Canvas", "Assign tqueue(%p) to Ecore_Evas.", NULL,
+         e_comp_screen->tqueue);
+
+   return (void *)e_comp_screen->tqueue;
+}
+
+static Ecore_Evas *
+_e_hwc_ecore_evas_tbm_alloc(E_Comp_Screen *e_comp_screen, int src_w, int src_h)
+{
+   Ecore_Evas *ee;
+   E_Comp *comp;
+
+   comp = e_comp_get();
+   if (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 *)e_comp_screen);
+     }
+   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 *)e_comp_screen);
+     }
+
+   ELOGF("Comp Screen", "ecore_evas engine:gl_tbm ee:%p avoid_afill:%d", NULL,
+         ee, comp->avoid_afill);
+
+   return ee;
+}
+
+static void
+_e_hwc_gbm_surface_free(void *data, void *gsurface)
+{
+   E_Comp_Screen *e_comp_screen = (E_Comp_Screen *)data;
+
+   ELOGF("Comp_Canvas", "The gbm_surface(%p) is destroyed.", NULL,
+         e_comp_screen->gsurface);
+
+   e_display_gbm_surface_destroy(e_comp_screen->gsurface);
+}
+
+static void *
+_e_hwc_gbm_surface_alloc(void *data, int w, int h)
+{
+   E_Comp_Screen *e_comp_screen = (E_Comp_Screen *)data;
+
+   e_comp_screen->gsurface =
+         e_display_gbm_surface_create(w, h, e_comp_screen->gbm_format);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_screen->gsurface, NULL);
+
+   ELOGF("Comp_Canvas", "Assign gbm_surface(%p) to Ecore_Evas.", NULL,
+         e_comp_screen->gsurface);
+
+   return (void *)e_comp_screen->gsurface;
+}
+
+static Ecore_Evas *
+_e_hwc_ecore_evas_gbm_alloc(E_Comp_Screen *e_comp_screen, int src_w, int src_h)
+{
+   Ecore_Evas *ee;
+   E_Comp *comp;
+   struct gbm_device *gdevice;
+   int gbm_formats[2] = {GBM_FORMAT_ABGR8888, GBM_FORMAT_ARGB8888};
+   int i, format_count;
+
+   gdevice = e_display_gbm_device_get();
+   if (!gdevice) return NULL;
+
+   format_count = sizeof(gbm_formats) / sizeof(int);
+   comp = e_comp_get();
+   for (i = 0; i < format_count; i++)
+     {
+        e_comp_screen->gbm_format = gbm_formats[i];
+
+        if (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 *)e_comp_screen);
+          }
+        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 *)e_comp_screen);
+          }
+
+        if (ee) break;
+     }
+
+   ELOGF("Comp_Canvas", "ee engine:gl_tbm with gbm ee:%p avaoid_afill:%d", NULL,
+         ee, comp->avoid_afill);
+
+   return ee;
+}
+
+static void
+_e_hwc_ecore_evas_deinit(Ecore_Evas *ee)
+{
+   if (!ee) return;
+
+   ecore_evas_free(ee);
+}
+
+static Ecore_Evas *
+_e_hwc_ecore_evas_init(E_Comp_Screen *e_comp_screen, int w, int y)
+{
+   Ecore_Evas *ee;
+   int scr_w = 1, scr_h = 1;
+   char buf[1024];
+
+   ELOGF("Comp_Canvas", "ecore evase engine init.", NULL);
+
+   /* set env for use tbm_surface_queue*/
+   setenv("USE_EVAS_SOFTWARE_TBM_ENGINE", "1", 1);
+   //setenv("USE_EVAS_GL_TBM_ENGINE", "1", 1);
+
+   /* set gl available if we have ecore_evas support */
+   if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_DRM) ||
+       ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_TBM))
+     e_comp_gl_set(EINA_TRUE);
+
+   e_comp_screen_size_get(e_comp_screen, &scr_w, &scr_h);
+
+   ELOGF("COMP_SCREEN", "GL available:%d config engine:%d screen size:%dx%d", NULL,
+       e_comp_gl_get(), e_comp_config_get()->engine, scr_w, scr_h);
+
+   if ((e_comp_gl_get()) &&
+       (e_comp_config_get()->engine == E_COMP_ENGINE_GL))
+     {
+        e_main_ts_begin("\tEE_GL_TBM New");
+        if (e_comp_screen_prefer_gbm_check())
+          {
+             ee = _e_hwc_ecore_evas_gbm_alloc(e_comp_screen, scr_w, scr_h);
+             if (!ee)
+               ee = _e_hwc_ecore_evas_tbm_alloc(e_comp_screen, scr_w, scr_h);
+          }
+        else
+          {
+             ee = _e_hwc_ecore_evas_tbm_alloc(e_comp_screen, scr_w, scr_h);
+             if (!ee)
+               ee = _e_hwc_ecore_evas_gbm_alloc(e_comp_screen, 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)
+          e_comp_gl_set(EINA_FALSE);
+     }
+
+   /* fallback to framebuffer drm (non-accel) */
+   if (!ee)
+     {
+        e_main_ts_begin("\tEE_DRM New");
+        ee = ecore_evas_tbm_allocfunc_new("software_tbm",
+                     scr_w, scr_h,
+                     _e_hwc_tbm_surface_queue_alloc, _e_hwc_tbm_surface_queue_free,
+                     (void *)e_comp_screen);
+        ELOGF("Comp_Canvas", "ecore_evas engine:software_tbm fallback to software engine.", NULL);
+        snprintf(buf, sizeof(buf), "\tEE_DRM New Done %p %dx%d", ee, scr_w, scr_h);
+        e_main_ts_end(buf);
+     }
+
+   if (!ee)
+     {
+        ERR("Enlightenment cannot initialize outputs!");
+        _e_hwc_ecore_evas_deinit(ee);
+        return EINA_FALSE;
+     }
+
+   return ee;
+}
+
+
 EINTERN Eina_Bool
-e_comp_canvas_init(int w, int h)
+e_comp_canvas_init(E_Comp_Screen *e_comp_screen)
 {
    E_View_Rect *rect;
    E_View *view;
    E_View_Tree *layer_tree;
    E_View_Render_Op opmode = E_VIEW_RENDER_BLEND;
    E_Comp *comp;
+   Ecore_Evas *ee;
+   E_Output *primary_output;
    int color[4] = {0, 0, 0, 255};
+   int w, h;
+   int screen_rotation;
 
    TRACE_DS_BEGIN(COMP_CANVAS:INIT);
 
+   primary_output = e_display_primary_output_get();
+   EINA_SAFETY_ON_NULL_RETURN_VAL(primary_output, EINA_FALSE);
+
+   screen_rotation = e_comp_screen->rotation;
+
+   e_comp_screen_size_get(e_comp_screen, &w, &h);
+
+   ee = _e_hwc_ecore_evas_init(e_comp_screen, w, h);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EINA_FALSE);
+
+   ELOGF("Comp_Canvas", "ee(%p) with the tqueue(%p) is created.", NULL,
+         ee, e_comp_screen->tqueue);
+
    comp = e_comp_get();
-   comp->evas = ecore_evas_get(comp->ee);
+   comp->ee = ee;
+   comp->evas = ecore_evas_get(ee);
+   ecore_evas_data_set(comp->ee, "comp", comp);
+
+   if (screen_rotation)
+     {
+        /* SHOULD called with resize option after ecore_evas_resize */
+        ecore_evas_rotation_with_resize_set(comp->ee, screen_rotation);
+        ecore_evas_geometry_get(comp->ee, NULL, NULL, &w, &h);
+        ELOGF("Comp_Canvas", "Rotate and Resize %d, %dx%d", NULL,
+              screen_rotation, w, h);
+     }
+
+   if (!e_hwc_windows_ecore_evas_set(primary_output->hwc, ee))
+     {
+        ERR("fail to e_hwc_windows_ecore_evas_set");
+        _e_hwc_ecore_evas_deinit(ee);
+        return EINA_FALSE;
+     }
+
    comp->canvas = e_canvas_create(comp->evas);
    comp->w = w;
    comp->h = h;
@@ -117,6 +358,7 @@ e_comp_canvas_clear(void)
 
    E_FREE_LIST(handlers, ecore_event_handler_del);
 
+   _e_hwc_ecore_evas_deinit(comp->ee);
    e_view_destroy(comp->bg_blank_view);
    e_canvas_destroy(comp->canvas);
    evas_event_freeze(comp->evas);
index 8a061507d8e3e4d6b84c62669f8e28c6a48c63a0..a384da973a6e9186527ea60130ce4c3ea5c77b9e 100644 (file)
@@ -4,7 +4,7 @@
 #include "e_intern.h"
 #include "e_comp_canvas.h"
 
-EINTERN Eina_Bool  e_comp_canvas_init(int w, int h);
+EINTERN Eina_Bool  e_comp_canvas_init(E_Comp_Screen *e_comp_screen);
 EINTERN void       e_comp_canvas_clear(void);
 EINTERN void       e_comp_all_freeze(void);
 EINTERN void       e_comp_all_thaw(void);
index 771f74615609190c713bd135ba25576c459a6463..4ca15ed552491062b3fe2d151ee5659a6d287252 100644 (file)
@@ -615,6 +615,113 @@ e_display_num_outputs_get(void)
    return g_display->num_outputs;
 }
 
+EINTERN void *
+e_display_tbm_buffer_queue_create(int w, int h)
+{
+   E_Output *primary_output;
+   E_Hwc *hwc;
+   tbm_surface_queue_h tqueue = NULL;
+   tdm_error error;
+   int queue_w, queue_h;
+
+   primary_output = e_display_primary_output_get();
+   EINA_SAFETY_ON_NULL_RETURN_VAL(primary_output, EINA_FALSE);
+
+   hwc = primary_output->hwc;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
+
+   if ((primary_output->tdm_hwc) && (!primary_output->fake_config))
+     {
+        tqueue = tdm_hwc_get_client_target_buffer_queue(hwc->thwc, &error);
+        if (error != TDM_ERROR_NONE)
+         {
+            ERR("fail to tdm_hwc_get_client_target_buffer_queue");
+            return (void *)NULL;
+         }
+     }
+   else
+     {
+        tqueue = tbm_surface_queue_create(3, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
+        if (!tqueue)
+          {
+             ERR("fail to tbm_surface_queue_create");
+             return (void *)NULL;
+          }
+     }
+
+   queue_w = tbm_surface_queue_get_width(tqueue);
+   queue_h = tbm_surface_queue_get_height(tqueue);
+
+   if ((w != queue_w) || (h != queue_h))
+     tbm_surface_queue_reset(tqueue, w, h, tbm_surface_queue_get_format(tqueue));
+
+   hwc->target_buffer_queue = tqueue;
+
+   ELOGF("Display", "The tqueue(%p, %dx%d) is created.", NULL,
+         tqueue, queue_w, queue_h);
+
+   return (void *)tqueue;
+}
+
+EINTERN void
+e_display_tbm_buffer_queue_destroy(void *tqueue)
+{
+   if (!tqueue) return;
+
+   tbm_surface_queue_destroy(tqueue);
+}
+
+EINTERN void *
+e_display_gbm_surface_create(int w, int h, unsigned int gbm_format)
+{
+   E_Output *primary_output;
+   E_Hwc *hwc;
+   struct gbm_device *gdevice;
+   struct gbm_surface *gsurface;
+
+   primary_output = e_display_primary_output_get();
+   EINA_SAFETY_ON_NULL_RETURN_VAL(primary_output, EINA_FALSE);
+
+   hwc = primary_output->hwc;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
+
+   if (primary_output->tdm_hwc)
+     {
+        EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_get(), NULL);
+
+        gdevice = e_display_gbm_device_get();
+        EINA_SAFETY_ON_NULL_RETURN_VAL(gdevice, NULL);
+
+        gsurface = gbm_surface_create(gdevice, w, h,
+                                      gbm_format,
+                                      GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+        EINA_SAFETY_ON_NULL_RETURN_VAL(gsurface, NULL);
+     }
+   else
+     {
+        ERR("only tdm hwc support gbm_surface");
+        return (void *) NULL;
+     }
+
+   hwc->gsurface = gsurface;
+   hwc->gsurface_width = w;
+   hwc->gsurface_height = h;
+   hwc->gsurface_format = gbm_format;
+
+   ELOGF("Display", "The gbm_surface(%p, %dx%d) fmt(%c%c%c%c)is created.", NULL,
+         gsurface, w, h, EHW_FOURCC_STR(hwc->gsurface_format));
+
+   return (void *)gsurface;
+}
+
+EINTERN void
+e_display_gbm_surface_destroy(void *gsurface)
+{
+   if (!gsurface) return;
+
+   gbm_surface_destroy(gsurface);
+}
+
 EINTERN Eina_Bool
 e_display_pp_support(void)
 {
index 424532259b757eb5593d1c5502c595b3611f8849..45ac7b20201eb5793d0820df35897eeb7ca9cea6 100644 (file)
@@ -15,6 +15,12 @@ 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 void      *e_display_tbm_buffer_queue_create(int w, int h);
+EINTERN void       e_display_tbm_buffer_queue_destroy(void *tqueue);
+
+EINTERN void      *e_display_gbm_surface_create(int w, int h, unsigned int gbm_format);
+EINTERN void       e_display_gbm_surface_destroy(void *surface);
+
 EINTERN Eina_Bool  e_display_available_video_formats_get(const tbm_format **formats, int *count);
 
 EINTERN Eina_Bool  e_display_pp_support(void);
index 77ec9cb7ed99a2c431467e6ffb996bb3b22b4289..7a0ac6f0fe99a32020b1f7f7a88283f008e5284d 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <tizen-extension-server-protocol.h>
 #include <tbm_bufmgr_internal.h>
+#include <gbm.h>
 
 #define PATH "/org/enlightenment/wm"
 #define IFACE "org.enlightenment.wm.screen_rotation"
@@ -763,7 +764,7 @@ e_comp_screen_init()
    E_Comp *comp;
    E_Comp_Wl_Data *comp_wl;
    E_Comp_Screen *e_comp_screen;
-   int w, h, ptr_x = 0, ptr_y = 0;
+   int ptr_x = 0, ptr_y = 0;
    int screen_rotation;
 
    E_EVENT_SCREEN_CHANGE = ecore_event_type_new();
@@ -801,6 +802,7 @@ e_comp_screen_init()
      }
    e_main_ts_end("\te_display_init Done");
 
+   // Decide the size of Comp Screen and Get the Memory from E_Display
    e_comp_screen_size_update(e_comp_screen_get());
 
    e_comp_screen->num_outputs = e_display_num_outputs_get();
@@ -822,6 +824,7 @@ e_comp_screen_init()
 
    ecore_event_add(E_EVENT_SCREEN_CHANGE, NULL, NULL, NULL);
 
+#if 0
    e_main_ts_begin("\tE_Hwc Ecore_Evas Init");
    if (!e_hwc_ecore_evas_init())
      {
@@ -830,13 +833,11 @@ e_comp_screen_init()
         goto failed_comp_screen;
      }
    e_main_ts_end("\tE_Hwc Ecore_Evas Init Done");
-
-   /* get the current screen geometry */
-   ecore_evas_geometry_get(comp->ee, NULL, NULL, &w, &h);
+#endif
 
    /* canvas */
    e_main_ts_begin("\tE_Comp_Canvas Init");
-   if (!e_comp_canvas_init(w, h))
+   if (!e_comp_canvas_init(e_comp_screen))
      {
         e_main_ts_end("\tE_Comp_Canvas Init Failed");
         e_error_message_show(_("Enlightenment cannot initialize outputs!\n"));
@@ -1072,3 +1073,22 @@ e_comp_screen_policy_zone_get(E_Zone *zone)
 
    return NULL;
 }
+
+EINTERN Eina_Bool
+e_comp_screen_prefer_gbm_check(void)
+{
+   const char *backend_name;
+   struct gbm_device *gdevice;
+
+   if (e_comp_hwc_is_prefer_gbm())
+      return EINA_TRUE;
+
+   gdevice = e_display_gbm_device_get();
+   if (!gdevice) return EINA_FALSE;
+
+   backend_name = gbm_device_get_backend_name(gdevice);
+   if (!backend_name) return EINA_FALSE;
+   if (!e_util_strcmp(backend_name, "gbm_tbm")) return EINA_FALSE;
+
+   return EINA_TRUE;
+}
index a614d606a3a88143531e491798b4136514279f4d..958eaf6b5922b426cc394e4eff6bce4ac9708a42 100644 (file)
@@ -20,8 +20,12 @@ struct _E_Comp_Screen
    int            num_outputs;
    tdm_display   *tdisplay;
    tbm_bufmgr     bufmgr;
+   tbm_surface_queue_h tqueue;
+
    void          *gdevice;
    int            gdevice_fd;
+   void          *gsurface;
+   int            gbm_format;
 
    /* for sw compositing */
    const Eina_List *devices;
index d598a10da0dc477313b5cac80aa6f4ce297d5087..76a0995e876457a6bc922a6fc7c27c10396eea7c 100644 (file)
@@ -15,4 +15,6 @@ E_API Eina_Bool  e_comp_screen_available_video_formats_get(const tbm_format **fo
 E_API void       e_comp_screen_keymap_set(struct xkb_context **ctx, struct xkb_keymap **map);
 E_API Eina_List *e_comp_screen_outputs_get(E_Comp_Screen *e_comp_screen);
 
+EINTERN Eina_Bool e_comp_screen_prefer_gbm_check(void);
+
 #endif /*E_COMP_SCREEN_H*/