forked from enlightenment/efl
wayland_shm: Add wl_shm to dmabuf
wl_shm and dmabuf only really need to differ in how they allocate a buffer, but right now we've got them in separate files. This dramatically reduces the complexity of the wl_shm code and shares much more implementation with the dmabuf code. This throws away at least one "optimization" wl_shm used - over-allocating buffers so that window resizing doesn't always require a new buffer allocation. If people feel that window resizing has become too slow now this can be added to the dmabuf code to the benefit of both allocators. Disabling dmabuf by env var still uses the old wl_shm implementation for now, but soon that code will be removed entirely and the env var disable will use this path.
This commit is contained in:
parent
d346ac7b2e
commit
c54a12aca6
|
@ -322,6 +322,89 @@ err:
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Buffer_Handle *
|
||||
_wl_shm_alloc(Buffer_Manager *self EINA_UNUSED, const char *name EINA_UNUSED, int w, int h, unsigned long *stride, int32_t *fd)
|
||||
{
|
||||
Efl_Vpath_File *file_obj;
|
||||
Eina_Tmpstr *fullname;
|
||||
size_t size = w * h * 4;
|
||||
void *out = NULL;
|
||||
|
||||
file_obj = efl_vpath_manager_fetch(EFL_VPATH_MANAGER_CLASS,
|
||||
"(:run:)/evas-wayland_shm-XXXXXX");
|
||||
*fd = eina_file_mkstemp(efl_vpath_file_result_get(file_obj), &fullname);
|
||||
efl_del(file_obj);
|
||||
if (*fd < 0) return NULL;
|
||||
|
||||
unlink(fullname);
|
||||
eina_tmpstr_del(fullname);
|
||||
|
||||
*stride = w * 4;
|
||||
if (ftruncate(*fd, size) < 0) goto err;
|
||||
|
||||
out = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, *fd, 0);
|
||||
if (out == MAP_FAILED) goto err;
|
||||
|
||||
return out;
|
||||
|
||||
err:
|
||||
close(*fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
_wl_shm_map(Dmabuf_Buffer *buf)
|
||||
{
|
||||
return buf->bh;
|
||||
}
|
||||
|
||||
static void
|
||||
_wl_shm_unmap(Dmabuf_Buffer *buf EINA_UNUSED)
|
||||
{
|
||||
/* wl_shm is mapped for its lifetime */
|
||||
}
|
||||
|
||||
static void
|
||||
_wl_shm_discard(Dmabuf_Buffer *buf)
|
||||
{
|
||||
munmap(buf->bh, buf->size);
|
||||
}
|
||||
|
||||
static void
|
||||
_wl_shm_manager_destroy()
|
||||
{
|
||||
/* Nop. */
|
||||
}
|
||||
|
||||
static struct wl_buffer *
|
||||
_wl_shm_to_buffer(Ecore_Wl2_Display *ewd, Dmabuf_Buffer *db)
|
||||
{
|
||||
struct wl_buffer *buf;
|
||||
struct wl_shm_pool *pool;
|
||||
struct wl_shm *shm;
|
||||
|
||||
shm = ecore_wl2_display_shm_get(ewd);
|
||||
pool = wl_shm_create_pool(shm, db->fd, db->size);
|
||||
buf = wl_shm_pool_create_buffer(pool, 0, db->w, db->h, db->stride, 0);
|
||||
wl_shm_pool_destroy(pool);
|
||||
close(db->fd);
|
||||
db->fd = -1;
|
||||
wl_buffer_add_listener(buf, &buffer_listener, db);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_wl_shm_buffer_manager_setup(int fd EINA_UNUSED)
|
||||
{
|
||||
buffer_manager->alloc = _wl_shm_alloc;
|
||||
buffer_manager->to_buffer = _wl_shm_to_buffer;
|
||||
buffer_manager->map = _wl_shm_map;
|
||||
buffer_manager->unmap = _wl_shm_unmap;
|
||||
buffer_manager->discard = _wl_shm_discard;
|
||||
buffer_manager->manager_destroy = _wl_shm_manager_destroy;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Buffer_Manager *
|
||||
_buffer_manager_get(void)
|
||||
{
|
||||
|
@ -342,6 +425,7 @@ _buffer_manager_get(void)
|
|||
|
||||
success = _intel_buffer_manager_setup(fd);
|
||||
if (!success) success = _exynos_buffer_manager_setup(fd);
|
||||
if (!success) success = _wl_shm_buffer_manager_setup(fd);
|
||||
if (!success) goto err_bm;
|
||||
|
||||
drm_fd = fd;
|
||||
|
|
Loading…
Reference in New Issue