forked from enlightenment/efl
evas: use eina_file_virtualize() in evas_object_memfile_set().
NOTE: I am tempted to mark evas_object_memfile_set() as deprecated due to the forced memcpy it introduced and the fact that it is now a 3 lines of code to do the same in a more efficient way.
This commit is contained in:
parent
f2de8970a1
commit
e0b8e3f5e7
|
@ -1,6 +1,7 @@
|
|||
2013-07-31 Cedric Bail
|
||||
|
||||
* Eina: add eina_file_virtualize() and eina_file_virtual().
|
||||
* Evas: use eina_file_virtualize() for evas_object_image_memfile_set().
|
||||
|
||||
2013-07-25 ChunEon Park (Hermet)
|
||||
|
||||
|
|
1
NEWS
1
NEWS
|
@ -55,6 +55,7 @@ Additions:
|
|||
- Add multiple font draws support to engines
|
||||
- Add Cserve2 scalecache support
|
||||
- Add evas_object_image_source_clip_set()/get()
|
||||
- Use eina_file_virtualize() for evas_object_image_memfile_set().
|
||||
* Ecore_X:
|
||||
- Add window profile support.
|
||||
ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED
|
||||
|
|
|
@ -5524,7 +5524,6 @@ extern EAPI Eo_Op EVAS_OBJ_IMAGE_BASE_ID;
|
|||
|
||||
enum
|
||||
{
|
||||
EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET,
|
||||
EVAS_OBJ_IMAGE_SUB_ID_FILE_SET,
|
||||
EVAS_OBJ_IMAGE_SUB_ID_MMAP_SET,
|
||||
EVAS_OBJ_IMAGE_SUB_ID_FILE_GET,
|
||||
|
@ -5607,21 +5606,6 @@ enum
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @def evas_obj_image_memfile_set
|
||||
* @since 1.8
|
||||
*
|
||||
* Sets the data for an image from memory to be loaded
|
||||
*
|
||||
* @param[in] data in
|
||||
* @param[in] size in
|
||||
* @param[in] format in
|
||||
* @param[in] key in
|
||||
*
|
||||
* @see evas_object_image_memfile_set
|
||||
*/
|
||||
#define evas_obj_image_memfile_set(data, size, format, key) EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET), EO_TYPECHECK(void *, data), EO_TYPECHECK(int, size), EO_TYPECHECK(char *, format), EO_TYPECHECK(char *, key)
|
||||
|
||||
/**
|
||||
* @def evas_obj_image_file_set
|
||||
* @since 1.8
|
||||
|
|
|
@ -64,9 +64,6 @@ struct _Evas_Object_Image_Pixels
|
|||
} func;
|
||||
|
||||
Evas_Video_Surface video;
|
||||
|
||||
const char *tmpf;
|
||||
int tmpf_fd;
|
||||
};
|
||||
|
||||
struct _Evas_Object_Image_State
|
||||
|
@ -181,8 +178,6 @@ static void _proxy_unset(Evas_Object *proxy, Evas_Object_Protected_Data *obj, Ev
|
|||
static void _proxy_set(Evas_Object *proxy, Evas_Object *src);
|
||||
static void _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface, int x, int y, Eina_Bool do_async);
|
||||
|
||||
static void _cleanup_tmpf(Evas_Object *eo_obj);
|
||||
|
||||
static const Evas_Object_Func object_func =
|
||||
{
|
||||
/* methods (compulsory) */
|
||||
|
@ -214,7 +209,7 @@ static const Evas_Object_Image_Load_Opts default_load_opts = {
|
|||
};
|
||||
|
||||
static const Evas_Object_Image_Pixels default_pixels = {
|
||||
NULL, { NULL, NULL }, { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, NULL, -1
|
||||
NULL, { NULL, NULL }, { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static const Evas_Object_Image_State default_state = {
|
||||
|
@ -281,7 +276,6 @@ _evas_object_image_cleanup(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
|
|||
o->engine_data,
|
||||
eo_obj);
|
||||
}
|
||||
if (o->pixels->tmpf) _cleanup_tmpf(eo_obj);
|
||||
if (o->cur->source) _proxy_unset(eo_obj, obj, o);
|
||||
}
|
||||
|
||||
|
@ -374,139 +368,19 @@ evas_object_image_filled_add(Evas *eo_e)
|
|||
return eo_obj;
|
||||
}
|
||||
|
||||
static void
|
||||
_cleanup_tmpf(Evas_Object *eo_obj)
|
||||
{
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
Evas_Object_Image *o;
|
||||
|
||||
o = eo_data_scope_get(eo_obj, MY_CLASS);
|
||||
if (!o->pixels->tmpf) return;
|
||||
#ifdef __linux__
|
||||
#else
|
||||
unlink(o->pixels->tmpf);
|
||||
#endif
|
||||
EINA_COW_PIXEL_WRITE_BEGIN(o, pixels)
|
||||
{
|
||||
if (pixels->tmpf_fd >= 0) close(pixels->tmpf_fd);
|
||||
eina_stringshare_del(pixels->tmpf);
|
||||
pixels->tmpf_fd = -1;
|
||||
pixels->tmpf = NULL;
|
||||
}
|
||||
EINA_COW_PIXEL_WRITE_END(o, pixels);
|
||||
#else
|
||||
(void) eo_obj;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
_create_tmpf(Evas_Object *eo_obj, void *data, int size, char *format EINA_UNUSED)
|
||||
{
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
Evas_Object_Image *o;
|
||||
char buf[PATH_MAX];
|
||||
void *dst;
|
||||
int fd = -1;
|
||||
|
||||
o = eo_data_scope_get(eo_obj, MY_CLASS);
|
||||
#ifdef __linux__
|
||||
snprintf(buf, sizeof(buf), "/dev/shm/.evas-tmpf-%i-%p-%i-XXXXXX",
|
||||
(int)getpid(), data, (int)size);
|
||||
fd = mkstemp(buf);
|
||||
#endif
|
||||
if (fd < 0)
|
||||
{
|
||||
const char *tmpdir = getenv("TMPDIR");
|
||||
|
||||
if (!tmpdir)
|
||||
{
|
||||
tmpdir = getenv("TMP");
|
||||
if (!tmpdir)
|
||||
{
|
||||
tmpdir = getenv("TEMP");
|
||||
if (!tmpdir) tmpdir = "/tmp";
|
||||
}
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%s/.evas-tmpf-%i-%p-%i-XXXXXX",
|
||||
tmpdir, (int)getpid(), data, (int)size);
|
||||
fd = mkstemp(buf);
|
||||
if (fd < 0) return;
|
||||
}
|
||||
if (ftruncate(fd, size) < 0)
|
||||
{
|
||||
unlink(buf);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
#ifdef __linux__
|
||||
unlink(buf);
|
||||
#endif
|
||||
|
||||
eina_mmap_safety_enabled_set(EINA_TRUE);
|
||||
|
||||
dst = mmap(NULL, size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
fd, 0);
|
||||
if (dst == MAP_FAILED)
|
||||
{
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
EINA_COW_PIXEL_WRITE_BEGIN(o, pixels)
|
||||
pixels->tmpf_fd = fd;
|
||||
EINA_COW_PIXEL_WRITE_END(o, pixels);
|
||||
#ifdef __linux__
|
||||
snprintf(buf, sizeof(buf), "/proc/%li/fd/%i", (long)getpid(), fd);
|
||||
#endif
|
||||
EINA_COW_PIXEL_WRITE_BEGIN(o, pixels)
|
||||
pixels->tmpf = eina_stringshare_add(buf);
|
||||
EINA_COW_PIXEL_WRITE_END(o, pixels);
|
||||
memcpy(dst, data, size);
|
||||
munmap(dst, size);
|
||||
#else
|
||||
(void) eo_obj;
|
||||
(void) data;
|
||||
(void) size;
|
||||
(void) format;
|
||||
#endif
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_object_image_memfile_set(Evas_Object *eo_obj, void *data, int size, char *format, char *key)
|
||||
evas_object_image_memfile_set(Evas_Object *eo_obj, void *data, int size, char *format EINA_UNUSED, char *key)
|
||||
{
|
||||
Eina_File *f;
|
||||
|
||||
MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);
|
||||
return;
|
||||
MAGIC_CHECK_END();
|
||||
eo_do(eo_obj, evas_obj_image_memfile_set(data, size, format, key));
|
||||
}
|
||||
|
||||
static void
|
||||
_image_memfile_set(Eo *eo_obj, void *_pd, va_list *list)
|
||||
{
|
||||
Evas_Object_Image *o = _pd;
|
||||
|
||||
void *data = va_arg(*list, void *);
|
||||
int size = va_arg(*list, int);
|
||||
char *format = va_arg(*list, char*);
|
||||
char *key = va_arg(*list, char*);
|
||||
|
||||
_cleanup_tmpf(eo_obj);
|
||||
evas_object_image_file_set(eo_obj, NULL, NULL);
|
||||
// invalidate the cache effectively
|
||||
evas_object_image_alpha_set(eo_obj, !o->cur->has_alpha);
|
||||
evas_object_image_alpha_set(eo_obj, o->cur->has_alpha);
|
||||
|
||||
if ((size < 1) || (!data)) return;
|
||||
|
||||
_create_tmpf(eo_obj, data, size, format);
|
||||
evas_object_image_file_set(eo_obj, o->pixels->tmpf, key);
|
||||
if (!o->engine_data)
|
||||
{
|
||||
ERR("unable to load '%s' from memory", o->pixels->tmpf);
|
||||
_cleanup_tmpf(eo_obj);
|
||||
return;
|
||||
}
|
||||
f = eina_file_virtualize(data, size, EINA_TRUE);
|
||||
if (!f) return ;
|
||||
eo_do(eo_obj, evas_obj_image_mmap_set(f, key));
|
||||
eina_file_close(f);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -635,7 +509,6 @@ _image_mmap_set(Eo *eo_obj, void *_pd, va_list *list)
|
|||
Eina_File *f = va_arg(*list, Eina_File *);
|
||||
const char *key = va_arg(*list, const char*);
|
||||
|
||||
if (o->pixels->tmpf) _cleanup_tmpf(eo_obj);
|
||||
if (o->cur->u.f == f)
|
||||
{
|
||||
if ((!o->cur->key) && (!key))
|
||||
|
@ -672,7 +545,6 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list)
|
|||
const char *file = va_arg(*list, const char*);
|
||||
const char *key = va_arg(*list, const char*);
|
||||
|
||||
if ((o->pixels->tmpf) && (file != o->pixels->tmpf)) _cleanup_tmpf(eo_obj);
|
||||
if ((o->cur->u.file) && (file) && (!strcmp(o->cur->u.file, file)))
|
||||
{
|
||||
if ((!o->cur->key) && (!key))
|
||||
|
@ -3676,7 +3548,6 @@ evas_object_image_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
|
|||
Eina_Rectangle *r;
|
||||
|
||||
/* free obj */
|
||||
_cleanup_tmpf(eo_obj);
|
||||
if (o->cur->u.file && !o->cur->mmaped_source) eina_stringshare_del(o->cur->u.file);
|
||||
if (o->cur->key) eina_stringshare_del(o->cur->key);
|
||||
if (o->cur->source) _proxy_unset(eo_obj, obj, o);
|
||||
|
@ -5327,7 +5198,6 @@ _class_constructor(Eo_Class *klass)
|
|||
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
|
||||
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
|
||||
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DBG_INFO_GET), _dbg_info_get),
|
||||
EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET), _image_memfile_set),
|
||||
EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_FILE_SET), _image_file_set),
|
||||
EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_MMAP_SET), _image_mmap_set),
|
||||
EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_FILE_GET), _image_file_get),
|
||||
|
@ -5406,7 +5276,6 @@ _class_constructor(Eo_Class *klass)
|
|||
}
|
||||
|
||||
static const Eo_Op_Description op_desc[] = {
|
||||
EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET, "Sets the data for an image from memory to be loaded"),
|
||||
EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_FILE_SET, "Set the source file from where an image object must fetch the real"),
|
||||
EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_MMAP_SET, "Set the source mmaped file from where an image object must fetch the real"),
|
||||
EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_FILE_GET, "Retrieve the source file from where an image object is to fetch the"),
|
||||
|
|
Loading…
Reference in New Issue