forked from enlightenment/efl
evas_object_image: save EVAS_IMAGE_CONTENT_HINT_DYNAMIC image
Summary: evas_gl_common_image_content_hint_set makes RGBA_Image NULL if content hint is EVAS_IMAGE_CONTENT_HINT_DYNAMIC with 'sec_tbm_surface' and 'egl_tbm_ext'. efl_file_save(_efl_canvas_image_internal_efl_file_save_save) does not work in this case because ENFN->image_data_direct_get returns FALSE. This patch makes ENFN->image_data_direct_get work but you need to free its returned data after using it. Reviewers: Hermet, jsuya Reviewed By: Hermet Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8516
This commit is contained in:
parent
c380c496dc
commit
c3c9fed7d9
|
@ -722,7 +722,8 @@ _efl_canvas_image_efl_gfx_buffer_buffer_managed_get(Eo *eo_obj, void *_pd EINA_U
|
||||||
if (!o->buffer_data_set || !o->engine_data || !ENFN->image_data_direct_get)
|
if (!o->buffer_data_set || !o->engine_data || !ENFN->image_data_direct_get)
|
||||||
return slice;
|
return slice;
|
||||||
|
|
||||||
ENFN->image_data_direct_get(ENC, o->engine_data, plane, &slice, &cspace, EINA_FALSE);
|
ENFN->image_data_direct_get(ENC, o->engine_data, plane, &slice, &cspace, EINA_FALSE, NULL);
|
||||||
|
|
||||||
return slice;
|
return slice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -880,6 +880,7 @@ _efl_canvas_image_internal_efl_file_save_save(const Eo *eo_obj, Evas_Image_Data
|
||||||
Evas_Colorspace want_cspace = EVAS_COLORSPACE_ARGB8888;
|
Evas_Colorspace want_cspace = EVAS_COLORSPACE_ARGB8888;
|
||||||
Evas_Object_Protected_Data *obj;
|
Evas_Object_Protected_Data *obj;
|
||||||
Eina_Bool unmap_it = EINA_FALSE;
|
Eina_Bool unmap_it = EINA_FALSE;
|
||||||
|
Eina_Bool tofree = EINA_FALSE;
|
||||||
int imagew, imageh, uvw, uvh;
|
int imagew, imageh, uvw, uvh;
|
||||||
Eina_Rw_Slice slice = {};
|
Eina_Rw_Slice slice = {};
|
||||||
DATA32 *data = NULL;
|
DATA32 *data = NULL;
|
||||||
|
@ -932,7 +933,7 @@ _efl_canvas_image_internal_efl_file_save_save(const Eo *eo_obj, Evas_Image_Data
|
||||||
Evas_Colorspace cs;
|
Evas_Colorspace cs;
|
||||||
Eina_Slice sl;
|
Eina_Slice sl;
|
||||||
|
|
||||||
ok = ENFN->image_data_direct_get(ENC, pixels, 0, &sl, &cs, EINA_TRUE);
|
ok = ENFN->image_data_direct_get(ENC, pixels, 0, &sl, &cs, EINA_TRUE, &tofree);
|
||||||
if (ok && (cs == want_cspace))
|
if (ok && (cs == want_cspace))
|
||||||
data = (DATA32 *)sl.mem;
|
data = (DATA32 *)sl.mem;
|
||||||
}
|
}
|
||||||
|
@ -966,6 +967,8 @@ _efl_canvas_image_internal_efl_file_save_save(const Eo *eo_obj, Evas_Image_Data
|
||||||
if (unmap_it)
|
if (unmap_it)
|
||||||
ENFN->image_data_unmap(ENC, pixels, &slice);
|
ENFN->image_data_unmap(ENC, pixels, &slice);
|
||||||
|
|
||||||
|
if (tofree) free(data);
|
||||||
|
|
||||||
if (!ok) ERR("Image save failed.");
|
if (!ok) ERR("Image save failed.");
|
||||||
return ok;
|
return ok;
|
||||||
|
|
||||||
|
|
|
@ -1336,7 +1336,7 @@ struct _Evas_Func
|
||||||
void *(*image_dirty_region) (void *engine, void *image, int x, int y, int w, int h);
|
void *(*image_dirty_region) (void *engine, void *image, int x, int y, int w, int h);
|
||||||
void *(*image_data_get) (void *engine, void *image, int to_write, DATA32 **image_data, int *err, Eina_Bool *tofree);
|
void *(*image_data_get) (void *engine, void *image, int to_write, DATA32 **image_data, int *err, Eina_Bool *tofree);
|
||||||
void *(*image_data_put) (void *engine, void *image, DATA32 *image_data);
|
void *(*image_data_put) (void *engine, void *image, DATA32 *image_data);
|
||||||
Eina_Bool (*image_data_direct_get) (void *engine, void *image, int plane, Eina_Slice *slice, Evas_Colorspace *cspace, Eina_Bool load);
|
Eina_Bool (*image_data_direct_get) (void *engine, void *image, int plane, Eina_Slice *slice, Evas_Colorspace *cspace, Eina_Bool load, Eina_Bool *tofree);
|
||||||
void (*image_data_preload_request) (void *engine, void *image, const Eo *target);
|
void (*image_data_preload_request) (void *engine, void *image, const Eo *target);
|
||||||
void (*image_data_preload_cancel) (void *engine, void *image, const Eo *target, Eina_Bool force);
|
void (*image_data_preload_cancel) (void *engine, void *image, const Eo *target, Eina_Bool force);
|
||||||
void *(*image_alpha_set) (void *engine, void *image, int has_alpha);
|
void *(*image_alpha_set) (void *engine, void *image, int has_alpha);
|
||||||
|
|
|
@ -301,20 +301,86 @@ eng_image_file_colorspace_get(void *engine EINA_UNUSED, void *image)
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
eng_image_data_direct_get(void *engine EINA_UNUSED, void *image, int plane,
|
eng_image_data_direct_get(void *engine EINA_UNUSED, void *image, int plane,
|
||||||
Eina_Slice *slice, Evas_Colorspace *cspace,
|
Eina_Slice *slice, Evas_Colorspace *cspace,
|
||||||
Eina_Bool load)
|
Eina_Bool load, Eina_Bool *tofree)
|
||||||
{
|
{
|
||||||
|
Eina_Bool ret = EINA_FALSE;
|
||||||
Evas_GL_Image *im = image;
|
Evas_GL_Image *im = image;
|
||||||
|
int bpp = 0;
|
||||||
|
|
||||||
if (!slice || !im || !im->im)
|
if (!slice || !im) return ret;
|
||||||
return EINA_FALSE;
|
|
||||||
|
/* If content hint is DYNAMIC, the im->im could be NULL. If the im->im does
|
||||||
|
not exist, eng_image_data_direct_get needs to return copied dyn.data to
|
||||||
|
make functions including efl_file_save work. */
|
||||||
|
if ((im->content_hint == EVAS_IMAGE_CONTENT_HINT_DYNAMIC) &&
|
||||||
|
tofree &&
|
||||||
|
(im->tex_only) && (!im->im) &&
|
||||||
|
(im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
|
||||||
|
{
|
||||||
|
*tofree = EINA_FALSE;
|
||||||
|
switch ( im->cs.space)
|
||||||
|
{
|
||||||
|
case EFL_GFX_COLORSPACE_ARGB8888:
|
||||||
|
bpp = 4;
|
||||||
|
EINA_FALLTHROUGH;
|
||||||
|
// falltrhough is intended
|
||||||
|
case EFL_GFX_COLORSPACE_AGRY88:
|
||||||
|
if (!bpp) bpp = 2;
|
||||||
|
EINA_FALLTHROUGH;
|
||||||
|
// falltrhough is intended
|
||||||
|
case EFL_GFX_COLORSPACE_GRY8:
|
||||||
|
if (!bpp) bpp = 1;
|
||||||
|
*tofree = EINA_TRUE;
|
||||||
|
im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
|
||||||
|
im->im->cache_entry.flags.alpha = im->alpha;
|
||||||
|
im->im->cache_entry.space = im->cs.space;
|
||||||
|
evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space);
|
||||||
|
im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h);
|
||||||
|
|
||||||
|
DATA8 *pixels = (DATA8 *)im->tex->pt->dyn.data;
|
||||||
|
for (int i = 0; i < im->tex->pt->dyn.h; i++)
|
||||||
|
{
|
||||||
|
memcpy(im->im->image.data + (im->w * i),
|
||||||
|
pixels + (im->tex->pt->dyn.stride * i),
|
||||||
|
im->w * bpp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!im->im) return ret;
|
||||||
|
|
||||||
if (cspace) *cspace = im->im->cache_entry.space;
|
if (cspace) *cspace = im->im->cache_entry.space;
|
||||||
if (load)
|
if (load)
|
||||||
{
|
{
|
||||||
if (evas_cache_image_load_data(&im->im->cache_entry) != 0)
|
if (evas_cache_image_load_data(&im->im->cache_entry) != 0)
|
||||||
return EINA_FALSE;
|
{
|
||||||
|
/* Only valid when content hint is DYNAMIC */
|
||||||
|
if (tofree && *tofree)
|
||||||
|
{
|
||||||
|
evas_cache_image_drop(&im->im->cache_entry);
|
||||||
|
im->im = NULL;
|
||||||
}
|
}
|
||||||
return _evas_common_rgba_image_plane_get(im->im, plane, slice);
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _evas_common_rgba_image_plane_get(im->im, plane, slice);
|
||||||
|
|
||||||
|
/* The im->im is not necessary, because it is created temporal purpose to
|
||||||
|
get the slice used by out side of this function. */
|
||||||
|
if (tofree && *tofree)
|
||||||
|
{
|
||||||
|
if (ret)
|
||||||
|
*slice = eina_rw_slice_slice_get(eina_slice_dup(*slice));
|
||||||
|
|
||||||
|
evas_cache_image_drop(&im->im->cache_entry);
|
||||||
|
im->im = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -1049,9 +1049,10 @@ eng_image_file_colorspace_get(void *data EINA_UNUSED, void *image)
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
eng_image_data_direct_get(void *data EINA_UNUSED, void *image, int plane,
|
eng_image_data_direct_get(void *data EINA_UNUSED, void *image, int plane,
|
||||||
Eina_Slice *slice, Evas_Colorspace *cspace,
|
Eina_Slice *slice, Evas_Colorspace *cspace,
|
||||||
Eina_Bool load)
|
Eina_Bool load, Eina_Bool *tofree)
|
||||||
{
|
{
|
||||||
RGBA_Image *im = image;
|
RGBA_Image *im = image;
|
||||||
|
if (tofree) *tofree = EINA_FALSE;
|
||||||
|
|
||||||
if (!slice || !im)
|
if (!slice || !im)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
|
Loading…
Reference in New Issue