derekf pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=d485e1f161c297bbc77a1cff63ccd993d0bc4765
commit d485e1f161c297bbc77a1cff63ccd993d0bc4765 Author: Derek Foreman <der...@osg.samsung.com> Date: Wed May 18 10:27:32 2016 -0500 software_generic: Add wayland dmabuf native surface support --- src/Makefile_Evas.am | 2 + .../evas/engines/software_generic/evas_engine.c | 2 + .../engines/software_generic/evas_native_common.h | 2 + .../engines/software_generic/evas_native_dmabuf.c | 137 +++++++++++++++++++++ 4 files changed, 143 insertions(+) diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index d3efc57..10df07e 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -627,6 +627,7 @@ lib_evas_libevas_la_SOURCES += \ modules/evas/engines/software_generic/evas_engine.c \ modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h \ modules/evas/engines/software_generic/evas_native_tbm.c \ +modules/evas/engines/software_generic/evas_native_dmabuf.c \ modules/evas/engines/software_generic/evas_ector_software_buffer.c \ modules/evas/engines/software_generic/evas_native_common.h lib_evas_libevas_la_LIBADD += @@ -644,6 +645,7 @@ modules_evas_engines_software_generic_module_la_SOURCES = \ modules/evas/engines/software_generic/evas_engine.c \ modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h \ modules/evas/engines/software_generic/evas_native_tbm.c \ +modules/evas/engines/software_generic/evas_native_dmabuf.c \ modules/evas/engines/software_generic/evas_ector_software_buffer.c \ modules/evas/engines/software_generic/evas_native_common.h modules_evas_engines_software_generic_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 322ef8d..40c084a 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -1151,6 +1151,8 @@ eng_image_native_set(void *data EINA_UNUSED, void *image, void *native) #endif evas_cache_image_drop(ie); + if (ns->type == EVAS_NATIVE_SURFACE_WL_DMABUF) + return _evas_native_dmabuf_surface_image_set(ie2, ns); return ie2; } diff --git a/src/modules/evas/engines/software_generic/evas_native_common.h b/src/modules/evas/engines/software_generic/evas_native_common.h index 3b51b1a..7bcc5ea 100644 --- a/src/modules/evas/engines/software_generic/evas_native_common.h +++ b/src/modules/evas/engines/software_generic/evas_native_common.h @@ -110,6 +110,8 @@ EAPI void *_evas_native_tbm_surface_image_set(void *data, void *image, void *nat EAPI int _evas_native_tbm_init(void); EAPI void _evas_native_tbm_shutdown(void); +void *_evas_native_dmabuf_surface_image_set(void *image, void *native); + typedef void *(*Evas_Native_Tbm_Surface_Image_Set_Call)(void *data, void *image, void *native); #endif //_EVAS_NATIVE_COMMON_H diff --git a/src/modules/evas/engines/software_generic/evas_native_dmabuf.c b/src/modules/evas/engines/software_generic/evas_native_dmabuf.c new file mode 100644 index 0000000..e19db5b --- /dev/null +++ b/src/modules/evas/engines/software_generic/evas_native_dmabuf.c @@ -0,0 +1,137 @@ +#include "evas_common_private.h" +#include "evas_private.h" +#include "evas_native_common.h" + +#if defined HAVE_DLSYM && ! defined _WIN32 +# include <dlfcn.h> /* dlopen,dlclose,etc */ +#else +# warning native_dmabuf should not get compiled if dlsym is not found on the system! +#endif + +#include <sys/mman.h> + +#define DRM_FORMAT_ARGB8888 0x34325241 +#define DRM_FORMAT_XRGB8888 0x34325258 + +static void +_native_bind_cb(void *image, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) +{ + struct dmabuf_attributes *a; + int size; + RGBA_Image *im = image; + Native *n = im->native.data; + + if (!im || !n) return; + if (n->ns.type != EVAS_NATIVE_SURFACE_WL_DMABUF) + return; + + if (im->image.data) return; + + a = (struct dmabuf_attributes *)&n->ns_data.wl_surface_dmabuf; + if (n->ns_data.wl_surface_dmabuf.ptr) + { + im->image.data = n->ns_data.wl_surface_dmabuf.ptr; + return; + } + size = a->height * a->stride[0]; + im->image.data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, a->fd[0], 0); + if (im->image.data == MAP_FAILED) im->image.data = NULL; + n->ns_data.wl_surface_dmabuf.size = size; + n->ns_data.wl_surface_dmabuf.ptr = im->image.data; +} + +static void +_native_unbind_cb(void *image) +{ + RGBA_Image *im = image; + Native *n = im->native.data; + + if (!im || !n) return; + if (n->ns.type != EVAS_NATIVE_SURFACE_WL_DMABUF) + return; +} + +static void +_native_free_cb(void *image) +{ + RGBA_Image *im = image; + Native *n = im->native.data; + + if (!im) return; + + if (im->image.data) + munmap(n->ns_data.wl_surface_dmabuf.ptr, + n->ns_data.wl_surface_dmabuf.size); + + im->native.data = NULL; + im->native.func.bind = NULL; + im->native.func.unbind = NULL; + im->native.func.free = NULL; + im->image.data = NULL; + + free(n); +} + +void * +_evas_native_dmabuf_surface_image_set(void *image, void *native) +{ + Evas_Native_Surface *ns = native; + RGBA_Image *im = image; + + if (!im) return NULL; + if (ns) + { + struct dmabuf_attributes *a; + int h, stride; + int32_t format; + Native *n; + + if (ns->type != EVAS_NATIVE_SURFACE_WL_DMABUF) + return NULL; + + n = im->native.data; + if (n) + { + if (n->ns_data.wl_surface_dmabuf.ptr) + { + munmap(n->ns_data.wl_surface_dmabuf.ptr, + n->ns_data.wl_surface_dmabuf.size); + n->ns_data.wl_surface_dmabuf.size = 0; + n->ns_data.wl_surface_dmabuf.ptr = NULL; + } + free(im->native.data); + } + n = calloc(1, sizeof(Native)); + if (!n) return NULL; + + a = ns->data.wl_dmabuf.attr; + if (a->version != 1) + { + free(n); + return NULL; + } + + h = a->height; + stride = a->stride[0]; + format = a->format; + im->cache_entry.w = stride; + im->cache_entry.h = h; + + /* This block assumes single planar formats, which are all we + * currently support. */ + im->cache_entry.w = stride / 4; + evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_ARGB8888); + im->cache_entry.flags.alpha = (format == DRM_FORMAT_XRGB8888 ? 0 : 1); + im->image.data = NULL;; + im->image.no_free = 1; + + memcpy(n, ns, sizeof(Evas_Native_Surface)); + memcpy(&n->ns_data.wl_surface_dmabuf.attr, a, sizeof(*a)); + 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; + } + + return im; +} --