diff --git a/src/lib/evas/canvas/efl_canvas_image.c b/src/lib/evas/canvas/efl_canvas_image.c index 45e5d50fae..66d7b8c9ea 100644 --- a/src/lib/evas/canvas/efl_canvas_image.c +++ b/src/lib/evas/canvas/efl_canvas_image.c @@ -762,34 +762,39 @@ _efl_canvas_image_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED, { Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS); - int len = 0, str = 0; + int len = 0, s = 0, width = 0, height = 0; void *data = NULL; if (!ENFN->image_data_map) goto end; // not implemented - if (!o->engine_data) + if (o->engine_data) + ENFN->image_size_get(ENDT, o->engine_data, &width, &height); + + if (!o->engine_data || !width || !height) { - if (o->cur->u.file) - ERR("image is not loaded yet"); + // TODO: Create a map_surface and draw there. Maybe. This could + // depend on the flags (eg. add a "force render" flag). + WRN("This image image has no data available"); goto end; } - if (!w) w = o->cur->image.w; - if (!h) h = o->cur->image.h; + if (!w) w = width; + if (!h) h = height; - if ((x < 0) || (y < 0) || ((x + (int) w) > (int) o->cur->image.w) || ((y + (int) h) > (int) o->cur->image.h)) + if ((x < 0) || (y < 0) || ((x + w) > width) || ((y + h) > height)) { ERR("Invalid map dimensions: %dx%d +%d,%d. Image is %dx%d.", - w, h, x, y, o->cur->image.w, o->cur->image.h); + w, h, x, y, width, height); goto end; } - data = ENFN->image_data_map(ENDT, &o->engine_data, &len, &str, x, y, w, h, cspace, mode); + 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); end: if (length) *length = len; - if (stride) *stride = str; + if (stride) *stride = s; return data; } @@ -803,7 +808,7 @@ _efl_canvas_image_efl_gfx_buffer_buffer_unmap(Eo *eo_obj, void *_pd EINA_UNUSED, if (!ENFN->image_data_unmap || !o->engine_data) return EINA_FALSE; - if (!ENFN->image_data_unmap(ENDT, &o->engine_data, data, length)) + if (!ENFN->image_data_unmap(ENDT, o->engine_data, data, length)) 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 9648027424..27d8170a84 100644 --- a/src/lib/evas/canvas/efl_canvas_proxy.c +++ b/src/lib/evas/canvas/efl_canvas_proxy.c @@ -57,7 +57,7 @@ _evas_image_proxy_source_set(Eo *eo_obj, Evas_Object *eo_src) } EOLIAN static Eina_Bool -_efl_canvas_proxy_source_set(Eo *eo_obj, void *pd EINA_UNUSED, Evas_Object *eo_src) +_efl_canvas_proxy_source_set(Eo *eo_obj, void *_pd EINA_UNUSED, Evas_Object *eo_src) { return _evas_image_proxy_source_set(eo_obj, eo_src); } @@ -70,7 +70,7 @@ _evas_image_proxy_source_get(const Eo *eo_obj) } EOLIAN static Evas_Object * -_efl_canvas_proxy_source_get(Eo *eo_obj, void *pd EINA_UNUSED) +_efl_canvas_proxy_source_get(Eo *eo_obj, void *_pd EINA_UNUSED) { return _evas_image_proxy_source_get(eo_obj); } @@ -94,7 +94,7 @@ _evas_image_proxy_source_clip_set(Eo *eo_obj, Eina_Bool source_clip) } EOLIAN static void -_efl_canvas_proxy_source_clip_set(Eo *eo_obj, void *pd EINA_UNUSED, Eina_Bool source_clip) +_efl_canvas_proxy_source_clip_set(Eo *eo_obj, void *_pd EINA_UNUSED, Eina_Bool source_clip) { return _evas_image_proxy_source_clip_set(eo_obj, source_clip); } @@ -107,7 +107,7 @@ _evas_image_proxy_source_clip_get(const Eo *eo_obj) } EOLIAN static Eina_Bool -_efl_canvas_proxy_source_clip_get(Eo *eo_obj, void *pd EINA_UNUSED) +_efl_canvas_proxy_source_clip_get(Eo *eo_obj, void *_pd EINA_UNUSED) { return _evas_image_proxy_source_clip_get(eo_obj); } @@ -131,7 +131,7 @@ _evas_image_proxy_source_events_set(Eo *eo_obj, Eina_Bool source_events) } EOLIAN static void -_efl_canvas_proxy_source_events_set(Eo *eo_obj, void *pd EINA_UNUSED, Eina_Bool repeat) +_efl_canvas_proxy_source_events_set(Eo *eo_obj, void *_pd EINA_UNUSED, Eina_Bool repeat) { return _evas_image_proxy_source_events_set(eo_obj, repeat); } @@ -144,7 +144,7 @@ _evas_image_proxy_source_events_get(const Eo *eo_obj) } EOLIAN static Eina_Bool -_efl_canvas_proxy_source_events_get(Eo *eo_obj, void *pd EINA_UNUSED) +_efl_canvas_proxy_source_events_get(Eo *eo_obj, void *_pd EINA_UNUSED) { return _evas_image_proxy_source_events_get(eo_obj); } @@ -241,6 +241,92 @@ _evas_image_proxy_set(Evas_Object *eo_proxy, Evas_Object *eo_src) EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_src_write); } +static inline void * +_proxy_image_get(Evas_Image_Data *o) +{ + Evas_Object_Protected_Data *source = eo_data_scope_get(o->cur->source, EVAS_OBJECT_CLASS); + Evas_Image_Data *source_img = NULL; + + if (!source) + return NULL; + + if (eo_isa(o->cur->source, EVAS_IMAGE_CLASS)) + source_img = eo_data_scope_get(o->cur->source, EVAS_IMAGE_CLASS); + + if (source_img) + return source_img->engine_data; + else + return source->proxy->surface; +} + +EOLIAN static void * +_efl_canvas_proxy_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED, + int *length, + Efl_Gfx_Buffer_Access_Mode mode, + int x, int y, int w, int h, + Efl_Gfx_Colorspace cspace, int *stride) +{ + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS); + int len = 0, s = 0, width = 0, height = 0; + void *image, *data = NULL; + + if (!ENFN->image_data_map) + goto end; // not implemented + + if (mode & EFL_GFX_BUFFER_ACCESS_MODE_WRITE) + { + ERR("invalid map mode for Proxy object"); + goto end; + } + + image = _proxy_image_get(o); + if (image) + ENFN->image_size_get(ENDT, image, &width, &height); + + if (!image || !width || !height) + { + // TODO: Create a map_surface and draw there. Maybe. This could + // depend on the flags (eg. add a "force render" flag). + WRN("This proxy image has no data available"); + goto end; + } + + if (!w) w = width; + if (!h) h = height; + + if ((x < 0) || (y < 0) || ((x + w) > width) || ((y + h) > height)) + { + ERR("Invalid map dimensions: %dx%d +%d,%d. Image is %dx%d.", + w, h, x, y, width, height); + 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); + +end: + if (length) *length = len; + if (stride) *stride = s; + return data; +} + +EOLIAN static Eina_Bool +_efl_canvas_proxy_efl_gfx_buffer_buffer_unmap(Eo *eo_obj, void *_pd EINA_UNUSED, + void *data, int length) +{ + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS); + + if (!ENFN->image_data_unmap || !o->engine_data) + return EINA_FALSE; + + if (!ENFN->image_data_unmap(ENDT, o->engine_data, data, length)) + return EINA_FALSE; + + return EINA_TRUE; +} + /* Some moron just set a proxy on a proxy. * Give them some pixels. A random color */ diff --git a/src/lib/evas/canvas/efl_canvas_proxy.eo b/src/lib/evas/canvas/efl_canvas_proxy.eo index 2c6f6b3d8a..6c42aa74ee 100644 --- a/src/lib/evas/canvas/efl_canvas_proxy.eo +++ b/src/lib/evas/canvas/efl_canvas_proxy.eo @@ -1,4 +1,4 @@ -class Efl.Canvas.Proxy (Evas.Image) +class Efl.Canvas.Proxy (Evas.Image, Efl.Gfx.Buffer) { [[Low-level proxy image object. @@ -73,5 +73,7 @@ class Efl.Canvas.Proxy (Evas.Image) } } implements { + Efl.Gfx.Buffer.buffer_map; + Efl.Gfx.Buffer.buffer_unmap; } } diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 92ef4b5055..4a8b37ae79 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1361,9 +1361,10 @@ struct _Evas_Func Evas_Colorspace (*image_file_colorspace_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 */ 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, void *image, void **maps, int *lengths); + 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); 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_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index cb25114bd1..c46fb7511e 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -2770,6 +2770,11 @@ module_open(Evas_Module *em) return 0; } + /* disable map/unmap for now as it's not implemented */ + pfunc.image_data_map = NULL; + pfunc.image_data_unmap = NULL; + pfunc.image_data_maps_get = NULL; + ector_init(); ector_glsym_set(dlsym, RTLD_DEFAULT); diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 1d43e78266..2d50fb3197 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -1666,17 +1666,15 @@ _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, void *memory, int length) { RGBA_Image_Data_Map *map; - RGBA_Image *im; + RGBA_Image *im = image; Eina_Bool found = EINA_FALSE; - if (!image || !*image || !memory) + if (!im || !memory) return EINA_FALSE; - im = *image; - EINA_INLIST_FOREACH(EINA_INLIST_GET(im->maps), map) { if ((map->ptr == memory) && (map->size == length)) @@ -1702,10 +1700,10 @@ eng_image_data_unmap(void *engdata EINA_UNUSED, void **image, void *memory, int } static int -eng_image_data_maps_get(void *engdata EINA_UNUSED, void *image, void **maps, int *lenghts) +eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, void **maps, int *lenghts) { RGBA_Image_Data_Map *map; - RGBA_Image *im = image; + const RGBA_Image *im = image; int k = 0; if (!im) return -1;