evas: Internally switch to Eina_Slice for buffers

This will be used for the gfx buffer map/unmap eo apis.
This commit is contained in:
Jean-Philippe Andre 2016-09-01 21:04:37 +09:00
parent d7b8d97fd5
commit 1773ba5d82
7 changed files with 72 additions and 67 deletions

View File

@ -601,7 +601,7 @@ _image_pixels_set(Evas_Object_Protected_Data *obj,
if (ENFN->image_data_maps_get)
{
if (ENFN->image_data_maps_get(ENDT, o->engine_data, NULL, NULL) > 0)
if (ENFN->image_data_maps_get(ENDT, o->engine_data, NULL) > 0)
{
ERR("can not set pixels when there are open memory maps");
return EINA_FALSE;
@ -780,8 +780,8 @@ _efl_canvas_image_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
int len = 0, s = 0, width = 0, height = 0;
void *data = NULL;
int s = 0, width = 0, height = 0;
const Eina_Rw_Slice *slice = NULL;
if (!ENFN->image_data_map)
goto end; // not implemented
@ -807,13 +807,18 @@ _efl_canvas_image_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
goto end;
}
data = ENFN->image_data_map(ENDT, &o->engine_data, &len, &s, x, y, w, h, cspace, mode);
DBG("map(%p, %d,%d %dx%d) -> %p (%d bytes)", eo_obj, x, y, w, h, data, len);
slice = ENFN->image_data_map(ENDT, &o->engine_data, &s, x, y, w, h, cspace, mode);
if (slice)
{
DBG("map(%p, %d,%d %dx%d) -> %p (%zu bytes)", eo_obj, x, y, w, h,
slice->mem, slice->len);
}
else DBG("map(%p, %d,%d %dx%d) -> (null)", eo_obj, x, y, w, h);
end:
if (length) *length = len;
if (length) *length = slice->len;
if (stride) *stride = s;
return data;
return slice->mem;
}
EOLIAN static Eina_Bool
@ -822,11 +827,14 @@ _efl_canvas_image_efl_gfx_buffer_buffer_unmap(Eo *eo_obj, void *_pd EINA_UNUSED,
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
Eina_Rw_Slice slice;
if (!ENFN->image_data_unmap || !o->engine_data)
return EINA_FALSE;
if (!ENFN->image_data_unmap(ENDT, o->engine_data, data, length))
slice.mem = data;
slice.len = length;
if (!ENFN->image_data_unmap(ENDT, o->engine_data, &slice))
return EINA_FALSE;
return EINA_TRUE;

View File

@ -269,6 +269,7 @@ _efl_canvas_proxy_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
int len = 0, s = 0, width = 0, height = 0;
const Eina_Rw_Slice *slice = NULL;
void *image, *data = NULL;
if (!ENFN->image_data_map)
@ -302,8 +303,13 @@ _efl_canvas_proxy_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
goto end;
}
data = ENFN->image_data_map(ENDT, &image, &len, &s, x, y, w, h, cspace, mode);
DBG("map(%p, %d,%d %dx%d) -> %p (%d bytes)", eo_obj, x, y, w, h, data, len);
slice = ENFN->image_data_map(ENDT, &image, &s, x, y, w, h, cspace, mode);
if (slice)
{
DBG("map(%p, %d,%d %dx%d) -> %p (%zu bytes)", eo_obj, x, y, w, h,
slice->mem, slice->len);
}
else DBG("map(%p, %d,%d %dx%d) -> (null)", eo_obj, x, y, w, h);
end:
if (length) *length = len;
@ -317,11 +323,14 @@ _efl_canvas_proxy_efl_gfx_buffer_buffer_unmap(Eo *eo_obj, void *_pd EINA_UNUSED,
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
Eina_Rw_Slice slice;
if (!ENFN->image_data_unmap || !o->engine_data)
return EINA_FALSE;
if (!ENFN->image_data_unmap(ENDT, o->engine_data, data, length))
slice.mem = data;
slice.len = length;
if (!ENFN->image_data_unmap(ENDT, o->engine_data, &slice))
return EINA_FALSE;
return EINA_TRUE;

View File

@ -840,8 +840,9 @@ struct _RGBA_Pipe_Thread_Info
struct _RGBA_Image_Data_Map {
EINA_INLIST;
unsigned char *ptr, *baseptr;
int size, stride; // in bytes
unsigned char *baseptr;
Eina_Rw_Slice slice;
int stride; // in bytes
int rx, ry, rw, rh; // actual map region
int plane;
Evas_Colorspace cspace;

View File

@ -1369,9 +1369,9 @@ struct _Evas_Func
Eina_Bool (*image_can_region_get) (void *data, void *image);
/* image data map/unmap: direct or indirect access to pixels data */
void *(*image_data_map) (void *data, void **image, int *length, int *stride, int x, int y, int w, int h, Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode);
Eina_Bool (*image_data_unmap) (void *data, void *image, void *map, int length);
int (*image_data_maps_get) (void *data, const void *image, void **maps, int *lengths);
const Eina_Rw_Slice *(*image_data_map) (void *data, void **image, int *stride, int x, int y, int w, int h, Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode);
Eina_Bool (*image_data_unmap) (void *data, void *image, const Eina_Rw_Slice *slice);
int (*image_data_maps_get) (void *data, const void *image, const Eina_Rw_Slice **slices);
int (*image_native_init) (void *data, Evas_Native_Surface_Type type);
void (*image_native_shutdown) (void *data, Evas_Native_Surface_Type type);

View File

@ -491,8 +491,8 @@ struct _Evas_GL_Image_Data_Map
EINA_INLIST;
Evas_GL_Texture *tex; // one or the other
RGBA_Image *im; // one or the other
unsigned char *ptr;
int size, stride; // in bytes
Eina_Rw_Slice slice;
int stride; // in bytes
int rx, ry, rw, rh; // actual map region
Evas_Colorspace cspace;
Efl_Gfx_Buffer_Access_Mode mode;

View File

@ -2794,16 +2794,15 @@ eng_ector_end(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
}
}
static void *
static const Eina_Rw_Slice *
eng_image_data_map(void *engdata EINA_UNUSED, void **image,
int *length, int *stride,
int x, int y, int w, int h,
int *stride, int x, int y, int w, int h,
Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode)
{
Eina_Bool cow = EINA_FALSE, to_write = EINA_FALSE;
Evas_GL_Image_Data_Map *map = NULL;
const Eina_Rw_Slice *slice = NULL;
Evas_GL_Image *im;
void *ret;
EINA_SAFETY_ON_FALSE_RETURN_VAL(image && *image, NULL);
im = *image;
@ -2816,12 +2815,12 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
if (im->im)
{
int len = 0, strid = 0;
int strid = 0;
// Call sw generic implementation. Should work for simple cases.
ret = pfunc.image_data_map(NULL, (void **) &im->im, &len, &strid,
x, y, w, h, cspace, mode);
if (ret)
slice = pfunc.image_data_map(NULL, (void **) &im->im, &strid,
x, y, w, h, cspace, mode);
if (slice)
{
map = calloc(1, sizeof(*map));
map->cspace = cspace;
@ -2830,15 +2829,13 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
map->rw = w;
map->rh = h;
map->mode = mode;
map->size = len;
map->slice = *slice;
map->stride = strid;
map->im = im->im; // ref?
map->ptr = ret;
im->maps = eina_inlist_prepend(im->maps, EINA_INLIST_GET(map));
}
if (length) *length = len;
if (stride) *stride = strid;
return ret;
return &map->slice;
}
// TODO: glReadPixels from FBO if possible
@ -2847,22 +2844,22 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
}
static Eina_Bool
eng_image_data_unmap(void *engdata EINA_UNUSED, void *image, void *memory, int length)
eng_image_data_unmap(void *engdata EINA_UNUSED, void *image, const Eina_Rw_Slice *slice)
{
Evas_GL_Image_Data_Map *map;
Evas_GL_Image *im = image;
Eina_Bool found = EINA_FALSE;
if (!im || !memory)
if (!im || !slice)
return EINA_FALSE;
EINA_INLIST_FOREACH(im->maps, map)
{
if ((map->ptr == memory) && (map->size == length))
if ((map->slice.len == slice->len) && (map->slice.mem == slice->mem))
{
found = EINA_TRUE;
if (map->im)
found = pfunc.image_data_unmap(NULL, map->im, memory, length);
found = pfunc.image_data_unmap(NULL, map->im, slice);
if (found)
{
if (im->im && im->tex &&
@ -2875,12 +2872,12 @@ eng_image_data_unmap(void *engdata EINA_UNUSED, void *image, void *memory, int l
}
}
ERR("failed to unmap region %p (%u bytes)", memory, length);
ERR("failed to unmap region %p (%zu bytes)", slice->mem, slice->len);
return EINA_FALSE;
}
static int
eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, void **maps, int *lengths)
eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, const Eina_Rw_Slice **slices)
{
Evas_GL_Image_Data_Map *map;
const Evas_GL_Image *im = image;
@ -2888,15 +2885,11 @@ eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, void **map
if (!im) return -1;
if (!maps || !lengths)
if (!slices)
return eina_inlist_count(im->maps);
EINA_INLIST_FOREACH(im->maps, map)
{
maps[k] = map->ptr;
lengths[k] = map->size;
k++;
}
slices[k++] = &map->slice;
return k;
}

View File

@ -1453,10 +1453,9 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
return im;
}
static void *
static const Eina_Rw_Slice *
eng_image_data_map(void *engdata EINA_UNUSED, void **image,
int *length, int *stride,
int x, int y, int w, int h,
int *stride, int x, int y, int w, int h,
Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode)
{
Eina_Bool cow = EINA_FALSE, to_write = EINA_FALSE;
@ -1592,8 +1591,8 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
map->rw = rw;
map->mode = mode;
map->baseptr = data;
map->ptr = map->baseptr + dst_offset;
map->size = dst_len;
map->slice.mem = map->baseptr + dst_offset;
map->slice.len = dst_len;
map->stride = dst_stride;
}
else
@ -1607,8 +1606,8 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
if (!map) return NULL;
map->baseptr = im->image.data8;
map->ptr = im->image.data8 + src_offset;
map->size = end_offset - src_offset;
map->slice.mem = im->image.data8 + src_offset;
map->slice.len = end_offset - src_offset;
}
else
{
@ -1626,8 +1625,8 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
map->allocated = EINA_TRUE;
map->baseptr = data;
map->ptr = data;
map->size = size;
map->slice.mem = data;
map->slice.len = size;
}
map->cspace = cspace;
map->rx = x;
@ -1639,9 +1638,8 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
im->maps = (RGBA_Image_Data_Map *)
eina_inlist_prepend(EINA_INLIST_GET(im->maps), EINA_INLIST_GET(map));
if (length) *length = map->size;
if (stride) *stride = map->stride;
return map->ptr;
return &map->slice;
}
static void
@ -1658,13 +1656,13 @@ _image_data_commit(RGBA_Image *im, RGBA_Image_Data_Map *map)
if (dst_stride == (int) map->stride)
{
DBG("unmap commit: single memcpy");
memcpy(dst, map->ptr, dst_stride * map->rh);
memcpy(dst, map->slice.bytes, dst_stride * map->rh);
}
else
{
DBG("unmap commit: multiple memcpy");
for (int k = 0; k < dst_stride; k++)
memcpy(dst + k * dst_stride, map->ptr + k * dst_stride, dst_stride);
memcpy(dst + k * dst_stride, map->slice.bytes + k * dst_stride, dst_stride);
}
}
else
@ -1678,7 +1676,7 @@ _image_data_commit(RGBA_Image *im, RGBA_Image_Data_Map *map)
DBG("unmap commit: convert func (%p)", cs_func);
if (can_region)
{
cs_func(dst, map->ptr, map->rw, map->rh, map->stride, dst_stride,
cs_func(dst, map->slice.mem, map->rw, map->rh, map->stride, dst_stride,
ie->flags.alpha, map->cspace, ie->space);
}
else
@ -1690,17 +1688,17 @@ _image_data_commit(RGBA_Image *im, RGBA_Image_Data_Map *map)
}
static Eina_Bool
eng_image_data_unmap(void *engdata EINA_UNUSED, void *image, void *memory, int length)
eng_image_data_unmap(void *engdata EINA_UNUSED, void *image, const Eina_Rw_Slice *slice)
{
RGBA_Image_Data_Map *map;
RGBA_Image *im = image;
if (!im || !memory)
if (!im || !slice)
return EINA_FALSE;
EINA_INLIST_FOREACH(EINA_INLIST_GET(im->maps), map)
{
if ((map->ptr == memory) && (map->size == length))
if ((map->slice.len == slice->len) && (map->slice.mem == slice->mem))
{
if (map->allocated)
{
@ -1715,12 +1713,12 @@ eng_image_data_unmap(void *engdata EINA_UNUSED, void *image, void *memory, int l
}
}
ERR("failed to unmap region %p (%u bytes)", memory, length);
ERR("failed to unmap region %p (%zu bytes)", slice->mem, slice->len);
return EINA_FALSE;
}
static int
eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, void **maps, int *lengths)
eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, const Eina_Rw_Slice **slices)
{
RGBA_Image_Data_Map *map;
const RGBA_Image *im = image;
@ -1728,15 +1726,11 @@ eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, void **map
if (!im) return -1;
if (!maps || !lengths)
if (!slices)
return eina_inlist_count(EINA_INLIST_GET(im->maps));
EINA_INLIST_FOREACH(EINA_INLIST_GET(im->maps), map)
{
maps[k] = map->ptr;
lengths[k] = map->size;
k++;
}
slices[k++] = &map->slice;
return k;
}