#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;
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;
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);
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)
{
#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"
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();
}
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();
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())
{
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"));
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;
+}