wl_buffer's native surface type is added to drm/wayland_shm backend.
This patch is for selective compositor.
Change-Id: I0d891ff6c0b9a5d7f92d3071fa1af52dece9d4b0
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
#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;
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;
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)
{
free(re);
}
+ if (tbm_server_lib)
+ {
+ dlclose(tbm_server_lib);
+ tbm_server_lib = NULL;
+ }
+
evas_common_shutdown();
}
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)
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);
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)
{
_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
{
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 */
#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;
"libtbm.so.0",
NULL,
};
+
int i, fail;
#define SYM(lib, xx) \
do { \
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;
}
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
}
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;
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())
{
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;
}
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;
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;
}
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
_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;
}
free(re);
}
+ if (tbm_server_lib)
+ {
+ dlclose(tbm_server_lib);
+ tbm_server_lib = NULL;
+ }
+
evas_common_shutdown();
}
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)
{
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;
}