struct wl_global *global;
struct wl_resource *resource;
Eina_List *handlers;
+
+ tdm_display *dpy;
+ tbm_bufmgr bufmgr;
+ int fd;
};
typedef struct _Ecore_Drm_Hal_Output
{
tdm_layer *layer;
tdm_output *output;
+ tbm_surface_h dst_buffers;
} Eom_Event;
static Eom_Event g_eom_event;
static E_Client_Hook *fullscreen_pre_hook = NULL;
-
static E_Comp_Wl_Output *
_e_eom_e_comp_wl_output_get(Eina_List *outputs, const char *id)
{
Eina_List *l;
- E_Comp_Wl_Output *output, *out;
+ E_Comp_Wl_Output *output = NULL, *out;
int num_outputs = 0;
EINA_LIST_FOREACH(outputs, l, out)
return output;
}
-static Ecore_Drm_Hal_Output *
-_e_eom_e_comp_hal_output_get(const char *id, int primary_output_id)
+static tdm_output *
+_e_eom_hal_output_get(const char *id, int primary_output_id)
{
- Ecore_Drm_Hal_Output * hal_output;
Ecore_Drm_Output *drm_output;
Ecore_Drm_Device *dev;
Eina_List *l;
+ int crtc_id = 0;
+ tdm_error err = TDM_ERROR_NONE;
+
+ tdm_output *output = NULL;
/*
- * Temporary take into account only HDMI
- */
+ * Temporary take into account only HDMI
+ */
if (strcmp(id, "HDMI-A-0"))
{
EOM_DBG("not find output\n");
return NULL;
}
- hal_output = ecore_drm_output_hal_private_get(drm_output);
- if (!hal_output)
+ crtc_id = ecore_drm_output_crtc_id_get(drm_output);
+ if (crtc_id == 0)
+ {
+ EOM_DBG("crtc is 0\n");
+ return NULL;
+ }
+
+ output = tdm_display_get_output(g_eom->dpy, crtc_id, NULL);
+ if (!output)
{
- EOM_DBG("not find hal output output\n");
+ EOM_DBG("there is no HAL output for:%d\n", crtc_id);
return NULL;
}
EOM_DBG("find\n");
- return hal_output;
+ return output;
+}
+
+static tdm_layer *
+_e_eom_hal_layer_get(tdm_output *output, int width, int height)
+{
+ int i = 0;
+ int count = 0;
+ tdm_layer *layer;
+ tdm_error err = TDM_ERROR_NONE;
+ tdm_layer_capability capa;
+
+ tdm_info_layer set_layer_info;
+
+ err = tdm_output_get_layer_count(output, &count);
+ if (err != TDM_ERROR_NONE)
+ {
+ EOM_DBG ("tdm_output_get_layer_count fail(%d)\n", err);
+ return NULL;
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ layer = (tdm_layer *)tdm_output_get_layer(output, i, &err);
+ if (err != TDM_ERROR_NONE)
+ {
+ EOM_DBG ("tdm_output_get_layer fail(%d)\n", err);
+ return NULL;
+ }
+
+ err = tdm_layer_get_capabilities(layer, &capa);
+ if (err != TDM_ERROR_NONE)
+ {
+ EOM_DBG ("tdm_layer_get_capabilities fail(%d)\n", err);
+ return NULL;
+ }
+
+ if (capa & TDM_LAYER_CAPABILITY_PRIMARY)
+ {
+ EOM_DBG("TDM_LAYER_CAPABILITY_PRIMARY layer found : %d\n", i);
+ break;
+ }
+ }
+
+ memset(&set_layer_info, 0x0, sizeof(tdm_info_layer));
+ set_layer_info.src_config.size.h = width;
+ set_layer_info.src_config.size.v = height;
+ set_layer_info.src_config.pos.x = 0;
+ set_layer_info.src_config.pos.y = 0;
+ set_layer_info.src_config.pos.w = width;
+ set_layer_info.src_config.pos.h = height;
+ set_layer_info.src_config.format = TBM_FORMAT_ARGB8888;
+ set_layer_info.dst_pos.x = 0;
+ set_layer_info.dst_pos.y = 0;
+ set_layer_info.dst_pos.w = width;
+ set_layer_info.dst_pos.h = height;
+ set_layer_info.transform = TDM_TRANSFORM_NORMAL;
+
+ err = tdm_layer_set_info(layer, &set_layer_info);
+ if (err != TDM_ERROR_NONE)
+ {
+ EOM_DBG ("tdm_layer_set_info fail(%d)\n", err);
+ return NULL;
+ }
+
+ return layer;
}
static tbm_surface_h
-_e_eom_e_comp_tdm_surface_get()
+_e_eom_root_window_tdm_surface_get()
{
Evas_Engine_Info_Drm *einfo;
Ecore_Drm_Fb* fb;
- Ecore_Evas *ee;
- Evas *evas;
- EOM_DBG("1\n");
-
- if (!e_comp || !e_comp->evas /*|| e_comp->ee->evas*/)
- return NULL;
-
- EOM_DBG("2\n");
+ if (!e_comp || !e_comp->evas)
+ return NULL;
einfo = (Evas_Engine_Info_Drm *)evas_engine_info_get(e_comp->evas);
- EOM_DBG("3\n");
-
fb = _ecore_drm_display_fb_find_with_id(einfo->info.buffer_id);
if (!fb)
{
}
static void
-_ecore_drm_display_output_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUSED,
+_e_eom_output_cb_commit(tdm_output *output EINA_UNUSED, unsigned int sequence EINA_UNUSED,
unsigned int tv_sec EINA_UNUSED, unsigned int tv_usec EINA_UNUSED,
void *user_data)
{
Eom_Event *eom_event = (Eom_Event *)user_data;
tdm_error err = TDM_ERROR_NONE;
+ tbm_surface_h src_buffer;
+ tbm_surface_h dst_buffer;
+
+ EOM_ERR("Event\n");
- tbm_surface_h tdm_buffer = _e_eom_e_comp_tdm_surface_get();
- if (!tdm_buffer)
+ src_buffer = _e_eom_root_window_tdm_surface_get();
+ if (!src_buffer )
{
EOM_ERR("Event: tdm_buffer is NULL\n");
return;
}
+ dst_buffer = eom_event->dst_buffers;
+
/* Do clone */
- tdm_layer_set_buffer(eom_event->layer, tdm_buffer);
+ tdm_layer_set_buffer(eom_event->layer, dst_buffer);
err = tdm_output_commit(eom_event->output, 0, NULL, eom_event);
if (err != TDM_ERROR_NONE)
}
}
+static tbm_surface_h
+_e_eom_create_extrenal_output_buffer(int width, int height)
+{
+ tbm_surface_h buffer;
+ tbm_surface_info_s buffer_info;
+
+ /*
+ * TODO: Add support of other formats
+ */
+ buffer = tbm_surface_internal_create_with_flags(width, height,
+ TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
+ if (!buffer)
+ {
+ EOM_DBG("can not create dst_buffer\n");
+ return NULL;
+ }
+
+ /*
+ * TODO: temp code for testing, actual convert will be in _e_eom_put_src_to_dst()
+ */
+ memset(&buffer_info, 0x0, sizeof(tbm_surface_info_s));
+ if (tbm_surface_map(buffer,
+ TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE,
+ &buffer_info) != TBM_SURFACE_ERROR_NONE)
+ {
+ EOM_DBG("can not mmap buffer\n");
+ return NULL;
+ }
+
+ memset(buffer_info.planes[0].ptr, 0xff, buffer_info.planes[0].size);
+ tbm_surface_unmap(buffer);
+
+ return buffer;
+}
+
+static void
+_e_eom_put_src_to_dst( tbm_surface_h src_buffer, tbm_surface_h dst_buffer)
+{
+
+
+
+}
+
static Eina_Bool
_e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Drm_Event_Output *e;
E_EomPtr eom = data;
E_Comp_Wl_Output *wl_output;
- Ecore_Drm_Hal_Output *hal_output;
- tbm_surface_h tdm_buffer;
- tbm_surface_info_s tdm_buffer_info;
- Ecore_Drm_Fb *fb;
- Ecore_Drm_Device *dev;
- Eina_List *l, *l2;
+ tdm_output *hal_output;
+ tdm_layer *hal_layer;
+ tdm_info_layer layer_info;
+ tbm_surface_h src_buffer;
+ tbm_surface_h dst_buffer;
+ tbm_surface_info_s src_buffer_info ;
+ Eina_List *l2;
Eom_Event *eom_event = &g_eom_event;
struct wl_resource *output_resource;
enum wl_eom_type eom_type = WL_EOM_TYPE_NONE;
char buff[PATH_MAX];
- tdm_error err = TDM_ERROR_NONE;
+ tdm_error tdm_err = TDM_ERROR_NONE;
+ int tbm_err = 0;
if (!(e = event)) goto end;
}
/* Get hal output */
- hal_output = _e_eom_e_comp_hal_output_get(buff, e->id);
+ hal_output = _e_eom_hal_output_get(buff, e->id);
if (!hal_output)
{
EOM_ERR("no hal outputs, (%s)\n", buff);
goto end;
}
+ hal_layer = _e_eom_hal_layer_get(hal_output, e->w, e->h);
+ if (!hal_layer)
+ {
+ EOM_ERR("no hal layer\n");
+ goto end;
+ }
+
/* Get main frame buffer */
- tdm_buffer = _e_eom_e_comp_tdm_surface_get();
- if (!tdm_buffer )
+ src_buffer = _e_eom_root_window_tdm_surface_get();
+ if (!src_buffer )
{
EOM_ERR("no framebuffer\n");
goto end;
}
- tbm_surface_get_info(tdm_buffer, tdm_buffer_info );
+ dst_buffer = _e_eom_create_extrenal_output_buffer(e->w, e->h);
+ if (!dst_buffer )
+ {
+ EOM_ERR("no framebuffer\n");
+ goto end;
+ }
- EOM_DBG("%dx%d bpp:%d size:%d", tdm_buffer_info->width,
- tdm_buffer_info->height, tdm_buffer_info->bpp, tdm_buffer_info->size);
+ tbm_surface_get_info(src_buffer, &src_buffer_info );
- /*
- * TODO: convert primary output size to external one
- */
+ EOM_DBG("FRAMEBUFFER buffer: %dx%d bpp:%d size:%d",
+ src_buffer_info.width,
+ src_buffer_info.height,
+ src_buffer_info.bpp,
+ src_buffer_info.size);
- /* Do clone */
- tdm_layer_set_buffer(hal_output->primary_layer, tdm_buffer);
+ _e_eom_put_src_to_dst(src_buffer, dst_buffer);
- eom_event->layer = hal_output->primary_layer;
- eom_event->output = hal_output->output;
- err = tdm_output_commit(hal_output->output, 0, _ecore_drm_display_output_cb_commit, &eom_event);
- if (err != TDM_ERROR_NONE)
+ tdm_err = tdm_layer_get_info(hal_layer, &layer_info);
+ if (tdm_err != TDM_ERROR_NONE)
{
- EOM_ERR("Cannot commit crtc\n");
- return ECORE_CALLBACK_PASS_ON;
+ EOM_ERR ("failed get layer info", tdm_err);
+ goto end;
+ }
+
+ EOM_DBG("LAYER INFO: %dx%d, pos (x:%d, y:%d, w:%d, h:%d, dpos (x:%d, y:%d, w:%d, h:%d))",
+ layer_info.src_config.size.h, layer_info.src_config.size.v,
+ layer_info.src_config.pos.x, layer_info.src_config.pos.y,
+ layer_info.src_config.pos.w, layer_info.src_config.pos.h,
+ layer_info.dst_pos.x, layer_info.dst_pos.y,
+ layer_info.dst_pos.w, layer_info.dst_pos.h);
+
+ tdm_err = tdm_layer_set_buffer(hal_layer, dst_buffer);
+ if (tdm_err != TDM_ERROR_NONE)
+ {
+ EOM_ERR("Failed set buffer on layer:%d\n", tdm_err);
+ goto end;
}
+ eom_event->layer = hal_layer;
+ eom_event->output = hal_output;
+ eom_event->dst_buffers = dst_buffer;
+
+ tdm_err = tdm_output_commit(hal_output, 0, _e_eom_output_cb_commit, &eom_event);
+ if (tdm_err != TDM_ERROR_NONE)
+ {
+ EOM_ERR("Cannot commit crtc:%d\n", tdm_err);
+ goto end;
+ }
EINA_LIST_FOREACH(wl_output->resources, l2, output_resource)
{
if (e->plug)
- wl_eom_send_output_type(eom->resource,
+ {
+
+ wl_eom_send_output_type(eom->resource,
output_resource,
eom_type,
WL_EOM_STATUS_CONNECTION);
+ }
else
+ {
+ EOM_DBG("7\n");
+
wl_eom_send_output_type(eom->resource,
output_resource,
eom_type,
WL_EOM_STATUS_DISCONNECTION);
+ }
}
+ EOM_DBG("8\n");
+
end:
return ECORE_CALLBACK_PASS_ON;
}
MIN(version, 1),
id);
if (!resource)
- {
- EOM_ERR("error. resource is null. (version :%d, id:%d)\n", version, id);
- wl_client_post_no_memory(client);
- return;
- }
+ {
+ EOM_ERR("error. resource is null. (version :%d, id:%d)\n", version, id);
+ wl_client_post_no_memory(client);
+ return;
+ }
wl_resource_set_implementation(resource,
&_e_eom_wl_implementation,
E_FREE(g_eom);
}
+int
+_e_eom_init_internal()
+{
+ tdm_error err = TDM_ERROR_NONE;
+
+ EOM_DBG("1\n");
+
+ g_eom->dpy = tdm_display_init(&err);
+ if (err != TDM_ERROR_NONE)
+ {
+ EOM_DBG("failed initialize TDM\n");
+ goto err;
+ }
+
+ EOM_DBG("2\n");
+
+ err = tdm_display_get_fd(g_eom->dpy, &g_eom->fd);
+ if (err != TDM_ERROR_NONE)
+ {
+ EOM_DBG("failed get FD\n");
+ goto err;
+ }
+
+ EOM_DBG("3\n");
+
+ g_eom->bufmgr = tbm_bufmgr_init(g_eom->fd);
+ if (!g_eom->bufmgr)
+ {
+ EOM_DBG("failed initialize buffer manager\n");
+ goto err;
+ }
+
+ EOM_DBG("4\n");
+
+ return 1;
+err:
+ return 0;
+}
+
static Eina_Bool
_e_eom_init()
{
+ int ret = 0;
+
EINA_SAFETY_ON_NULL_GOTO(e_comp_wl, err);
+
g_eom = E_NEW(E_Eom, 1);
EINA_SAFETY_ON_NULL_RETURN_VAL(g_eom, EINA_FALSE);
_e_eom_wl_bind_cb);
EINA_SAFETY_ON_NULL_GOTO(g_eom->global, err);
+ ret = _e_eom_init_internal();
+ if (!ret)
+ {
+ EOM_ERR("failed init_internal()");
+ goto err;
+ }
+
E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_ACTIVATE, _e_eom_ecore_drm_activate_cb, g_eom);
E_LIST_HANDLER_APPEND(g_eom->handlers, ECORE_DRM_EVENT_OUTPUT, _e_eom_ecore_drm_output_cb, g_eom);