[Evas] Add wl_buffer native_surface_type. 07/82207/2
authorWonsik, Jung <sidein@samsung.com>
Tue, 2 Aug 2016 01:19:04 +0000 (10:19 +0900)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Tue, 2 Aug 2016 01:20:46 +0000 (18:20 -0700)
wl_buffer's native surface type is added to drm/wayland_shm backend.
This patch is for selective compositor.

Change-Id: I0d891ff6c0b9a5d7f92d3071fa1af52dece9d4b0

packaging/efl.spec
src/modules/evas/engines/drm/evas_engine.c
src/modules/evas/engines/software_generic/evas_engine.c
src/modules/evas/engines/software_generic/evas_native_common.h
src/modules/evas/engines/software_generic/evas_native_tbm.c
src/modules/evas/engines/wayland_shm/evas_engine.c

index e936f11..9f5f67e 100755 (executable)
@@ -26,6 +26,7 @@ BuildRequires:  pkgconfig(wayland-egl)
 BuildRequires:  pkgconfig(text-client)
 BuildRequires:  pkgconfig(xdg-shell-client)
 BuildRequires:  pkgconfig(wayland-tbm-client)
+BuildRequires:  pkgconfig(wayland-tbm-server)
 BuildRequires:  pkgconfig(tizen-extension-client)
 Requires:       libwayland-extension-client
 %endif
index 13216c1..24282f7 100644 (file)
@@ -1,5 +1,11 @@
 #include "evas_engine.h"
 
+#include "../software_generic/evas_native_common.h"
+
+#ifdef HAVE_DLSYM
+# include <dlfcn.h>
+#endif
+
 /* local structures */
 typedef struct _Render_Engine Render_Engine;
 
@@ -8,6 +14,13 @@ struct _Render_Engine
    Render_Engine_Software_Generic generic;
 };
 
+Evas_Native_Tbm_Surface_Image_Set_Call  glsym_evas_native_tbm_surface_image_set = NULL;
+
+/* For wl_buffer's native set */
+static void *tbm_server_lib = NULL;
+typedef struct _tbm_surface * tbm_surface_h;
+static tbm_surface_h (*glsym_wayland_tbm_server_get_surface) (struct wayland_tbm_server *tbm_srv, struct wl_resource *wl_buffer) = NULL;
+
 /* function tables - filled in later (func and parent func) */
 static Evas_Func func, pfunc;
 
@@ -85,6 +98,48 @@ eng_info_free(Evas *evas EINA_UNUSED, void *einfo)
      free(info);
 }
 
+static void
+_symbols(void)
+{
+   static int done = 0;
+   int fail = 0;
+   const char *wayland_tbm_server_lib = "libwayland-tbm-server.so.0";
+
+   if (done) return;
+
+#define LINK2GENERIC(sym)                   \
+   glsym_##sym = dlsym(RTLD_DEFAULT, #sym); \
+   if (!(glsym_##sym))                      \
+     {                                      \
+       ERR("%s", dlerror());                \
+       fail = 1;                            \
+     }
+
+   // Get function pointer to native_common that is now provided through the link of SW_Generic.
+   LINK2GENERIC(evas_native_tbm_surface_image_set);
+   if (fail == 1)
+     {
+       ERR("fail to dlsym about evas_native_tbm_surface_image_set symbol");
+       return;
+     }
+   tbm_server_lib = dlopen(wayland_tbm_server_lib, RTLD_LOCAL | RTLD_LAZY);
+   if (tbm_server_lib)
+     {
+        LINK2GENERIC(wayland_tbm_server_get_surface);
+        if (fail == 1)
+          {
+             ERR("fail to dlsym about wayland_tbm_server_get_surface symbol");
+             dlclose(tbm_server_lib);
+             tbm_server_lib = NULL;
+             return;
+          }
+     }
+   else
+     return;
+
+   done = 1;
+}
+
 static int
 eng_setup(Evas *evas, void *einfo)
 {
@@ -148,6 +203,12 @@ eng_output_free(void *data)
         free(re);
      }
 
+   if (tbm_server_lib)
+     {
+       dlclose(tbm_server_lib);
+       tbm_server_lib = NULL;
+     }
+
    evas_common_shutdown();
 }
 
@@ -165,6 +226,108 @@ eng_output_copy(void *data, void *buffer, int stride, int width, int height, uin
    evas_outbuf_copy(ob, buffer, stride, width, height, format, sx, sy, sw, sh, dx, dy, dw, dh);
 }
 
+static void *
+eng_image_native_set(void *data EINA_UNUSED, void *image, void *native)
+{
+   Evas_Native_Surface *ns = native;
+   Image_Entry *ie = image;
+   RGBA_Image *im = image, *im2;
+   void *wl_buf = NULL;
+
+   if (!im || !ns) return im;
+
+   if (ns)
+     {
+        if (ns->type == EVAS_NATIVE_SURFACE_TBM)
+          {
+             if (im->native.data)
+               {
+                  //image have native surface already
+                  Evas_Native_Surface *ens = im->native.data;
+
+                  if ((ens->type == ns->type) &&
+                      (ens->data.tbm.buffer == ns->data.tbm.buffer))
+                    return im;
+               }
+          }
+        else if (ns->type == EVAS_NATIVE_SURFACE_WL)
+          {
+             wl_buf = ns->data.wl.legacy_buffer;
+             if (im->native.data)
+               {
+                  Evas_Native_Surface *ens;
+
+                  ens = im->native.data;
+                  if (ens->data.wl.legacy_buffer == wl_buf)
+                    return im;
+               }
+          }
+     }
+
+   if ((ns->type == EVAS_NATIVE_SURFACE_OPENGL) &&
+       (ns->version == EVAS_NATIVE_SURFACE_VERSION))
+     im2 = evas_cache_image_data(evas_common_image_cache_get(),
+                                 ie->w, ie->h,
+                                 ns->data.x11.visual, 1,
+                                 EVAS_COLORSPACE_ARGB8888);
+   else
+     im2 = evas_cache_image_data(evas_common_image_cache_get(),
+                                 ie->w, ie->h,
+                                 NULL, 1,
+                                 EVAS_COLORSPACE_ARGB8888);
+
+   if (im->native.data)
+      {
+         if (im->native.func.free)
+            im->native.func.free(im->native.func.data, im);
+      }
+
+#ifdef EVAS_CSERVE2
+   if (evas_cserve2_use_get() && evas_cache2_image_cached(ie))
+     evas_cache2_image_close(ie);
+   else
+#endif
+   evas_cache_image_drop(ie);
+   im = im2;
+
+   if (ns->type == EVAS_NATIVE_SURFACE_TBM)
+     {
+        if (glsym_evas_native_tbm_surface_image_set)
+          return glsym_evas_native_tbm_surface_image_set(NULL, im, ns);
+        else
+          return NULL;
+     }
+   else if (ns->type == EVAS_NATIVE_SURFACE_WL)
+     {
+       // TODO  : need the code for all wl_buffer type
+       // For TBM surface
+       if (glsym_wayland_tbm_server_get_surface && glsym_evas_native_tbm_surface_image_set)
+         {
+            tbm_surface_h _tbm_surface;
+
+            _tbm_surface = glsym_wayland_tbm_server_get_surface(NULL,ns->data.wl.legacy_buffer);
+            return glsym_evas_native_tbm_surface_image_set(_tbm_surface, im, ns);
+         }
+       else
+         {
+            return NULL;
+         }
+     }
+
+   return im;
+}
+
+static void *
+eng_image_native_get(void *data EINA_UNUSED, void *image)
+{
+   RGBA_Image *im = image;
+   Native *n;
+   if (!im) return NULL;
+   n = im->native.data;
+   if (!n) return NULL;
+   return &(n->ns);
+}
+
 /* module api functions */
 static int
 module_open(Evas_Module *em)
@@ -195,6 +358,10 @@ module_open(Evas_Module *em)
    EVAS_API_OVERRIDE(setup, &func, eng_);
    EVAS_API_OVERRIDE(output_free, &func, eng_);
    EVAS_API_OVERRIDE(output_copy, &func, eng_);
+   EVAS_API_OVERRIDE(image_native_set, &func, eng_);
+   EVAS_API_OVERRIDE(image_native_get, &func, eng_);
+
+   _symbols();
 
    /* advertise our engine functions */
    em->functions = (void *)(&func);
index 3857dd1..2775997 100644 (file)
@@ -1921,7 +1921,7 @@ eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image
    if (!image) return EINA_FALSE;
    im = image;
    if (im->native.func.bind)
-      im->native.func.bind(data, image, src_x, src_y, src_w, src_h);
+     im->native.func.bind(data, image, src_x, src_y, src_w, src_h);
 
    if (do_async)
      {
@@ -1953,7 +1953,7 @@ eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image
                                                         _image_thr_cb_sample,
                                                         _image_thr_cb_smooth);
         if (im->native.func.unbind)
-           im->native.func.unbind(data, image);
+          im->native.func.unbind(data, image);
         return ret;
      }
 #ifdef BUILD_PIPE_RENDER
index 0ff0b74..24db735 100644 (file)
@@ -52,6 +52,7 @@ struct _Native
       {
          void                     *wl_buf; /* struct wl_buffer */
          void                     *surface; /*egl surface*/
+         void                     *tbm_surface; /*tbm surface for wl_buffer*/
       } wl_surface; /**< Set this struct fields if surface data is Wayland based. */
 
       /* EVAS_NATIVE_SURFACE_OPENGL */
index b6931a9..4c47824 100644 (file)
 #define __tbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
                              ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
 
-#define TBM_FORMAT_ARGB8888 __tbm_fourcc_code('A', 'R', '2', '4')
-#define TBM_FORMAT_ABGR8888 __tbm_fourcc_code('A', 'B', '2', '4')
-#define TBM_FORMAT_RGBX8888    __tbm_fourcc_code('R', 'X', '2', '4') /* [31:0] R:G:B:x 8:8:8:8 little endian */
-#define TBM_FORMAT_RGBA8888    __tbm_fourcc_code('R', 'A', '2', '4') /* [31:0] R:G:B:A 8:8:8:8 little endian */
-#define TBM_FORMAT_BGRA8888    __tbm_fourcc_code('B', 'A', '2', '4') /* [31:0] B:G:R:A 8:8:8:8 little endian */
-#define TBM_FORMAT_NV12                __tbm_fourcc_code('N', 'V', '1', '2') /* 2x2 subsampled Cr:Cb plane */
-#define TBM_FORMAT_YUV420      __tbm_fourcc_code('Y', 'U', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */
-#define TBM_FORMAT_YVU420      __tbm_fourcc_code('Y', 'V', '1', '2') /* 2x2 subsampled Cr (1) and Cb (2) planes */
+#define TBM_FORMAT_ARGB8888  __tbm_fourcc_code('A', 'R', '2', '4')
+#define TBM_FORMAT_ABGR8888  __tbm_fourcc_code('A', 'B', '2', '4')
+#define TBM_FORMAT_RGBX8888  __tbm_fourcc_code('R', 'X', '2', '4') /* [31:0] R:G:B:x 8:8:8:8 little endian */
+#define TBM_FORMAT_RGBA8888  __tbm_fourcc_code('R', 'A', '2', '4') /* [31:0] R:G:B:A 8:8:8:8 little endian */
+#define TBM_FORMAT_BGRA8888  __tbm_fourcc_code('B', 'A', '2', '4') /* [31:0] B:G:R:A 8:8:8:8 little endian */
+#define TBM_FORMAT_XRGB8888  __tbm_fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */
+#define TBM_FORMAT_NV12      __tbm_fourcc_code('N', 'V', '1', '2') /* 2x2 subsampled Cr:Cb plane */
+#define TBM_FORMAT_YUV420    __tbm_fourcc_code('Y', 'U', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */
+#define TBM_FORMAT_YVU420    __tbm_fourcc_code('Y', 'V', '1', '2') /* 2x2 subsampled Cr (1) and Cb (2) planes */
 
 static void *tbm_lib = NULL;
 static int   tbm_ref = 0;
@@ -82,6 +83,7 @@ tbm_init(void)
       "libtbm.so.0",
       NULL,
    };
+
    int i, fail;
 #define SYM(lib, xx)                            \
   do {                                          \
@@ -213,12 +215,19 @@ _native_bind_cb(void *data EINA_UNUSED, void *image, int x EINA_UNUSED, int y EI
    tbm_surface_h tbm_surf;
 
    if (!im || !n) return;
-   if (n->ns.type != EVAS_NATIVE_SURFACE_TBM)
+
+   if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
+     tbm_surf = n->ns.data.tbm.buffer;
+   else if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
+     tbm_surf = n->ns_data.wl_surface.tbm_surface;
+   else
      return;
 
-   tbm_surf = n->ns.data.tbm.buffer;
    if (sym_tbm_surface_map(tbm_surf, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info))
-     return;
+     {
+        ERR("Fail to tbm_surface_map()");
+        return;
+     }
 
    im->image.data = (DATA32 *)info.planes[0].ptr;
 }
@@ -231,11 +240,19 @@ _native_unbind_cb(void *data EINA_UNUSED, void *image)
    tbm_surface_h tbm_surf;
 
    if (!im || !n) return;
-   if (n->ns.type != EVAS_NATIVE_SURFACE_TBM)
-     return;
 
-   tbm_surf = n->ns.data.tbm.buffer;
-   sym_tbm_surface_unmap(tbm_surf);
+   if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
+     tbm_surf = n->ns.data.tbm.buffer;
+   else if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
+     tbm_surf = n->ns_data.wl_surface.tbm_surface;
+   else
+      return;
+
+   if (sym_tbm_surface_unmap(tbm_surf))
+     {
+        ERR("Fail to tbm_surface_unmap()");
+        return;
+     }
 }
 
 static void
@@ -258,7 +275,7 @@ _native_free_cb(void *data EINA_UNUSED, void *image)
 }
 
 EAPI void *
-evas_native_tbm_surface_image_set(void *data EINA_UNUSED, void *image, void *native)
+evas_native_tbm_surface_image_set(void *data, void *image, void *native)
 {
    Evas_Native_Surface *ns = native;
    RGBA_Image *im = image;
@@ -274,10 +291,14 @@ evas_native_tbm_surface_image_set(void *data EINA_UNUSED, void *image, void *nat
         tbm_surface_info_s info;
         Native *n;
 
-        if (ns->type != EVAS_NATIVE_SURFACE_TBM)
-          return NULL;
+        if (ns->type == EVAS_NATIVE_SURFACE_TBM)
+          tbm_surf = ns->data.tbm.buffer;
+        else if (ns->type == EVAS_NATIVE_SURFACE_WL)
+          tbm_surf = (tbm_surface_h)data;
+        else
+          tbm_surf = NULL;
 
-        tbm_surf = ns->data.tbm.buffer;
+        if (!tbm_surf) return NULL;
 
         if (!tbm_init())
           {
@@ -290,6 +311,7 @@ evas_native_tbm_surface_image_set(void *data EINA_UNUSED, void *image, void *nat
 
         if (sym_tbm_surface_map(tbm_surf, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info))
           {
+             ERR("Fail to tbm_surface_map()");
              free(n);
              return im;
           }
@@ -310,9 +332,15 @@ evas_native_tbm_surface_image_set(void *data EINA_UNUSED, void *image, void *nat
            case TBM_FORMAT_BGRA8888:
            case TBM_FORMAT_ARGB8888:
            case TBM_FORMAT_ABGR8888:
+           case TBM_FORMAT_XRGB8888:
               im->cache_entry.w = stride / 4;
               evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_ARGB8888);
-              im->cache_entry.flags.alpha = (format == TBM_FORMAT_RGBX8888 ? 0 : 1);
+
+              if (format == TBM_FORMAT_RGBX8888 || format == TBM_FORMAT_XRGB8888)
+                im->cache_entry.flags.alpha = 0;
+              else
+                im->cache_entry.flags.alpha = 1;
+
               im->image.data = pixels_data;
               im->image.no_free = 1;
               break;
@@ -334,18 +362,26 @@ evas_native_tbm_surface_image_set(void *data EINA_UNUSED, void *image, void *nat
               break;
               /* Not planning to handle those in software */
            default:
+              ERR("not supported format");
               sym_tbm_surface_unmap(ns->data.tbm.buffer);
               free(n);
               return im;
           }
 
         memcpy(n, ns, sizeof(Evas_Native_Surface));
+        if (ns->type == EVAS_NATIVE_SURFACE_WL)
+          n->ns_data.wl_surface.tbm_surface = tbm_surf;
         im->native.data = n;
         im->native.func.bind   = _native_bind_cb;
         im->native.func.unbind = _native_unbind_cb;
         im->native.func.free   = _native_free_cb;
 
-        sym_tbm_surface_unmap(tbm_surf);
+        if (sym_tbm_surface_unmap(tbm_surf))
+          {
+             ERR("Fail to tbm_surface_unmap()");
+             free(n);
+             return im;
+          }
      }
    return im;
 }
index 38f11e5..256d901 100755 (executable)
@@ -19,6 +19,11 @@ static Evas_Func func, pfunc;
 
 Evas_Native_Tbm_Surface_Image_Set_Call  glsym_evas_native_tbm_surface_image_set = NULL;
 
+/* For wl_buffer's native set */
+static void *tbm_server_lib = NULL;
+typedef struct _tbm_surface * tbm_surface_h;
+static tbm_surface_h (*glsym_wayland_tbm_server_get_surface) (struct wayland_tbm_server *tbm_srv, struct wl_resource *wl_buffer) = NULL;
+
 /* engine structure data */
 typedef struct _Render_Engine Render_Engine;
 struct _Render_Engine
@@ -87,14 +92,40 @@ static void
 _symbols(void)
 {
    static int done = 0;
+   int fail = 0;
+   const char *wayland_tbm_server_lib = "libwayland-tbm-server.so.0";
 
    if (done) return;
 
-#define LINK2GENERIC(sym) \
-   glsym_##sym = dlsym(RTLD_DEFAULT, #sym);
+#define LINK2GENERIC(sym)                     \
+   glsym_##sym = dlsym(RTLD_DEFAULT, #sym);   \
+   if (!(glsym_##sym))                        \
+     {                                        \
+        ERR("%s", dlerror());                 \
+        fail = 1;                             \
+     }
 
    // Get function pointer to native_common that is now provided through the link of SW_Generic.
    LINK2GENERIC(evas_native_tbm_surface_image_set);
+   if (fail == 1)
+     {
+        ERR("fail to dlsym about evas_native_tbm_surface_image_set symbol");
+        return;
+     }
+   tbm_server_lib = dlopen(wayland_tbm_server_lib, RTLD_LOCAL | RTLD_LAZY);
+   if (tbm_server_lib)
+     {
+        LINK2GENERIC(wayland_tbm_server_get_surface);
+        if (fail == 1)
+          {
+             ERR("fail to dlsym about wayland_tbm_server_get_surface symbol");
+             dlclose(tbm_server_lib);
+             tbm_server_lib = NULL;
+             return;
+          }
+     }
+   else
+     return;
 
    done = 1;
 }
@@ -207,6 +238,12 @@ eng_output_free(void *data)
         free(re);
      }
 
+   if (tbm_server_lib)
+     {
+       dlclose(tbm_server_lib);
+       tbm_server_lib = NULL;
+     }
+
    evas_common_shutdown();
 }
 
@@ -259,33 +296,49 @@ eng_image_native_set(void *data EINA_UNUSED, void *image, void *native)
    Evas_Native_Surface *ns = native;
    Image_Entry *ie = image;
    RGBA_Image *im = image, *im2;
+   void *wl_buf = NULL;
 
    if (!im || !ns) return im;
 
-   if (ns->type == EVAS_NATIVE_SURFACE_TBM)
+   if (ns)
      {
-        if (im->native.data)
+        if (ns->type == EVAS_NATIVE_SURFACE_TBM)
           {
-             //image have native surface already
-             Evas_Native_Surface *ens = im->native.data;
-
-             if ((ens->type == ns->type) &&
-                 (ens->data.tbm.buffer == ns->data.tbm.buffer))
-                return im;
+             if (im->native.data)
+               {
+                  //image have native surface already
+                  Evas_Native_Surface *ens = im->native.data;
+
+                  if ((ens->type == ns->type) &&
+                      (ens->data.tbm.buffer == ns->data.tbm.buffer))
+                     return im;
+               }
           }
-      }
-
-   if ((ns->type == EVAS_NATIVE_SURFACE_OPENGL) &&
-       (ns->version == EVAS_NATIVE_SURFACE_VERSION))
-     im2 = evas_cache_image_data(evas_common_image_cache_get(),
-                                 ie->w, ie->h,
-                                 ns->data.x11.visual, 1,
-                                 EVAS_COLORSPACE_ARGB8888);
-   else
-     im2 = evas_cache_image_data(evas_common_image_cache_get(),
-                                 ie->w, ie->h,
-                                 NULL, 1,
-                                 EVAS_COLORSPACE_ARGB8888);
+        else if (ns->type == EVAS_NATIVE_SURFACE_WL)
+          {
+             wl_buf = ns->data.wl.legacy_buffer;
+             if (im->native.data)
+               {
+                  Evas_Native_Surface *ens;
+
+                  ens = im->native.data;
+                  if (ens->data.wl.legacy_buffer == wl_buf)
+                    return im;
+               }
+           }
+
+        if ((ns->type == EVAS_NATIVE_SURFACE_OPENGL) &&
+            (ns->version == EVAS_NATIVE_SURFACE_VERSION))
+          im2 = evas_cache_image_data(evas_common_image_cache_get(),
+                                      ie->w, ie->h,
+                                      ns->data.x11.visual, 1,
+                                      EVAS_COLORSPACE_ARGB8888);
+        else
+          im2 = evas_cache_image_data(evas_common_image_cache_get(),
+                                      ie->w, ie->h,
+                                      NULL, 1,
+                                      EVAS_COLORSPACE_ARGB8888);
+     }
 
    if (im->native.data)
       {
@@ -302,7 +355,28 @@ eng_image_native_set(void *data EINA_UNUSED, void *image, void *native)
    im = im2;
 
    if (ns->type == EVAS_NATIVE_SURFACE_TBM)
-      return glsym_evas_native_tbm_surface_image_set(NULL, im, ns);
+     {
+        if (glsym_evas_native_tbm_surface_image_set)
+          return glsym_evas_native_tbm_surface_image_set(NULL, im, ns);
+        else
+          return NULL;
+     }
+   else if (ns->type == EVAS_NATIVE_SURFACE_WL)
+     {
+       // TODO  : need the code for all wl_buffer type
+       // First of all, for TBM surface
+       if (glsym_wayland_tbm_server_get_surface && glsym_evas_native_tbm_surface_image_set)
+         {
+            tbm_surface_h _tbm_surface;
+
+            _tbm_surface = glsym_wayland_tbm_server_get_surface(NULL,ns->data.wl.legacy_buffer);
+            return glsym_evas_native_tbm_surface_image_set(_tbm_surface, im, ns);
+         }
+       else
+         {
+            return NULL;
+         }
+     }
 
    return im;
 }