add reinitialization of external output layer and buffer 32/63032/3
authorRoman Peresipkyn <r.peresipkyn@samsung.com>
Mon, 21 Mar 2016 19:24:18 +0000 (21:24 +0200)
committerSooChan Lim <sc1.lim@samsung.com>
Fri, 15 Apr 2016 00:21:35 +0000 (17:21 -0700)
Change-Id: I642afed3fa954abed2dd0149127bab572c02dd19
Signed-off-by: Roman Peresipkyn <r.peresipkyn@samsung.com>
src/e_mod_main.c

index 241dd4d..7784bce 100644 (file)
@@ -20,6 +20,10 @@ struct _E_Eom
    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
@@ -32,6 +36,7 @@ typedef struct
 {
    tdm_layer *layer;
    tdm_output *output;
+   tbm_surface_h dst_buffers;
 } Eom_Event;
 
 static Eom_Event g_eom_event;
@@ -42,12 +47,11 @@ E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "EOM Module" };
 
 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)
@@ -79,18 +83,21 @@ _e_eom_e_comp_wl_output_get(Eina_List *outputs, const char *id)
    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");
@@ -108,36 +115,100 @@ _e_eom_e_comp_hal_output_get(const char *id, int primary_output_id)
        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)
      {
@@ -156,22 +227,28 @@ _e_eom_e_comp_tdm_surface_get()
 }
 
 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)
@@ -181,23 +258,68 @@ _ecore_drm_display_output_cb_commit(tdm_output *output EINA_UNUSED, unsigned int
      }
 }
 
+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;
 
@@ -217,58 +339,101 @@ _e_eom_ecore_drm_output_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *e
      }
 
    /* 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;
 }
@@ -416,11 +581,11 @@ _e_eom_wl_bind_cb(struct wl_client *client, void *data, uint32_t version, uint32
                          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,
@@ -456,11 +621,53 @@ _e_eom_deinit()
    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);
 
@@ -471,6 +678,13 @@ _e_eom_init()
                            _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);