diff --git a/src/lib/evas/canvas/evas_filter_mixin.c b/src/lib/evas/canvas/evas_filter_mixin.c index e93fa703e2..8c5c8ae9c7 100644 --- a/src/lib/evas/canvas/evas_filter_mixin.c +++ b/src/lib/evas/canvas/evas_filter_mixin.c @@ -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); diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index 6aa18902cd..148a032176 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c @@ -21,25 +21,28 @@ #endif #include "evas_filter_private.h" +#include +#include +#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) + // 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 + + 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 + + if (data) { - 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); - } + // 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 { - // FIXME: Directly calling the alloc functions since we want to use sw surfaces. - - 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 -#endif - image = (RGBA_Image *) evas_cache_image_copied_data - (evas_common_image_cache_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace); - } - 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) - ctx->post_run.buffers_to_free = - eina_list_append(ctx->post_run.buffers_to_free, stolen_buffer); else - _backing_free(ctx, stolen_buffer); + { + ctx->post_run.buffers_to_free = + eina_list_append(ctx->post_run.buffers_to_free, 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); - } + ENFN->image_free(ENDT, buffer); return ok; } diff --git a/src/lib/evas/filters/evas_filter_blend.c b/src/lib/evas/filters/evas_filter_blend.c index 0c7c5481f2..153e568a96 100644 --- a/src/lib/evas/filters/evas_filter_blend.c +++ b/src/lib/evas/filters/evas_filter_blend.c @@ -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; + return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba2rgba); } 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,27 +442,18 @@ 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->input->alpha_only) - { - if (cmd->output->alpha_only) - return _filter_blend_cpu_alpha; - else - return _filter_blend_cpu_mask_rgba; - } + if (cmd->output->alpha_only) + return _filter_blend_cpu_alpha; else - { - if (cmd->output->alpha_only) - return _filter_blend_cpu_rgba2alpha; - else - return _filter_blend_cpu_rgba; - } + return _filter_blend_cpu_alpha2rgba; } else { - CRI("Can't render to GL image for the moment!"); - //return _filter_blend_opengl_generic; - return NULL; + if (cmd->output->alpha_only) + return _filter_blend_cpu_rgba2alpha; + else + return _filter_blend_cpu_rgba; } } diff --git a/src/lib/evas/filters/evas_filter_blur.c b/src/lib/evas/filters/evas_filter_blur.c index fd444cc45b..9cf851faec 100644 --- a/src/lib/evas/filters/evas_filter_blur.c +++ b/src/lib/evas/filters/evas_filter_blur.c @@ -4,6 +4,8 @@ #include #include +// 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); - DEBUG_TIME_BEGIN(); - _gaussian_blur_vert_rgba_step(src, dst, radius, h, w, 1, weights, pow2_div); - DEBUG_TIME_END(); + 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 */ diff --git a/src/lib/evas/filters/evas_filter_bump.c b/src/lib/evas/filters/evas_filter_bump.c index 6155e6549d..e93f1adda6 100644 --- a/src/lib/evas/filters/evas_filter_bump.c +++ b/src/lib/evas/filters/evas_filter_bump.c @@ -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 diff --git a/src/lib/evas/filters/evas_filter_curve.c b/src/lib/evas/filters/evas_filter_curve.c index 0a9d761fc6..9950121ec3 100644 --- a/src/lib/evas/filters/evas_filter_curve.c +++ b/src/lib/evas/filters/evas_filter_curve.c @@ -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; } diff --git a/src/lib/evas/filters/evas_filter_displace.c b/src/lib/evas/filters/evas_filter_displace.c index 3a1829c03f..1513a919da 100644 --- a/src/lib/evas/filters/evas_filter_displace.c +++ b/src/lib/evas/filters/evas_filter_displace.c @@ -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 diff --git a/src/lib/evas/filters/evas_filter_fill.c b/src/lib/evas/filters/evas_filter_fill.c index 52932333e0..e7090d9913 100644 --- a/src/lib/evas/filters/evas_filter_fill.c +++ b/src/lib/evas/filters/evas_filter_fill.c @@ -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; } diff --git a/src/lib/evas/filters/evas_filter_mask.c b/src/lib/evas/filters/evas_filter_mask.c index 135d0dfbe9..d8d6ddabe7 100644 --- a/src/lib/evas/filters/evas_filter_mask.c +++ b/src/lib/evas/filters/evas_filter_mask.c @@ -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; } diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h index 02dd977d34..f3d7118be0 100644 --- a/src/lib/evas/filters/evas_filter_private.h +++ b/src/lib/evas/filters/evas_filter_private.h @@ -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 diff --git a/src/lib/evas/filters/evas_filter_transform.c b/src/lib/evas/filters/evas_filter_transform.c index 3deda12c89..fd05d5c7fa 100644 --- a/src/lib/evas/filters/evas_filter_transform.c +++ b/src/lib/evas/filters/evas_filter_transform.c @@ -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 diff --git a/src/lib/evas/filters/evas_filter_utils.c b/src/lib/evas/filters/evas_filter_utils.c index c643c67a5f..8bb98d5bf5 100644 --- a/src/lib/evas/filters/evas_filter_utils.c +++ b/src/lib/evas/filters/evas_filter_utils.c @@ -8,76 +8,35 @@ 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) + 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 + (srcim, dstim, &dc, 0, 0, src->w, src->h, 0, 0, w, h); + + if (!ok) { - 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; - - 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); - 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); + ERR("RGBA Image scaling failed."); + return NULL; } return fb; diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h index f1cbffb31c..bb7a32d287 100644 --- a/src/lib/evas/include/evas_filter.h +++ b/src/lib/evas/include/evas_filter.h @@ -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); diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 854d99d7db..8ca3c2b7f1 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -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); diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 0a9e0bcaa6..78a73f41d1 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -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); diff --git a/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c b/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c index 3d45862653..44ebf8fbd3 100644 --- a/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c +++ b/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c @@ -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)); } diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 22967ad14d..a32c7e60c6 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -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,