From c52a53c3dcecdefc1ea8c01688b032554fcc3a80 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Fri, 4 Mar 2016 16:51:37 +0900 Subject: [PATCH] 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 --- src/lib/evas/canvas/evas_image.eo | 3 + src/lib/evas/canvas/evas_object_image.c | 109 ++++++++++++++++++++++++++++++++ src/lib/evas/common/evas_image.h | 1 + src/lib/evas/common/evas_image_main.c | 2 +- 4 files changed, 114 insertions(+), 1 deletion(-) diff --git a/src/lib/evas/canvas/evas_image.eo b/src/lib/evas/canvas/evas_image.eo index 2e0d89b..7ed0ac2 100644 --- a/src/lib/evas/canvas/evas_image.eo +++ b/src/lib/evas/canvas/evas_image.eo @@ -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; diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index 4046b35..2bd78aa 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -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 diff --git a/src/lib/evas/common/evas_image.h b/src/lib/evas/common/evas_image.h index f21cd6c..917bfcd 100644 --- a/src/lib/evas/common/evas_image.h +++ b/src/lib/evas/common/evas_image.h @@ -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); diff --git a/src/lib/evas/common/evas_image_main.c b/src/lib/evas/common/evas_image_main.c index b82a851..01db75f 100644 --- a/src/lib/evas/common/evas_image_main.c +++ b/src/lib/evas/common/evas_image_main.c @@ -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) -- 2.7.4