forked from enlightenment/efl
Evas filters: Use Ector.Buffer instead of RGBA_Image
This is a major refactoring of the evas filters submodule. Use Ector.Buffer and the map/unmap methods instead of directly accessing image buffers with RGBA_Image. RGBA_Image is still used under the hood, for two reasons: - Required for the final output (blend onto Evas itself) - Required for the scaling routines FIXME: - Breaks proxy support (ie. all kind of texturing). - This breaks filters support for the GL engine.
This commit is contained in:
parent
e3af2783ff
commit
57902fffd3
|
@ -242,7 +242,8 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
|
|||
|
||||
// Request rendering from the object itself (child class)
|
||||
evas_filter_program_padding_get(pd->data->chain, &l, &r, &t, &b);
|
||||
eo_do(eo_obj, evas_filter_input_render(filter, drawctx, l, r, t, b, do_async));
|
||||
eo_do(eo_obj, ok = evas_filter_input_render(filter, drawctx, l, r, t, b, do_async));
|
||||
if (!ok) ERR("Filter input render failed.");
|
||||
|
||||
ENFN->context_free(ENDT, drawctx);
|
||||
|
||||
|
|
|
@ -21,25 +21,28 @@
|
|||
#endif
|
||||
|
||||
#include "evas_filter_private.h"
|
||||
#include <Ector.h>
|
||||
#include <software/Ector_Software.h>
|
||||
#include "evas_ector_buffer.eo.h"
|
||||
|
||||
#define _assert(a) if (!(a)) CRI("Failed on %s", #a);
|
||||
|
||||
static void _buffer_free(Evas_Filter_Buffer *fb);
|
||||
static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd);
|
||||
static RGBA_Image *_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data);
|
||||
static Ector_Buffer* _ector_buffer_create(Evas_Filter_Buffer const *fb, void *data);
|
||||
|
||||
#define DRAW_COLOR_SET(r, g, b, a) do { cmd->draw.R = r; cmd->draw.G = g; cmd->draw.B = b; cmd->draw.A = a; } while (0)
|
||||
#define DRAW_CLIP_SET(_x, _y, _w, _h) do { cmd->draw.clip.x = _x; cmd->draw.clip.y = _y; cmd->draw.clip.w = _w; cmd->draw.clip.h = _h; } while (0)
|
||||
#define DRAW_FILL_SET(fmode) do { cmd->draw.fillmode = fmode; } while (0)
|
||||
|
||||
typedef struct _Evas_Filter_Thread_Command Evas_Filter_Thread_Command;
|
||||
struct _Evas_Filter_Thread_Command
|
||||
static inline void *
|
||||
_evas_image_get(Ector_Buffer *buf)
|
||||
{
|
||||
Evas_Filter_Context *ctx;
|
||||
RGBA_Image *src, *mask, *dst;
|
||||
Evas_Filter_Apply_Func func;
|
||||
};
|
||||
|
||||
void *image = NULL;
|
||||
if (!buf) return NULL;
|
||||
eo_do(buf, evas_ector_buffer_engine_image_get(NULL, &image));
|
||||
return image;
|
||||
}
|
||||
|
||||
/* Main functions */
|
||||
|
||||
|
@ -67,6 +70,11 @@ evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async)
|
|||
* better and implement filters direcly with shaders.
|
||||
*/
|
||||
ctx->gl_engine = (evas->engine.func->gl_surface_read_pixels != NULL);
|
||||
if (ctx->gl_engine)
|
||||
{
|
||||
// FIXME!!!
|
||||
CRI("gl support not implemented");
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
@ -92,45 +100,22 @@ evas_filter_context_clear(Evas_Filter_Context *ctx)
|
|||
// Note: don't reset post_run, as it it set by the client
|
||||
}
|
||||
|
||||
static void
|
||||
_backing_free(Evas_Filter_Context *ctx, RGBA_Image *im)
|
||||
{
|
||||
if (!im) return;
|
||||
|
||||
if (!ctx->gl_engine)
|
||||
{
|
||||
if (!ctx->async)
|
||||
ENFN->image_free(ENDT, im);
|
||||
else
|
||||
evas_unref_queue_image_put(ctx->evas, &im->cache_entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
evas_cache2_image_close(&im->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_drop(&im->cache_entry);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_filter_buffer_backing_free(Evas_Filter_Buffer *fb)
|
||||
{
|
||||
if (!fb) return;
|
||||
|
||||
_backing_free(fb->ctx, fb->backing);
|
||||
if (fb->glimage)
|
||||
fb->ENFN->image_free(fb->ENDT, fb->glimage);
|
||||
fb->backing = NULL;
|
||||
fb->glimage = NULL;
|
||||
if (!fb || !fb->buffer) return;
|
||||
eo_del(fb->buffer);
|
||||
fb->buffer = NULL;
|
||||
}
|
||||
|
||||
/* GL engine stuff: read-back from texture */
|
||||
static Eina_Bool
|
||||
_filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb, void *glimage)
|
||||
_filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb EINA_UNUSED, void *glimage EINA_UNUSED)
|
||||
{
|
||||
CRI("not implemented");
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
Eina_Bool ok;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
|
||||
|
@ -143,8 +128,8 @@ _filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb, void *glimage)
|
|||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_read_pixels, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_unlock, EINA_FALSE);
|
||||
|
||||
fb->backing = _rgba_image_alloc(fb, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb->backing, EINA_FALSE);
|
||||
fb->buffer = _ector_buffer_create(fb, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb->buffer, EINA_FALSE);
|
||||
|
||||
ok = fb->ENFN->gl_surface_lock(fb->ENDT, glimage);
|
||||
if (!ok)
|
||||
|
@ -163,13 +148,18 @@ _filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb, void *glimage)
|
|||
|
||||
ok &= fb->ENFN->gl_surface_unlock(fb->ENDT, glimage);
|
||||
return ok;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @hidden private render proxy objects */
|
||||
void
|
||||
evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
|
||||
Eina_Bool do_async)
|
||||
evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx EINA_UNUSED, Eo *eo_obj EINA_UNUSED,
|
||||
Eina_Bool do_async EINA_UNUSED)
|
||||
{
|
||||
CRI("not implemented");
|
||||
return;
|
||||
|
||||
#if 0
|
||||
Evas_Object_Protected_Data *source;
|
||||
Evas_Object_Protected_Data *obj;
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
@ -208,6 +198,7 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
|
|||
fb->alpha_only = EINA_FALSE;
|
||||
XDBG("Source has dimensions %dx%d (buffer %d)", fb->w, fb->h, fb->id);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -257,63 +248,43 @@ _buffer_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only)
|
|||
return fb;
|
||||
}
|
||||
|
||||
static RGBA_Image *
|
||||
_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data)
|
||||
static Ector_Buffer *
|
||||
_ector_buffer_create(Evas_Filter_Buffer const *fb, void *data)
|
||||
{
|
||||
Evas_Colorspace cspace;
|
||||
RGBA_Image *image;
|
||||
size_t sz;
|
||||
Image_Entry *ie;
|
||||
|
||||
cspace = fb->alpha_only ? EVAS_COLORSPACE_GRY8 : EVAS_COLORSPACE_ARGB8888;
|
||||
if (!fb->ctx->gl_engine)
|
||||
{
|
||||
if (!data)
|
||||
{
|
||||
image = fb->ENFN->image_new_from_copied_data
|
||||
(fb->ENDT, fb->w, fb->h, NULL, EINA_TRUE, cspace);
|
||||
}
|
||||
else
|
||||
{
|
||||
image = fb->ENFN->image_new_from_data
|
||||
(fb->ENDT, fb->w, fb->h, data, EINA_TRUE, cspace);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: Directly calling the alloc functions since we want to use sw surfaces.
|
||||
// FIXME: We still rely on evas image structs (scaling and target render)
|
||||
// This should be fixed by implementing full support in ector
|
||||
// Note: dropped support for cserve2, that was not needed anyway
|
||||
|
||||
if (!data)
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
image = (RGBA_Image *) evas_cache2_image_copied_data
|
||||
(evas_common_image_cache2_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace);
|
||||
else
|
||||
cspace = fb->alpha_only ? E_ALPHA : E_ARGB;
|
||||
#if 0
|
||||
// ideal code
|
||||
return fb->ENFN->ector_buffer_new(fb->ENDT, fb->ctx->evas->evas,
|
||||
data, fb->w, fb->h, 0,
|
||||
cspace, EINA_TRUE, 0, 0, 0, 0,
|
||||
ECTOR_BUFFER_FLAG_CPU_READABLE |
|
||||
ECTOR_BUFFER_FLAG_CPU_WRITABLE);
|
||||
#endif
|
||||
image = (RGBA_Image *) evas_cache_image_copied_data
|
||||
(evas_common_image_cache_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace);
|
||||
|
||||
if (data)
|
||||
{
|
||||
// no copy
|
||||
ie = evas_cache_image_data(evas_common_image_cache_get(), fb->w, fb->h,
|
||||
data, EINA_TRUE, cspace);
|
||||
if (!ie) return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
image = (RGBA_Image *) evas_cache2_image_data
|
||||
(evas_common_image_cache2_get(), fb->w, fb->h, data, EINA_TRUE, cspace);
|
||||
else
|
||||
#endif
|
||||
image = (RGBA_Image *) evas_cache_image_data
|
||||
(evas_common_image_cache_get(), fb->w, fb->h, data, EINA_TRUE, cspace);
|
||||
// alloc buffer
|
||||
ie = evas_cache_image_copied_data(evas_common_image_cache_get(), fb->w, fb->h,
|
||||
NULL, EINA_TRUE, cspace);
|
||||
if (!ie) return NULL;
|
||||
data = ((RGBA_Image *) ie)->image.data;
|
||||
memset(data, 0, fb->w * fb->h * (fb->alpha_only ? 1 : 4));
|
||||
}
|
||||
}
|
||||
if (!image) return NULL;
|
||||
|
||||
if (fb->alpha_only)
|
||||
sz = image->cache_entry.w * image->cache_entry.h * sizeof(DATA8);
|
||||
else
|
||||
sz = image->cache_entry.w * image->cache_entry.h * sizeof(DATA32);
|
||||
if (!data) memset(image->image.data, 0, sz);
|
||||
|
||||
return image;
|
||||
return fb->ENFN->ector_buffer_wrap(fb->ENDT, fb->ctx->evas->evas, ie);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
|
@ -404,7 +375,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
|
|||
|
||||
EINA_LIST_FOREACH(ctx->buffers, li, fb)
|
||||
{
|
||||
if (fb->backing || fb->source || fb->glimage)
|
||||
if (fb->buffer || fb->source || fb->glimage)
|
||||
continue;
|
||||
|
||||
if (!fb->w && !fb->h)
|
||||
|
@ -413,10 +384,10 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
|
|||
continue;
|
||||
}
|
||||
|
||||
fb->backing = _rgba_image_alloc(fb, NULL);
|
||||
XDBG("Allocating buffer #%d of size %ux%u %s",
|
||||
fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba");
|
||||
if (!fb->backing) goto alloc_fail;
|
||||
fb->buffer = _ector_buffer_create(fb, NULL);
|
||||
XDBG("Allocated buffer #%d of size %ux%u %s: %p",
|
||||
fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba", fb->buffer);
|
||||
if (!fb->buffer) goto alloc_fail;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
|
@ -457,35 +428,29 @@ _filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data,
|
|||
if (w <= 0 || h <= 0)
|
||||
return EINA_FALSE;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->backing == NULL, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->buffer == NULL, EINA_FALSE);
|
||||
// TODO: Check input parameters?
|
||||
fb->alpha_only = alpha_only;
|
||||
fb->w = w;
|
||||
fb->h = h;
|
||||
|
||||
fb->backing = _rgba_image_alloc(fb, data);
|
||||
return (fb->backing != NULL);
|
||||
fb->buffer = _ector_buffer_create(fb, data);
|
||||
return (fb->buffer != NULL);
|
||||
}
|
||||
|
||||
int
|
||||
evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image)
|
||||
static int
|
||||
_filter_buffer_new_from_evas_surface(Evas_Filter_Context *ctx, void *image)
|
||||
{
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
|
||||
|
||||
image = ENFN->image_ref(ENDT, image);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(image, -1);
|
||||
|
||||
fb = calloc(1, sizeof(Evas_Filter_Buffer));
|
||||
if (!fb) return -1;
|
||||
|
||||
fb->id = ++(ctx->last_buffer_id);
|
||||
fb->ctx = ctx;
|
||||
if (!ctx->gl_engine)
|
||||
fb->backing = image;
|
||||
else
|
||||
fb->glimage = image;
|
||||
fb->buffer = ENFN->ector_buffer_wrap(ENDT, ctx->evas->evas, image);
|
||||
ENFN->image_size_get(ENDT, image, &fb->w, &fb->h);
|
||||
fb->alpha_only = (ENFN->image_colorspace_get(ENDT, image)
|
||||
== EVAS_COLORSPACE_GRY8);
|
||||
|
@ -544,12 +509,12 @@ _filter_buffer_get(Evas_Filter_Context *ctx, int bufid)
|
|||
void *
|
||||
evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid)
|
||||
{
|
||||
Evas_Filter_Buffer *buffer;
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
||||
buffer = _filter_buffer_get(ctx, bufid);
|
||||
if (!buffer) return NULL;
|
||||
fb = _filter_buffer_get(ctx, bufid);
|
||||
if (!fb) return NULL;
|
||||
|
||||
return buffer->backing;
|
||||
return _evas_image_get(fb->buffer);
|
||||
}
|
||||
|
||||
void *
|
||||
|
@ -557,15 +522,10 @@ evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid)
|
|||
{
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
|
||||
|
||||
fb = _filter_buffer_get(ctx, bufid);
|
||||
if (!fb) return NULL;
|
||||
|
||||
if (ctx->gl_engine)
|
||||
return fb->ENFN->image_ref(fb->ENDT, fb->glimage);
|
||||
else
|
||||
return fb->ENFN->image_ref(fb->ENDT, fb->backing);
|
||||
return fb->ENFN->image_ref(fb->ENDT, _evas_image_get(fb->buffer));
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
|
@ -577,11 +537,11 @@ evas_filter_buffer_backing_release(Evas_Filter_Context *ctx,
|
|||
|
||||
if (ctx->async)
|
||||
evas_unref_queue_image_put(ctx->evas, stolen_buffer);
|
||||
else if (ctx->gl_engine)
|
||||
else
|
||||
{
|
||||
ctx->post_run.buffers_to_free =
|
||||
eina_list_append(ctx->post_run.buffers_to_free, stolen_buffer);
|
||||
else
|
||||
_backing_free(ctx, stolen_buffer);
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
@ -1345,12 +1305,6 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (in->alpha_only != out->alpha_only)
|
||||
{
|
||||
CRI("Incompatible buffer formats");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd = _command_new(ctx, EVAS_FILTER_MODE_TRANSFORM, in, NULL, out);
|
||||
if (!cmd) return -1;
|
||||
|
||||
|
@ -1372,7 +1326,7 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
|
|||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
|
||||
|
||||
ctx->target.bufid = evas_filter_buffer_image_new(ctx, surface);
|
||||
ctx->target.bufid = _filter_buffer_new_from_evas_surface(ctx, surface);
|
||||
ctx->target.x = x;
|
||||
ctx->target.y = y;
|
||||
ctx->target.clip_use = ENFN->context_clip_get
|
||||
|
@ -1391,6 +1345,7 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
|
|||
ctx->evas->engine.func->image_free(ctx->evas->engine.data.output, ctx->target.mask);
|
||||
ctx->target.mask = mask;
|
||||
|
||||
#if 0
|
||||
if (ctx->gl_engine)
|
||||
{
|
||||
// Since GL has sync rendering, draw_context is safe to keep around
|
||||
|
@ -1410,6 +1365,7 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
|
|||
XDBG("Set target as #%d (%p) and output #%d (%p, gl %p)",
|
||||
ctx->target.bufid, surface, fb->id, fb->backing, fb->glimage);
|
||||
}
|
||||
#endif
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
@ -1418,7 +1374,7 @@ static Eina_Bool
|
|||
_filter_target_render(Evas_Filter_Context *ctx)
|
||||
{
|
||||
Evas_Filter_Buffer *src, *dst;
|
||||
void *drawctx, *image, *surface;
|
||||
void *drawctx, *image = NULL, *surface = NULL;
|
||||
int cx, cy, cw, ch;
|
||||
Eina_Bool use_clip = EINA_FALSE;
|
||||
|
||||
|
@ -1429,13 +1385,8 @@ _filter_target_render(Evas_Filter_Context *ctx)
|
|||
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
|
||||
|
||||
if (!ctx->gl_engine)
|
||||
{
|
||||
drawctx = ENFN->context_new(ENDT);
|
||||
surface = dst->backing;
|
||||
image = src->backing;
|
||||
}
|
||||
else
|
||||
#if 0
|
||||
if (ctx->gl_engine)
|
||||
{
|
||||
drawctx = ctx->target.context;
|
||||
surface = dst->glimage;
|
||||
|
@ -1456,9 +1407,18 @@ _filter_target_render(Evas_Filter_Context *ctx)
|
|||
}
|
||||
image = src->glimage;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
drawctx = ENFN->context_new(ENDT);
|
||||
image = _evas_image_get(src->buffer);
|
||||
surface = _evas_image_get(dst->buffer);
|
||||
}
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
|
||||
|
||||
// FIXME: Use ector buffer RENDERER here
|
||||
|
||||
if (ctx->target.clip_use)
|
||||
{
|
||||
use_clip = ENFN->context_clip_get(ENDT, drawctx, &cx, &cy, &cw, &ch);
|
||||
|
@ -1511,12 +1471,10 @@ evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
|
|||
{
|
||||
Eina_Bool async_unref;
|
||||
Evas_Filter_Buffer *fb;
|
||||
void *surface;
|
||||
void *surface = NULL;
|
||||
|
||||
fb = _filter_buffer_get(ctx, bufid);
|
||||
if (!fb) return EINA_FALSE;
|
||||
|
||||
surface = fb->backing;
|
||||
surface = _evas_image_get(fb->buffer);
|
||||
if (!surface) return EINA_FALSE;
|
||||
|
||||
if (!ctx->gl_engine)
|
||||
|
@ -1771,10 +1729,7 @@ end:
|
|||
DEBUG_TIME_END();
|
||||
|
||||
EINA_LIST_FREE(ctx->post_run.buffers_to_free, buffer)
|
||||
{
|
||||
if (ctx->gl_engine)
|
||||
ENFN->image_free(ENDT, buffer);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
#include "evas_filter.h"
|
||||
#include "evas_filter_private.h"
|
||||
#include "evas_blend_private.h"
|
||||
#include "ector_buffer.h"
|
||||
#include "draw.h"
|
||||
|
||||
// FIXME: This should all be based on ector renderer
|
||||
|
||||
// Use a better formula than R+G+B for rgba to alpha conversion (RGB to YCbCr)
|
||||
#define RGBA2ALPHA_WEIGHTED 1
|
||||
|
||||
typedef Eina_Bool (*image_draw_func) (void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async);
|
||||
static Eina_Bool _mapped_blend(void *data, void *drawctx, void *in, void *out, Evas_Filter_Fill_Mode fillmode, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, image_draw_func image_draw);
|
||||
typedef Eina_Bool (*draw_func) (void *data, void *context, const void *src_map, unsigned int src_stride, void *dst_map, unsigned int dst_stride, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async);
|
||||
static Eina_Bool _mapped_blend(void *data, void *drawctx, const void *src_map, unsigned int src_stride, void *dst_map, unsigned int dst_stride, Evas_Filter_Fill_Mode fillmode, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, draw_func image_draw);
|
||||
|
||||
struct Filter_Blend_Draw_Context
|
||||
{
|
||||
Efl_Gfx_Render_Op rop;
|
||||
DATA32 color;
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
#define LINELEN(stride, ptr) (stride / (sizeof(*ptr)))
|
||||
|
||||
static Eina_Bool
|
||||
_image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context,
|
||||
void *surface, void *image,
|
||||
const void *src_map, unsigned int src_stride,
|
||||
void *dst_map, unsigned int dst_stride,
|
||||
int src_x, int src_y, int src_w, int src_h,
|
||||
int dst_x, int dst_y, int dst_w, int dst_h,
|
||||
int smooth EINA_UNUSED,
|
||||
Eina_Bool do_async EINA_UNUSED)
|
||||
{
|
||||
struct Filter_Blend_Draw_Context *dc = context;
|
||||
RGBA_Image *src = image;
|
||||
RGBA_Image *dst = surface;
|
||||
DATA8* srcdata = src->image.data8;
|
||||
DATA8* dstdata = dst->image.data8;
|
||||
const uint8_t *srcdata = src_map;
|
||||
uint8_t *dstdata = dst_map;
|
||||
Alpha_Gfx_Func func;
|
||||
int y, sw, dw;
|
||||
|
||||
|
@ -36,8 +40,8 @@ _image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context,
|
|||
func = efl_draw_alpha_func_get(dc->rop, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
|
||||
|
||||
sw = src->cache_entry.w;
|
||||
dw = dst->cache_entry.w;
|
||||
sw = LINELEN(src_stride, srcdata);
|
||||
dw = LINELEN(dst_stride, dstdata);
|
||||
|
||||
srcdata += src_y * sw;
|
||||
dstdata += dst_y * dw;
|
||||
|
@ -53,28 +57,26 @@ _image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context,
|
|||
|
||||
static Eina_Bool
|
||||
_image_draw_cpu_alpha2rgba(void *data EINA_UNUSED, void *context,
|
||||
void *surface, void *image,
|
||||
const void *src_map, unsigned int src_stride,
|
||||
void *dst_map, unsigned int dst_stride,
|
||||
int src_x, int src_y, int src_w, int src_h,
|
||||
int dst_x, int dst_y, int dst_w, int dst_h,
|
||||
int smooth EINA_UNUSED,
|
||||
Eina_Bool do_async EINA_UNUSED)
|
||||
{
|
||||
struct Filter_Blend_Draw_Context *dc = context;
|
||||
RGBA_Image *src = image;
|
||||
RGBA_Image *dst = surface;
|
||||
DATA8* srcdata = src->image.data8;
|
||||
DATA32* dstdata = dst->image.data;
|
||||
uint8_t *srcdata = (uint8_t *) src_map;
|
||||
uint32_t *dstdata = dst_map;
|
||||
RGBA_Gfx_Func func;
|
||||
int y, sw, dw;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
|
||||
|
||||
func = evas_common_gfx_func_composite_mask_color_span_get
|
||||
(dc->color, dst->cache_entry.flags.alpha, 1, dc->rop);
|
||||
func = evas_common_gfx_func_composite_mask_color_span_get(dc->color, 1, 1, _gfx_to_evas_render_op(dc->rop));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
|
||||
|
||||
sw = src->cache_entry.w;
|
||||
dw = dst->cache_entry.w;
|
||||
sw = LINELEN(src_stride, srcdata);
|
||||
dw = LINELEN(dst_stride, dstdata);
|
||||
|
||||
srcdata += src_y * sw;
|
||||
dstdata += dst_y * dw;
|
||||
|
@ -88,122 +90,18 @@ _image_draw_cpu_alpha2rgba(void *data EINA_UNUSED, void *context,
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_filter_blend_cpu_generic_do(Evas_Filter_Command *cmd,
|
||||
image_draw_func image_draw)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
int sw, sh, dx, dy, dw, dh, sx, sy;
|
||||
struct Filter_Blend_Draw_Context dc;
|
||||
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
|
||||
|
||||
sx = 0;
|
||||
sy = 0;
|
||||
sw = in->cache_entry.w;
|
||||
sh = in->cache_entry.h;
|
||||
|
||||
dx = cmd->draw.ox;
|
||||
dy = cmd->draw.oy;
|
||||
dw = out->cache_entry.w;
|
||||
dh = out->cache_entry.h;
|
||||
|
||||
if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
|
||||
return EINA_TRUE;
|
||||
|
||||
// Stretch if necessary.
|
||||
|
||||
/* NOTE: As of 2014/03/11, this will happen only with RGBA buffers, since
|
||||
* only proxy sources may be scaled. So, we don't need an alpha scaling
|
||||
* algorithm just now.
|
||||
*/
|
||||
|
||||
if ((sw != dw || sh != dh) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
|
||||
{
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
|
||||
sw = dw;
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
|
||||
sh = dh;
|
||||
|
||||
BUFFERS_LOCK();
|
||||
fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->input, sw, sh);
|
||||
BUFFERS_UNLOCK();
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
|
||||
fb->locked = EINA_FALSE;
|
||||
in = fb->backing;
|
||||
}
|
||||
|
||||
dc.rop = cmd->draw.rop;
|
||||
dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
|
||||
return _mapped_blend(cmd->ENDT, &dc, in, out, cmd->draw.fillmode,
|
||||
sx, sy, sw, sh, dx, dy, dw, dh, image_draw);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED,
|
||||
void *surface, void *image,
|
||||
int src_x, int src_y, int src_w, int src_h,
|
||||
int dst_x, int dst_y, int dst_w, int dst_h,
|
||||
int smooth EINA_UNUSED,
|
||||
Eina_Bool do_async EINA_UNUSED)
|
||||
{
|
||||
RGBA_Image *src = image;
|
||||
RGBA_Image *dst = surface;
|
||||
DATA32* srcdata = src->image.data;
|
||||
DATA8* dstdata = dst->image.data8;
|
||||
int x, y, sw, dw;
|
||||
#if RGBA2ALPHA_WEIGHTED
|
||||
const int WR = 299;
|
||||
const int WG = 587;
|
||||
const int WB = 114;
|
||||
#else
|
||||
const int WR = 1;
|
||||
const int WG = 1;
|
||||
const int WB = 1;
|
||||
#endif
|
||||
DEFINE_DIVIDER(WR + WG + WB);
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
|
||||
|
||||
sw = src->cache_entry.w;
|
||||
dw = dst->cache_entry.w;
|
||||
|
||||
srcdata += src_y * sw;
|
||||
dstdata += dst_y * dw;
|
||||
for (y = src_h; y; y--)
|
||||
{
|
||||
DATA32 *s = srcdata + src_x;
|
||||
DATA8 *d = dstdata + dst_x;
|
||||
for (x = src_w; x; x--, d++, s++)
|
||||
*d = DIVIDE((R_VAL(s) * WR) + (G_VAL(s) * WG) + (B_VAL(s) * WB));
|
||||
srcdata += sw;
|
||||
dstdata += dw;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context,
|
||||
void *surface, void *image,
|
||||
const void *src_map, unsigned int src_stride,
|
||||
void *dst_map, unsigned int dst_stride,
|
||||
int src_x, int src_y, int src_w, int src_h,
|
||||
int dst_x, int dst_y, int dst_w, int dst_h,
|
||||
int smooth EINA_UNUSED,
|
||||
Eina_Bool do_async EINA_UNUSED)
|
||||
{
|
||||
struct Filter_Blend_Draw_Context *dc = context;
|
||||
RGBA_Image *src = image;
|
||||
RGBA_Image *dst = surface;
|
||||
DATA32* srcdata = src->image.data;
|
||||
DATA32* dstdata = dst->image.data;
|
||||
uint32_t *srcdata = (uint32_t *) src_map;
|
||||
uint32_t *dstdata = dst_map;
|
||||
RGBA_Gfx_Func func;
|
||||
int y, sw, dw;
|
||||
|
||||
|
@ -212,13 +110,13 @@ _image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context,
|
|||
if (!dc->color)
|
||||
return EINA_TRUE;
|
||||
else if (dc->color == 0xFFFFFFFF)
|
||||
func = evas_common_gfx_func_composite_pixel_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dst->cache_entry.flags.alpha, 1, dc->rop);
|
||||
func = evas_common_gfx_func_composite_pixel_span_get(1, 0, 1, 1, _gfx_to_evas_render_op(dc->rop));
|
||||
else
|
||||
func = evas_common_gfx_func_composite_pixel_color_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dc->color, dst->cache_entry.flags.alpha, 1, dc->rop);
|
||||
func = evas_common_gfx_func_composite_pixel_color_span_get(1, 0, dc->color, 1, 1, _gfx_to_evas_render_op(dc->rop));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
|
||||
|
||||
sw = src->cache_entry.w;
|
||||
dw = dst->cache_entry.w;
|
||||
sw = LINELEN(src_stride, srcdata);
|
||||
dw = LINELEN(dst_stride, dstdata);
|
||||
|
||||
srcdata += src_y * sw;
|
||||
dstdata += dst_y * dw;
|
||||
|
@ -232,6 +130,109 @@ _image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context,
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED,
|
||||
const void *src_map, unsigned int src_stride,
|
||||
void *dst_map, unsigned int dst_stride,
|
||||
int src_x, int src_y, int src_w, int src_h,
|
||||
int dst_x, int dst_y, int dst_w, int dst_h,
|
||||
int smooth EINA_UNUSED,
|
||||
Eina_Bool do_async EINA_UNUSED)
|
||||
{
|
||||
uint32_t *srcdata = (uint32_t *) src_map;
|
||||
uint8_t *dstdata = dst_map;
|
||||
int x, y, sw, dw;
|
||||
#if RGBA2ALPHA_WEIGHTED
|
||||
const int WR = 299;
|
||||
const int WG = 587;
|
||||
const int WB = 114;
|
||||
#else
|
||||
const int WR = 1;
|
||||
const int WG = 1;
|
||||
const int WB = 1;
|
||||
#endif
|
||||
DEFINE_DIVIDER(WR + WG + WB);
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
|
||||
|
||||
sw = LINELEN(src_stride, srcdata);
|
||||
dw = LINELEN(dst_stride, dstdata);
|
||||
|
||||
srcdata += src_y * sw;
|
||||
dstdata += dst_y * dw;
|
||||
for (y = src_h; y; y--)
|
||||
{
|
||||
uint32_t *s = srcdata + src_x;
|
||||
uint8_t *d = dstdata + dst_x;
|
||||
for (x = src_w; x; x--, d++, s++)
|
||||
*d = DIVIDE((R_VAL(s) * WR) + (G_VAL(s) * WG) + (B_VAL(s) * WB));
|
||||
srcdata += sw;
|
||||
dstdata += dw;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, draw_func image_draw)
|
||||
{
|
||||
unsigned int src_len, src_stride, dst_len, dst_stride;
|
||||
int sw, sh, dx, dy, dw, dh, sx, sy;
|
||||
struct Filter_Blend_Draw_Context dc;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
Evas_Filter_Buffer *src_fb;
|
||||
void *src, *dst;
|
||||
|
||||
sx = 0;
|
||||
sy = 0;
|
||||
eo_do(cmd->input->buffer, ector_buffer_size_get(&sw, &sh));
|
||||
|
||||
dx = cmd->draw.ox;
|
||||
dy = cmd->draw.oy;
|
||||
eo_do(cmd->output->buffer, ector_buffer_size_get(&dw, &dh));
|
||||
|
||||
if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
|
||||
return EINA_TRUE;
|
||||
|
||||
// Stretch if necessary.
|
||||
|
||||
/* NOTE: As of 2014/03/11, this will happen only with RGBA buffers, since
|
||||
* only proxy sources may be scaled. So, we don't need an alpha scaling
|
||||
* algorithm just now.
|
||||
*/
|
||||
|
||||
if ((sw != dw || sh != dh) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
|
||||
{
|
||||
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
|
||||
sw = dw;
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
|
||||
sh = dh;
|
||||
|
||||
BUFFERS_LOCK();
|
||||
src_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->input, sw, sh);
|
||||
BUFFERS_UNLOCK();
|
||||
|
||||
EINA_SAFETY_ON_NULL_GOTO(src_fb, end);
|
||||
src_fb->locked = EINA_FALSE;
|
||||
}
|
||||
else src_fb = cmd->input;
|
||||
|
||||
src = _buffer_map_all(src_fb->buffer, &src_len, E_READ, src_fb->alpha_only ? E_ALPHA : E_ARGB, &src_stride);
|
||||
dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &dst_stride);
|
||||
|
||||
dc.rop = cmd->draw.rop;
|
||||
dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
|
||||
|
||||
ret = _mapped_blend(cmd->ENDT, &dc, src, src_stride, dst, dst_stride, cmd->draw.fillmode,
|
||||
sx, sy, sw, sh, dx, dy, dw, dh, image_draw);
|
||||
|
||||
end:
|
||||
eo_do(src_fb->buffer, ector_buffer_unmap(src, src_len));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_filter_blend_cpu_alpha(Evas_Filter_Command *cmd)
|
||||
{
|
||||
|
@ -239,7 +240,7 @@ _filter_blend_cpu_alpha(Evas_Filter_Command *cmd)
|
|||
}
|
||||
|
||||
static Eina_Bool
|
||||
_filter_blend_cpu_mask_rgba(Evas_Filter_Command *cmd)
|
||||
_filter_blend_cpu_alpha2rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_alpha2rgba);
|
||||
}
|
||||
|
@ -253,73 +254,19 @@ _filter_blend_cpu_rgba2alpha(Evas_Filter_Command *cmd)
|
|||
static Eina_Bool
|
||||
_filter_blend_cpu_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
RGBA_Draw_Context *drawctx;
|
||||
int sw, sh, dx, dy, dw, dh, sx, sy;
|
||||
Eina_Bool ret;
|
||||
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
|
||||
|
||||
if (cmd->ctx->gl_engine)
|
||||
return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba2rgba);
|
||||
|
||||
sx = 0;
|
||||
sy = 0;
|
||||
sw = in->cache_entry.w;
|
||||
sh = in->cache_entry.h;
|
||||
|
||||
dx = cmd->draw.ox;
|
||||
dy = cmd->draw.oy;
|
||||
dw = out->cache_entry.w;
|
||||
dh = out->cache_entry.h;
|
||||
|
||||
if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
|
||||
return EINA_TRUE;
|
||||
|
||||
drawctx = cmd->ENFN->context_new(cmd->ENDT);
|
||||
cmd->ENFN->context_color_set(cmd->ENDT, drawctx, 255, 255, 255, 255);
|
||||
if ((cmd->draw.R != 255) || (cmd->draw.G != 255) || (cmd->draw.B != 255) || (cmd->draw.A != 255))
|
||||
cmd->ENFN->context_multiplier_set(cmd->ENDT, drawctx, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
|
||||
else
|
||||
cmd->ENFN->context_multiplier_unset(cmd->ENDT, drawctx);
|
||||
cmd->ENFN->context_render_op_set(cmd->ENDT, drawctx, _gfx_to_evas_render_op(cmd->draw.rop));
|
||||
|
||||
if (cmd->draw.clip_use)
|
||||
{
|
||||
cmd->ENFN->context_clip_set(cmd->ENDT, drawctx,
|
||||
cmd->draw.clip.x, cmd->draw.clip.y,
|
||||
cmd->draw.clip.w, cmd->draw.clip.h);
|
||||
cmd->ENFN->context_clip_clip(cmd->ENDT, drawctx, 0, 0,
|
||||
out->cache_entry.w, out->cache_entry.h);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->ENFN->context_clip_set(cmd->ENDT, drawctx, 0, 0,
|
||||
out->cache_entry.w, out->cache_entry.h);
|
||||
}
|
||||
|
||||
ret = _mapped_blend(cmd->ENDT, drawctx, in, out, cmd->draw.fillmode,
|
||||
sx, sy, sw, sh, dx, dy, dw, dh,
|
||||
cmd->ENFN->image_draw);
|
||||
|
||||
cmd->ENFN->context_free(cmd->ENDT, drawctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_mapped_blend(void *data, void *drawctx,
|
||||
void *in, void *out,
|
||||
const void *src_map, unsigned int src_stride,
|
||||
void *dst_map, unsigned int dst_stride,
|
||||
Evas_Filter_Fill_Mode fillmode,
|
||||
int sx, int sy,
|
||||
int sw, int sh,
|
||||
int dx, int dy,
|
||||
int dw, int dh,
|
||||
image_draw_func image_draw)
|
||||
draw_func image_draw)
|
||||
{
|
||||
int right = 0, bottom = 0, left = 0, top = 0;
|
||||
int row, col, rows, cols;
|
||||
|
@ -336,7 +283,8 @@ _mapped_blend(void *data, void *drawctx,
|
|||
XDBG("blend: %d,%d,%d,%d --> %d,%d,%d,%d (from %dx%d to %dx%d +%d,%d)",
|
||||
0, 0, sw, sh, dx, dy, cols, rows, sw, sh, dw, dh, dx, dy);
|
||||
}
|
||||
image_draw(data, drawctx, out, in,
|
||||
image_draw(data, drawctx,
|
||||
src_map, src_stride, dst_map, dst_stride,
|
||||
sx, sy, cols, rows, // src
|
||||
dx, dy, cols, rows, // dst
|
||||
EINA_TRUE, // smooth
|
||||
|
@ -477,7 +425,8 @@ _mapped_blend(void *data, void *drawctx,
|
|||
dst_x, dst_y, dst_w, dst_h,
|
||||
sw, sh, dw, dh);
|
||||
}
|
||||
image_draw(data, drawctx, out, in,
|
||||
image_draw(data, drawctx,
|
||||
src_map, src_stride, dst_map, dst_stride,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h,
|
||||
EINA_TRUE, EINA_FALSE);
|
||||
|
@ -493,14 +442,12 @@ evas_filter_blend_cpu_func_get(Evas_Filter_Command *cmd)
|
|||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
|
||||
|
||||
if (!cmd->ctx->gl_engine || !cmd->output->glimage || cmd->output->backing)
|
||||
{
|
||||
if (cmd->input->alpha_only)
|
||||
{
|
||||
if (cmd->output->alpha_only)
|
||||
return _filter_blend_cpu_alpha;
|
||||
else
|
||||
return _filter_blend_cpu_mask_rgba;
|
||||
return _filter_blend_cpu_alpha2rgba;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -510,10 +457,3 @@ evas_filter_blend_cpu_func_get(Evas_Filter_Command *cmd)
|
|||
return _filter_blend_cpu_rgba;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CRI("Can't render to GL image for the moment!");
|
||||
//return _filter_blend_opengl_generic;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
// FIXME: Add proper stride support
|
||||
|
||||
static int
|
||||
_box_blur_auto_radius(int *radii, int r)
|
||||
{
|
||||
|
@ -45,7 +47,7 @@ _box_blur_auto_radius(int *radii, int r)
|
|||
#endif
|
||||
|
||||
static void
|
||||
_box_blur_horiz_rgba(DATA32 *src, DATA32 *dst, int* radii, int w, int h)
|
||||
_box_blur_horiz_rgba(uint32_t *src, uint32_t *dst, int* radii, int w, int h)
|
||||
{
|
||||
DEBUG_TIME_BEGIN();
|
||||
|
||||
|
@ -77,7 +79,7 @@ end:
|
|||
}
|
||||
|
||||
static void
|
||||
_box_blur_vert_rgba(DATA32 *src, DATA32 *dst, int* radii, int w, int h)
|
||||
_box_blur_vert_rgba(uint32_t *src, uint32_t *dst, int* radii, int w, int h)
|
||||
{
|
||||
DEBUG_TIME_BEGIN();
|
||||
|
||||
|
@ -108,64 +110,6 @@ end:
|
|||
DEBUG_TIME_END();
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_box_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
int radii[7] = {0};
|
||||
unsigned int r;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||
|
||||
r = abs(cmd->blur.dx);
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
|
||||
if (cmd->blur.auto_count)
|
||||
_box_blur_auto_radius(radii, r);
|
||||
else for (int k = 0; k < cmd->blur.count; k++)
|
||||
radii[k] = r;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
|
||||
|
||||
_box_blur_horiz_rgba(in->image.data, out->image.data, radii,
|
||||
in->cache_entry.w, in->cache_entry.h);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_box_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
int radii[7] = {0};
|
||||
unsigned int r;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||
|
||||
r = abs(cmd->blur.dy);
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
|
||||
if (cmd->blur.auto_count)
|
||||
_box_blur_auto_radius(radii, r);
|
||||
else for (int k = 0; k < cmd->blur.count; k++)
|
||||
radii[k] = r;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
|
||||
|
||||
_box_blur_vert_rgba(in->image.data, out->image.data, radii,
|
||||
in->cache_entry.w, in->cache_entry.h);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
#include "./blur/blur_box_alpha_.c"
|
||||
#ifdef BUILD_MMX
|
||||
#include "./blur/blur_box_alpha_i386.c"
|
||||
|
@ -178,7 +122,7 @@ _box_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
|
|||
#endif
|
||||
|
||||
static void
|
||||
_box_blur_horiz_alpha(DATA8 *src, DATA8 *dst, int* radii, int w, int h)
|
||||
_box_blur_horiz_alpha(const DATA8 *src, DATA8 *dst, int* radii, int w, int h)
|
||||
{
|
||||
DEBUG_TIME_BEGIN();
|
||||
|
||||
|
@ -210,7 +154,7 @@ end:
|
|||
}
|
||||
|
||||
static void
|
||||
_box_blur_vert_alpha(DATA8 *src, DATA8 *dst, int* radii, int w, int h)
|
||||
_box_blur_vert_alpha(const DATA8 *src, DATA8 *dst, int* radii, int w, int h)
|
||||
{
|
||||
DEBUG_TIME_BEGIN();
|
||||
|
||||
|
@ -242,61 +186,70 @@ end:
|
|||
}
|
||||
|
||||
static Eina_Bool
|
||||
_box_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
|
||||
_box_blur_apply(Evas_Filter_Command *cmd, Eina_Bool vert, Eina_Bool rgba)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
unsigned int src_len, src_stride, dst_len, dst_stride;
|
||||
Eina_Bool ret = EINA_TRUE;
|
||||
int radii[7] = {0};
|
||||
unsigned int r;
|
||||
void *src, *dst;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||
|
||||
r = abs(cmd->blur.dx);
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
r = abs(vert ? cmd->blur.dy : cmd->blur.dx);
|
||||
src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, rgba ? E_ARGB : E_ALPHA, &src_stride);
|
||||
dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, rgba ? E_ARGB : E_ALPHA, &dst_stride);
|
||||
|
||||
if (cmd->blur.auto_count)
|
||||
_box_blur_auto_radius(radii, r);
|
||||
else for (int k = 0; k < cmd->blur.count; k++)
|
||||
radii[k] = r;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
|
||||
if (src && dst)
|
||||
{
|
||||
if (rgba)
|
||||
{
|
||||
if (!vert)
|
||||
_box_blur_horiz_rgba(src, dst, radii, cmd->input->w, cmd->input->h);
|
||||
else
|
||||
_box_blur_vert_rgba(src, dst, radii, cmd->input->w, cmd->input->h);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!vert)
|
||||
_box_blur_horiz_alpha(src, dst, radii, cmd->input->w, cmd->input->h);
|
||||
else
|
||||
_box_blur_vert_alpha(src, dst, radii, cmd->input->w, cmd->input->h);
|
||||
}
|
||||
}
|
||||
else ret = EINA_FALSE;
|
||||
|
||||
_box_blur_horiz_alpha(in->image.data8, out->image.data8, radii,
|
||||
in->cache_entry.w, in->cache_entry.h);
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
|
||||
|
||||
return EINA_TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_box_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
|
||||
{
|
||||
return _box_blur_apply(cmd, 0, 0);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_box_blur_vert_apply_alpha(Evas_Filter_Command *cmd)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
int radii[7] = {0};
|
||||
unsigned int r;
|
||||
return _box_blur_apply(cmd, 1, 0);
|
||||
}
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||
static Eina_Bool
|
||||
_box_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
return _box_blur_apply(cmd, 0, 1);
|
||||
}
|
||||
|
||||
r = abs(cmd->blur.dy);
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
|
||||
if (cmd->blur.auto_count)
|
||||
_box_blur_auto_radius(radii, r);
|
||||
else for (int k = 0; k < cmd->blur.count; k++)
|
||||
radii[k] = r;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
|
||||
|
||||
_box_blur_vert_alpha(in->image.data8, out->image.data8, radii,
|
||||
in->cache_entry.w, in->cache_entry.h);
|
||||
|
||||
return EINA_TRUE;
|
||||
static Eina_Bool
|
||||
_box_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
return _box_blur_apply(cmd, 1, 1);
|
||||
}
|
||||
|
||||
/* Gaussian blur */
|
||||
|
@ -342,165 +295,86 @@ _sin_blur_weights_get(int *weights, int *pow2_divider, int radius)
|
|||
#define STEP 1
|
||||
#include "./blur/blur_gaussian_alpha_.c"
|
||||
|
||||
static void
|
||||
_gaussian_blur_horiz_alpha(const DATA8 *src, DATA8 *dst, int radius, int w, int h)
|
||||
{
|
||||
int *weights;
|
||||
int pow2_div = 0;
|
||||
|
||||
weights = alloca((2 * radius + 1) * sizeof(int));
|
||||
_sin_blur_weights_get(weights, &pow2_div, radius);
|
||||
|
||||
DEBUG_TIME_BEGIN();
|
||||
_gaussian_blur_horiz_alpha_step(src, dst, radius, w, h, w, weights, pow2_div);
|
||||
DEBUG_TIME_END();
|
||||
}
|
||||
|
||||
// Step size is w (row by row), loops = w, so STEP = 'loops'
|
||||
#define FUNCTION_NAME _gaussian_blur_vert_alpha_step
|
||||
#define STEP loops
|
||||
#include "./blur/blur_gaussian_alpha_.c"
|
||||
|
||||
static void
|
||||
_gaussian_blur_vert_alpha(const DATA8 *src, DATA8 *dst, int radius, int w, int h)
|
||||
{
|
||||
int *weights;
|
||||
int pow2_div = 0;
|
||||
|
||||
weights = alloca((2 * radius + 1) * sizeof(int));
|
||||
_sin_blur_weights_get(weights, &pow2_div, radius);
|
||||
|
||||
DEBUG_TIME_BEGIN();
|
||||
_gaussian_blur_vert_alpha_step(src, dst, radius, h, w, 1, weights, pow2_div);
|
||||
DEBUG_TIME_END();
|
||||
}
|
||||
|
||||
#define FUNCTION_NAME _gaussian_blur_horiz_rgba_step
|
||||
#define STEP 1
|
||||
#include "./blur/blur_gaussian_rgba_.c"
|
||||
|
||||
static void
|
||||
_gaussian_blur_horiz_rgba(DATA32 *src, DATA32 *dst, int radius, int w, int h)
|
||||
{
|
||||
int *weights;
|
||||
int pow2_div = 0;
|
||||
|
||||
weights = alloca((2 * radius + 1) * sizeof(int));
|
||||
_sin_blur_weights_get(weights, &pow2_div, radius);
|
||||
|
||||
DEBUG_TIME_BEGIN();
|
||||
_gaussian_blur_horiz_rgba_step(src, dst, radius, w, h, w, weights, pow2_div);
|
||||
DEBUG_TIME_END();
|
||||
}
|
||||
|
||||
#define FUNCTION_NAME _gaussian_blur_vert_rgba_step
|
||||
#define STEP loops
|
||||
#include "./blur/blur_gaussian_rgba_.c"
|
||||
|
||||
static void
|
||||
_gaussian_blur_vert_rgba(DATA32 *src, DATA32 *dst, int radius, int w, int h)
|
||||
static Eina_Bool
|
||||
_gaussian_blur_apply(Evas_Filter_Command *cmd, Eina_Bool vert, Eina_Bool rgba)
|
||||
{
|
||||
unsigned int src_len, src_stride, dst_len, dst_stride, radius;
|
||||
Eina_Bool ret = EINA_TRUE;
|
||||
int pow2_div = 0, w, h;
|
||||
void *src, *dst;
|
||||
int *weights;
|
||||
int pow2_div = 0;
|
||||
|
||||
radius = abs(vert ? cmd->blur.dy : cmd->blur.dx);
|
||||
src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, rgba ? E_ARGB : E_ALPHA, &src_stride);
|
||||
dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, rgba ? E_ARGB : E_ALPHA, &dst_stride);
|
||||
w = cmd->input->w;
|
||||
h = cmd->input->h;
|
||||
|
||||
weights = alloca((2 * radius + 1) * sizeof(int));
|
||||
_sin_blur_weights_get(weights, &pow2_div, radius);
|
||||
|
||||
if (src && dst)
|
||||
{
|
||||
DEBUG_TIME_BEGIN();
|
||||
if (rgba)
|
||||
{
|
||||
if (!vert)
|
||||
_gaussian_blur_horiz_rgba_step(src, dst, radius, w, h, w, weights, pow2_div);
|
||||
else
|
||||
_gaussian_blur_vert_rgba_step(src, dst, radius, h, w, 1, weights, pow2_div);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!vert)
|
||||
_gaussian_blur_horiz_alpha_step(src, dst, radius, w, h, w, weights, pow2_div);
|
||||
else
|
||||
_gaussian_blur_vert_alpha_step(src, dst, radius, h, w, 1, weights, pow2_div);
|
||||
}
|
||||
DEBUG_TIME_END();
|
||||
}
|
||||
else ret = EINA_FALSE;
|
||||
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_gaussian_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
unsigned int r;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||
|
||||
r = abs(cmd->blur.dx);
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
|
||||
|
||||
_gaussian_blur_horiz_alpha(in->image.data8, out->image.data8, r,
|
||||
in->cache_entry.w, in->cache_entry.h);
|
||||
|
||||
return EINA_TRUE;
|
||||
return _gaussian_blur_apply(cmd, 0, 0);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_gaussian_blur_vert_apply_alpha(Evas_Filter_Command *cmd)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
unsigned int r;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||
|
||||
r = abs(cmd->blur.dy);
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
|
||||
|
||||
_gaussian_blur_vert_alpha(in->image.data8, out->image.data8, r,
|
||||
in->cache_entry.w, in->cache_entry.h);
|
||||
|
||||
return EINA_TRUE;
|
||||
return _gaussian_blur_apply(cmd, 1, 0);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_gaussian_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
unsigned int r;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||
|
||||
r = abs(cmd->blur.dx);
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
|
||||
|
||||
_gaussian_blur_horiz_rgba(in->image.data, out->image.data, r,
|
||||
in->cache_entry.w, in->cache_entry.h);
|
||||
|
||||
return EINA_TRUE;
|
||||
return _gaussian_blur_apply(cmd, 0, 1);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_gaussian_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
unsigned int r;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||
|
||||
r = abs(cmd->blur.dy);
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
|
||||
|
||||
_gaussian_blur_vert_rgba(in->image.data, out->image.data, r,
|
||||
in->cache_entry.w, in->cache_entry.h);
|
||||
|
||||
return EINA_TRUE;
|
||||
return _gaussian_blur_apply(cmd, 1, 1);
|
||||
}
|
||||
|
||||
/* Main entry point */
|
||||
|
|
|
@ -50,7 +50,7 @@ evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd)
|
|||
}
|
||||
|
||||
static void
|
||||
_phong_alpha_generate(DATA8 *phong, DATA8 dark, DATA8 color, DATA8 white,
|
||||
_phong_alpha_generate(uint8_t *phong, uint8_t dark, uint8_t color, uint8_t white,
|
||||
float sf)
|
||||
{
|
||||
int x, y;
|
||||
|
@ -100,22 +100,23 @@ _phong_alpha_generate(DATA8 *phong, DATA8 dark, DATA8 color, DATA8 white,
|
|||
static Eina_Bool
|
||||
_bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd)
|
||||
{
|
||||
DATA8 *src, *map, *dst, *map_y1, *map_y2;
|
||||
DATA8 dark, color, white;
|
||||
DATA8 *phong;
|
||||
uint8_t *src_map, *map_map, *dst_map;
|
||||
uint8_t *src, *map, *dst, *map_y1, *map_y2;
|
||||
uint8_t dark, color, white;
|
||||
uint8_t *phong = NULL;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
int x, y, w, h, lx, ly;
|
||||
unsigned int ss, ms, ds, slen, dlen, mlen;
|
||||
float xyangle, zangle, sf, lxy;
|
||||
|
||||
w = cmd->input->w;
|
||||
h = cmd->input->h;
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 2 && h > 2, EINA_FALSE);
|
||||
|
||||
src = ((RGBA_Image *) cmd->input->backing)->image.data8;
|
||||
map = ((RGBA_Image *) cmd->mask->backing)->image.data8;
|
||||
dst = ((RGBA_Image *) cmd->output->backing)->image.data8;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(map, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
|
||||
src_map = src = _buffer_map_all(cmd->input->buffer, &slen, E_READ, E_ALPHA, &ss);
|
||||
map_map = map = _buffer_map_all(cmd->mask->buffer, &mlen, E_READ, E_ALPHA, &ms);
|
||||
dst_map = dst = _buffer_map_all(cmd->output->buffer, &dlen, E_WRITE, E_ALPHA, &ds);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(src && dst && map, end);
|
||||
|
||||
xyangle = cmd->bump.xyangle;
|
||||
zangle = cmd->bump.zangle;
|
||||
|
@ -150,7 +151,7 @@ _bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd)
|
|||
|
||||
// Generate light table
|
||||
phong = malloc(256 * 256 * sizeof(*phong));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(phong, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_GOTO(phong, end);
|
||||
_phong_alpha_generate(phong, dark, color, white, sf);
|
||||
|
||||
for (y = 0; y < h; y++)
|
||||
|
@ -228,31 +229,36 @@ _bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd)
|
|||
src++;
|
||||
}
|
||||
|
||||
ret = EINA_TRUE;
|
||||
|
||||
end:
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, slen));
|
||||
eo_do(cmd->mask->buffer, ector_buffer_unmap(map_map, mlen));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dlen));
|
||||
free(phong);
|
||||
return EINA_TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_bump_map_cpu_alpha_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
DATA8 *src, *map, *map_y1, *map_y2;
|
||||
DATA32 *dst;
|
||||
DATA32 dark, color, white, col;
|
||||
//DATA32 *phong;
|
||||
Eina_Bool compensate;
|
||||
uint8_t *src_map, *map_map;
|
||||
uint8_t *src, *map, *map_y1, *map_y2;
|
||||
uint32_t *dst, *dst_map;
|
||||
uint32_t dark, color, white, col;
|
||||
Eina_Bool compensate, ret = EINA_FALSE;
|
||||
int x, y, w, h, lx, ly, lz, gz, NL, diffusion, gzlz, gz2;
|
||||
unsigned int ss, ms, ds, slen, dlen, mlen;
|
||||
double xyangle, zangle, sf, lxy, elevation;
|
||||
|
||||
w = cmd->input->w;
|
||||
h = cmd->input->h;
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 2 && h > 2, EINA_FALSE);
|
||||
|
||||
src = ((RGBA_Image *) cmd->input->backing)->image.data8;
|
||||
map = ((RGBA_Image *) cmd->mask->backing)->image.data8;
|
||||
dst = ((RGBA_Image *) cmd->output->backing)->image.data;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(map, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
|
||||
src_map = src = _buffer_map_all(cmd->input->buffer, &slen, E_READ, E_ALPHA, &ss);
|
||||
map_map = map = _buffer_map_all(cmd->mask->buffer, &mlen, E_READ, E_ALPHA, &ms);
|
||||
dst_map = dst = (uint32_t *) _buffer_map_all(cmd->output->buffer, &dlen, E_WRITE, E_ARGB, &ds);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(src && dst && map, end);
|
||||
|
||||
xyangle = cmd->bump.xyangle;
|
||||
zangle = cmd->bump.zangle;
|
||||
|
@ -403,7 +409,13 @@ _bump_map_cpu_alpha_rgba(Evas_Filter_Command *cmd)
|
|||
}
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
ret = EINA_TRUE;
|
||||
|
||||
end:
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, slen));
|
||||
eo_do(cmd->mask->buffer, ector_buffer_unmap(map_map, mlen));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dlen));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
|
|
|
@ -5,23 +5,23 @@
|
|||
static Eina_Bool
|
||||
_filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
DATA32 *src, *dst, *d, *s;
|
||||
DATA8 *curve;
|
||||
unsigned int src_len, src_stride, dst_len, dst_stride;
|
||||
void *src_map = NULL, *dst_map;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
uint32_t *src, *dst, *d, *s;
|
||||
uint8_t *curve;
|
||||
int k, offset = -1, len;
|
||||
|
||||
#define C_VAL(p) (((DATA8 *)(p))[offset])
|
||||
#define C_VAL(p) (((uint8_t *)(p))[offset])
|
||||
|
||||
// FIXME: support src_stride != dst_stride
|
||||
// Note: potentially mapping the same region twice (read then write)
|
||||
src_map = src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ARGB, &src_stride);
|
||||
dst_map = dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(src && dst && (src_len == dst_len), end);
|
||||
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
|
||||
src = in->image.data;
|
||||
dst = out->image.data;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
|
||||
curve = cmd->curve.data;
|
||||
len = in->cache_entry.w * in->cache_entry.h;
|
||||
len = dst_len / sizeof(uint32_t);
|
||||
|
||||
switch (cmd->curve.channel)
|
||||
{
|
||||
|
@ -38,11 +38,11 @@ _filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
|
|||
case EVAS_FILTER_CHANNEL_RGB: break;
|
||||
default:
|
||||
ERR("Invalid color channel %d", (int) cmd->curve.channel);
|
||||
return EINA_FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (src != dst)
|
||||
memcpy(dst, src, len * sizeof(DATA32));
|
||||
memcpy(dst, src, dst_len);
|
||||
evas_data_argb_unpremul(dst, len);
|
||||
|
||||
// One channel (R, G or B)
|
||||
|
@ -82,31 +82,39 @@ _filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
|
|||
|
||||
premul:
|
||||
evas_data_argb_premul(dst, len);
|
||||
return EINA_TRUE;
|
||||
ret = EINA_TRUE;
|
||||
|
||||
end:
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_filter_curve_cpu_alpha(Evas_Filter_Command *cmd)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
DATA8 *src, *dst;
|
||||
DATA8 *curve;
|
||||
unsigned int src_len, src_stride, dst_len, dst_stride;
|
||||
uint8_t *src, *dst, *curve;
|
||||
void *src_map, *dst_map;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
int k;
|
||||
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
|
||||
src = in->image.data8;
|
||||
dst = out->image.data8;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
|
||||
// FIXME: support src_stride != dst_stride
|
||||
// Note: potentially mapping the same region twice (read then write)
|
||||
src_map = src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
|
||||
dst_map = dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ALPHA, &dst_stride);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(src && dst && (src_len == dst_len), end);
|
||||
curve = cmd->curve.data;
|
||||
|
||||
for (k = in->cache_entry.w * in->cache_entry.h; k; k--)
|
||||
for (k = src_len; k; k--)
|
||||
*dst++ = curve[*src++];
|
||||
|
||||
return EINA_TRUE;
|
||||
ret = EINA_TRUE;
|
||||
|
||||
end:
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
|
||||
return ret;
|
||||
}
|
||||
|
||||
Evas_Filter_Apply_Func
|
||||
|
@ -124,6 +132,8 @@ evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd)
|
|||
if (cmd->input->alpha_only && cmd->output->alpha_only)
|
||||
return _filter_curve_cpu_alpha;
|
||||
|
||||
CRI("Incompatible image formats");
|
||||
return NULL;
|
||||
// Rely on ector buffer's implicit conversion. not great but the command
|
||||
// doesn't make much sense (curve requires same channel count).
|
||||
WRN("Incompatible image formats");
|
||||
return _filter_curve_cpu_rgba;
|
||||
}
|
||||
|
|
|
@ -3,22 +3,24 @@
|
|||
|
||||
static void
|
||||
_filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
|
||||
DATA8 *src, DATA8 *dst, DATA32 *map_start,
|
||||
uint8_t *src, uint8_t *dst, uint32_t *map_start,
|
||||
Eina_Bool stretch, Eina_Bool smooth,
|
||||
Eina_Bool blend)
|
||||
{
|
||||
int x, y, map_x, map_y;
|
||||
const int dx = RED;
|
||||
const int dy = GREEN;
|
||||
DATA8 *map;
|
||||
uint8_t *map;
|
||||
|
||||
// FIXME: Add stride support
|
||||
|
||||
for (y = 0, map_y = 0; y < h; y++, map_y++)
|
||||
{
|
||||
if (map_y >= map_h) map_y = 0;
|
||||
map = (DATA8 *) (map_start + map_y * map_w);
|
||||
map = (uint8_t *) (map_start + map_y * map_w);
|
||||
|
||||
for (x = 0, map_x = 0; x < w;
|
||||
x++, dst++, src++, map_x++, map += sizeof(DATA32))
|
||||
x++, dst++, src++, map_x++, map += sizeof(uint32_t))
|
||||
{
|
||||
int offx = 0, offy = 0, offx_dec = 0, offy_dec = 0, val = 0;
|
||||
Eina_Bool out = 0;
|
||||
|
@ -27,7 +29,7 @@ _filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
|
|||
if (map_x >= map_w)
|
||||
{
|
||||
map_x = 0;
|
||||
map = (DATA8 *) (map_start + map_y * map_w);
|
||||
map = (uint8_t *) (map_start + map_y * map_w);
|
||||
}
|
||||
|
||||
// x
|
||||
|
@ -76,7 +78,7 @@ _filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
|
|||
|
||||
static void
|
||||
_filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
|
||||
DATA32 *src, DATA32 *dst, DATA32 *map_start,
|
||||
uint32_t *src, uint32_t *dst, uint32_t *map_start,
|
||||
Eina_Bool stretch, Eina_Bool smooth,
|
||||
Eina_Bool blend)
|
||||
{
|
||||
|
@ -84,25 +86,25 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
|
|||
const int dx = RED;
|
||||
const int dy = GREEN;
|
||||
Eina_Bool unpremul = EINA_FALSE;
|
||||
DATA8 *map;
|
||||
uint8_t *map;
|
||||
|
||||
for (y = 0, map_y = 0; y < h; y++, map_y++)
|
||||
{
|
||||
if (map_y >= map_h) map_y = 0;
|
||||
map = (DATA8 *) (map_start + map_y * map_w);
|
||||
map = (uint8_t *) (map_start + map_y * map_w);
|
||||
|
||||
for (x = 0, map_x = 0; x < w;
|
||||
x++, dst++, src++, map_x++, map += sizeof(DATA32))
|
||||
x++, dst++, src++, map_x++, map += sizeof(uint32_t))
|
||||
{
|
||||
int offx = 0, offy = 0, offx_dec = 0, offy_dec = 0, val = 0;
|
||||
DATA32 col = 0;
|
||||
uint32_t col = 0;
|
||||
Eina_Bool out = 0;
|
||||
|
||||
// wrap (x)
|
||||
if (map_x >= map_w)
|
||||
{
|
||||
map_x = 0;
|
||||
map = (DATA8 *) (map_start + map_y * map_w);
|
||||
map = (uint8_t *) (map_start + map_y * map_w);
|
||||
}
|
||||
|
||||
if (!map[ALPHA]) continue;
|
||||
|
@ -134,7 +136,7 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
|
|||
else
|
||||
{
|
||||
int R, G, B, A;
|
||||
DATA32 s00, s01, s10, s11; // indexes represent x,y
|
||||
uint32_t s00, s01, s10, s11; // indexes represent x,y
|
||||
int mul00, mul01, mul10, mul11;
|
||||
|
||||
mul00 = (128 - offx_dec) * (128 - offy_dec);
|
||||
|
@ -172,7 +174,7 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
|
|||
|
||||
if (blend)
|
||||
{
|
||||
DATA32 a = 256 - ALPHA_OF(col);
|
||||
uint32_t a = 256 - ALPHA_OF(col);
|
||||
*dst = col + MUL_256(a, *dst);
|
||||
}
|
||||
else
|
||||
|
@ -193,26 +195,21 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
|
|||
static Eina_Bool
|
||||
_filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
|
||||
{
|
||||
unsigned int src_len, src_stride, map_len, map_stride, dst_len, dst_stride;
|
||||
int w, h, map_w, map_h, intensity;
|
||||
DATA8 *dst, *src;
|
||||
DATA32 *map_start;
|
||||
uint8_t *dst, *src;
|
||||
uint32_t *map_start;
|
||||
Eina_Bool stretch, smooth, blend;
|
||||
Evas_Filter_Buffer *map_fb;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
w = cmd->input->w;
|
||||
h = cmd->input->h;
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||
|
||||
src = ((RGBA_Image *) cmd->input->backing)->image.data8;
|
||||
map_start = ((RGBA_Image *) cmd->mask->backing)->image.data;
|
||||
dst = ((RGBA_Image *) cmd->output->backing)->image.data8;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
|
||||
|
||||
src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
|
||||
dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ, E_ALPHA, &dst_stride);
|
||||
stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH;
|
||||
smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR;
|
||||
map_w = cmd->mask->w;
|
||||
|
@ -223,26 +220,32 @@ _filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
|
|||
// Stretch if necessary.
|
||||
if ((map_w != w || map_h != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
|
||||
{
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
|
||||
map_w = w;
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
|
||||
map_h = h;
|
||||
|
||||
BUFFERS_LOCK();
|
||||
fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
|
||||
map_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
|
||||
BUFFERS_UNLOCK();
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
|
||||
fb->locked = EINA_FALSE;
|
||||
map_start = ((RGBA_Image *) fb->backing)->image.data;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(map_fb, EINA_FALSE);
|
||||
map_fb->locked = EINA_FALSE;
|
||||
}
|
||||
else map_fb = cmd->mask;
|
||||
|
||||
map_start = (uint32_t *) _buffer_map_all(map_fb->buffer, &map_len, E_READ, E_ARGB, &map_stride);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(src && dst && map_start, end);
|
||||
|
||||
_filter_displace_cpu_alpha_do(w, h, map_w, map_h, intensity,
|
||||
src, dst, map_start, stretch, smooth, blend);
|
||||
|
||||
return EINA_TRUE;
|
||||
ret = EINA_TRUE;
|
||||
end:
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
|
||||
eo_do(map_fb->buffer, ector_buffer_unmap(map_start, map_len));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -254,25 +257,20 @@ _filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
|
|||
static Eina_Bool
|
||||
_filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
unsigned int src_len, src_stride, map_len, map_stride, dst_len, dst_stride;
|
||||
int w, h, map_w, map_h, intensity;
|
||||
DATA32 *dst, *src, *map_start;
|
||||
uint32_t *dst, *src, *map_start;
|
||||
Eina_Bool stretch, smooth, blend;
|
||||
Evas_Filter_Buffer *map_fb;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
w = cmd->input->w;
|
||||
h = cmd->input->h;
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||
|
||||
src = ((RGBA_Image *) cmd->input->backing)->image.data;
|
||||
map_start = ((RGBA_Image *) cmd->mask->backing)->image.data;
|
||||
dst = ((RGBA_Image *) cmd->output->backing)->image.data;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
|
||||
|
||||
src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ARGB, &src_stride);
|
||||
dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ, E_ARGB, &dst_stride);
|
||||
stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH;
|
||||
smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR;
|
||||
map_w = cmd->mask->w;
|
||||
|
@ -283,26 +281,32 @@ _filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
|
|||
// Stretch if necessary.
|
||||
if ((map_w != w || map_h != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
|
||||
{
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
|
||||
map_w = w;
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
|
||||
map_h = h;
|
||||
|
||||
BUFFERS_LOCK();
|
||||
fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
|
||||
map_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
|
||||
BUFFERS_UNLOCK();
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
|
||||
fb->locked = EINA_FALSE;
|
||||
map_start = ((RGBA_Image *) fb->backing)->image.data;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(map_fb, EINA_FALSE);
|
||||
map_fb->locked = EINA_FALSE;
|
||||
}
|
||||
else map_fb = cmd->mask;
|
||||
|
||||
map_start = (uint32_t *) _buffer_map_all(map_fb->buffer, &map_len, E_READ, E_ARGB, &map_stride);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(src && dst && map_start, end);
|
||||
|
||||
_filter_displace_cpu_rgba_do(w, h, map_w, map_h, intensity,
|
||||
src, dst, map_start, stretch, smooth, blend);
|
||||
|
||||
return EINA_TRUE;
|
||||
ret = EINA_TRUE;
|
||||
end:
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
|
||||
eo_do(map_fb->buffer, ector_buffer_unmap(map_start, map_len));
|
||||
return ret;
|
||||
}
|
||||
|
||||
Evas_Filter_Apply_Func
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
#include "evas_filter_private.h"
|
||||
#include "draw.h"
|
||||
|
||||
static Eina_Bool
|
||||
_fill_cpu(Evas_Filter_Command *cmd)
|
||||
{
|
||||
Evas_Filter_Buffer *fb = cmd->output;
|
||||
int step = fb->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
|
||||
int step = fb->alpha_only ? sizeof(uint8_t) : sizeof(uint32_t);
|
||||
int x = MAX(0, cmd->draw.clip.x);
|
||||
int y = MAX(0, cmd->draw.clip.y);
|
||||
DATA8 *ptr = ((RGBA_Image *) fb->backing)->image.data8;
|
||||
int w, h, k, j;
|
||||
uint32_t color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
|
||||
unsigned int stride, len;
|
||||
int w, h, k;
|
||||
uint8_t *ptr;
|
||||
|
||||
if (!cmd->draw.clip_mode_lrtb)
|
||||
{
|
||||
|
@ -29,30 +32,28 @@ _fill_cpu(Evas_Filter_Command *cmd)
|
|||
h = CLAMP(0, fb->h - y - cmd->draw.clip.b, fb->h - y);
|
||||
}
|
||||
|
||||
ptr += y * step * fb->w;
|
||||
if ((fb->alpha_only)
|
||||
|| (!cmd->draw.R && !cmd->draw.G && !cmd->draw.B && !cmd->draw.A)
|
||||
|| ((cmd->draw.R == 0xff) && (cmd->draw.G == 0xff)
|
||||
&& (cmd->draw.B == 0xff) && (cmd->draw.A == 0xff)))
|
||||
ptr = _buffer_map_all(fb->buffer, &len, E_WRITE, fb->alpha_only ? E_ALPHA : E_ARGB, &stride);
|
||||
if (!ptr) return EINA_FALSE;
|
||||
|
||||
ptr += y * stride;
|
||||
if (fb->alpha_only)
|
||||
{
|
||||
for (k = 0; k < h; k++)
|
||||
{
|
||||
memset(ptr + (x * step), cmd->draw.A, step * w);
|
||||
ptr += step * fb->w;
|
||||
ptr += stride;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DATA32 *dst = ((DATA32 *) ptr) + x;
|
||||
DATA32 color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
|
||||
for (k = 0; k < h; k++)
|
||||
{
|
||||
for (j = 0; j < w; j++)
|
||||
*dst++ = color;
|
||||
dst += fb->w - w;
|
||||
uint32_t *dst = ((uint32_t *) (ptr + (y + k) * stride)) + x;
|
||||
draw_memset32(dst, color, w);
|
||||
}
|
||||
}
|
||||
|
||||
eo_do(fb->buffer, ector_buffer_unmap(ptr, len));
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@ evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd)
|
|||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask, NULL);
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, NULL);
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->buffer, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->buffer, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->buffer, NULL);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->input->w > 0) && (cmd->input->h > 0), NULL);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->mask->w > 0) && (cmd->mask->h > 0), NULL);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->w == cmd->output->w, NULL);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->h == cmd->output->h, NULL);
|
||||
|
||||
|
@ -53,12 +53,14 @@ evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd)
|
|||
static Eina_Bool
|
||||
_mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
|
||||
{
|
||||
Alpha_Gfx_Func func;
|
||||
RGBA_Image *in, *out, *mask;
|
||||
DATA8 *src, *dst, *msk;
|
||||
unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
|
||||
Efl_Gfx_Render_Op render_op = cmd->draw.rop;
|
||||
Evas_Filter_Buffer *msk_fb;
|
||||
Alpha_Gfx_Func func;
|
||||
uint8_t *src_map = NULL, *dst, *dst_map = NULL, *msk, *msk_map = NULL;
|
||||
int w, h, mw, mh, x, y, my;
|
||||
int stepsize, stepcount, step;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
/* Mechanism:
|
||||
* 1. Stretch mask as requested in fillmode
|
||||
|
@ -68,56 +70,57 @@ _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
|
|||
* FIXME: Could probably be optimized into a single op :)
|
||||
*/
|
||||
|
||||
in = (RGBA_Image *) cmd->input->backing;
|
||||
out = (RGBA_Image *) cmd->output->backing;
|
||||
mask = (RGBA_Image *) cmd->mask->backing;
|
||||
|
||||
w = cmd->input->w;
|
||||
h = cmd->input->h;
|
||||
mw = cmd->mask->w;
|
||||
mh = cmd->mask->h;
|
||||
src = in->image.data8;
|
||||
dst = out->image.data8;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
|
||||
|
||||
stepsize = MIN(mw, w);
|
||||
stepcount = w / stepsize;
|
||||
|
||||
// Stretch if necessary.
|
||||
if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
|
||||
{
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
|
||||
mw = w;
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
|
||||
mh = h;
|
||||
|
||||
BUFFERS_LOCK();
|
||||
fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
|
||||
msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
|
||||
BUFFERS_UNLOCK();
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
|
||||
fb->locked = EINA_FALSE;
|
||||
mask = fb->backing;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
|
||||
msk_fb->locked = EINA_FALSE;
|
||||
}
|
||||
else msk_fb = cmd->mask;
|
||||
|
||||
msk = mask->image.data8;
|
||||
msk_map = msk = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ALPHA, &msk_stride);
|
||||
dst_map = dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ALPHA, &dst_stride);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(dst_map && msk_map, end);
|
||||
|
||||
// First pass: copy to dest
|
||||
if (src != dst)
|
||||
memcpy(dst, src, w * h * sizeof(DATA8));
|
||||
if (cmd->input->buffer != cmd->output->buffer)
|
||||
{
|
||||
src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(src_map, end);
|
||||
if (dst_stride == src_stride)
|
||||
memcpy(dst_map, src_map, dst_stride * h * sizeof(uint8_t));
|
||||
else
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
memcpy(dst_map + (y * dst_stride), src_map + (y * src_stride),
|
||||
MIN(dst_stride, src_stride) * h * sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
// Second pass: apply render op
|
||||
func = efl_draw_alpha_func_get(render_op, EINA_FALSE);
|
||||
for (y = 0, my = 0; y < h; y++, my++, msk += mw)
|
||||
for (y = 0, my = 0; y < h; y++, my++)
|
||||
{
|
||||
if (my >= mh)
|
||||
{
|
||||
my = 0;
|
||||
msk = mask->image.data8;
|
||||
}
|
||||
if (my >= mh) my = 0;
|
||||
|
||||
msk = msk_map + (my * msk_stride);
|
||||
dst = dst_map + (y * dst_stride);
|
||||
|
||||
for (step = 0; step < stepcount; step++, dst += stepsize)
|
||||
func(msk, dst, stepsize);
|
||||
|
@ -126,11 +129,16 @@ _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
|
|||
if (x < w)
|
||||
{
|
||||
func(msk, dst, w - x);
|
||||
dst += w - x;
|
||||
}
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
ret = EINA_TRUE;
|
||||
|
||||
end:
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
|
||||
eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
|
@ -161,14 +169,16 @@ _mask_cpu_rgba_alpha_rgba(Evas_Filter_Command *cmd)
|
|||
static Eina_Bool
|
||||
_mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
RGBA_Gfx_Func func1, func2;
|
||||
RGBA_Image *in, *out, *mask;
|
||||
DATA8 *src;
|
||||
DATA32 *dst, *msk, *span;
|
||||
unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
|
||||
Efl_Gfx_Render_Op op = cmd->draw.rop;
|
||||
int w, h, mw, mh, y, my, r;
|
||||
Evas_Filter_Buffer *msk_fb;
|
||||
RGBA_Gfx_Func func1, func2;
|
||||
uint8_t *src, *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
|
||||
uint32_t *dst, *msk, *span;
|
||||
int w, h, mw, mh, x, y, my;
|
||||
int stepsize, stepcount, step;
|
||||
DATA32 color2;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
uint32_t color;
|
||||
|
||||
/* Mechanism:
|
||||
* 1. Stretch mask as requested in fillmode
|
||||
|
@ -178,94 +188,88 @@ _mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd)
|
|||
* FIXME: Could probably be optimized into a single op :)
|
||||
*/
|
||||
|
||||
in = (RGBA_Image *) cmd->input->backing;
|
||||
out = (RGBA_Image *) cmd->output->backing;
|
||||
mask = (RGBA_Image *) cmd->mask->backing;
|
||||
|
||||
w = cmd->input->w;
|
||||
h = cmd->input->h;
|
||||
mw = cmd->mask->w;
|
||||
mh = cmd->mask->h;
|
||||
src = in->image.data8;
|
||||
dst = out->image.data;
|
||||
color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
|
||||
stepsize = MIN(mw, w);
|
||||
stepcount = w / stepsize;
|
||||
span = alloca(stepsize * sizeof(uint32_t));
|
||||
|
||||
// Stretch if necessary.
|
||||
if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
|
||||
{
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
|
||||
mw = w;
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
|
||||
mh = h;
|
||||
|
||||
BUFFERS_LOCK();
|
||||
fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
|
||||
msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
|
||||
BUFFERS_UNLOCK();
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
|
||||
fb->locked = EINA_FALSE;
|
||||
mask = fb->backing;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
|
||||
msk_fb->locked = EINA_FALSE;
|
||||
}
|
||||
else msk_fb = cmd->mask;
|
||||
|
||||
color2 = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
|
||||
msk = mask->image.data;
|
||||
src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ALPHA, &src_stride);
|
||||
msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ARGB, &msk_stride);
|
||||
dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end);
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msk, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
|
||||
|
||||
stepsize = MIN(mw, w);
|
||||
stepcount = w / stepsize;
|
||||
span = malloc(stepsize * sizeof(DATA32));
|
||||
|
||||
func1 = evas_common_gfx_func_composite_pixel_mask_span_get(mask->cache_entry.flags.alpha, mask->cache_entry.flags.alpha_sparse, out->cache_entry.flags.alpha, 1, EVAS_RENDER_COPY);
|
||||
func2 = evas_common_gfx_func_composite_pixel_color_span_get(mask->cache_entry.flags.alpha, mask->cache_entry.flags.alpha_sparse, color2, out->cache_entry.flags.alpha, 1, _gfx_to_evas_render_op(op));
|
||||
func1 = evas_common_gfx_func_composite_pixel_mask_span_get(1, 0, 1, 1, EVAS_RENDER_COPY);
|
||||
func2 = evas_common_gfx_func_composite_pixel_color_span_get(1, 0, color, 1, 1, _gfx_to_evas_render_op(op));
|
||||
|
||||
// Apply mask using Gfx functions
|
||||
for (y = 0, my = 0; y < h; y++, my++, msk += mw)
|
||||
for (y = 0, my = 0; y < h; y++, my++)
|
||||
{
|
||||
if (my >= mh)
|
||||
{
|
||||
my = 0;
|
||||
msk = mask->image.data;
|
||||
}
|
||||
if (my >= mh) my = 0;
|
||||
|
||||
src = src_map + (y * src_stride);
|
||||
msk = (uint32_t *) (msk_map + (my * msk_stride));
|
||||
dst = (uint32_t *) (dst_map + (y * dst_stride));
|
||||
|
||||
for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
|
||||
{
|
||||
memset(span, 0, stepsize * sizeof(DATA32));
|
||||
memset(span, 0, stepsize * sizeof(uint32_t));
|
||||
func1(msk, src, 0, span, stepsize);
|
||||
func2(span, NULL, color2, dst, stepsize);
|
||||
func2(span, NULL, color, dst, stepsize);
|
||||
}
|
||||
|
||||
r = w - (stepsize * stepcount);
|
||||
if (r > 0)
|
||||
x = stepsize * stepcount;
|
||||
if (x < w)
|
||||
{
|
||||
memset(span, 0, r * sizeof(DATA32));
|
||||
func1(msk, src, 0, span, r);
|
||||
func2(span, NULL, color2, dst, r);
|
||||
dst += r;
|
||||
src += r;
|
||||
memset(span, 0, (w - x) * sizeof(uint32_t));
|
||||
func1(msk, src, 0, span, w - x);
|
||||
func2(span, NULL, color, dst, w - x);
|
||||
}
|
||||
}
|
||||
|
||||
free(span);
|
||||
return EINA_TRUE;
|
||||
ret = EINA_TRUE;
|
||||
|
||||
end:
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
|
||||
eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
|
||||
uint8_t *src, *msk, *span, *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
|
||||
Evas_Filter_Buffer *msk_fb;
|
||||
RGBA_Gfx_Func func;
|
||||
Alpha_Gfx_Func span_func;
|
||||
RGBA_Image *in, *out, *mask;
|
||||
DATA8 *src, *msk, *span;
|
||||
DATA32 *dst;
|
||||
DATA32 color;
|
||||
uint32_t *dst;
|
||||
uint32_t color;
|
||||
Efl_Gfx_Render_Op op = cmd->draw.rop;
|
||||
int w, h, mw, mh, y, my, r;
|
||||
int w, h, mw, mh, x, y, my;
|
||||
int stepsize, stepcount, step;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
/* Mechanism:
|
||||
* 1. Copy mask to span buffer (1 line)
|
||||
|
@ -275,155 +279,147 @@ _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
|
|||
* FIXME: Could probably be optimized into a single op :)
|
||||
*/
|
||||
|
||||
in = (RGBA_Image *) cmd->input->backing;
|
||||
out = (RGBA_Image *) cmd->output->backing;
|
||||
mask = (RGBA_Image *) cmd->mask->backing;
|
||||
|
||||
w = cmd->input->w;
|
||||
h = cmd->input->h;
|
||||
mw = cmd->mask->w;
|
||||
mh = cmd->mask->h;
|
||||
src = in->image.data8;
|
||||
dst = out->image.data;
|
||||
color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
|
||||
stepsize = MIN(mw, w);
|
||||
stepcount = w / stepsize;
|
||||
span = alloca(stepsize * sizeof(uint32_t));
|
||||
|
||||
// Stretch if necessary.
|
||||
if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
|
||||
{
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
|
||||
mw = w;
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
|
||||
mh = h;
|
||||
|
||||
BUFFERS_LOCK();
|
||||
fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
|
||||
msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
|
||||
BUFFERS_UNLOCK();
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
|
||||
fb->locked = EINA_FALSE;
|
||||
mask = fb->backing;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
|
||||
msk_fb->locked = EINA_FALSE;
|
||||
}
|
||||
else msk_fb = cmd->mask;
|
||||
|
||||
msk = mask->image.data8;
|
||||
stepsize = MIN(mw, w);
|
||||
stepcount = w / stepsize;
|
||||
span = malloc(stepsize * sizeof(DATA8));
|
||||
src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ALPHA, &src_stride);
|
||||
msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ARGB, &msk_stride);
|
||||
dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end);
|
||||
|
||||
func = evas_common_gfx_func_composite_mask_color_span_get(color, out->cache_entry.flags.alpha, 1, _gfx_to_evas_render_op(op));
|
||||
func = evas_common_gfx_func_composite_mask_color_span_get(color, 1, 1, _gfx_to_evas_render_op(op));
|
||||
span_func = efl_draw_alpha_func_get(cmd->draw.rop, EINA_TRUE);
|
||||
|
||||
for (y = 0, my = 0; y < h; y++, my++, msk += mw)
|
||||
{
|
||||
if (my >= mh)
|
||||
{
|
||||
my = 0;
|
||||
msk = mask->image.data8;
|
||||
}
|
||||
if (my >= mh) my = 0;
|
||||
|
||||
src = src_map + (y * src_stride);
|
||||
msk = msk_map + (my * msk_stride);
|
||||
dst = (uint32_t *) (dst_map + (y * dst_stride));
|
||||
|
||||
for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
|
||||
{
|
||||
memcpy(span, msk, stepsize * sizeof(DATA8));
|
||||
memcpy(span, msk, stepsize * sizeof(uint8_t));
|
||||
span_func(src, span, stepsize);
|
||||
func(NULL, span, color, dst, stepsize);
|
||||
}
|
||||
|
||||
r = w - (stepsize * stepcount);
|
||||
if (r > 0)
|
||||
x = stepsize * stepcount;
|
||||
if (x < w)
|
||||
{
|
||||
memcpy(span, msk, r * sizeof(DATA8));
|
||||
span_func(src, span, r);
|
||||
func(NULL, span, color, dst, r);
|
||||
dst += r;
|
||||
src += r;
|
||||
memcpy(span, msk, (w - x) * sizeof(uint8_t));
|
||||
span_func(src, span, w - x);
|
||||
func(NULL, span, color, dst, w -x);
|
||||
}
|
||||
}
|
||||
|
||||
free(span);
|
||||
return EINA_TRUE;
|
||||
ret = EINA_TRUE;
|
||||
|
||||
end:
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
|
||||
eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd)
|
||||
{
|
||||
unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
|
||||
uint8_t *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
|
||||
Draw_Func_ARGB_Mix3 func;
|
||||
RGBA_Image *in, *out, *mask;
|
||||
DATA32 *dst, *msk, *src;
|
||||
int w, h, mw, mh, y, my, r;
|
||||
Evas_Filter_Buffer *msk_fb;
|
||||
uint32_t *dst, *msk, *src;
|
||||
int w, h, mw, mh, x, y, my;
|
||||
int stepsize, stepcount, step;
|
||||
DATA32 color;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
uint32_t color;
|
||||
|
||||
/* Mechanism:
|
||||
* 1. Stretch mask as requested in fillmode
|
||||
* 2. Mix 3 colors
|
||||
*/
|
||||
|
||||
in = (RGBA_Image *) cmd->input->backing;
|
||||
out = (RGBA_Image *) cmd->output->backing;
|
||||
mask = (RGBA_Image *) cmd->mask->backing;
|
||||
|
||||
w = cmd->input->w;
|
||||
h = cmd->input->h;
|
||||
mw = cmd->mask->w;
|
||||
mh = cmd->mask->h;
|
||||
src = in->image.data;
|
||||
dst = out->image.data;
|
||||
color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
|
||||
stepsize = MIN(mw, w);
|
||||
stepcount = w / stepsize;
|
||||
|
||||
// Stretch if necessary.
|
||||
if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
|
||||
{
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
|
||||
mw = w;
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
|
||||
mh = h;
|
||||
|
||||
BUFFERS_LOCK();
|
||||
fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
|
||||
msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
|
||||
BUFFERS_UNLOCK();
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
|
||||
fb->locked = EINA_FALSE;
|
||||
mask = fb->backing;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
|
||||
msk_fb->locked = EINA_FALSE;
|
||||
}
|
||||
else msk_fb = cmd->mask;
|
||||
|
||||
color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
|
||||
msk = mask->image.data;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msk, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
|
||||
|
||||
stepsize = MIN(mw, w);
|
||||
stepcount = w / stepsize;
|
||||
src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ARGB, &src_stride);
|
||||
msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ARGB, &msk_stride);
|
||||
dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end);
|
||||
|
||||
func = efl_draw_func_argb_mix3_get(cmd->draw.rop, color);
|
||||
|
||||
// Apply mask using Gfx functions
|
||||
for (y = 0, my = 0; y < h; y++, my++, msk += mw)
|
||||
for (y = 0, my = 0; y < h; y++, my++)
|
||||
{
|
||||
if (my >= mh)
|
||||
{
|
||||
my = 0;
|
||||
msk = mask->image.data;
|
||||
}
|
||||
if (my >= mh) my = 0;
|
||||
|
||||
src = (uint32_t *) (src_map + (y * src_stride));
|
||||
msk = (uint32_t *) (msk_map + (my * msk_stride));
|
||||
dst = (uint32_t *) (dst_map + (y * dst_stride));
|
||||
|
||||
for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
|
||||
func(dst, src, msk, stepsize, color);
|
||||
|
||||
r = w - (stepsize * stepcount);
|
||||
if (r > 0)
|
||||
x = stepsize * stepcount;
|
||||
if (x < w)
|
||||
{
|
||||
func(dst, src, msk, r, color);
|
||||
dst += r;
|
||||
src += r;
|
||||
func(dst, src, msk, w - x, color);
|
||||
}
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
ret = EINA_TRUE;
|
||||
|
||||
end:
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
|
||||
eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
|
||||
eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ struct _Evas_Filter_Buffer
|
|||
|
||||
Evas_Object *source;
|
||||
Eina_Stringshare *source_name;
|
||||
RGBA_Image *backing;
|
||||
Ector_Generic_Buffer *buffer;
|
||||
void *glimage;
|
||||
int w, h;
|
||||
|
||||
|
@ -275,4 +275,20 @@ int evas_filter_smallest_pow2_larger_than(int val);
|
|||
|
||||
void evas_filter_parser_shutdown(void);
|
||||
|
||||
#define E_READ ECTOR_BUFFER_ACCESS_FLAG_READ
|
||||
#define E_WRITE ECTOR_BUFFER_ACCESS_FLAG_WRITE
|
||||
#define E_ALPHA EFL_GFX_COLORSPACE_GRY8
|
||||
#define E_ARGB EFL_GFX_COLORSPACE_ARGB8888
|
||||
|
||||
static inline void *
|
||||
_buffer_map_all(Ector_Buffer *buf, unsigned int *len, Ector_Buffer_Access_Flag mode, Efl_Gfx_Colorspace cspace, unsigned int *stride)
|
||||
{
|
||||
void *ret = NULL;
|
||||
int w, h;
|
||||
if (!buf) return NULL;
|
||||
eo_do(buf, ector_buffer_size_get(&w, &h);
|
||||
ret = ector_buffer_map(len, mode, 0, 0, w, h, cspace, stride));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // EVAS_FILTER_PRIVATE_H
|
||||
|
|
|
@ -10,27 +10,22 @@
|
|||
static Eina_Bool
|
||||
_vflip_cpu(Evas_Filter_Command *cmd)
|
||||
{
|
||||
size_t datasize, stride;
|
||||
DATA8 *in, *out, *span = NULL;
|
||||
unsigned int src_len, src_stride, dst_len, dst_stride;
|
||||
uint8_t *in, *out = NULL, *span = NULL;
|
||||
int w, h, sy, dy, oy, center, t, b, objh;
|
||||
int s0, s1, d0, d1;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||
Eina_Bool ret = 0;
|
||||
|
||||
w = cmd->input->w;
|
||||
h = cmd->input->h;
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->w == w, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->h == h, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->alpha_only == cmd->input->alpha_only, EINA_FALSE);
|
||||
in = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &src_stride);
|
||||
if (cmd->input->buffer != cmd->output->buffer)
|
||||
out = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &dst_stride);
|
||||
|
||||
in = ((RGBA_Image *) cmd->input->backing)->image.data8;
|
||||
out = ((RGBA_Image *) cmd->output->backing)->image.data8;
|
||||
datasize = cmd->input->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
|
||||
stride = w * datasize;
|
||||
EINA_SAFETY_ON_FALSE_GOTO(cmd->output->w == w, end);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(cmd->output->h == h, end);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(src_stride <= dst_stride, end);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(cmd->output->alpha_only == cmd->input->alpha_only, end);
|
||||
|
||||
oy = cmd->draw.oy;
|
||||
t = cmd->ctx->padt;
|
||||
|
@ -53,28 +48,32 @@ _vflip_cpu(Evas_Filter_Command *cmd)
|
|||
|
||||
if (in == out)
|
||||
{
|
||||
span = malloc(stride);
|
||||
if (!span) return EINA_FALSE;
|
||||
span = alloca(src_stride);
|
||||
if (!span) goto end;
|
||||
}
|
||||
|
||||
for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--)
|
||||
{
|
||||
DATA8* src = in + stride * sy;
|
||||
DATA8* dst = out + stride * dy;
|
||||
uint8_t* src = in + src_stride * sy;
|
||||
uint8_t* dst = out + dst_stride * dy;
|
||||
|
||||
if (in == out)
|
||||
{
|
||||
if (src == dst) break;
|
||||
memcpy(span, dst, stride);
|
||||
memcpy(dst, src, stride);
|
||||
memcpy(src, span, stride);
|
||||
memcpy(span, dst, src_stride);
|
||||
memcpy(dst, src, src_stride);
|
||||
memcpy(src, span, src_stride);
|
||||
if (sy >= center) break;
|
||||
}
|
||||
else
|
||||
memcpy(dst, src, stride);
|
||||
memcpy(dst, src, src_stride);
|
||||
}
|
||||
free(span);
|
||||
return EINA_TRUE;
|
||||
ret = EINA_TRUE;
|
||||
|
||||
end:
|
||||
eo_do(cmd->input->buffer, ector_buffer_unmap(in, src_len));
|
||||
if (in != out) eo_do(cmd->output->buffer, ector_buffer_unmap(out, dst_len));
|
||||
return ret;
|
||||
}
|
||||
|
||||
Evas_Filter_Apply_Func
|
||||
|
|
|
@ -8,77 +8,36 @@ evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx,
|
|||
unsigned w, unsigned h)
|
||||
{
|
||||
Evas_Filter_Buffer *fb;
|
||||
Image_Entry *dstdata = NULL;
|
||||
Image_Entry *srcdata;
|
||||
void *drawctx;
|
||||
RGBA_Image *dstim, *srcim;
|
||||
RGBA_Draw_Context dc;
|
||||
Eina_Bool ok;
|
||||
|
||||
srcdata = evas_filter_buffer_backing_get(ctx, src->id);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(srcdata, NULL);
|
||||
// only for RGBA
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(!src->alpha_only, NULL);
|
||||
|
||||
if (src->alpha_only)
|
||||
{
|
||||
// There is no supporting function in Evas for alpha scaling...
|
||||
// but guess what? There is also no use case in the filters :)
|
||||
CRI("Alpha buffer scaling is not supported");
|
||||
return NULL;
|
||||
}
|
||||
srcim = evas_filter_buffer_backing_get(ctx, src->id);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(srcim, NULL);
|
||||
|
||||
fb = evas_filter_temporary_buffer_get(ctx, w, h, src->alpha_only);
|
||||
if (!fb) return NULL;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb, NULL);
|
||||
|
||||
dstdata = evas_filter_buffer_backing_get(ctx, fb->id);
|
||||
if (!dstdata)
|
||||
{
|
||||
CRI("No backing found for buffer %d", fb->id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((dstdata->w != w) || (dstdata->h != h))
|
||||
{
|
||||
CRI("Buffer size mismatch: got %dx%d requested %dx%d",
|
||||
dstdata->w, dstdata->h, w, h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx->gl_engine)
|
||||
{
|
||||
RGBA_Image *s = (RGBA_Image *) srcdata;
|
||||
RGBA_Image *d = (RGBA_Image *) dstdata;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(s->image.data, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(d->image.data, NULL);
|
||||
|
||||
if (src->w == (int) w && src->h == (int) h)
|
||||
memcpy(d->image.data, s->image.data, w * h * 4);
|
||||
else
|
||||
{
|
||||
Eina_Bool ok;
|
||||
RGBA_Draw_Context dc;
|
||||
dstim = evas_filter_buffer_backing_get(ctx, fb->id);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dstim, NULL);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((dstim->cache_entry.w == w) &&
|
||||
(dstim->cache_entry.h == h), NULL);
|
||||
|
||||
memset(&dc, 0, sizeof(dc));
|
||||
dc.sli.h = 1;
|
||||
dc.render_op = EVAS_RENDER_COPY;
|
||||
|
||||
ok = evas_common_scale_rgba_in_to_out_clip_smooth
|
||||
(s, d, &dc, 0, 0, src->w, src->h, 0, 0, w, h);
|
||||
(srcim, dstim, &dc, 0, 0, src->w, src->h, 0, 0, w, h);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
ERR("RGBA Image scaling failed.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
drawctx = ENFN->context_new(ENDT);
|
||||
ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
|
||||
ENFN->context_render_op_set(ENDT, drawctx, EVAS_RENDER_COPY);
|
||||
ENFN->image_draw(ENDT, drawctx, dstdata, srcdata,
|
||||
0, 0, src->w, src->h, // src
|
||||
0, 0, w, h, // dst
|
||||
EINA_TRUE, // smooth
|
||||
EINA_FALSE); // Not async
|
||||
ENFN->context_free(ENDT, drawctx);
|
||||
}
|
||||
|
||||
return fb;
|
||||
}
|
||||
|
|
|
@ -143,7 +143,6 @@ void evas_filter_context_post_run_callback_set(Evas_Filter_C
|
|||
Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx);
|
||||
|
||||
int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only);
|
||||
int evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image);
|
||||
void *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid);
|
||||
void *evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid);
|
||||
Eina_Bool evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer);
|
||||
|
|
|
@ -1450,7 +1450,8 @@ struct _Evas_Func
|
|||
|
||||
Ector_Surface *(*ector_create) (void *data);
|
||||
void (*ector_destroy) (void *data, Ector_Surface *surface);
|
||||
Ector_Buffer *(*ector_buffer_new) (void *data, Evas *e, void *engine_image); // free it with eo_del
|
||||
Ector_Buffer *(*ector_buffer_wrap) (void *data, Evas *e, void *engine_image);
|
||||
Ector_Buffer *(*ector_buffer_new) (void *data, Evas *e, void *pixels, int width, int height, int stride, Efl_Gfx_Colorspace cspace, Eina_Bool writeable, int l, int r, int t, int b, Ector_Buffer_Flag flags);
|
||||
void (*ector_begin) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, int x, int y, Eina_Bool do_async);
|
||||
void (*ector_renderer_draw) (void *data, void *context, void *surface, void *engine_data, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
|
||||
void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async);
|
||||
|
|
|
@ -2465,17 +2465,20 @@ eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector)
|
|||
}
|
||||
|
||||
static Ector_Buffer *
|
||||
eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image)
|
||||
eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image)
|
||||
{
|
||||
Evas_GL_Image *im = engine_image;
|
||||
Ector_Buffer *buf = NULL;
|
||||
|
||||
if (!im) return NULL;
|
||||
|
||||
#warning FIXME: implement me
|
||||
(void) e;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buf;
|
||||
static Ector_Buffer *
|
||||
eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *pixels,
|
||||
int width, int height, int stride,
|
||||
Efl_Gfx_Colorspace cspace, Eina_Bool writeable,
|
||||
int l, int r, int t, int b, Ector_Buffer_Flag flags)
|
||||
{
|
||||
#warning FIXME: implement me
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Efl_Gfx_Render_Op
|
||||
|
@ -2836,6 +2839,7 @@ module_open(Evas_Module *em)
|
|||
|
||||
ORD(ector_create);
|
||||
ORD(ector_destroy);
|
||||
ORD(ector_buffer_wrap);
|
||||
ORD(ector_buffer_new);
|
||||
ORD(ector_begin);
|
||||
ORD(ector_renderer_draw);
|
||||
|
|
|
@ -49,7 +49,7 @@ _evas_ector_software_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ect
|
|||
|
||||
eo_do(obj, ector_buffer_pixels_set(im->image.data,
|
||||
im->cache_entry.w, im->cache_entry.h, 0,
|
||||
_evas_to_gfx_render_op(im->cache_entry.space),
|
||||
im->cache_entry.space,
|
||||
EINA_TRUE, 0, 0, 0, 0));
|
||||
}
|
||||
|
||||
|
|
|
@ -3758,7 +3758,7 @@ eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector)
|
|||
}
|
||||
|
||||
static Ector_Buffer *
|
||||
eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image)
|
||||
eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image)
|
||||
{
|
||||
Image_Entry *ie = engine_image;
|
||||
Ector_Buffer *buf = NULL;
|
||||
|
@ -3771,6 +3771,22 @@ eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image)
|
|||
return buf;
|
||||
}
|
||||
|
||||
static Ector_Buffer *
|
||||
eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *pixels,
|
||||
int width, int height, int stride,
|
||||
Efl_Gfx_Colorspace cspace, Eina_Bool writeable,
|
||||
int l, int r, int t, int b,
|
||||
Ector_Buffer_Flag flags EINA_UNUSED)
|
||||
{
|
||||
Ector_Buffer *buf = NULL;
|
||||
|
||||
buf = eo_add(ECTOR_SOFTWARE_BUFFER_CLASS, e,
|
||||
ector_buffer_pixels_set(pixels, width, height, stride, cspace,
|
||||
writeable, l, r, t, b));
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static Efl_Gfx_Render_Op
|
||||
_evas_render_op_to_ector_rop(Evas_Render_Op op)
|
||||
{
|
||||
|
@ -4182,6 +4198,7 @@ static Evas_Func func =
|
|||
NULL, // eng_texture_image_get
|
||||
eng_ector_create,
|
||||
eng_ector_destroy,
|
||||
eng_ector_buffer_wrap,
|
||||
eng_ector_buffer_new,
|
||||
eng_ector_begin,
|
||||
eng_ector_renderer_draw,
|
||||
|
|
Loading…
Reference in New Issue