forked from enlightenment/efl
evas: Switch EO APIs to Eina_Slice for gfx buffers (map)
This adds a plane and eina slice argument to the map/unmap functions, instead of void_ptr + length.
This commit is contained in:
parent
1773ba5d82
commit
8ee431572d
|
@ -26,8 +26,8 @@
|
|||
#define IMG_WIDTH 256
|
||||
#define IMG_HEIGHT 256
|
||||
|
||||
// TODO: remove this when map/unmap are fully supported (GL engine)
|
||||
#undef USE_EO_IMAGE
|
||||
// undef this to test the legacy API for images
|
||||
#define USE_EO_IMAGE
|
||||
|
||||
typedef struct _Scene_Data
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ _animate_scene(void *data)
|
|||
static float angle = 0.0f;
|
||||
Scene_Data *scene = (Scene_Data *)data;
|
||||
unsigned int *pixels;
|
||||
int i, j, stride, length;
|
||||
int i, j, stride;
|
||||
|
||||
angle += 0.5;
|
||||
|
||||
|
@ -83,11 +83,12 @@ _animate_scene(void *data)
|
|||
if (angle > 360.0) angle -= 360.0f;
|
||||
|
||||
#ifdef USE_EO_IMAGE
|
||||
pixels = efl_gfx_buffer_map(source, &length, EFL_GFX_BUFFER_ACCESS_MODE_WRITE, 0, 0, 0, 0,
|
||||
EFL_GFX_COLORSPACE_ARGB8888, &stride);
|
||||
if (!pixels) return EINA_TRUE;
|
||||
Eina_Rw_Slice slice;
|
||||
if (!efl_gfx_buffer_map(source, &slice, EFL_GFX_BUFFER_ACCESS_MODE_WRITE, 0, 0, 0, 0,
|
||||
EFL_GFX_COLORSPACE_ARGB8888, 0, &stride))
|
||||
return EINA_TRUE;
|
||||
pixels = slice.mem;
|
||||
#else
|
||||
(void) length;
|
||||
pixels = evas_object_image_data_get(source, EINA_TRUE);
|
||||
stride = evas_object_image_stride_get(source);
|
||||
#endif
|
||||
|
@ -103,7 +104,7 @@ _animate_scene(void *data)
|
|||
}
|
||||
|
||||
#ifdef USE_EO_IMAGE
|
||||
efl_gfx_buffer_unmap(source, pixels, length);
|
||||
efl_gfx_buffer_unmap(source, &slice);
|
||||
efl_gfx_buffer_update_add(source, 0, 0, IMG_WIDTH, IMG_HEIGHT);
|
||||
#else
|
||||
evas_object_image_data_set(source, pixels);
|
||||
|
@ -226,7 +227,7 @@ main(void)
|
|||
/* Add a background image. */
|
||||
#ifdef USE_EO_IMAGE
|
||||
source = efl_add(EFL_CANVAS_IMAGE_CLASS, evas);
|
||||
efl_gfx_buffer_data_set(source, NULL, WIDTH, HEIGHT, 0, EFL_GFX_COLORSPACE_ARGB8888);
|
||||
efl_gfx_buffer_copy_set(source, NULL, IMG_WIDTH, IMG_HEIGHT, 0, EFL_GFX_COLORSPACE_ARGB8888, 0);
|
||||
efl_gfx_position_set(source, (WIDTH / 2), (HEIGHT / 2));
|
||||
efl_gfx_size_set(source, (WIDTH / 2), (HEIGHT / 2));
|
||||
efl_gfx_visible_set(source, EINA_TRUE);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import efl_gfx_types;
|
||||
import eina_types;
|
||||
|
||||
/* FIXME: this is very very low level. expose to apps? */
|
||||
enum Efl.Gfx.Buffer.Access_Mode {
|
||||
|
@ -8,6 +9,8 @@ enum Efl.Gfx.Buffer.Access_Mode {
|
|||
cow = 0x4, [[Forces copy-on-write if already mapped as read-only. Requires write.]]
|
||||
}
|
||||
|
||||
/* FIXME: YUV and other planar formats are not properly handled in this API! */
|
||||
|
||||
interface Efl.Gfx.Buffer ()
|
||||
{
|
||||
[[Common APIs for all objects representing images and 2D pixel buffers.]]
|
||||
|
@ -129,7 +132,7 @@ interface Efl.Gfx.Buffer ()
|
|||
be negative.
|
||||
]]
|
||||
params {
|
||||
@out length: int @nonull; [[Accessible buffer size in bytes, should not be $null.]]
|
||||
@out slice: Eina.Rw_Slice; [[Pointer to the top-left pixel data.]]
|
||||
@in mode: Efl.Gfx.Buffer.Access_Mode; [[Specifies whether to map for read-only,
|
||||
write-only or read-write access (OR combinaison of flags).]]
|
||||
@in x: int @optional; [[X position of the top-left pixel to map, defaults to 0.]]
|
||||
|
@ -139,48 +142,25 @@ interface Efl.Gfx.Buffer ()
|
|||
@in cspace: Efl.Gfx.Colorspace @optional; [[Requested colorspace. If differen from the internal cspace,
|
||||
map should try to convert the data into a new buffer.
|
||||
argb8888 by default.]]
|
||||
@in plane: int @optional; [[Plane ID. 0 by default. Useful for planar formats only.]]
|
||||
@out stride: int @optional; [[Returns the length in bytes of a mapped line]]
|
||||
}
|
||||
return: void_ptr @warn_unused; [[Pointer to the top-left pixel data. Returns $null in case of failure]]
|
||||
return: bool;
|
||||
}
|
||||
buffer_unmap {
|
||||
[[Unmap a region of this buffer, and update the internal data if needed.
|
||||
|
||||
EFL will update the internal image if the map had write access.
|
||||
|
||||
Note: The $slice struct does not need to be the one returned
|
||||
by @.buffer_map, only its contents ($mem and $len) must match. But
|
||||
after a call to @.buffer_unmap the original $slice structure is not
|
||||
valid anymore.
|
||||
]]
|
||||
params {
|
||||
@in data: void_ptr; [[Data pointer returned by a previous call to map]]
|
||||
@in length: int; [[Must be the same as returned by map.]]
|
||||
@in slice: const(Eina.Rw_Slice)*; [[Data slice returned by a previous call to map.]]
|
||||
}
|
||||
return: bool; [[This will return $false in case of failure (invalid
|
||||
parameters or state of the object).]]
|
||||
}
|
||||
|
||||
/* FIXME: naming: buffer_set, buffer_attach, external_data_set, ...? */
|
||||
buffer_data_set {
|
||||
[[Set the pixels for this buffer, or allocate a new memory region.
|
||||
|
||||
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.
|
||||
|
||||
The memory buffer $pixels must be large enough to hold
|
||||
$width x $height pixels encoded in the colorspace $cspace.
|
||||
|
||||
See also @.buffer_copy_set if you want EFL to copy the input buffer
|
||||
internally.
|
||||
]]
|
||||
params {
|
||||
@in pixels: void_ptr @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.]]
|
||||
}
|
||||
return: bool @warn_unused; [[This function returns $false in case of failure.]]
|
||||
return: bool;
|
||||
}
|
||||
buffer_copy_set {
|
||||
[[Set the pixels for this buffer by copying them, or allocate
|
||||
|
@ -192,32 +172,61 @@ interface Efl.Gfx.Buffer ()
|
|||
|
||||
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_data_set.
|
||||
be dropped. This is the same as @.buffer_managed_set.
|
||||
|
||||
The memory buffer $pixels must be large enough to hold
|
||||
$width x $height pixels encoded in the colorspace $cspace.
|
||||
|
||||
$pixels should not be the return value of @.buffer_data_get.
|
||||
$slice should not be the return value of @.buffer_managed_get.
|
||||
]]
|
||||
params {
|
||||
@in pixels: const(void_ptr) @nullable; [[If $null, allocates an empty buffer]]
|
||||
@in slice: const(Eina.Slice)* @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 plane: int @optional; [[Plane ID. 0 by default. Useful for planar formats only.]]
|
||||
}
|
||||
return: bool @warn_unused; [[This function returns $false in case of failure.]]
|
||||
return: bool;
|
||||
}
|
||||
buffer_data_get {
|
||||
buffer_managed_set {
|
||||
[[Set the pixels for this buffer, managed externally by the client.
|
||||
|
||||
EFL will use the pixel data directly, and update the GPU-side
|
||||
texture if required. This will mark the image as dirty. If $slice
|
||||
is $null, this will detach the pixel data.
|
||||
|
||||
If the buffer already had pixel data, the previous image data will
|
||||
be dropped. This is the same as @.buffer_copy_set.
|
||||
|
||||
The memory buffer $pixels must be large enough to hold
|
||||
$width x $height pixels encoded in the colorspace $cspace.
|
||||
|
||||
See also @.buffer_copy_set if you want EFL to copy the input buffer
|
||||
internally.
|
||||
]]
|
||||
params {
|
||||
@in slice: const(Eina.Slice)* @nullable; [[If $null, detaches the previous 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 plane: int @optional; [[Plane ID. 0 by default. Useful for planar formats only.]]
|
||||
}
|
||||
return: bool;
|
||||
}
|
||||
buffer_managed_get {
|
||||
[[Get a direct pointer to the internal pixel data, if available.
|
||||
|
||||
This will return $null unless @.buffer_data_set was used to pass in an
|
||||
external data pointer.
|
||||
|
||||
Note: This is different from the legacy API data, which is now
|
||||
replaced by map/unmap.
|
||||
This will return $null unless @.buffer_managed_set was used to pass
|
||||
in an external data pointer. The returned @Eina.Slice struct must be
|
||||
freed by the caller.
|
||||
]]
|
||||
return: void_ptr @warn_unused;
|
||||
params {
|
||||
@out slice: Eina.Slice;
|
||||
@in plane: int @optional; [[Plane ID. 0 by default. Useful for planar formats only.]]
|
||||
}
|
||||
return: bool;
|
||||
}
|
||||
/* Note: border, span and buffer flags not imported from ector buffer */
|
||||
}
|
||||
|
|
|
@ -591,13 +591,22 @@ _efl_canvas_image_efl_gfx_buffer_buffer_size_get(Eo *eo_obj, void *_pd EINA_UNUS
|
|||
|
||||
static Eina_Bool
|
||||
_image_pixels_set(Evas_Object_Protected_Data *obj,
|
||||
Evas_Image_Data *o, void *pixels, int w, int h, int stride,
|
||||
Efl_Gfx_Colorspace cspace, Eina_Bool copy)
|
||||
Evas_Image_Data *o, const Eina_Slice *slice,
|
||||
int w, int h, int stride, Efl_Gfx_Colorspace cspace, int plane,
|
||||
Eina_Bool copy)
|
||||
{
|
||||
Eina_Bool resized = EINA_FALSE, ret = EINA_FALSE, easy_copy = EINA_FALSE;
|
||||
int int_stride = 0;
|
||||
void *pixels = NULL;
|
||||
|
||||
// FIXME: buffer border support is not implemented
|
||||
// FIXME: implement YUV support
|
||||
|
||||
if (plane)
|
||||
{
|
||||
ERR("planar formats not supported yet");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (ENFN->image_data_maps_get)
|
||||
{
|
||||
|
@ -627,6 +636,12 @@ _image_pixels_set(Evas_Object_Protected_Data *obj,
|
|||
o->file_obj = NULL;
|
||||
}
|
||||
|
||||
if (!slice && !copy)
|
||||
{
|
||||
ret = EINA_TRUE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch (cspace)
|
||||
{
|
||||
case EVAS_COLORSPACE_ARGB8888:
|
||||
|
@ -638,6 +653,20 @@ _image_pixels_set(Evas_Object_Protected_Data *obj,
|
|||
break;
|
||||
}
|
||||
|
||||
// FIXME: Properly handle YUV and other planar formats
|
||||
if (slice && easy_copy)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
pixels = (void *) slice->mem;
|
||||
len = _evas_common_rgba_image_surface_size(w, h, cspace, NULL, NULL, NULL, NULL);
|
||||
if ((stride && (slice->len < (size_t) (stride * h))) || (slice->len < len))
|
||||
{
|
||||
ERR("data slice is too short! (%zub, %dx%d)", slice->len, w, h);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
int_stride = _evas_common_rgba_image_surface_size(w, 1, cspace, NULL, NULL, NULL, NULL);
|
||||
if (!stride) stride = int_stride;
|
||||
|
||||
|
@ -738,50 +767,82 @@ end:
|
|||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_image_efl_gfx_buffer_buffer_data_set(Eo *eo_obj, void *_pd EINA_UNUSED,
|
||||
void *pixels, int w, int h, int stride,
|
||||
Efl_Gfx_Colorspace cspace)
|
||||
_efl_canvas_image_efl_gfx_buffer_buffer_managed_set(Eo *eo_obj, void *_pd EINA_UNUSED,
|
||||
const Eina_Slice *slice,
|
||||
int w, int h, int stride,
|
||||
Efl_Gfx_Colorspace cspace,
|
||||
int plane)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
||||
Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
|
||||
|
||||
return _image_pixels_set(obj, o, pixels, w, h, stride, cspace, EINA_FALSE);
|
||||
return _image_pixels_set(obj, o, slice, w, h, stride, cspace, plane, EINA_FALSE);
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_image_efl_gfx_buffer_buffer_copy_set(Eo *eo_obj, void *_pd EINA_UNUSED,
|
||||
const void *pixels, int w, int h, int stride,
|
||||
Efl_Gfx_Colorspace cspace)
|
||||
const Eina_Slice *slice, int w, int h, int stride,
|
||||
Efl_Gfx_Colorspace cspace, int plane)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
||||
Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
|
||||
|
||||
return _image_pixels_set(obj, o, (void *) pixels, w, h, stride, cspace, EINA_TRUE);
|
||||
return _image_pixels_set(obj, o, slice, w, h, stride, cspace, plane, EINA_TRUE);
|
||||
}
|
||||
|
||||
EOLIAN static void *
|
||||
_efl_canvas_image_efl_gfx_buffer_buffer_data_get(Eo *eo_obj, void *_pd EINA_UNUSED EINA_UNUSED)
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_image_efl_gfx_buffer_buffer_managed_get(Eo *eo_obj, void *_pd EINA_UNUSED EINA_UNUSED,
|
||||
Eina_Slice *slice, int plane)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
||||
Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
|
||||
Evas_Colorspace cspace = EVAS_COLORSPACE_ARGB8888;
|
||||
int w = 0, h = 0;
|
||||
void *pixels;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(slice, EINA_FALSE);
|
||||
|
||||
slice->len = 0;
|
||||
slice->mem = NULL;
|
||||
|
||||
if (plane)
|
||||
{
|
||||
ERR("planar formats not supported yet!");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!o->buffer_data_set || !o->engine_data || !ENFN->image_data_direct)
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
|
||||
return ENFN->image_data_direct(ENDT, o->engine_data, NULL);
|
||||
pixels = ENFN->image_data_direct(ENDT, o->engine_data, &cspace);
|
||||
if (!pixels) return EINA_FALSE;
|
||||
|
||||
slice->mem = pixels;
|
||||
|
||||
// note: length may not be same as what was originally given
|
||||
ENFN->image_size_get(ENDT, o->engine_data, &w, &h);
|
||||
slice->len = _evas_common_rgba_image_surface_size(w, h, cspace, NULL, NULL, NULL, NULL);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EOLIAN static void *
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_image_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
|
||||
int *length,
|
||||
Eina_Rw_Slice *slice,
|
||||
Efl_Gfx_Buffer_Access_Mode mode,
|
||||
int x, int y, int w, int h,
|
||||
Efl_Gfx_Colorspace cspace, int *stride)
|
||||
Efl_Gfx_Colorspace cspace,
|
||||
int plane, int *stride)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
||||
Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
|
||||
int s = 0, width = 0, height = 0;
|
||||
const Eina_Rw_Slice *slice = NULL;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(slice, EINA_FALSE);
|
||||
|
||||
slice->len = 0;
|
||||
slice->mem = NULL;
|
||||
|
||||
if (!ENFN->image_data_map)
|
||||
goto end; // not implemented
|
||||
|
@ -807,34 +868,30 @@ _efl_canvas_image_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
|
|||
goto end;
|
||||
}
|
||||
|
||||
slice = ENFN->image_data_map(ENDT, &o->engine_data, &s, x, y, w, h, cspace, mode);
|
||||
if (slice)
|
||||
if (ENFN->image_data_map(ENDT, &o->engine_data, slice, &s, x, y, w, h, cspace, mode, plane))
|
||||
{
|
||||
DBG("map(%p, %d,%d %dx%d) -> %p (%zu bytes)", eo_obj, x, y, w, h,
|
||||
slice->mem, slice->len);
|
||||
DBG("map(%p, %d,%d %dx%d plane:%d) -> " EINA_SLICE_FMT,
|
||||
eo_obj, x, y, w, h, plane, EINA_SLICE_PRINT(*slice));
|
||||
ret = EINA_TRUE;
|
||||
}
|
||||
else DBG("map(%p, %d,%d %dx%d) -> (null)", eo_obj, x, y, w, h);
|
||||
else DBG("map(%p, %d,%d %dx%d plane:%d) -> (null)", eo_obj, x, y, w, h, plane);
|
||||
|
||||
end:
|
||||
if (length) *length = slice->len;
|
||||
if (stride) *stride = s;
|
||||
return slice->mem;
|
||||
return ret;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_image_efl_gfx_buffer_buffer_unmap(Eo *eo_obj, void *_pd EINA_UNUSED,
|
||||
void *data, int length)
|
||||
const Eina_Rw_Slice *slice)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
||||
Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
|
||||
Eina_Rw_Slice slice;
|
||||
|
||||
if (!ENFN->image_data_unmap || !o->engine_data)
|
||||
if (!slice || !ENFN->image_data_unmap || !o->engine_data)
|
||||
return EINA_FALSE;
|
||||
|
||||
slice.mem = data;
|
||||
slice.len = length;
|
||||
if (!ENFN->image_data_unmap(ENDT, o->engine_data, &slice))
|
||||
if (!ENFN->image_data_unmap(ENDT, o->engine_data, slice))
|
||||
return EINA_FALSE;
|
||||
|
||||
return EINA_TRUE;
|
||||
|
|
|
@ -10,8 +10,8 @@ class Efl.Canvas.Image (Efl.Canvas.Image.Internal, Efl.Gfx.Buffer,
|
|||
]]
|
||||
data: null;
|
||||
implements {
|
||||
Efl.Gfx.Buffer.buffer_data_get;
|
||||
Efl.Gfx.Buffer.buffer_data_set;
|
||||
Efl.Gfx.Buffer.buffer_managed_get;
|
||||
Efl.Gfx.Buffer.buffer_managed_set;
|
||||
Efl.Gfx.Buffer.buffer_copy_set;
|
||||
Efl.Gfx.Buffer.buffer_size.get;
|
||||
Efl.Gfx.Buffer.buffer_map;
|
||||
|
|
|
@ -259,25 +259,37 @@ _proxy_image_get(Evas_Image_Data *o)
|
|||
return source->proxy->surface;
|
||||
}
|
||||
|
||||
EOLIAN static void *
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_proxy_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
|
||||
int *length,
|
||||
Eina_Rw_Slice *slice,
|
||||
Efl_Gfx_Buffer_Access_Mode mode,
|
||||
int x, int y, int w, int h,
|
||||
Efl_Gfx_Colorspace cspace, int *stride)
|
||||
Efl_Gfx_Colorspace cspace, int plane,
|
||||
int *stride)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
||||
Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
|
||||
int len = 0, s = 0, width = 0, height = 0;
|
||||
const Eina_Rw_Slice *slice = NULL;
|
||||
void *image, *data = NULL;
|
||||
int s = 0, width = 0, height = 0;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
void *image;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(slice, EINA_FALSE);
|
||||
|
||||
slice->len = 0;
|
||||
slice->mem = NULL;
|
||||
|
||||
if (!ENFN->image_data_map)
|
||||
goto end; // not implemented
|
||||
|
||||
if (plane)
|
||||
{
|
||||
ERR("invalid plane id for proxy object");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (mode & EFL_GFX_BUFFER_ACCESS_MODE_WRITE)
|
||||
{
|
||||
ERR("invalid map mode for Proxy object");
|
||||
ERR("invalid map mode for proxy object");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -303,34 +315,30 @@ _efl_canvas_proxy_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
|
|||
goto end;
|
||||
}
|
||||
|
||||
slice = ENFN->image_data_map(ENDT, &image, &s, x, y, w, h, cspace, mode);
|
||||
if (slice)
|
||||
if (ENFN->image_data_map(ENDT, &o->engine_data, slice, &s, x, y, w, h, cspace, mode, plane))
|
||||
{
|
||||
DBG("map(%p, %d,%d %dx%d) -> %p (%zu bytes)", eo_obj, x, y, w, h,
|
||||
slice->mem, slice->len);
|
||||
DBG("map(%p, %d,%d %dx%d plane:%d) -> " EINA_SLICE_FMT,
|
||||
eo_obj, x, y, w, h, plane, EINA_SLICE_PRINT(*slice));
|
||||
ret = EINA_TRUE;
|
||||
}
|
||||
else DBG("map(%p, %d,%d %dx%d) -> (null)", eo_obj, x, y, w, h);
|
||||
else DBG("map(%p, %d,%d %dx%d plane:%d) -> (null)", eo_obj, x, y, w, h, plane);
|
||||
|
||||
end:
|
||||
if (length) *length = len;
|
||||
if (stride) *stride = s;
|
||||
return data;
|
||||
return ret;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_proxy_efl_gfx_buffer_buffer_unmap(Eo *eo_obj, void *_pd EINA_UNUSED,
|
||||
void *data, int length)
|
||||
const Eina_Rw_Slice *slice)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
||||
Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
|
||||
Eina_Rw_Slice slice;
|
||||
|
||||
if (!ENFN->image_data_unmap || !o->engine_data)
|
||||
if (!slice || !ENFN->image_data_unmap || !o->engine_data)
|
||||
return EINA_FALSE;
|
||||
|
||||
slice.mem = data;
|
||||
slice.len = length;
|
||||
if (!ENFN->image_data_unmap(ENDT, o->engine_data, &slice))
|
||||
if (!ENFN->image_data_unmap(ENDT, o->engine_data, slice))
|
||||
return EINA_FALSE;
|
||||
|
||||
return EINA_TRUE;
|
||||
|
|
|
@ -208,12 +208,13 @@ _evas_image_3d_unset(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data
|
|||
EINA_COW_WRITE_END(evas_object_3d_cow, obj->data_3d, data);
|
||||
}
|
||||
|
||||
EOLIAN static void *
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_scene3d_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
|
||||
int *length EINA_UNUSED,
|
||||
Eina_Rw_Slice *slice,
|
||||
Efl_Gfx_Buffer_Access_Mode mode,
|
||||
int x, int y, int w, int h,
|
||||
Efl_Gfx_Colorspace cspace, int *stride EINA_UNUSED)
|
||||
Efl_Gfx_Colorspace cspace, int plane,
|
||||
int *stride)
|
||||
{
|
||||
Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
|
||||
Evas_Public_Data *e;
|
||||
|
@ -221,21 +222,27 @@ _efl_canvas_scene3d_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
|
|||
Evas_Canvas3D_Scene_Data *pd_scene;
|
||||
int width = -1, height = -1, ntex = -1;
|
||||
unsigned char *pixels = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(slice, EINA_FALSE);
|
||||
|
||||
slice->len = 0;
|
||||
slice->mem = NULL;
|
||||
|
||||
if (!o->cur->scene)
|
||||
{
|
||||
ERR("invalid scene data");
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
if (mode & EFL_GFX_BUFFER_ACCESS_MODE_WRITE)
|
||||
{
|
||||
ERR("invalid map access mode");
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
if (cspace != EFL_GFX_COLORSPACE_ARGB8888)
|
||||
{
|
||||
ERR("invalid map colorspace. Only ARGB is supported");
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
pd_parent = efl_data_scope_get(o->cur->scene, EVAS_CANVAS3D_OBJECT_CLASS);
|
||||
|
@ -252,7 +259,7 @@ _efl_canvas_scene3d_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
|
|||
{
|
||||
ERR("Invalid map dimensions : %dx%d +%d,%d. Image is %dx%d.",
|
||||
w, h, x, y, width, height);
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (e->engine.func->drawable_texture_target_id_get)
|
||||
|
@ -261,23 +268,30 @@ _efl_canvas_scene3d_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
|
|||
|
||||
if (e->engine.func->drawable_texture_rendered_pixels_get)
|
||||
{
|
||||
pixels = malloc(w * h * sizeof(DATA32)); //four component texture
|
||||
len = w * h * sizeof(DATA32); //four component texture
|
||||
pixels = malloc(len + sizeof(*slice) + 8);
|
||||
e->engine.func->drawable_texture_rendered_pixels_get(ntex, x, y, w, h,
|
||||
pd_scene->surface, pixels);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
|
||||
return pixels;
|
||||
if (stride) *stride = w * sizeof(DATA32);
|
||||
slice->mem = pixels;
|
||||
slice->len = len;
|
||||
DBG("map(%p, %d,%d %dx%d plane:%d) -> " EINA_SLICE_FMT,
|
||||
eo_obj, x, y, w, h, plane, EINA_SLICE_PRINT(*slice));
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_scene3d_efl_gfx_buffer_buffer_unmap(Eo *eo_obj EINA_UNUSED, void *_pd EINA_UNUSED,
|
||||
void *data, int length EINA_UNUSED)
|
||||
const Eina_Rw_Slice *slice)
|
||||
{
|
||||
free(data);
|
||||
free(slice->mem);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -1369,7 +1369,7 @@ struct _Evas_Func
|
|||
Eina_Bool (*image_can_region_get) (void *data, void *image);
|
||||
|
||||
/* image data map/unmap: direct or indirect access to pixels data */
|
||||
const Eina_Rw_Slice *(*image_data_map) (void *data, void **image, int *stride, int x, int y, int w, int h, Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode);
|
||||
Eina_Bool (*image_data_map) (void *data, void **image, Eina_Rw_Slice *slice, int *stride, int x, int y, int w, int h, Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode, int plane);
|
||||
Eina_Bool (*image_data_unmap) (void *data, void *image, const Eina_Rw_Slice *slice);
|
||||
int (*image_data_maps_get) (void *data, const void *image, const Eina_Rw_Slice **slices);
|
||||
|
||||
|
|
|
@ -2794,17 +2794,18 @@ eng_ector_end(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
|
|||
}
|
||||
}
|
||||
|
||||
static const Eina_Rw_Slice *
|
||||
eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
||||
static Eina_Bool
|
||||
eng_image_data_map(void *engdata EINA_UNUSED, void **image, Eina_Rw_Slice *slice,
|
||||
int *stride, int x, int y, int w, int h,
|
||||
Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode)
|
||||
Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode,
|
||||
int plane)
|
||||
{
|
||||
Eina_Bool cow = EINA_FALSE, to_write = EINA_FALSE;
|
||||
Evas_GL_Image_Data_Map *map = NULL;
|
||||
const Eina_Rw_Slice *slice = NULL;
|
||||
Evas_GL_Image *im;
|
||||
Eina_Bool ok;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(image && *image, NULL);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(image && *image && slice, EINA_FALSE);
|
||||
im = *image;
|
||||
|
||||
if (mode & EFL_GFX_BUFFER_ACCESS_MODE_COW)
|
||||
|
@ -2818,9 +2819,9 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
|||
int strid = 0;
|
||||
|
||||
// Call sw generic implementation. Should work for simple cases.
|
||||
slice = pfunc.image_data_map(NULL, (void **) &im->im, &strid,
|
||||
x, y, w, h, cspace, mode);
|
||||
if (slice)
|
||||
ok = pfunc.image_data_map(NULL, (void **) &im->im, slice, &strid,
|
||||
x, y, w, h, cspace, mode, plane);
|
||||
if (ok)
|
||||
{
|
||||
map = calloc(1, sizeof(*map));
|
||||
map->cspace = cspace;
|
||||
|
@ -2835,12 +2836,12 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
|||
im->maps = eina_inlist_prepend(im->maps, EINA_INLIST_GET(map));
|
||||
}
|
||||
if (stride) *stride = strid;
|
||||
return &map->slice;
|
||||
return ok;
|
||||
}
|
||||
|
||||
// TODO: glReadPixels from FBO if possible
|
||||
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
|
@ -2850,7 +2851,7 @@ eng_image_data_unmap(void *engdata EINA_UNUSED, void *image, const Eina_Rw_Slice
|
|||
Evas_GL_Image *im = image;
|
||||
Eina_Bool found = EINA_FALSE;
|
||||
|
||||
if (!im || !slice)
|
||||
if (!(image && slice))
|
||||
return EINA_FALSE;
|
||||
|
||||
EINA_INLIST_FOREACH(im->maps, map)
|
||||
|
|
|
@ -1453,10 +1453,11 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
|
|||
return im;
|
||||
}
|
||||
|
||||
static const Eina_Rw_Slice *
|
||||
eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
||||
static Eina_Bool
|
||||
eng_image_data_map(void *engdata EINA_UNUSED, void **image, Eina_Rw_Slice *slice,
|
||||
int *stride, int x, int y, int w, int h,
|
||||
Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode)
|
||||
Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode,
|
||||
int plane)
|
||||
{
|
||||
Eina_Bool cow = EINA_FALSE, to_write = EINA_FALSE;
|
||||
RGBA_Image_Data_Map *map;
|
||||
|
@ -1465,17 +1466,26 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
|||
int src_stride, src_offset;
|
||||
void *data;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(image && *image, NULL);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(image && *image && slice, EINVAL);
|
||||
im = *image;
|
||||
ie = &im->cache_entry;
|
||||
|
||||
slice->len = 0;
|
||||
slice->mem = NULL;
|
||||
|
||||
// FIXME: implement planes support (YUV, RGB565, ETC1+Alpha)
|
||||
// FIXME: implement YUV support (im->cs.data)
|
||||
if (plane)
|
||||
{
|
||||
ERR("planar formats support not implemented yet!");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!im->image.data)
|
||||
{
|
||||
int error = evas_cache_image_load_data(ie);
|
||||
if (error != EVAS_LOAD_ERROR_NONE)
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (mode & EFL_GFX_BUFFER_ACCESS_MODE_COW)
|
||||
|
@ -1490,7 +1500,7 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
|||
{
|
||||
ERR("invalid region for colorspace %d: %dx%d + %d,%d, image: %dx%d",
|
||||
cspace, w, h, x, y, ie->w, ie->h);
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
src_stride = _evas_common_rgba_image_data_offset(ie->w, 0, 0, 0, 0, im);
|
||||
|
@ -1502,7 +1512,7 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
|||
{
|
||||
ERR("can't map shared image data multiple times with "
|
||||
"different COW flag");
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1510,7 +1520,7 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
|||
if (cow)
|
||||
{
|
||||
ie = evas_cache_image_alone(ie);
|
||||
if (!ie) return NULL;
|
||||
if (!ie) return EINA_FALSE;
|
||||
im = (RGBA_Image *) ie;
|
||||
*image = im;
|
||||
}
|
||||
|
@ -1519,7 +1529,7 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
|||
if (to_write && (ie->references > 1))
|
||||
{
|
||||
ERR("write map requires COW flag for shared images");
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1535,11 +1545,11 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
|||
int dst_stride, dst_len, dst_offset = 0;
|
||||
|
||||
cs_func = efl_draw_convert_func_get(ie->space, cspace, &can_region);
|
||||
if (!cs_func) return NULL;
|
||||
if (!cs_func) return EINA_FALSE;
|
||||
|
||||
// make sure we can convert back, if map for writing
|
||||
if (to_write && !efl_draw_convert_func_get(cspace, ie->space, NULL))
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
|
||||
if (can_region)
|
||||
{
|
||||
|
@ -1568,20 +1578,20 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
|||
dst_len = rh * dst_stride;
|
||||
|
||||
data = malloc(dst_len);
|
||||
if (!data) return NULL;
|
||||
if (!data) return EINA_FALSE;
|
||||
|
||||
if (!cs_func(data, src_data, rw, rh, src_stride, dst_stride, ie->flags.alpha, ie->space, cspace))
|
||||
{
|
||||
ERR("color conversion failed");
|
||||
free(data);
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
map = calloc(1, sizeof(*map));
|
||||
if (!map)
|
||||
{
|
||||
free(data);
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
map->allocated = EINA_TRUE;
|
||||
map->cspace = cspace;
|
||||
|
@ -1603,7 +1613,7 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
|||
// no copy
|
||||
int end_offset = _evas_common_rgba_image_data_offset(x + w, y + h, 0, 0, 0, im) - src_stride;
|
||||
map = calloc(1, sizeof(*map));
|
||||
if (!map) return NULL;
|
||||
if (!map) return EINA_FALSE;
|
||||
|
||||
map->baseptr = im->image.data8;
|
||||
map->slice.mem = im->image.data8 + src_offset;
|
||||
|
@ -1614,12 +1624,12 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
|||
// copy
|
||||
int size = _evas_common_rgba_image_data_offset(w, h, 0, 0, 0, im);
|
||||
data = malloc(size);
|
||||
if (!data) return NULL;
|
||||
if (!data) return EINA_FALSE;
|
||||
map = calloc(1, sizeof(*map));
|
||||
if (!map)
|
||||
{
|
||||
free(data);
|
||||
return NULL;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
memcpy(data, im->image.data8 + src_offset, size);
|
||||
|
||||
|
@ -1639,7 +1649,9 @@ eng_image_data_map(void *engdata EINA_UNUSED, void **image,
|
|||
im->maps = (RGBA_Image_Data_Map *)
|
||||
eina_inlist_prepend(EINA_INLIST_GET(im->maps), EINA_INLIST_GET(map));
|
||||
if (stride) *stride = map->stride;
|
||||
return &map->slice;
|
||||
slice->mem = map->slice.mem;
|
||||
slice->len = map->slice.len;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1693,7 +1705,7 @@ eng_image_data_unmap(void *engdata EINA_UNUSED, void *image, const Eina_Rw_Slice
|
|||
RGBA_Image_Data_Map *map;
|
||||
RGBA_Image *im = image;
|
||||
|
||||
if (!im || !slice)
|
||||
if (!(image && slice))
|
||||
return EINA_FALSE;
|
||||
|
||||
EINA_INLIST_FOREACH(EINA_INLIST_GET(im->maps), map)
|
||||
|
|
|
@ -659,15 +659,13 @@ START_TEST(evas_object_image_map_unmap)
|
|||
{
|
||||
Evas *e = _setup_evas();
|
||||
Evas_Object *o, *o2;
|
||||
void *data;
|
||||
int len, stride;
|
||||
int w, h, rx, ry, rw, rh;
|
||||
int stride, w, h, rx, ry, rw, rh;
|
||||
Efl_Gfx_Colorspace cs;
|
||||
Eina_Tmpstr *tmp;
|
||||
int fd;
|
||||
uint32_t *data32;
|
||||
uint8_t *data8;
|
||||
Eina_Bool all_white = 1, all_transparent = 1;
|
||||
Eina_Rw_Slice slice;
|
||||
|
||||
const char *imgpath = TESTS_IMG_DIR "/Pic4.png";
|
||||
|
||||
|
@ -682,26 +680,23 @@ START_TEST(evas_object_image_map_unmap)
|
|||
rh = (h / 2) & ~3;
|
||||
|
||||
// same cspace, full image
|
||||
data = efl_gfx_buffer_map(o, &len, EFL_GFX_BUFFER_ACCESS_MODE_READ, 0, 0, w, h, cs, &stride);
|
||||
fail_if(!data);
|
||||
fail_if(!len);
|
||||
fail_if(!efl_gfx_buffer_map(o, &slice, EFL_GFX_BUFFER_ACCESS_MODE_READ, 0, 0, w, h, cs, 0, &stride));
|
||||
fail_if(!slice.len || !slice.mem);
|
||||
fail_if(!stride);
|
||||
efl_gfx_buffer_unmap(o, data, len);
|
||||
efl_gfx_buffer_unmap(o, &slice);
|
||||
|
||||
// same cspace, partial image
|
||||
data = efl_gfx_buffer_map(o, &len, EFL_GFX_BUFFER_ACCESS_MODE_READ, rx, ry, rw, rh, cs, &stride);
|
||||
fail_if(!data);
|
||||
fail_if(!len);
|
||||
fail_if(!efl_gfx_buffer_map(o, &slice, EFL_GFX_BUFFER_ACCESS_MODE_READ, rx, ry, rw, rh, cs, 0, &stride));
|
||||
fail_if(!slice.len || !slice.mem);
|
||||
fail_if(!stride);
|
||||
efl_gfx_buffer_unmap(o, data, len);
|
||||
efl_gfx_buffer_unmap(o, &slice);
|
||||
|
||||
// argb cspace, full image
|
||||
data = efl_gfx_buffer_map(o, &len, EFL_GFX_BUFFER_ACCESS_MODE_READ, 0, 0, w, h, EFL_GFX_COLORSPACE_ARGB8888, &stride);
|
||||
fail_if(!data);
|
||||
fail_if(!len);
|
||||
fail_if(!efl_gfx_buffer_map(o, &slice, EFL_GFX_BUFFER_ACCESS_MODE_READ, 0, 0, w, h, EFL_GFX_COLORSPACE_ARGB8888, 0, &stride));
|
||||
fail_if(!slice.len || !slice.mem);
|
||||
fail_if(!stride);
|
||||
data32 = data;
|
||||
for (int k = 0; (k < len) && (all_white || all_transparent); k++)
|
||||
data32 = slice.mem;
|
||||
for (int k = 0; (k < slice.len) && (all_white || all_transparent); k++)
|
||||
{
|
||||
if (data32[k])
|
||||
all_transparent = 0;
|
||||
|
@ -709,49 +704,45 @@ START_TEST(evas_object_image_map_unmap)
|
|||
all_white = 0;
|
||||
}
|
||||
fail_if(all_white || all_transparent);
|
||||
efl_gfx_buffer_unmap(o, data, len);
|
||||
efl_gfx_buffer_unmap(o, &slice);
|
||||
|
||||
// argb cspace, partial image
|
||||
data = efl_gfx_buffer_map(o, &len, EFL_GFX_BUFFER_ACCESS_MODE_READ, rx, ry, rw, rh, EFL_GFX_COLORSPACE_ARGB8888, &stride);
|
||||
fail_if(!data);
|
||||
fail_if(!len);
|
||||
fail_if(!efl_gfx_buffer_map(o, &slice, EFL_GFX_BUFFER_ACCESS_MODE_READ, rx, ry, rw, rh, EFL_GFX_COLORSPACE_ARGB8888, 0, &stride));
|
||||
fail_if(!slice.len || !slice.mem);
|
||||
fail_if(!stride);
|
||||
efl_gfx_buffer_unmap(o, data, len);
|
||||
efl_gfx_buffer_unmap(o, &slice);
|
||||
|
||||
// argb cspace, partial image, write
|
||||
data = efl_gfx_buffer_map(o, &len, EFL_GFX_BUFFER_ACCESS_MODE_WRITE, rx, ry, rw, rh, EFL_GFX_COLORSPACE_ARGB8888, &stride);
|
||||
fail_if(!data);
|
||||
fail_if(!len);
|
||||
fail_if(!efl_gfx_buffer_map(o, &slice, EFL_GFX_BUFFER_ACCESS_MODE_WRITE, rx, ry, rw, rh, EFL_GFX_COLORSPACE_ARGB8888, 0, &stride));
|
||||
fail_if(!slice.len || !slice.mem);
|
||||
fail_if(!stride);
|
||||
data32 = data;
|
||||
data32 = slice.mem;
|
||||
for (int y = 0; y < rh; y += 2)
|
||||
for (int x = 0; x < rw; x++)
|
||||
{
|
||||
data32[y*stride/4 + x] = 0xFF00FF00;
|
||||
data32[(y+1)*stride/4 + x] = 0xFFFF0000;
|
||||
}
|
||||
efl_gfx_buffer_unmap(o, data, len);
|
||||
efl_gfx_buffer_unmap(o, &slice);
|
||||
|
||||
// argb cspace, partial image, write
|
||||
data = efl_gfx_buffer_map(o, &len, EFL_GFX_BUFFER_ACCESS_MODE_READ| EFL_GFX_BUFFER_ACCESS_MODE_WRITE,
|
||||
rx, ry, rw, rh / 2, EFL_GFX_COLORSPACE_GRY8, &stride);
|
||||
fail_if(!data);
|
||||
fail_if(!len);
|
||||
fail_if(!efl_gfx_buffer_map(o, &slice, EFL_GFX_BUFFER_ACCESS_MODE_READ| EFL_GFX_BUFFER_ACCESS_MODE_WRITE,
|
||||
rx, ry, rw, rh / 2, EFL_GFX_COLORSPACE_GRY8, 0, &stride));
|
||||
fail_if(!slice.len || !slice.mem);
|
||||
fail_if(!stride);
|
||||
data8 = data;
|
||||
for (int y = 0; y < rh / 4; y++)
|
||||
for (int x = 0; x < rw; x++)
|
||||
data8[y*stride + x] = x & 0xFF;
|
||||
efl_gfx_buffer_unmap(o, data, len);
|
||||
slice.bytes[y*stride + x] = x & 0xFF;
|
||||
efl_gfx_buffer_unmap(o, &slice);
|
||||
|
||||
// save file, verify its pixels
|
||||
fd = eina_file_mkstemp("/tmp/evas-test.XXXXXX.png", &tmp);
|
||||
close(fd);
|
||||
if (efl_file_save(o, tmp, NULL, NULL))
|
||||
{
|
||||
int w2, h2, stride2, len2;
|
||||
uint32_t *data2, *orig;
|
||||
int x, y;
|
||||
Eina_Rw_Slice sorig, sdest;
|
||||
int w2, h2, stride2, x, y;
|
||||
uint32_t *dest, *orig;
|
||||
|
||||
o2 = efl_add(EFL_CANVAS_IMAGE_CLASS, e);
|
||||
efl_file_set(o2, tmp, NULL);
|
||||
|
@ -763,20 +754,21 @@ START_TEST(evas_object_image_map_unmap)
|
|||
fail_if(w2 != w);
|
||||
fail_if(h2 != h);
|
||||
|
||||
orig = efl_gfx_buffer_map(o, &len, EFL_GFX_BUFFER_ACCESS_MODE_READ, 0, 0, w, h, EFL_GFX_COLORSPACE_ARGB8888, &stride);
|
||||
fail_if(!orig);
|
||||
fail_if(!len);
|
||||
fail_if(!efl_gfx_buffer_map(o, &sorig, EFL_GFX_BUFFER_ACCESS_MODE_READ, 0, 0, w, h, EFL_GFX_COLORSPACE_ARGB8888, 0, &stride));
|
||||
fail_if(!sorig.len || !sorig.mem);
|
||||
fail_if(!stride);
|
||||
|
||||
data2 = efl_gfx_buffer_map(o2, &len2, EFL_GFX_BUFFER_ACCESS_MODE_READ, 0, 0, w2, h2, EFL_GFX_COLORSPACE_ARGB8888, &stride2);
|
||||
fail_if(!data2);
|
||||
fail_if(len2 != len);
|
||||
fail_if(!efl_gfx_buffer_map(o2, &sdest, EFL_GFX_BUFFER_ACCESS_MODE_READ, 0, 0, w2, h2, EFL_GFX_COLORSPACE_ARGB8888, 0, &stride2));
|
||||
fail_if(sorig.len != sdest.len);
|
||||
fail_if(stride2 != stride);
|
||||
|
||||
dest = sdest.mem;
|
||||
orig = sorig.mem;
|
||||
|
||||
// first quarter: same image
|
||||
for (y = 0; y < h / 4; y++)
|
||||
for (x = 0; x < w; x++)
|
||||
fail_if(orig[y*stride/4 + x] != data2[y*stride2/4+x], "pixels differ [1]");
|
||||
fail_if(orig[y*stride/4 + x] != dest[y*stride2/4+x], "pixels differ [1]");
|
||||
|
||||
// middle zone top: grey gradient
|
||||
for (y = ry; y < (ry + rh / 4); y++)
|
||||
|
@ -784,28 +776,28 @@ START_TEST(evas_object_image_map_unmap)
|
|||
{
|
||||
uint32_t c = (x - rx) & 0xFF;
|
||||
c = 0xFF000000 | (c << 16) | (c << 8) | c;
|
||||
fail_if(data2[y*stride/4 + x] != c, "pixels differ [2]");
|
||||
fail_if(dest[y*stride/4 + x] != c, "pixels differ [2]");
|
||||
}
|
||||
|
||||
// middle zone: grey image
|
||||
for (y = (ry + rh / 4 + 1); y < (ry + rh / 2); y++)
|
||||
for (x = rx; x < rx + rw; x++)
|
||||
{
|
||||
uint32_t c = data2[y*stride/4 + x] & 0xFF;
|
||||
uint32_t c = dest[y*stride/4 + x] & 0xFF;
|
||||
c = 0xFF000000 | (c << 16) | (c << 8) | c;
|
||||
fail_if(data2[y*stride/4 + x] != c, "pixels differ [2bis]");
|
||||
fail_if(dest[y*stride/4 + x] != c, "pixels differ [2bis]");
|
||||
}
|
||||
|
||||
// next lines: green & red
|
||||
y = ry + rh / 2;
|
||||
for (x = rx; x < rx + rw; x++)
|
||||
{
|
||||
fail_if(data2[y*stride/4 + x] != 0xFF00FF00, "pixels differ [3]");
|
||||
fail_if(data2[(y+1)*stride/4 + x] != 0xFFFF0000, "pixels differ [4]");
|
||||
fail_if(dest[y*stride/4 + x] != 0xFF00FF00, "pixels differ [3]");
|
||||
fail_if(dest[(y+1)*stride/4 + x] != 0xFFFF0000, "pixels differ [4]");
|
||||
}
|
||||
|
||||
efl_gfx_buffer_unmap(o, orig, len);
|
||||
efl_gfx_buffer_unmap(o2, data2, len2);
|
||||
efl_gfx_buffer_unmap(o, &sorig);
|
||||
efl_gfx_buffer_unmap(o2, &sdest);
|
||||
}
|
||||
else unlink(tmp);
|
||||
eina_tmpstr_del(tmp);
|
||||
|
|
Loading…
Reference in New Issue