evas-wayland-shm: Remove old wayland_shm engine swapper files

Summary: Part of engine refactor to address resize issue in E wayland
compositor

Signed-off-by: Chris Michael <cp.michael@samsung.com>
This commit is contained in:
Chris Michael 2015-03-17 15:32:29 -04:00
parent 9baacf802d
commit 5c753a859b
4 changed files with 0 additions and 1112 deletions

View File

@ -1,537 +0,0 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
//#include <sys/mman.h>
#ifdef EVAS_CSERVE2
# include "evas_cs2_private.h"
#endif
#include "evas_common_private.h"
#include "evas_macros.h"
#include "evas_engine.h"
#include "evas_swapbuf.h"
#include "evas_swapper.h"
#define RED_MASK 0x00ff0000
#define GREEN_MASK 0x0000ff00
#define BLUE_MASK 0x000000ff
/* local function prototypes */
Outbuf *
evas_swapbuf_setup(Evas_Engine_Info_Wayland_Shm *info, int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *wl_shm, struct wl_surface *wl_surface)
{
Outbuf *ob = NULL;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* try to allocate a new Outbuf */
if (!(ob = calloc(1, sizeof(Outbuf))))
return NULL;
/* set some properties */
ob->w = w;
ob->h = h;
ob->rotation = rotation;
ob->depth = depth;
ob->priv.destination_alpha = alpha;
ob->priv.wl.shm = wl_shm;
ob->priv.wl.surface = wl_surface;
ob->info = info;
if ((ob->rotation == 0) || (ob->rotation == 180))
{
ob->priv.swapper =
evas_swapper_setup(0, 0, w, h, depth, alpha, ob->priv.wl.shm,
ob->priv.wl.surface);
}
else if ((ob->rotation == 90) || (ob->rotation == 270))
{
ob->priv.swapper =
evas_swapper_setup(0, 0, h, w, depth, alpha, ob->priv.wl.shm,
ob->priv.wl.surface);
}
/* check that a swapper was created */
if (!ob->priv.swapper)
{
/* free the Outbuf structure allocation */
free(ob);
return NULL;
}
/* set step size of regions array */
eina_array_step_set(&ob->priv.onebuf_regions, sizeof(Eina_Array), 8);
/* return allocated Outbuf */
return ob;
}
void
evas_swapbuf_free(Outbuf *ob)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* check for valid output buffer */
if (!ob) return;
/* flush the output buffer */
evas_swapbuf_flush(ob, NULL, MODE_FULL);
evas_swapbuf_idle_flush(ob);
evas_swapper_free(ob->priv.swapper);
eina_array_flush(&ob->priv.onebuf_regions);
/* free the allocated structure */
free(ob);
}
void
evas_swapbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, int rotation, Outbuf_Depth depth, Eina_Bool alpha)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* check for valid output buffer */
if (!ob) return;
if (depth == OUTBUF_DEPTH_INHERIT) depth = ob->depth;
/* check that something was actually changed */
if ((ob->w == w) && (ob->h == h) &&
(ob->rotation == rotation) && (ob->depth == depth))
return;
/* set some properties */
ob->w = w;
ob->h = h;
ob->rotation = rotation;
ob->depth = depth;
ob->priv.destination_alpha = alpha;
/* check for valid swapper */
if (ob->priv.swapper)
{
if ((ob->rotation == 0) || (ob->rotation == 180))
ob->priv.swapper = evas_swapper_reconfigure(ob->priv.swapper,
x, y, w, h, depth,
alpha);
else if ((ob->rotation == 90) || (ob->rotation == 270))
ob->priv.swapper = evas_swapper_reconfigure(ob->priv.swapper,
x, y, h, w, depth,
alpha);
return;
}
/* create new swapper */
if ((ob->rotation == 0) || (ob->rotation == 180))
{
ob->priv.swapper =
evas_swapper_setup(x, y, w, h, depth, alpha, ob->priv.wl.shm,
ob->priv.wl.surface);
}
else if ((ob->rotation == 90) || (ob->rotation == 270))
{
ob->priv.swapper =
evas_swapper_setup(x, y, h, w, depth, alpha, ob->priv.wl.shm,
ob->priv.wl.surface);
}
}
void *
evas_swapbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
{
RGBA_Image *img;
Eina_Rectangle *rect;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, ob->w, ob->h);
if ((w <= 0) || (h <= 0)) return NULL;
if (ob->rotation == 0)
{
if (!(img = ob->priv.onebuf))
{
int bpl = 0;
int bw = 0, bh = 0;
void *data;
data = evas_swapper_buffer_map(ob->priv.swapper, &bw, &bh);
bpl = (bw * sizeof(int));
#ifdef EVAS_CSERVE2
if (evas_cserve2_use_get())
img = (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(),
bpl / sizeof(int), bh,
data,
ob->priv.destination_alpha,
EVAS_COLORSPACE_ARGB8888);
else
#endif
img = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
bpl / sizeof(int), bh,
data,
ob->priv.destination_alpha,
EVAS_COLORSPACE_ARGB8888);
ob->priv.onebuf = img;
if (!img) return NULL;
}
if (!(rect = eina_rectangle_new(x, y, w, h)))
return NULL;
if (!eina_array_push(&ob->priv.onebuf_regions, rect))
{
#ifdef EVAS_CSERVE2
if (evas_cserve2_use_get())
evas_cache2_image_close(&img->cache_entry);
else
#endif
evas_cache_image_drop(&img->cache_entry);
eina_rectangle_free(rect);
return NULL;
}
/* clip the region to the onebuf region */
if (cx) *cx = x;
if (cy) *cy = y;
if (cw) *cw = w;
if (ch) *ch = h;
return img;
}
else
{
if (!(rect = eina_rectangle_new(x, y, w, h)))
return NULL;
#ifdef EVAS_CSERVE2
if (evas_cserve2_use_get())
img = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
else
#endif
img = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
if (!img)
{
eina_rectangle_free(rect);
return NULL;
}
img->cache_entry.flags.alpha |= ob->priv.destination_alpha;
#ifdef EVAS_CSERVE2
if (evas_cserve2_use_get())
evas_cache2_image_surface_alloc(&img->cache_entry, w, h);
else
#endif
evas_cache_image_surface_alloc(&img->cache_entry, w, h);
img->extended_info = rect;
ob->priv.pending_writes =
eina_list_append(ob->priv.pending_writes, img);
if (cx) *cx = 0;
if (cy) *cy = 0;
if (cw) *cw = w;
if (ch) *ch = h;
return img;
}
return NULL;
}
void
evas_swapbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h)
{
Gfx_Func_Convert func = NULL;
Eina_Rectangle rect = {0, 0, 0, 0}, pr;
DATA32 *src;
DATA8 *dst;
int depth = 32, bpp = 0, bpl = 0, wid = 0;
int ww = 0, hh = 0;
int rx = 0, ry = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* check for valid output buffer */
if (!ob) return;
/* check for pending writes */
if (!ob->priv.pending_writes) return;
if ((ob->rotation == 0) || (ob->rotation == 180))
{
func =
evas_common_convert_func_get(0, w, h, depth,
RED_MASK, GREEN_MASK, BLUE_MASK,
PAL_MODE_NONE, ob->rotation);
}
else if ((ob->rotation == 90) || (ob->rotation == 270))
{
func =
evas_common_convert_func_get(0, h, w, depth,
RED_MASK, GREEN_MASK, BLUE_MASK,
PAL_MODE_NONE, ob->rotation);
}
/* make sure we have a valid convert function */
if (!func) return;
/* based on rotation, set rectangle position */
if (ob->rotation == 0)
{
rect.x = x;
rect.y = y;
}
else if (ob->rotation == 90)
{
rect.x = y;
rect.y = (ob->w - x - w);
}
else if (ob->rotation == 180)
{
rect.x = (ob->w - x - w);
rect.y = (ob->h - y - h);
}
else if (ob->rotation == 270)
{
rect.x = (ob->h - y - h);
rect.y = x;
}
/* based on rotation, set rectangle size */
if ((ob->rotation == 0) || (ob->rotation == 180))
{
rect.w = w;
rect.h = h;
}
else if ((ob->rotation == 90) || (ob->rotation == 270))
{
rect.w = h;
rect.h = w;
}
/* check for valid update image data */
if (!(src = update->image.data)) return;
bpp = depth / 8;
if (bpp <= 0) return;
/* check for valid desination data */
if (!(dst = evas_swapper_buffer_map(ob->priv.swapper, &ww, &hh))) return;
bpl = (ww * sizeof(int));
if (ob->rotation == 0)
{
RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh);
dst += (bpl * rect.y) + (rect.x * bpp);
w -= rx;
}
else if (ob->rotation == 180)
{
pr = rect;
RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh);
rx = pr.w - rect.w;
ry = pr.h - rect.h;
src += (update->cache_entry.w * ry) + rx;
w -= rx;
}
else if (ob->rotation == 90)
{
pr = rect;
RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh);
rx = pr.w - rect.w; ry = pr.h - rect.h;
src += ry;
w -= ry;
}
else if (ob->rotation == 270)
{
pr = rect;
RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh);
rx = pr.w - rect.w; ry = pr.h - rect.h;
src += (update->cache_entry.w * rx);
w -= ry;
}
if ((rect.w <= 0) || (rect.h <= 0)) return;
wid = bpl / bpp;
dst += (bpl * rect.y) + (rect.x * bpp);
func(src, dst, (update->cache_entry.w - w), (wid - rect.w),
rect.w, rect.h, x + rx, y + ry, NULL);
}
void
evas_swapbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED)
{
/* NB: nothing to do, they are cleaned up on flush */
}
void
evas_swapbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode)
{
Eina_Rectangle *result;
RGBA_Image *img;
unsigned int n = 0, i = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return;
/* check for valid output buffer */
if (!ob) return;
/* check for pending writes */
if (!ob->priv.pending_writes)
{
Eina_Rectangle *rect;
Eina_Array_Iterator it;
/* get number of buffer regions */
n = eina_array_count_get(&ob->priv.onebuf_regions);
if (n == 0) return;
/* allocate rectangles */
if (!(result = alloca(n * sizeof(Eina_Rectangle)))) return;
/* loop the buffer regions and assign to result */
EINA_ARRAY_ITER_NEXT(&ob->priv.onebuf_regions, i, rect, it)
result[i] = *rect;
/* unmap the buffer */
evas_swapper_buffer_unmap(ob->priv.swapper);
/* force a buffer swap */
evas_swapper_swap(ob->priv.swapper, result, n);
/* clean array */
eina_array_clean(&ob->priv.onebuf_regions);
img = ob->priv.onebuf;
ob->priv.onebuf = NULL;
if (img)
{
#ifdef EVAS_CSERVE2
if (evas_cserve2_use_get())
evas_cache2_image_close(&img->cache_entry);
else
#endif
evas_cache_image_drop(&img->cache_entry);
}
}
else
{
/* get number of pending writes */
n = eina_list_count(ob->priv.pending_writes);
if (n == 0) return;
/* allocate rectangles */
if (!(result = alloca(n * sizeof(Eina_Rectangle)))) return;
/* loop the pending writes */
EINA_LIST_FREE(ob->priv.pending_writes, img)
{
Eina_Rectangle *rect;
int x = 0, y = 0, w = 0, h = 0;
if (!(rect = img->extended_info)) continue;
x = rect->x; y = rect->y; w = rect->w; h = rect->h;
/* based on rotation, set rectangle position */
if (ob->rotation == 0)
{
result[i].x = x;
result[i].y = y;
}
else if (ob->rotation == 90)
{
result[i].x = y;
result[i].y = (ob->w - x - w);
}
else if (ob->rotation == 180)
{
result[i].x = (ob->w - x - w);
result[i].y = (ob->h - y - h);
}
else if (ob->rotation == 270)
{
result[i].x = (ob->h - y - h);
result[i].y = x;
}
/* based on rotation, set rectangle size */
if ((ob->rotation == 0) || (ob->rotation == 180))
{
result[i].w = w;
result[i].h = h;
}
else if ((ob->rotation == 90) || (ob->rotation == 270))
{
result[i].w = h;
result[i].h = w;
}
eina_rectangle_free(rect);
#ifdef EVAS_CSERVE2
if (evas_cserve2_use_get())
evas_cache2_image_close(&img->cache_entry);
else
#endif
evas_cache_image_drop(&img->cache_entry);
i++;
}
/* unmap the buffer */
evas_swapper_buffer_unmap(ob->priv.swapper);
/* force a buffer swap */
evas_swapper_swap(ob->priv.swapper, result, n);
}
}
void
evas_swapbuf_idle_flush(Outbuf *ob EINA_UNUSED)
{
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* check for valid output buffer */
/* if (!ob) return; */
/* check for valid swapper */
/* if (!ob->priv.swapper) return; */
/* tell the swapper to release any buffers that have been rendered */
/* evas_swapper_buffer_idle_flush(ob->priv.swapper); */
}
Render_Engine_Swap_Mode
evas_swapbuf_state_get(Outbuf *ob)
{
int mode = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!ob->priv.swapper) return MODE_FULL;
mode = evas_swapper_buffer_state_get(ob->priv.swapper);
return mode;
}
int
evas_swapbuf_rotation_get(Outbuf *ob)
{
return ob->rotation;
}
/* local functions */

View File

@ -1,17 +0,0 @@
#ifndef _EVAS_SWAPBUF_H
# define _EVAS_SWAPBUF_H
# include "evas_engine.h"
Outbuf *evas_swapbuf_setup(Evas_Engine_Info_Wayland_Shm *info, int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *wl_shm, struct wl_surface *wl_surface);
void evas_swapbuf_free(Outbuf *ob);
void evas_swapbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, int rotation, Outbuf_Depth depth, Eina_Bool alpha);
void *evas_swapbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
void evas_swapbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
void evas_swapbuf_update_region_free(Outbuf *ob, RGBA_Image *update);
void evas_swapbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode);
void evas_swapbuf_idle_flush(Outbuf *ob EINA_UNUSED);
Render_Engine_Swap_Mode evas_swapbuf_state_get(Outbuf *ob);
int evas_swapbuf_rotation_get(Outbuf *ob);
#endif

View File

@ -1,541 +0,0 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/mman.h>
#ifdef EVAS_CSERVE2
# include "evas_cs2_private.h"
#endif
#include "evas_common_private.h"
#include "evas_macros.h"
#include "evas_engine.h"
#include "evas_swapper.h"
/* local structures */
typedef struct _Wl_Buffer Wl_Buffer;
struct _Wl_Buffer
{
Wl_Swapper *ws;
int w, h;
struct wl_buffer *buffer;
void *data;
int offset;
size_t size;
Eina_Bool valid : 1;
};
struct _Wl_Swapper
{
Wl_Buffer buff[3];
Wl_Buffer *buffer_sent;
int in_use;
int dx, dy, w, h, depth;
int buff_cur, buff_num, buff_last;
struct wl_shm *shm;
struct wl_surface *surface;
struct wl_shm_pool *pool;
size_t pool_size;
size_t used_size;
void *data;
Eina_Bool alpha : 1;
Eina_Bool mapped : 1;
Eina_Bool delete_me : 1;
};
/* local function prototypes */
static Eina_Bool _evas_swapper_shm_pool_new(Wl_Swapper *ws);
static void _evas_swapper_shm_pool_free(Wl_Swapper *ws);
static Eina_Bool _evas_swapper_buffer_new(Wl_Swapper *ws, Wl_Buffer *wb);
static void _evas_swapper_buffer_free(Wl_Buffer *wb);
static void _evas_swapper_buffer_put(Wl_Swapper *ws, Wl_Buffer *wb, Eina_Rectangle *rects, unsigned int count);
static void _evas_swapper_buffer_release(void *data, struct wl_buffer *buffer);
static const struct wl_buffer_listener _evas_swapper_buffer_listener =
{
_evas_swapper_buffer_release
};
/* local variables */
Wl_Swapper *
evas_swapper_setup(int dx, int dy, int w, int h, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface)
{
Wl_Swapper *ws;
int i = 0;
char *num_buffers;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* try to allocate a new swapper */
if (!(ws = calloc(1, sizeof(Wl_Swapper))))
return NULL;
/* set some properties */
ws->dx = dx;
ws->dy = dy;
ws->w = w;
ws->h = h;
ws->depth = depth;
ws->alpha = alpha;
ws->shm = shm;
ws->surface = surface;
/* double buffer by default */
ws->buff_num = 2;
/* check for buffer override number */
if ((num_buffers = getenv("EVAS_WAYLAND_SHM_BUFFERS")))
{
int num = 0;
num = atoi(num_buffers);
if (num <= 0) num = 1;
if (num > 3) num = 3;
ws->buff_num = num;
}
/* create the shm pool */
if (!_evas_swapper_shm_pool_new(ws))
{
evas_swapper_free(ws);
return NULL;
}
for (i = 0; i < ws->buff_num; i++)
{
/* try to create new internal Wl_Buffer */
if (!_evas_swapper_buffer_new(ws, &(ws->buff[i])))
{
/* failed to create wl_buffer. free the swapper */
evas_swapper_free(ws);
return NULL;
}
}
/* return allocated swapper */
return ws;
}
Wl_Swapper *
evas_swapper_reconfigure(Wl_Swapper *ws, int dx, int dy, int w, int h, Outbuf_Depth depth, Eina_Bool alpha)
{
int i = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!ws)
{
ERR("No swapper to reconfigure.");
return NULL;
}
/* loop the swapper's buffers and free them */
for (i = 0; i < ws->buff_num; i++)
_evas_swapper_buffer_free(&(ws->buff[i]));
/* free the shm pool */
_evas_swapper_shm_pool_free(ws);
ws->dx += dx;
ws->dy += dy;
ws->w = w;
ws->h = h;
ws->depth = depth;
ws->alpha = alpha;
/* create the shm pool */
if (!_evas_swapper_shm_pool_new(ws))
{
ERR("Could not allocate new shm pool.");
evas_swapper_free(ws);
return NULL;
}
for (i = 0; i < ws->buff_num; i++)
{
/* try to create new internal Wl_Buffer */
if (!_evas_swapper_buffer_new(ws, &(ws->buff[i])))
{
ERR("failed to create wl_buffer. free the swapper.");
evas_swapper_free(ws);
return NULL;
}
}
/* return reconfigured swapper */
return ws;
}
void
evas_swapper_swap(Wl_Swapper *ws, Eina_Rectangle *rects, unsigned int count)
{
int n = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* check for valid swapper */
if (!ws) return;
ws->buff_last = n = ws->buff_cur;
_evas_swapper_buffer_put(ws, &(ws->buff[n]), rects, count);
ws->buff[n].valid = EINA_TRUE;
ws->in_use++;
ws->buff_cur = (ws->buff_cur + 1) % ws->buff_num;
}
void
evas_swapper_free(Wl_Swapper *ws)
{
int i = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* check for valid swapper */
if (!ws) return;
/* loop the swapper's buffers and free them */
for (i = 0; i < ws->buff_num; i++)
_evas_swapper_buffer_free(&(ws->buff[i]));
if (ws->in_use)
{
ws->delete_me = EINA_TRUE;
return;
}
/* free the shm pool */
_evas_swapper_shm_pool_free(ws);
/* free the allocated structure */
free(ws);
}
void *
evas_swapper_buffer_map(Wl_Swapper *ws, int *w, int *h)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* check for valid swapper */
if (!ws) return NULL;
/* set mapped property */
ws->mapped = EINA_TRUE;
if (w) *w = ws->w;
if (h) *h = ws->h;
/* return wl_buffer data */
return ws->buff[ws->buff_cur].data;
}
void
evas_swapper_buffer_unmap(Wl_Swapper *ws)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* check for valid swapper */
if (!ws) return;
ws->mapped = EINA_FALSE;
}
int
evas_swapper_buffer_state_get(Wl_Swapper *ws)
{
int delta;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
delta = (ws->buff_last - ws->buff_cur +
(ws->buff_last > ws->buff_last ?
0 : ws->buff_num)) % ws->buff_num;
/* This is the number of frame since last frame */
switch (delta)
{
case 0:
return MODE_COPY;
case 1:
return MODE_DOUBLE;
case 2:
return MODE_TRIPLE;
default:
return MODE_FULL;
}
}
void
evas_swapper_buffer_idle_flush(Wl_Swapper *ws)
{
int i = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* check for valid swapper */
if (!ws) return;
/* loop the swapper's buffers and free them */
for (i = 0; i < ws->buff_num; i++)
{
Wl_Buffer *wb = NULL;
/* try to get out Wl_Buffer struct */
if (!(wb = (&(ws->buff[i])))) continue;
/* if this buffer is not valid, then unmap data */
if (!wb->valid) _evas_swapper_buffer_free(wb);
}
}
/* local functions */
static Eina_Bool
_evas_swapper_shm_pool_new(Wl_Swapper *ws)
{
static const char tmp[] = "/evas-wayland_shm-XXXXXX";
const char *path;
char *name;
size_t size;
int fd = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* make sure swapper has a shm */
if (!ws->shm) return EINA_FALSE;
/* calculate new required size */
size = (((ws->w * sizeof(int)) * ws->h) * ws->buff_num);
/* check pool size to see if we need to realloc the pool */
if (size <= ws->pool_size) return EINA_TRUE;
/* create tmp file, trying to use XDG_RUNTIME if set */
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 EINA_FALSE;
strcat(name, tmp);
/* try to create the tmp file */
if ((fd = mkstemp(name)) < 0)
{
ERR("Could not create temporary file.");
free(name);
return EINA_FALSE;
}
/* unlink the temp file */
unlink(name);
free(name);
/* try to truncate the tmp file to requested size */
if (ftruncate(fd, size) < 0)
{
ERR("Could not truncate temporary file.");
close(fd);
return EINA_FALSE;
}
/* mem map the file */
ws->data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0);
/* if we failed to mem map the file, return an error */
if (ws->data == MAP_FAILED)
{
ERR("Could not mmap temporary file.");
close(fd);
return EINA_FALSE;
}
/* actually create the shm pool */
ws->pool = wl_shm_create_pool(ws->shm, fd, size);
ws->pool_size = size;
ws->used_size = 0;
/* close the file */
close(fd);
return EINA_TRUE;
}
static void
_evas_swapper_shm_pool_free(Wl_Swapper *ws)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* check for valid swapper */
if (!ws) return;
/* check for valid pool */
if (!ws->pool) return;
/* unmap any existing data */
if (ws->data) munmap(ws->data, ws->pool_size);
/* destroy the shm pool */
wl_shm_pool_destroy(ws->pool);
ws->pool_size = 0;
ws->used_size = 0;
}
static Eina_Bool
_evas_swapper_buffer_new(Wl_Swapper *ws, Wl_Buffer *wb)
{
unsigned int format = WL_SHM_FORMAT_XRGB8888;
size_t size;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* make sure swapper has a shm */
if (!ws->shm) return EINA_FALSE;
wb->w = ws->w;
wb->h = ws->h;
/* calculate new required size */
size = ((wb->w * sizeof(int)) * wb->h);
/* check pool size to see if we need to realloc the pool */
if (ws->used_size + size > ws->pool_size)
{
size_t newsize;
/* calculate new required size */
newsize = (ws->pool_size + size);
/* resize the shm pool */
wl_shm_pool_resize(ws->pool, newsize);
ws->pool_size = newsize;
}
/* check if this buffer needs argb and set format */
if (ws->alpha) format = WL_SHM_FORMAT_ARGB8888;
/* create actual wl_buffer */
wb->buffer =
wl_shm_pool_create_buffer(ws->pool, ws->used_size, wb->w, wb->h,
(wb->w * sizeof(int)), format);
/* add wayland buffer listener */
wl_buffer_add_listener(wb->buffer, &_evas_swapper_buffer_listener, wb);
wb->data = (char *)ws->data + ws->used_size;
wb->size = size;
ws->used_size += size;
wb->ws = ws;
/* return allocated buffer */
return EINA_TRUE;
}
static void
_evas_swapper_buffer_free(Wl_Buffer *wb)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* check for valid buffer */
if ((!wb) || (wb->valid)) return;
/* kill the wl_buffer */
if (wb->buffer) wl_buffer_destroy(wb->buffer);
wb->buffer = NULL;
/* unmap the buffer data */
/* if (wb->data) munmap(wb->data, wb->size); */
wb->data = NULL;
}
static void
_evas_swapper_buffer_put(Wl_Swapper *ws, Wl_Buffer *wb, Eina_Rectangle *rects, unsigned int count)
{
Eina_Rectangle *rect;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* check for valid swapper */
if (!ws) return;
/* make sure swapper has a surface */
if (!ws->surface) return;
/* check for valid buffer */
if (!wb) return;
/* make sure buffer has mapped data */
if ((!wb->data) || (!wb->buffer))
{
/* call function to mmap buffer data */
/* if (!_evas_swapper_buffer_new(ws, wb)) */
return;
}
rect = eina_rectangle_new(0, 0, 0, 0);
if ((rects) && (count > 0))
{
unsigned int i = 0;
for (i = 0; i < count; i++)
eina_rectangle_union(rect, &rects[i]);
}
else
{
Eina_Rectangle r;
r.x = 0; r.y = 0;
r.w = wb->w; r.h = wb->h;
eina_rectangle_union(rect, &r);
}
/* surface attach */
if (ws->buffer_sent != wb)
{
wl_surface_attach(ws->surface, wb->buffer, ws->dx, ws->dy);
ws->dx = 0;
ws->dy = 0;
ws->buffer_sent = wb;
}
wl_surface_damage(ws->surface, rect->x, rect->y, rect->w, rect->h);
/* surface commit */
wl_surface_commit(ws->surface);
eina_rectangle_free(rect);
}
static void
_evas_swapper_buffer_release(void *data, struct wl_buffer *buffer EINA_UNUSED)
{
Wl_Buffer *wb = NULL;
Wl_Swapper *ws = NULL;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* try to get out Wl_Buffer struct */
if (!(wb = data)) return;
/* invalidate buffer */
wb->valid = EINA_FALSE;
ws = wb->ws;
ws->in_use--;
if (ws->delete_me && (ws->in_use <= 0))
evas_swapper_free(ws);
}

View File

@ -1,17 +0,0 @@
#ifndef _EVAS_SWAPPER_H
# define _EVAS_SWAPPER_H
#include "evas_engine.h"
typedef struct _Wl_Swapper Wl_Swapper;
Wl_Swapper *evas_swapper_setup(int dx, int dy, int w, int h, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface);
Wl_Swapper *evas_swapper_reconfigure(Wl_Swapper *ws, int dx, int dy, int w, int h, Outbuf_Depth depth, Eina_Bool alpha);
void evas_swapper_swap(Wl_Swapper *ws, Eina_Rectangle *rects, unsigned int count);
void evas_swapper_free(Wl_Swapper *ws);
void *evas_swapper_buffer_map(Wl_Swapper *ws, int *w, int *h);
void evas_swapper_buffer_unmap(Wl_Swapper *ws);
int evas_swapper_buffer_state_get(Wl_Swapper *ws);
void evas_swapper_buffer_idle_flush(Wl_Swapper *ws);
#endif