2015-03-17 12:49:09 -07:00
|
|
|
#include "evas_common_private.h"
|
|
|
|
#include "evas_private.h"
|
|
|
|
#include "evas_engine.h"
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
2015-03-19 13:15:11 -07:00
|
|
|
static Eina_Bool _shm_leaf_create(Shm_Surface *surface, Shm_Leaf *leaf, int w, int h);
|
|
|
|
static void _shm_leaf_release(Shm_Leaf *leaf);
|
2015-03-17 12:49:09 -07:00
|
|
|
|
|
|
|
static struct wl_shm_pool *
|
|
|
|
_shm_pool_make(struct wl_shm *shm, int size, void **data)
|
|
|
|
{
|
|
|
|
struct wl_shm_pool *pool;
|
|
|
|
static const char tmp[] = "/evas-wayland_shm-XXXXXX";
|
|
|
|
const char *path;
|
|
|
|
char *name;
|
|
|
|
int fd = 0;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
/* check for valid wl_shm */
|
|
|
|
if (!shm) return NULL;
|
|
|
|
|
|
|
|
/* create tmp file name */
|
|
|
|
if ((path = getenv("XDG_RUNTIME_DIR")))
|
|
|
|
{
|
|
|
|
if ((name = malloc(strlen(path) + sizeof(tmp))))
|
|
|
|
strcpy(name, path);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((name = malloc(strlen("/tmp") + sizeof(tmp))))
|
|
|
|
strcpy(name, "/tmp");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!name) return NULL;
|
|
|
|
|
|
|
|
strcat(name, tmp);
|
|
|
|
|
|
|
|
/* try to create tmp file */
|
|
|
|
if ((fd = mkstemp(name)) < 0)
|
|
|
|
{
|
|
|
|
ERR("Could not create temporary file: %m");
|
|
|
|
free(name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
unlink(name);
|
|
|
|
free(name);
|
|
|
|
|
|
|
|
/* try to truncate file to size */
|
|
|
|
if (ftruncate(fd, size) < 0)
|
|
|
|
{
|
|
|
|
ERR("Could not truncate temporary file: %m");
|
|
|
|
goto fd_err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* try to mmap the file */
|
|
|
|
*data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0);
|
|
|
|
if (*data == MAP_FAILED)
|
|
|
|
{
|
|
|
|
ERR("Could not mmap temporary file: %m");
|
|
|
|
goto fd_err;
|
|
|
|
}
|
|
|
|
|
2015-07-27 12:53:02 -07:00
|
|
|
/* NB: Commented out. Used for debugging rendering issues */
|
|
|
|
/* memset(*data, 127, size); */
|
|
|
|
|
2015-03-17 12:49:09 -07:00
|
|
|
/* create wl_shm_pool using fd */
|
|
|
|
pool = wl_shm_create_pool(shm, fd, size);
|
|
|
|
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
return pool;
|
|
|
|
|
|
|
|
fd_err:
|
|
|
|
close(fd);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Shm_Pool *
|
|
|
|
_shm_pool_create(struct wl_shm *shm, size_t size)
|
|
|
|
{
|
|
|
|
Shm_Pool *pool;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (!(pool = malloc(sizeof(Shm_Pool)))) return NULL;
|
|
|
|
|
|
|
|
pool->pool = _shm_pool_make(shm, size, &pool->data);
|
|
|
|
if (!pool->pool) goto err;
|
|
|
|
|
|
|
|
pool->size = size;
|
|
|
|
pool->used = 0;
|
|
|
|
|
|
|
|
return pool;
|
|
|
|
|
|
|
|
err:
|
|
|
|
free(pool);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_shm_pool_destroy(Shm_Pool *pool)
|
|
|
|
{
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
munmap(pool->data, pool->size);
|
|
|
|
wl_shm_pool_destroy(pool->pool);
|
|
|
|
free(pool);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
_shm_pool_allocate(Shm_Pool *pool, size_t size, int *offset)
|
|
|
|
{
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if ((pool->used + size) > pool->size)
|
2015-03-19 13:15:11 -07:00
|
|
|
{
|
|
|
|
WRN("Shm Pool Too Small");
|
|
|
|
return NULL;
|
|
|
|
}
|
2015-03-17 12:49:09 -07:00
|
|
|
|
|
|
|
*offset = pool->used;
|
|
|
|
pool->used += size;
|
|
|
|
|
|
|
|
return (char *)pool->data + *offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_shm_pool_reset(Shm_Pool *pool)
|
|
|
|
{
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
pool->used = 0;
|
|
|
|
}
|
|
|
|
|
2015-03-19 13:15:11 -07:00
|
|
|
static void
|
|
|
|
_shm_frame_release(void *data, struct wl_callback *callback, uint32_t timestamp EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Shm_Surface *surf;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (!(surf = data)) return;
|
|
|
|
if (callback != surf->frame_cb) return;
|
|
|
|
|
|
|
|
wl_callback_destroy(surf->frame_cb);
|
|
|
|
surf->frame_cb = NULL;
|
|
|
|
surf->redraw = EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_callback_listener _shm_frame_listener =
|
|
|
|
{
|
|
|
|
_shm_frame_release
|
|
|
|
};
|
|
|
|
|
2015-03-17 12:49:09 -07:00
|
|
|
static Shm_Data *
|
|
|
|
_shm_data_create_from_pool(Shm_Pool *pool, int w, int h, Eina_Bool alpha)
|
|
|
|
{
|
|
|
|
Shm_Data *data;
|
|
|
|
int len, offset;
|
|
|
|
uint32_t wl_format = WL_SHM_FORMAT_XRGB8888;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
/* try to malloc space for data */
|
|
|
|
if (!(data = malloc(sizeof(Shm_Data))))
|
|
|
|
{
|
|
|
|
ERR("Could not allocate space for data");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = (w * sizeof(int)) * h;
|
|
|
|
data->pool = NULL;
|
|
|
|
|
|
|
|
if (!(data->map = _shm_pool_allocate(pool, len, &offset)))
|
|
|
|
{
|
|
|
|
ERR("Could not map leaf data");
|
2015-03-19 13:15:11 -07:00
|
|
|
goto err;
|
2015-03-17 12:49:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (alpha)
|
|
|
|
wl_format = WL_SHM_FORMAT_ARGB8888;
|
|
|
|
|
|
|
|
data->buffer =
|
|
|
|
wl_shm_pool_create_buffer(pool->pool, offset, w, h,
|
|
|
|
(w * sizeof(int)), wl_format);
|
|
|
|
if (!data->buffer)
|
|
|
|
{
|
|
|
|
ERR("Could not create buffer from pool: %m");
|
2015-03-19 13:15:11 -07:00
|
|
|
goto err;
|
2015-03-17 12:49:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return data;
|
2015-03-19 13:15:11 -07:00
|
|
|
|
|
|
|
err:
|
|
|
|
free(data);
|
|
|
|
return NULL;
|
2015-03-17 12:49:09 -07:00
|
|
|
}
|
|
|
|
|
2015-03-19 13:15:11 -07:00
|
|
|
static void
|
2015-03-17 12:49:09 -07:00
|
|
|
_shm_data_create(Shm_Pool *alt_pool, Shm_Data **ret, Shm_Surface *surface, int w, int h)
|
|
|
|
{
|
|
|
|
Shm_Pool *pool;
|
|
|
|
Shm_Data *data;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2015-03-19 13:15:11 -07:00
|
|
|
if (ret) *ret = NULL;
|
|
|
|
|
2015-03-17 12:49:09 -07:00
|
|
|
if (alt_pool)
|
|
|
|
{
|
|
|
|
_shm_pool_reset(alt_pool);
|
|
|
|
if ((data = _shm_data_create_from_pool(alt_pool, w, h, surface->alpha)))
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(pool = _shm_pool_create(surface->shm, ((w * sizeof(int)) * h))))
|
|
|
|
{
|
|
|
|
ERR("Could not create shm pool");
|
2015-03-19 13:15:11 -07:00
|
|
|
return;
|
2015-03-17 12:49:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!(data = _shm_data_create_from_pool(pool, w, h, surface->alpha)))
|
|
|
|
{
|
|
|
|
ERR("Could not create data from pool");
|
|
|
|
_shm_pool_destroy(pool);
|
2015-03-19 13:15:11 -07:00
|
|
|
return;
|
2015-03-17 12:49:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
data->pool = pool;
|
|
|
|
|
|
|
|
out:
|
|
|
|
if (ret) *ret = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_shm_data_destroy(Shm_Data *data)
|
|
|
|
{
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (data->buffer) wl_buffer_destroy(data->buffer);
|
|
|
|
if (data->pool) _shm_pool_destroy(data->pool);
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_shm_buffer_release(void *data, struct wl_buffer *buffer)
|
|
|
|
{
|
|
|
|
Shm_Surface *surf;
|
|
|
|
Shm_Leaf *leaf;
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
surf = data;
|
|
|
|
for (; i < surf->num_buff; i++)
|
|
|
|
{
|
|
|
|
leaf = &surf->leaf[i];
|
|
|
|
if ((leaf->data) && (leaf->data->buffer == buffer))
|
|
|
|
{
|
2015-03-19 13:15:11 -07:00
|
|
|
// DBG("Buffer Released: %d", (int)(leaf - &surf->leaf[0]));
|
2015-03-17 12:49:09 -07:00
|
|
|
leaf->busy = 0;
|
2015-03-19 13:15:11 -07:00
|
|
|
|
|
|
|
if (leaf->reconfigure)
|
|
|
|
{
|
|
|
|
_shm_leaf_release(leaf);
|
|
|
|
_shm_leaf_create(surf, leaf, surf->w, surf->h);
|
|
|
|
}
|
|
|
|
|
2015-03-17 12:49:09 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_buffer_listener _shm_buffer_listener =
|
|
|
|
{
|
|
|
|
_shm_buffer_release
|
|
|
|
};
|
|
|
|
|
2015-03-19 13:15:11 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_shm_leaf_create(Shm_Surface *surface, Shm_Leaf *leaf, int w, int h)
|
|
|
|
{
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
_shm_data_create(leaf->resize_pool, &leaf->data, surface, w, h);
|
|
|
|
if (!leaf->data)
|
|
|
|
{
|
|
|
|
CRI("Failed to create leaf data");
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
leaf->w = w;
|
|
|
|
leaf->h = h;
|
|
|
|
leaf->valid = EINA_TRUE;
|
|
|
|
|
|
|
|
wl_buffer_add_listener(leaf->data->buffer, &_shm_buffer_listener, surface);
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_shm_leaf_release(Shm_Leaf *leaf)
|
|
|
|
{
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (leaf->data) _shm_data_destroy(leaf->data);
|
|
|
|
if (leaf->resize_pool) _shm_pool_destroy(leaf->resize_pool);
|
|
|
|
memset(leaf, 0, sizeof(*leaf));
|
|
|
|
leaf->valid = EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2015-03-17 12:49:09 -07:00
|
|
|
Shm_Surface *
|
2015-03-19 13:15:11 -07:00
|
|
|
_evas_shm_surface_create(struct wl_shm *shm, struct wl_surface *surface, int w, int h, int num_buff, Eina_Bool alpha)
|
2015-03-17 12:49:09 -07:00
|
|
|
{
|
|
|
|
Shm_Surface *surf;
|
2015-03-19 13:15:11 -07:00
|
|
|
int i = 0;
|
2015-03-17 12:49:09 -07:00
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (!(surf = calloc(1, sizeof(Shm_Surface)))) return NULL;
|
|
|
|
|
|
|
|
surf->dx = 0;
|
|
|
|
surf->dy = 0;
|
|
|
|
surf->w = w;
|
|
|
|
surf->h = h;
|
|
|
|
surf->shm = shm;
|
|
|
|
surf->surface = surface;
|
2015-03-19 13:15:11 -07:00
|
|
|
surf->num_buff = num_buff;
|
2015-03-17 12:49:09 -07:00
|
|
|
surf->alpha = alpha;
|
|
|
|
surf->flags = 0;
|
|
|
|
|
2015-03-19 13:15:11 -07:00
|
|
|
/* create surface buffers */
|
|
|
|
for (; i < surf->num_buff; i++)
|
|
|
|
{
|
|
|
|
if (!_shm_leaf_create(surf, &(surf->leaf[i]), w, h))
|
|
|
|
{
|
|
|
|
ERR("Could not create surface leaf");
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-17 12:49:09 -07:00
|
|
|
return surf;
|
2015-03-19 13:15:11 -07:00
|
|
|
|
|
|
|
err:
|
|
|
|
_evas_shm_surface_destroy(surf);
|
|
|
|
return NULL;
|
2015-03-17 12:49:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_evas_shm_surface_destroy(Shm_Surface *surface)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
for (; i < surface->num_buff; i++)
|
|
|
|
_shm_leaf_release(&surface->leaf[i]);
|
|
|
|
|
|
|
|
free(surface);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-03-19 13:15:11 -07:00
|
|
|
_evas_shm_surface_reconfigure(Shm_Surface *surface, int dx, int dy, int w, int h, int num_buff, uint32_t flags)
|
2015-03-17 12:49:09 -07:00
|
|
|
{
|
|
|
|
int i = 0, resize = 0;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
resize = !!(flags & SURFACE_HINT_RESIZING);
|
|
|
|
|
2015-03-19 13:15:11 -07:00
|
|
|
for (; i < surface->num_buff; i++)
|
|
|
|
{
|
|
|
|
/* don't resize any busy leafs */
|
|
|
|
if (surface->leaf[i].busy)
|
|
|
|
{
|
|
|
|
surface->leaf[i].reconfigure = EINA_TRUE;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clear this leaf */
|
|
|
|
_shm_leaf_release(&surface->leaf[i]);
|
|
|
|
}
|
|
|
|
|
2015-03-17 12:49:09 -07:00
|
|
|
surface->w = w;
|
|
|
|
surface->h = h;
|
|
|
|
surface->dx = dx;
|
|
|
|
surface->dy = dy;
|
2015-03-19 13:15:11 -07:00
|
|
|
surface->flags = flags;
|
2015-03-17 12:49:09 -07:00
|
|
|
surface->num_buff = num_buff;
|
|
|
|
|
2015-03-19 13:15:11 -07:00
|
|
|
for (i = 0; i < surface->num_buff; i++)
|
2015-03-17 12:49:09 -07:00
|
|
|
{
|
|
|
|
if (surface->leaf[i].busy) continue;
|
2015-03-19 13:15:11 -07:00
|
|
|
|
|
|
|
if ((resize) && (!surface->leaf[i].resize_pool))
|
2015-03-17 12:49:09 -07:00
|
|
|
{
|
2015-03-19 13:15:11 -07:00
|
|
|
surface->leaf[i].resize_pool =
|
|
|
|
_shm_pool_create(surface->shm, 10 * 1024 * 1024);
|
2015-03-17 12:49:09 -07:00
|
|
|
}
|
|
|
|
|
2015-03-19 13:15:11 -07:00
|
|
|
if (!_shm_leaf_create(surface, &surface->leaf[i], w, h))
|
|
|
|
{
|
|
|
|
CRI("Failed to create leaf data");
|
|
|
|
abort();
|
|
|
|
}
|
2015-03-17 12:49:09 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_evas_shm_surface_swap(Shm_Surface *surface, Eina_Rectangle *rects, unsigned int count)
|
|
|
|
{
|
2015-03-19 13:15:11 -07:00
|
|
|
Shm_Leaf *leaf = NULL;
|
2015-03-17 12:49:09 -07:00
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2015-04-29 08:49:49 -07:00
|
|
|
leaf = &surface->leaf[surface->curr_buff];
|
|
|
|
if (!leaf) return;
|
2015-03-17 12:49:09 -07:00
|
|
|
|
2015-04-29 08:49:49 -07:00
|
|
|
if (leaf->busy)
|
2015-03-17 12:49:09 -07:00
|
|
|
{
|
2015-04-29 08:49:49 -07:00
|
|
|
WRN("Trying to use a busy buffer");
|
2015-03-17 12:49:09 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-30 08:13:36 -07:00
|
|
|
/* DBG("Current Leaf %d", (int)(leaf - &surface->leaf[0])); */
|
|
|
|
|
|
|
|
surface->last_buff = surface->curr_buff;
|
2015-03-19 13:15:11 -07:00
|
|
|
|
|
|
|
wl_surface_attach(surface->surface, leaf->data->buffer, 0, 0);
|
|
|
|
|
2015-03-17 12:49:09 -07:00
|
|
|
if ((rects) && (count > 0))
|
|
|
|
{
|
2015-03-25 10:49:02 -07:00
|
|
|
unsigned int k = 0;
|
2015-03-17 12:49:09 -07:00
|
|
|
|
2015-03-25 10:49:02 -07:00
|
|
|
for (; k < count; k++)
|
2015-03-19 13:15:11 -07:00
|
|
|
wl_surface_damage(surface->surface,
|
2015-03-25 10:49:02 -07:00
|
|
|
rects[k].x, rects[k].y,
|
|
|
|
rects[k].w, rects[k].h);
|
2015-03-17 12:49:09 -07:00
|
|
|
}
|
|
|
|
else
|
2015-03-19 13:15:11 -07:00
|
|
|
wl_surface_damage(surface->surface, 0, 0, leaf->w, leaf->h);
|
2015-03-17 12:49:09 -07:00
|
|
|
|
|
|
|
surface->dx = 0;
|
|
|
|
surface->dy = 0;
|
|
|
|
surface->redraw = EINA_TRUE;
|
2015-04-30 08:13:36 -07:00
|
|
|
surface->mapped = EINA_TRUE;
|
2015-03-17 12:49:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
2015-03-19 13:15:11 -07:00
|
|
|
_evas_shm_surface_data_get(Shm_Surface *surface, int *w, int *h)
|
2015-03-17 12:49:09 -07:00
|
|
|
{
|
2015-03-19 13:15:11 -07:00
|
|
|
Shm_Leaf *leaf = NULL;
|
|
|
|
int i = 0;
|
2015-03-17 12:49:09 -07:00
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2015-03-19 13:15:11 -07:00
|
|
|
if (w) *w = 0;
|
|
|
|
if (h) *h = 0;
|
2015-03-17 12:49:09 -07:00
|
|
|
|
2015-03-19 13:15:11 -07:00
|
|
|
for (; i < surface->num_buff; i++)
|
2015-03-17 12:49:09 -07:00
|
|
|
{
|
2015-03-19 13:15:11 -07:00
|
|
|
if (surface->leaf[i].busy) continue;
|
|
|
|
if ((!leaf) || (leaf->valid))
|
2015-03-17 12:49:09 -07:00
|
|
|
{
|
2015-03-19 13:15:11 -07:00
|
|
|
leaf = &surface->leaf[i];
|
|
|
|
break;
|
2015-03-17 12:49:09 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-19 13:15:11 -07:00
|
|
|
if (!leaf)
|
|
|
|
{
|
2015-04-30 08:13:36 -07:00
|
|
|
/* WRN("All buffers held by server"); */
|
2015-03-19 13:15:11 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* DBG("Leaf Data Get %d", (int)(leaf - &surface->leaf[0])); */
|
|
|
|
|
|
|
|
if (w) *w = leaf->w;
|
|
|
|
if (h) *h = leaf->h;
|
2015-03-17 12:49:09 -07:00
|
|
|
|
2015-04-29 08:49:49 -07:00
|
|
|
surface->curr_buff = (int)(leaf - &surface->leaf[0]);
|
|
|
|
|
2015-03-17 12:49:09 -07:00
|
|
|
return leaf->data->map;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_evas_shm_surface_redraw(Shm_Surface *surface)
|
|
|
|
{
|
2015-07-27 12:53:02 -07:00
|
|
|
Shm_Leaf *leaf = NULL;
|
|
|
|
|
2015-03-17 12:49:09 -07:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (surface->frame_cb)
|
|
|
|
{
|
|
|
|
if (!surface->redraw) return;
|
|
|
|
wl_callback_destroy(surface->frame_cb);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!surface->surface) return;
|
|
|
|
|
|
|
|
surface->frame_cb = wl_surface_frame(surface->surface);
|
2015-03-19 13:15:11 -07:00
|
|
|
wl_callback_add_listener(surface->frame_cb, &_shm_frame_listener, surface);
|
2015-07-27 12:53:02 -07:00
|
|
|
|
|
|
|
wl_surface_commit(surface->surface);
|
|
|
|
|
|
|
|
leaf = &surface->leaf[surface->curr_buff];
|
|
|
|
leaf->busy = 1;
|
2015-03-17 12:49:09 -07:00
|
|
|
}
|