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.
This commit is contained in:
Jean-Philippe Andre 2016-03-04 15:57:36 +09:00
parent b458341a13
commit ba53f0e785
4 changed files with 359 additions and 275 deletions

View File

@ -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 and the internal buffer may be resized to fit the new
pixel data.
be dropped. This is the same as @.buffer_copy_set.
Note: Use @Efl.Gfx.Buffer.buffer_size.set and @.buffer_map to
request EFL to allocate the buffer itself, instead of using this
function.
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: ubyte*; [[If $null, allocates an empty buffer]]
@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 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!]]
/* FIXME: do we need writable flag? */
}
return: bool;
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. 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.
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: 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 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!]]
}
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: void* @warn_unused;
}
/* Note: border, span and buffer flags not imported from ector buffer */
}

View File

@ -3359,6 +3359,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.
*

View File

@ -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;

View File

@ -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