forked from enlightenment/efl
167 lines
4.5 KiB
C
167 lines
4.5 KiB
C
#include "evas_common_private.h"
|
|
#include "evas_private.h"
|
|
#include "evas_native_common.h"
|
|
|
|
#if defined HAVE_DLSYM
|
|
# include <dlfcn.h> /* dlopen,dlclose,etc */
|
|
#elif _WIN32
|
|
# include <evil_private.h> /* dlopen dlclose dlsym mmap */
|
|
#else
|
|
# warning native_dmabuf should not get compiled if dlsym is not found on the system!
|
|
#endif
|
|
|
|
#ifndef _WIN32
|
|
# include <sys/mman.h>
|
|
#endif
|
|
|
|
#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;
|
|
|
|
if (!im) return;
|
|
Native *n = im->native.data;
|
|
if (!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, 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;
|
|
|
|
if (!im) return;
|
|
Native *n = im->native.data;
|
|
if (!n) return;
|
|
if (n->ns.type != EVAS_NATIVE_SURFACE_WL_DMABUF)
|
|
return;
|
|
}
|
|
|
|
static void
|
|
_native_free_cb(void *image)
|
|
{
|
|
RGBA_Image *im = image;
|
|
|
|
if (!im) return;
|
|
Native *n = im->native.data;
|
|
|
|
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)
|
|
{
|
|
if (ns && ns->type == EVAS_NATIVE_SURFACE_WL_DMABUF &&
|
|
!ns->data.wl_dmabuf.resource)
|
|
{
|
|
struct dmabuf_attributes *attr;
|
|
|
|
attr = ns->data.wl_dmabuf.attr;
|
|
if (attr->version != EVAS_DMABUF_ATTRIBUTE_VERSION)
|
|
return NULL;
|
|
if (attr->n_planes != 1)
|
|
return NULL;
|
|
if (attr->format != DRM_FORMAT_ARGB8888 &&
|
|
attr->format != DRM_FORMAT_XRGB8888)
|
|
return NULL;
|
|
|
|
return evas_cache_image_data(evas_common_image_cache_get(),
|
|
attr->width, attr->height,
|
|
NULL, 1,
|
|
EVAS_COLORSPACE_ARGB8888);
|
|
}
|
|
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 != EVAS_DMABUF_ATTRIBUTE_VERSION)
|
|
{
|
|
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;
|
|
}
|