software_generic: Add wayland dmabuf native surface support
authorDerek Foreman <derekf@osg.samsung.com>
Wed, 18 May 2016 15:27:32 +0000 (10:27 -0500)
committerDerek Foreman <derekf@osg.samsung.com>
Wed, 18 May 2016 16:52:24 +0000 (11:52 -0500)
src/Makefile_Evas.am
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_dmabuf.c [new file with mode: 0644]

index d3efc57..10df07e 100644 (file)
@@ -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 \
index 322ef8d..40c084a 100644 (file)
@@ -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;
 }
index 3b51b1a..7bcc5ea 100644 (file)
@@ -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 (file)
index 0000000..e19db5b
--- /dev/null
@@ -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;
+}