Evas Image: Implement Gfx.Buffer get/set/copy_set APIs

Those APIs should provide a cleaner interface than the
old data_set/data_get APIs, by making sure the operations are
atomic (ie. no need to call size_set, cspace_set and then data_set).

padding/duplicated borders are not supported.

TODO: Implement legacy API on top of the new API, instead of
      this quick patch
This commit is contained in:
Jean-Philippe Andre 2016-03-04 16:51:37 +09:00
parent ba53f0e785
commit c52a53c3dc
4 changed files with 114 additions and 1 deletions

View File

@ -343,6 +343,9 @@ class Evas.Image (Evas.Object, Efl.File, Efl.Image, Efl.Image_Load, Efl.Image_An
Efl.Gfx.Buffer.buffer_update_add;
Efl.Gfx.Buffer.stride.get;
Efl.Gfx.Buffer.colorspace.get;
Efl.Gfx.Buffer.buffer_get;
Efl.Gfx.Buffer.buffer_set;
Efl.Gfx.Buffer.buffer_copy_set;
Efl.Gfx.Fill.fill.set;
Efl.Gfx.Fill.fill.get;
Efl.Gfx.Fill.filled.get;

View File

@ -4670,6 +4670,115 @@ _evas_object_image_surface_get(Evas_Object *eo, Evas_Object_Protected_Data *obj)
return pd->engine_data;
}
EOLIAN static void *
_evas_image_efl_gfx_buffer_buffer_get(Eo *eo_obj, Evas_Image_Data *o,
Eina_Bool to_write, unsigned int *length_out,
int *width, int *height, int *stride_out,
Efl_Gfx_Colorspace *cspace, Eina_Bool *alpha,
unsigned int *l, unsigned int *r, unsigned int *t, unsigned int *b)
{
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
int stride = 0, length = 0;
void *data;
// use the old api - same behaviour with more return info
data = evas_object_image_data_get(eo_obj, to_write);
if (!data) goto end;
// FIXME: length needs to be properly checked with the engine
// as we just ignore l,r,t,b here
ENFN->image_stride_get(ENDT, o->engine_data, &stride);
if (stride)
length = stride * o->cur->image.h;
else
{
length = _evas_common_rgba_image_surface_size(o->cur->image.w, o->cur->image.h, o->cur->cspace, NULL, NULL, NULL, NULL);
stride = _evas_common_rgba_image_surface_size(o->cur->image.w, 1, o->cur->cspace, NULL, NULL, NULL, NULL);
}
end:
// TODO: support duplicated borders
if (l) *l = 0;
if (r) *r = 0;
if (t) *t = 0;
if (b) *b = 0;
if (alpha) *alpha = o->cur->has_alpha;
if (width) *width = o->cur->image.w;
if (height) *height = o->cur->image.h;
if (cspace) *cspace = (Efl_Gfx_Colorspace) o->cur->cspace;
if (length_out) *length_out = length;
if (stride_out) *stride_out = stride;
return data;
}
static Eina_Bool
_evas_image_buffer_set_common(Eo *obj, Evas_Image_Data *o, void *pixels,
int width, int height, int stride,
Efl_Gfx_Colorspace cspace, Eina_Bool alpha,
unsigned int l, unsigned int r, unsigned int t, unsigned int b,
Eina_Bool copy)
{
Evas_Colorspace cs = (Evas_Colorspace) cspace;
int stride_min;
if (l || r || t || b)
{
// TODO
ERR("Buffer borders are not supported yet!");
return EINA_FALSE;
}
stride_min = _evas_common_rgba_image_surface_size(width, 1, cs, NULL, NULL, NULL, NULL);
if (!stride) stride = stride_min;
if (stride < stride_min)
{
ERR("Image stride is too small: given %d needs %d", stride, stride_min);
return EINA_FALSE;
}
if (stride > stride_min) // FIXME/TODO
{
ERR("Image stride support is not implemented: given %d needs %d", stride, stride_min);
return EINA_FALSE;
}
if (cs != o->cur->cspace)
evas_object_image_colorspace_set(obj, cs);
if ((width != o->cur->image.w) || (height != o->cur->image.h))
evas_object_image_size_set(obj, width, height);
alpha = !!alpha;
if (alpha != o->cur->has_alpha)
evas_object_image_alpha_set(obj, alpha);
if (!pixels)
evas_object_image_data_set(obj, NULL);
else if (!copy)
evas_object_image_data_set(obj, pixels);
else
evas_object_image_data_copy_set(obj, pixels);
return o->engine_data ? EINA_TRUE : EINA_FALSE;
}
EOLIAN static Eina_Bool
_evas_image_efl_gfx_buffer_buffer_set(Eo *obj, Evas_Image_Data *o, void *pixels,
int width, int height, int stride,
Efl_Gfx_Colorspace cspace, Eina_Bool alpha,
unsigned int l, unsigned int r, unsigned int t, unsigned int b)
{
return _evas_image_buffer_set_common(obj, o, pixels, width, height, stride, cspace, alpha, l, r, t, b, EINA_FALSE);
}
EOLIAN static Eina_Bool
_evas_image_efl_gfx_buffer_buffer_copy_set(Eo *obj, Evas_Image_Data *o, const void *pixels,
int width, int height, int stride,
Efl_Gfx_Colorspace cspace, Eina_Bool alpha,
unsigned int l, unsigned int r, unsigned int t, unsigned int b)
{
return _evas_image_buffer_set_common(obj, o, (void *) pixels, width, height, stride, cspace, alpha, l, r, t, b, EINA_TRUE);
}
/* Legacy deprecated functions */
EAPI void

View File

@ -76,6 +76,7 @@ EAPI int evas_common_load_rgba_image_data_from_file (Image_Entry *im);
EAPI double evas_common_load_rgba_image_frame_duration_from_file(Image_Entry *im, int start_frame, int frame_num);
void _evas_common_rgba_image_post_surface(Image_Entry *ie);
int _evas_common_rgba_image_surface_size(unsigned int w, unsigned int h, Evas_Colorspace cspace, /* inout */ int *l, int *r, int *t, int *b);
EAPI Eina_Bool evas_common_extension_can_load_get(const char *file);

View File

@ -110,7 +110,7 @@ static const Evas_Cache2_Image_Func _evas_common_image_func2 =
};
#endif
static inline int
int
_evas_common_rgba_image_surface_size(unsigned int w, unsigned int h,
Evas_Colorspace cspace,
/* inout */ int *l, int *r, int *t, int *b)