From: Jean-Philippe Andre Date: Fri, 4 Mar 2016 06:57:36 +0000 (+0900) Subject: Efl.Gfx.Buffer: Introduce buffer_set/get/copy_set X-Git-Tag: upstream/1.20.0~7209 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ba53f0e7857f9753e8e639ec5768112630b227ad;p=platform%2Fupstream%2Fefl.git Efl.Gfx.Buffer: Introduce buffer_set/get/copy_set Hopefully the doc and signature are better than the current evas image equivalents data_get/data_set. Those APIs are not like map/unmap so we need to decide which model we prefer. --- diff --git a/src/lib/efl/interfaces/efl_gfx_buffer.eo b/src/lib/efl/interfaces/efl_gfx_buffer.eo index f74e801..0b19b98 100644 --- a/src/lib/efl/interfaces/efl_gfx_buffer.eo +++ b/src/lib/efl/interfaces/efl_gfx_buffer.eo @@ -47,7 +47,7 @@ interface Efl.Gfx.Buffer () } } - @property buffer_stride { + @property stride { [[Length in bytes of one row of pixels in memory. Usually this will be equal to width * 4, with a plain BGRA image. @@ -62,7 +62,7 @@ interface Efl.Gfx.Buffer () } } - buffer_update_region_add { + buffer_update_add { [[Mark a sub-region of the given image object to be redrawn. This function schedules a particular rectangular region of an @@ -131,34 +131,116 @@ interface Efl.Gfx.Buffer () @in length: uint; [[Must be the same as returned by map.]] } } + /* note: not a property because the refcount needs to be explicit + * between set and get */ + /* FIXME: not bindable to JS, potentially tricky to bind to Lua */ buffer_set { [[Set the pixels for this buffer, or allocate a new memory region. - EFL will copy the $pixels to an internal buffer, and update the - GPU-side texture if required. This will mark the image as dirty. + EFL will use $pixels directly, and update the GPU-side texture + if required. This will mark the image as dirty. If $pixels is $null, then a new empty buffer will be allocated. + If the buffer already had pixel data, the previous image data will + be dropped. This is the same as @.buffer_copy_set. + + If $pixels is the return value of @.buffer_get then EFL will + decrement its internal reference count on the buffer data. Call + @.buffer_update_add to flush updates and indicate changes in + the pixel data. + + The memory buffer $pixels must be large enough to hold + $width x $height pixels encoded in the colorspace $cspace. + Alternatively $pixels must be larger than $height x $stride + in bytes. + + See also @.buffer_copy_set if you want EFL to copy the input buffer + internally. + ]] + params { + @in pixels: void* @nullable; [[If $null, allocates an empty buffer]] + @in width: int; + @in height: int; + @in stride: int @optional; [[If 0, automatically guessed from the $width.]] + @in cspace: Efl.Gfx.Colorspace @optional; [[argb8888 by default.]] + @in alpha: bool; [[$true if the alpha channel is used.]] + @in l: uint @optional; [[Left border pixels, usually 0 or 1. Not supported yet!]] + @in r: uint @optional; [[Right border pixels, usually 0 or 1. Not supported yet!]] + @in t: uint @optional; [[Top border pixels, usually 0 or 1. Not supported yet!]] + @in b: uint @optional; [[Bottom border pixels, usually 0 or 1. Not supported yet!]] + /* FIXME: do we need writable flag? */ + } + return: bool @warn_unused; [[This function returns $false in case of failure.]] + } + buffer_copy_set { + [[Set the pixels for this buffer by copying them, or allocate + a new memory region. + + This will allocate a new buffer in memory and copy the input + $pixels to it. The internal colorspace is not guaranteed to + be preserved, and colorspace conversion may happen internally. + If $pixels is $null, then a new empty buffer will be allocated. If the buffer already had pixel data, the previous image data will - be dropped and the internal buffer may be resized to fit the new - pixel data. + be dropped. This is the same as @.buffer_set. + + The memory buffer $pixels must be large enough to hold + $width x $height pixels encoded in the colorspace $cspace. + Alternatively $pixels must be larger than $height x $stride + in bytes. + + $pixels should not be the return value of @.buffer_get. - Note: Use @Efl.Gfx.Buffer.buffer_size.set and @.buffer_map to - request EFL to allocate the buffer itself, instead of using this - function. + There is no copy equivalent to this function, as you can easily + call @.buffer_get and allocate the proper buffer on your side, + followed by a memory copy and @.buffer_set. ]] params { - @in pixels: ubyte*; [[If $null, allocates an empty buffer]] + @in pixels: const(void)* @nullable; [[If $null, allocates an empty buffer]] @in width: int; @in height: int; - @in stride: int @optional; [[If 0, automatically guessed from the width.]] + @in stride: int @optional; [[If 0, automatically guessed from the $width.]] @in cspace: Efl.Gfx.Colorspace @optional; [[argb8888 by default.]] - @in l: uint @optional; [[Left border pixels, usually 0 or 1]] - @in r: uint @optional; [[Right border pixels, usually 0 or 1]] - @in t: uint @optional; [[Top border pixels, usually 0 or 1]] - @in b: uint @optional; [[Bottom border pixels, usually 0 or 1]] + @in alpha: bool; [[$true if the alpha channel is used.]] + @in l: uint @optional; [[Left border pixels, usually 0 or 1. Not supported yet!]] + @in r: uint @optional; [[Right border pixels, usually 0 or 1. Not supported yet!]] + @in t: uint @optional; [[Top border pixels, usually 0 or 1. Not supported yet!]] + @in b: uint @optional; [[Bottom border pixels, usually 0 or 1. Not supported yet!]] + } + return: bool @warn_unused; [[This function returns $false in case of failure.]] + } + buffer_get { + [[Get a direct pointer to the internal pixel data. + + This will increment an internal reference counter on the internal + buffer. + + If $to_write is $true, this may trigger a copy of the internal + pixel data, and return a writable memory block. + + Call @.buffer_size.get and @.buffer_borders.get to determine the + value of width, height and l, r, t, b. + + Warning: @.buffer_set MUST be called as soon as possible after + calling @.buffer_get. @.buffer_update_add should be called after + @.buffer_set if $to_write was $true and the pixel data has been + modified. Once @.buffer_set is called, the pointer return from + @.buffer_get is not valid anymore. + ]] + params { + @in to_write: bool; [[If $true, requests write access]] + @out length: uint @optional; [[Size of the buffer in bytes.]] + @out width: int @optional; + @out height: int @optional; + @out stride: int @optional; [[Returns the length of one row of pixels in bytes.]] + @out cspace: Efl.Gfx.Colorspace @optional; [[Pixel encoding of the returned buffer.]] + @out alpha: bool; [[$true if the alpha channel is used.]] + @out l: uint @optional; [[Left border pixels, usually 0 or 1. Not supported yet!]] + @out r: uint @optional; [[Right border pixels, usually 0 or 1. Not supported yet!]] + @out t: uint @optional; [[Top border pixels, usually 0 or 1. Not supported yet!]] + @out b: uint @optional; [[Bottom border pixels, usually 0 or 1. Not supported yet!]] } - return: bool; + return: void* @warn_unused; } /* Note: border, span and buffer flags not imported from ector buffer */ } diff --git a/src/lib/evas/Evas_Legacy.h b/src/lib/evas/Evas_Legacy.h index f5d91a4..73baa1a 100644 --- a/src/lib/evas/Evas_Legacy.h +++ b/src/lib/evas/Evas_Legacy.h @@ -3360,6 +3360,74 @@ EAPI Evas_Colorspace evas_object_image_colorspace_get(const Evas_Object *obj); EAPI int evas_object_image_stride_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT; /** + * @brief Replaces the raw image data of the given image object. + * + * This function lets the application replace an image object's internal pixel + * buffer with an user-allocated one. For best results, you should generally + * first call @ref evas_object_image_size_set with the width and height for the + * new buffer. + * + * This call is best suited for when you will be using image data with + * different dimensions than the existing image data, if any. If you only need + * to modify the existing image in some fashion, then using + * @ref evas_object_image_data_get is probably what you are after. + * + * Note that the caller is responsible for freeing the buffer when finished + * with it, as user-set image data will not be automatically freed when the + * image object is deleted. + * + * @param[in] data The raw data to replace. + * + * @ingroup Evas_Image + */ +EAPI void evas_object_image_data_copy_set(Evas_Object *obj, void *data); + +/** + * @brief Sets the raw image data of the given image object. + * + * Note that the raw data must be of the same size (see @ref + * evas_object_image_size_set, which has to be called before this one) and + * colorspace (see @Evas.Image.colorspace.set) of the image. If data is + * @c null, the current image data will be freed. Naturally, if one does not + * set an image object's data manually, it will still have one, allocated by + * Evas. + * + * @param[in] data The raw data, or @c null. + * + * @ingroup Evas_Image + */ +EAPI void evas_object_image_data_set(Evas_Object *obj, void *data); + +/** + * @brief Get a pointer to the raw image data of the given image object. + * + * This function returns a pointer to an image object's internal pixel buffer, + * for reading only or read/write. If you request it for writing, the image + * will be marked dirty so that it gets redrawn at the next update. + * + * Each time you call this function on an image object, its data buffer will + * have an internal reference counter incremented. Decrement it back by using + * @ref evas_object_image_data_set. + * + * This is best suited for when you want to modify an existing image, without + * changing its dimensions. + * + * @note The contents' format returned by it depend on the color space of the + * given image object. + * + * @note You may want to use @Evas.Image.data_update_add to inform data + * changes, if you did any. + * + * @param[in] for_writing Whether the data being retrieved will be modified + * ($true) or not ($false). + * + * @return The raw image data. + * + * @ingroup Evas_Image + */ +EAPI void *evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing) EINA_WARN_UNUSED_RESULT; + +/** * @brief Mark a sub-region of the given image object to be redrawn. * * This function schedules a particular rectangular region of an image object diff --git a/src/lib/evas/canvas/evas_image.eo b/src/lib/evas/canvas/evas_image.eo index 31acd3a..2e0d89b 100644 --- a/src/lib/evas/canvas/evas_image.eo +++ b/src/lib/evas/canvas/evas_image.eo @@ -249,30 +249,6 @@ class Evas.Image (Evas.Object, Efl.File, Efl.Image, Efl.Image_Load, Efl.Image_An surf: Evas.Native_Surface* @nonull; [[The native surface.]] } } - @property data_copy { - set { - [[Replaces the raw image data of the given image object. - - This function lets the application replace an image object's - internal pixel buffer with an user-allocated one. For best - results, you should generally first call - \@ref evas_object_image_size_set with the width and height - for the new buffer. - - This call is best suited for when you will be using image - data with different dimensions than the existing image data, - if any. If you only need to modify the existing image in some - fashion, then using @.data_get is probably what you are after. - - Note that the caller is responsible for freeing the buffer - when finished with it, as user-set image data will not be - automatically freed when the image object is deleted. - ]] - } - values { - data: void *; [[The raw data to replace.]] - } - } /* 3d */ @property scene { @@ -319,47 +295,6 @@ class Evas.Image (Evas.Object, Efl.File, Efl.Image, Efl.Image_Load, Efl.Image_An the Evas_Object_Image.]] } } - data_set { - [[Sets the raw image data of the given image object. - - Note that the raw data must be of the same size (see - \@ref evas_object_image_size_set, which has to be called before - this one) and colorspace (see \@.colorspace.set) of the image. - If data is $null, the current image data will be freed. - Naturally, if one does not set an image object's data - manually, it will still have one, allocated by Evas. - ]] - params { - @in data: void *; [[The raw data, or $null.]] - } - } - data_get @const { - [[Get a pointer to the raw image data of the given image object. - - This function returns a pointer to an image object's internal - pixel buffer, for reading only or read/write. If you request - it for writing, the image will be marked dirty so that it gets - redrawn at the next update. - - Each time you call this function on an image object, its data - buffer will have an internal reference counter incremented. - Decrement it back by using @.data_set. - - This is best suited for when you want to modify an existing - image, without changing its dimensions. - - Note: The contents' format returned by it depend on the color - space of the given image object. - - Note: You may want to use \@.data_update_add to inform data - changes, if you did any. - ]] - return: void * @warn_unused; [[ The raw image data.]] - params { - @in for_writing: bool; [[Whether the data being retrieved will - be modified ($true) or not ($false).]] - } - } } implements { Eo.Base.constructor; @@ -405,16 +340,15 @@ class Evas.Image (Evas.Object, Efl.File, Efl.Image, Efl.Image_Load, Efl.Image_An Efl.Image_Load.load_region.get; Efl.Image_Load.load_region.set; Efl.Image_Load.load_region_support.get; - Efl.Gfx.Buffer.buffer_update_region_add; - Efl.Gfx.Buffer.buffer_stride.get; + Efl.Gfx.Buffer.buffer_update_add; + Efl.Gfx.Buffer.stride.get; Efl.Gfx.Buffer.colorspace.get; Efl.Gfx.Fill.fill.set; Efl.Gfx.Fill.fill.get; Efl.Gfx.Fill.filled.get; Efl.Gfx.Fill.filled.set; - Efl.Gfx.View.view_size.set; - Efl.Gfx.View.view_size.get; Efl.Gfx.Filter.filter_program.set; + Efl.Gfx.View.view_size.get; Evas.Filter.filter_input_alpha; Evas.Filter.filter_input_render; Evas.Filter.filter_dirty; diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index 10fa5e8..4046b35 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -1013,10 +1013,12 @@ _evas_image_efl_gfx_fill_fill_get(Eo *eo_obj EINA_UNUSED, Evas_Image_Data *o, if (h) *h = o->cur->fill.h; } -EOLIAN static void -_evas_image_efl_gfx_view_view_size_set(Eo *eo_obj, Evas_Image_Data *o, int w, int h) +/* eo equivalent: pixels_set(null, w, h) to (re)allocate an image */ +EAPI void +evas_object_image_size_set(Eo *eo_obj, int w, int h) { Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + Evas_Image_Data *o = eo_data_scope_get(eo_obj, MY_CLASS); int stride = 0; @@ -1120,7 +1122,7 @@ _evas_image_efl_gfx_view_view_size_get(Eo *eo_obj, Evas_Image_Data *o, int *w, i } EOLIAN static int -_evas_image_efl_gfx_buffer_buffer_stride_get(Eo *eo_obj EINA_UNUSED, Evas_Image_Data *o) +_evas_image_efl_gfx_buffer_stride_get(Eo *eo_obj EINA_UNUSED, Evas_Image_Data *o) { return o->cur->image.stride; } @@ -1168,137 +1170,6 @@ evas_object_image_data_convert(Evas_Object *eo_obj, Evas_Colorspace to_cspace) return result; } -EOLIAN static void -_evas_image_data_set(Eo *eo_obj, Evas_Image_Data *o, void *data) -{ - Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); - void *p_data; - Eina_Bool resize_call = EINA_FALSE; - - - evas_object_async_block(obj); - evas_render_rendering_wait(obj->layer->evas); - - _evas_object_image_cleanup(eo_obj, obj, o); - p_data = o->engine_data; - if (data) - { - if (o->engine_data) - { - o->engine_data = ENFN->image_data_put(ENDT, o->engine_data, data); - } - else - { - o->engine_data = ENFN->image_new_from_data(ENDT, - o->cur->image.w, - o->cur->image.h, - data, - o->cur->has_alpha, - o->cur->cspace); - } - if (o->engine_data) - { - int stride = 0; - - if (ENFN->image_scale_hint_set) - ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint); - - if (ENFN->image_content_hint_set) - ENFN->image_content_hint_set(ENDT, o->engine_data, o->content_hint); - - if (ENFN->image_stride_get) - ENFN->image_stride_get(ENDT, o->engine_data, &stride); - else - stride = o->cur->image.w * 4; - - if (o->cur->image.stride != stride) - { - EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) - state_write->image.stride = stride; - EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); - } - } - o->written = EINA_TRUE; - } - else - { - if (o->engine_data) - ENFN->image_free(ENDT, o->engine_data); - o->load_error = EVAS_LOAD_ERROR_NONE; - if ((o->cur->image.w != 0) || (o->cur->image.h != 0)) - resize_call = EINA_TRUE; - - EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) - { - state_write->image.w = 0; - state_write->image.h = 0; - state_write->image.stride = 0; - } - EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); - - o->engine_data = NULL; - } -/* FIXME - in engine call above - if (o->engine_data) - o->engine_data = ENFN->image_alpha_set(ENDT, o->engine_data, o->cur->has_alpha); -*/ - if (o->pixels_checked_out > 0) o->pixels_checked_out--; - if (p_data != o->engine_data) - { - EVAS_OBJECT_WRITE_IMAGE_FREE_FILE_AND_KEY(o); - o->pixels_checked_out = 0; - } - if (resize_call) evas_object_inform_call_image_resize(eo_obj); -} - -EOLIAN static void* -_evas_image_data_get(const Eo *eo_obj, Evas_Image_Data *_pd EINA_UNUSED, Eina_Bool for_writing) -{ - Evas_Image_Data *o = (Evas_Image_Data *) _pd; - int stride = 0; - void *pixels; - DATA32 *data; - - if (!o->engine_data) return NULL; - - Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); - - if (for_writing) evas_object_async_block(obj); - if (for_writing) evas_render_rendering_wait(obj->layer->evas); - - data = NULL; - if (ENFN->image_scale_hint_set) - ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint); - if (ENFN->image_content_hint_set) - ENFN->image_content_hint_set(ENDT, o->engine_data, o->content_hint); - pixels = ENFN->image_data_get(ENDT, o->engine_data, for_writing, &data, &o->load_error, NULL); - - /* if we fail to get engine_data, we have to return NULL */ - if (!pixels) return NULL; - - o->engine_data = pixels; - if (ENFN->image_stride_get) - ENFN->image_stride_get(ENDT, o->engine_data, &stride); - else - stride = o->cur->image.w * 4; - - if (o->cur->image.stride != stride) - { - EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) - state_write->image.stride = stride; - EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); - } - - o->pixels_checked_out++; - if (for_writing) - { - o->written = EINA_TRUE; - EVAS_OBJECT_WRITE_IMAGE_FREE_FILE_AND_KEY(o); - } - - return data; -} - static void _image_preload_internal(Eo *eo_obj, void *_pd, Eina_Bool cancel) { @@ -1348,52 +1219,7 @@ _evas_image_efl_image_load_load_async_cancel(Eo *eo_obj, Evas_Image_Data *_pd EI } EOLIAN static void -_evas_image_data_copy_set(Eo *eo_obj, Evas_Image_Data *o, void *data) -{ - Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); - - if (!data) return; - evas_object_async_block(obj); - _evas_object_image_cleanup(eo_obj, obj, o); - if ((o->cur->image.w <= 0) || - (o->cur->image.h <= 0)) return; - if (o->engine_data) - ENFN->image_free(ENDT, o->engine_data); - o->engine_data = ENFN->image_new_from_copied_data(ENDT, - o->cur->image.w, - o->cur->image.h, - data, - o->cur->has_alpha, - o->cur->cspace); - if (o->engine_data) - { - int stride = 0; - - o->engine_data = - ENFN->image_alpha_set(ENDT, o->engine_data, o->cur->has_alpha); - if (ENFN->image_scale_hint_set) - ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint); - if (ENFN->image_content_hint_set) - ENFN->image_content_hint_set(ENDT, o->engine_data, o->content_hint); - if (ENFN->image_stride_get) - ENFN->image_stride_get(ENDT, o->engine_data, &stride); - else - stride = o->cur->image.w * 4; - - if (o->cur->image.stride != stride) - { - EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) - state_write->image.stride = stride; - EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); - } - o->written = EINA_TRUE; - } - o->pixels_checked_out = 0; - EVAS_OBJECT_WRITE_IMAGE_FREE_FILE_AND_KEY(o); -} - -EOLIAN static void -_evas_image_efl_gfx_buffer_buffer_update_region_add(Eo *eo_obj, Evas_Image_Data *o, int x, int y, int w, int h) +_evas_image_efl_gfx_buffer_buffer_update_add(Eo *eo_obj, Evas_Image_Data *o, int x, int y, int w, int h) { Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); Eina_Rectangle *r; @@ -3146,7 +2972,7 @@ _evas_image_evas_filter_filter_input_alpha(Eo *eo_obj EINA_UNUSED, Evas_Image_Da } EOLIAN static void -_evas_image_efl_gfx_filter_filter_program_set(Eo *obj, Evas_Image_Data *pd EINA_UNUSED, +_evas_image_efl_gfx_filter_filter_program_set(Eo *obj, Evas_Image_Data *pd, const char *code, const char *name) { pd->has_filter = (code != NULL); @@ -4844,6 +4670,186 @@ _evas_object_image_surface_get(Evas_Object *eo, Evas_Object_Protected_Data *obj) return pd->engine_data; } +/* Legacy deprecated functions */ + +EAPI void +evas_object_image_data_set(Eo *eo_obj, void *data) +{ + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + Evas_Image_Data *o = eo_data_scope_get(eo_obj, MY_CLASS); + void *p_data; + Eina_Bool resize_call = EINA_FALSE; + + + evas_object_async_block(obj); + evas_render_rendering_wait(obj->layer->evas); + + _evas_object_image_cleanup(eo_obj, obj, o); + p_data = o->engine_data; + if (data) + { + if (o->engine_data) + { + o->engine_data = ENFN->image_data_put(ENDT, o->engine_data, data); + } + else + { + o->engine_data = ENFN->image_new_from_data(ENDT, + o->cur->image.w, + o->cur->image.h, + data, + o->cur->has_alpha, + o->cur->cspace); + } + if (o->engine_data) + { + int stride = 0; + + if (ENFN->image_scale_hint_set) + ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint); + + if (ENFN->image_content_hint_set) + ENFN->image_content_hint_set(ENDT, o->engine_data, o->content_hint); + + if (ENFN->image_stride_get) + ENFN->image_stride_get(ENDT, o->engine_data, &stride); + else + stride = o->cur->image.w * 4; + + if (o->cur->image.stride != stride) + { + EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) + state_write->image.stride = stride; + EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); + } + } + o->written = EINA_TRUE; + } + else + { + if (o->engine_data) + ENFN->image_free(ENDT, o->engine_data); + o->load_error = EVAS_LOAD_ERROR_NONE; + if ((o->cur->image.w != 0) || (o->cur->image.h != 0)) + resize_call = EINA_TRUE; + + EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) + { + state_write->image.w = 0; + state_write->image.h = 0; + state_write->image.stride = 0; + } + EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); + + o->engine_data = NULL; + } +/* FIXME - in engine call above + if (o->engine_data) + o->engine_data = ENFN->image_alpha_set(ENDT, o->engine_data, o->cur->has_alpha); +*/ + if (o->pixels_checked_out > 0) o->pixels_checked_out--; + if (p_data != o->engine_data) + { + EVAS_OBJECT_WRITE_IMAGE_FREE_FILE_AND_KEY(o); + o->pixels_checked_out = 0; + } + if (resize_call) evas_object_inform_call_image_resize(eo_obj); +} + +EAPI void* +evas_object_image_data_get(const Eo *eo_obj, Eina_Bool for_writing) +{ + Evas_Image_Data *o = eo_data_scope_get(eo_obj, MY_CLASS); + int stride = 0; + void *pixels; + DATA32 *data; + + if (!o->engine_data) return NULL; + + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + + if (for_writing) evas_object_async_block(obj); + if (for_writing) evas_render_rendering_wait(obj->layer->evas); + + data = NULL; + if (ENFN->image_scale_hint_set) + ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint); + if (ENFN->image_content_hint_set) + ENFN->image_content_hint_set(ENDT, o->engine_data, o->content_hint); + pixels = ENFN->image_data_get(ENDT, o->engine_data, for_writing, &data, &o->load_error, NULL); + + /* if we fail to get engine_data, we have to return NULL */ + if (!pixels) return NULL; + + o->engine_data = pixels; + if (ENFN->image_stride_get) + ENFN->image_stride_get(ENDT, o->engine_data, &stride); + else + stride = o->cur->image.w * 4; + + if (o->cur->image.stride != stride) + { + EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) + state_write->image.stride = stride; + EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); + } + + o->pixels_checked_out++; + if (for_writing) + { + o->written = EINA_TRUE; + EVAS_OBJECT_WRITE_IMAGE_FREE_FILE_AND_KEY(o); + } + + return data; +} + +EAPI void +evas_object_image_data_copy_set(Eo *eo_obj, void *data) +{ + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + Evas_Image_Data *o = eo_data_scope_get(eo_obj, MY_CLASS); + + if (!data) return; + evas_object_async_block(obj); + _evas_object_image_cleanup(eo_obj, obj, o); + if ((o->cur->image.w <= 0) || + (o->cur->image.h <= 0)) return; + if (o->engine_data) + ENFN->image_free(ENDT, o->engine_data); + o->engine_data = ENFN->image_new_from_copied_data(ENDT, + o->cur->image.w, + o->cur->image.h, + data, + o->cur->has_alpha, + o->cur->cspace); + if (o->engine_data) + { + int stride = 0; + + o->engine_data = + ENFN->image_alpha_set(ENDT, o->engine_data, o->cur->has_alpha); + if (ENFN->image_scale_hint_set) + ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint); + if (ENFN->image_content_hint_set) + ENFN->image_content_hint_set(ENDT, o->engine_data, o->content_hint); + if (ENFN->image_stride_get) + ENFN->image_stride_get(ENDT, o->engine_data, &stride); + else + stride = o->cur->image.w * 4; + + if (o->cur->image.stride != stride) + { + EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) + state_write->image.stride = stride; + EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); + } + o->written = EINA_TRUE; + } + o->pixels_checked_out = 0; + EVAS_OBJECT_WRITE_IMAGE_FREE_FILE_AND_KEY(o); +} + /* Legacy wrappers */ EAPI Evas_Object * @@ -4963,13 +4969,7 @@ evas_object_image_border_center_fill_get(const Evas_Object *obj) EAPI void evas_object_image_size_get(const Evas_Image *obj, int *w, int *h) { - efl_gfx_view_size_get((Evas_Image *)obj, w, h); -} - -EAPI void -evas_object_image_size_set(Evas_Image *obj, int w, int h) -{ - efl_gfx_view_size_set(obj, w, h); + efl_gfx_view_size_get(obj, w, h); } EAPI Evas_Colorspace @@ -4987,7 +4987,7 @@ evas_object_image_stride_get(const Evas_Object *obj) EAPI void evas_object_image_data_update_add(Evas_Object *obj, int x, int y, int w, int h) { - efl_gfx_buffer_update_region_add(obj, x, y, w, h); + efl_gfx_buffer_update_add(obj, x, y, w, h); } EAPI void