diff --git a/src/lib/evas/canvas/efl_canvas_image.c b/src/lib/evas/canvas/efl_canvas_image.c index ee32e61697..73bffcec61 100644 --- a/src/lib/evas/canvas/efl_canvas_image.c +++ b/src/lib/evas/canvas/efl_canvas_image.c @@ -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; diff --git a/src/lib/evas/canvas/efl_canvas_proxy.c b/src/lib/evas/canvas/efl_canvas_proxy.c index 47f5a0158e..f0562e2d26 100644 --- a/src/lib/evas/canvas/efl_canvas_proxy.c +++ b/src/lib/evas/canvas/efl_canvas_proxy.c @@ -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; diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h index 77158ab434..8d66ad87f7 100644 --- a/src/lib/evas/include/evas_common_private.h +++ b/src/lib/evas/include/evas_common_private.h @@ -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; diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 845c7c41f9..7e4c2e4acd 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -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); diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index c390e3370b..23eddef590 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -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; diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index b6e08afcc8..e48dd259c7 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -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; } diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index b684cf0e77..17f9968e5b 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -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; }