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)
{ {
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"); ERR("can not set pixels when there are open memory maps");
return EINA_FALSE; 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_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); Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
int len = 0, s = 0, width = 0, height = 0; int s = 0, width = 0, height = 0;
void *data = NULL; const Eina_Rw_Slice *slice = NULL;
if (!ENFN->image_data_map) if (!ENFN->image_data_map)
goto end; // not implemented 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; goto end;
} }
data = ENFN->image_data_map(ENDT, &o->engine_data, &len, &s, x, y, w, h, cspace, mode); slice = ENFN->image_data_map(ENDT, &o->engine_data, &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); 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: end:
if (length) *length = len; if (length) *length = slice->len;
if (stride) *stride = s; if (stride) *stride = s;
return data; return slice->mem;
} }
EOLIAN static Eina_Bool 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_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); 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) if (!ENFN->image_data_unmap || !o->engine_data)
return EINA_FALSE; 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_FALSE;
return EINA_TRUE; 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_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); Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
int len = 0, s = 0, width = 0, height = 0; int len = 0, s = 0, width = 0, height = 0;
const Eina_Rw_Slice *slice = NULL;
void *image, *data = NULL; void *image, *data = NULL;
if (!ENFN->image_data_map) 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; goto end;
} }
data = ENFN->image_data_map(ENDT, &image, &len, &s, x, y, w, h, cspace, mode); slice = ENFN->image_data_map(ENDT, &image, &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); 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: end:
if (length) *length = len; 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_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); 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) if (!ENFN->image_data_unmap || !o->engine_data)
return EINA_FALSE; 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_FALSE;
return EINA_TRUE; return EINA_TRUE;

View File

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

View File

@ -1369,9 +1369,9 @@ struct _Evas_Func
Eina_Bool (*image_can_region_get) (void *data, void *image); Eina_Bool (*image_can_region_get) (void *data, void *image);
/* image data map/unmap: direct or indirect access to pixels data */ /* 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); 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, void *map, int length); Eina_Bool (*image_data_unmap) (void *data, void *image, const Eina_Rw_Slice *slice);
int (*image_data_maps_get) (void *data, const void *image, void **maps, int *lengths); 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); int (*image_native_init) (void *data, Evas_Native_Surface_Type type);
void (*image_native_shutdown) (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; EINA_INLIST;
Evas_GL_Texture *tex; // one or the other Evas_GL_Texture *tex; // one or the other
RGBA_Image *im; // one or the other RGBA_Image *im; // one or the other
unsigned char *ptr; Eina_Rw_Slice slice;
int size, stride; // in bytes int stride; // in bytes
int rx, ry, rw, rh; // actual map region int rx, ry, rw, rh; // actual map region
Evas_Colorspace cspace; Evas_Colorspace cspace;
Efl_Gfx_Buffer_Access_Mode mode; 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, eng_image_data_map(void *engdata EINA_UNUSED, void **image,
int *length, int *stride, int *stride, int x, int y, int w, int h,
int x, int y, int w, int h,
Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode) Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode)
{ {
Eina_Bool cow = EINA_FALSE, to_write = EINA_FALSE; Eina_Bool cow = EINA_FALSE, to_write = EINA_FALSE;
Evas_GL_Image_Data_Map *map = NULL; Evas_GL_Image_Data_Map *map = NULL;
const Eina_Rw_Slice *slice = NULL;
Evas_GL_Image *im; Evas_GL_Image *im;
void *ret;
EINA_SAFETY_ON_FALSE_RETURN_VAL(image && *image, NULL); EINA_SAFETY_ON_FALSE_RETURN_VAL(image && *image, NULL);
im = *image; im = *image;
@ -2816,12 +2815,12 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
if (im->im) if (im->im)
{ {
int len = 0, strid = 0; int strid = 0;
// Call sw generic implementation. Should work for simple cases. // Call sw generic implementation. Should work for simple cases.
ret = pfunc.image_data_map(NULL, (void **) &im->im, &len, &strid, slice = pfunc.image_data_map(NULL, (void **) &im->im, &strid,
x, y, w, h, cspace, mode); x, y, w, h, cspace, mode);
if (ret) if (slice)
{ {
map = calloc(1, sizeof(*map)); map = calloc(1, sizeof(*map));
map->cspace = cspace; map->cspace = cspace;
@ -2830,15 +2829,13 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
map->rw = w; map->rw = w;
map->rh = h; map->rh = h;
map->mode = mode; map->mode = mode;
map->size = len; map->slice = *slice;
map->stride = strid; map->stride = strid;
map->im = im->im; // ref? map->im = im->im; // ref?
map->ptr = ret;
im->maps = eina_inlist_prepend(im->maps, EINA_INLIST_GET(map)); im->maps = eina_inlist_prepend(im->maps, EINA_INLIST_GET(map));
} }
if (length) *length = len;
if (stride) *stride = strid; if (stride) *stride = strid;
return ret; return &map->slice;
} }
// TODO: glReadPixels from FBO if possible // TODO: glReadPixels from FBO if possible
@ -2847,22 +2844,22 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
} }
static Eina_Bool 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_Data_Map *map;
Evas_GL_Image *im = image; Evas_GL_Image *im = image;
Eina_Bool found = EINA_FALSE; Eina_Bool found = EINA_FALSE;
if (!im || !memory) if (!im || !slice)
return EINA_FALSE; return EINA_FALSE;
EINA_INLIST_FOREACH(im->maps, map) 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; found = EINA_TRUE;
if (map->im) 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 (found)
{ {
if (im->im && im->tex && 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; return EINA_FALSE;
} }
static int 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; Evas_GL_Image_Data_Map *map;
const Evas_GL_Image *im = image; 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 (!im) return -1;
if (!maps || !lengths) if (!slices)
return eina_inlist_count(im->maps); return eina_inlist_count(im->maps);
EINA_INLIST_FOREACH(im->maps, map) EINA_INLIST_FOREACH(im->maps, map)
{ slices[k++] = &map->slice;
maps[k] = map->ptr;
lengths[k] = map->size;
k++;
}
return k; return k;
} }

View File

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