Evas proxy: Implement buffer map/unmap

This commit is contained in:
Jean-Philippe Andre 2016-03-25 17:46:41 +09:00
parent 22353e31e1
commit cb93c26db7
6 changed files with 124 additions and 27 deletions

View File

@ -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;

View File

@ -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
*/

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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;