diff --git a/src/lib/evas/common/evas_map_image.c b/src/lib/evas/common/evas_map_image.c index 05ad32acfb..cec21f6480 100644 --- a/src/lib/evas/common/evas_map_image.c +++ b/src/lib/evas/common/evas_map_image.c @@ -675,7 +675,8 @@ void evas_common_map_rgba_internal_mmx(RGBA_Image *src, RGBA_Image *dst, RGBA_Dr _evas_common_map_rgba_internal_mmx(src, dst, clip_x, clip_y, clip_w, clip_h, mul_col, dc->render_op, - p, smooth, dc->anti_alias, level); + p, smooth, dc->anti_alias, level, + dc->clip.mask, dc->clip.mask_x, dc->clip.mask_y); } #endif @@ -703,7 +704,8 @@ void evas_common_map_rgba_internal(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_C _evas_common_map_rgba_internal(src, dst, clip_x, clip_y, clip_w, clip_h, mul_col, dc->render_op, - p, smooth, dc->anti_alias, level); + p, smooth, dc->anti_alias, level, + dc->clip.mask, dc->clip.mask_x, dc->clip.mask_y); } #ifdef BUILD_NEON @@ -731,7 +733,8 @@ void evas_common_map_rgba_internal_neon(RGBA_Image *src, RGBA_Image *dst, RGBA_D _evas_common_map_rgba_internal_neon(src, dst, clip_x, clip_y, clip_w, clip_h, mul_col, dc->render_op, - p, smooth, dc->anti_alias, level); + p, smooth, dc->anti_alias, level, + dc->clip.mask, dc->clip.mask_x, dc->clip.mask_y); } #endif @@ -863,7 +866,7 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst, } EAPI void -evas_common_map_rgba_draw(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 mul_col, int render_op, int npoints EINA_UNUSED, RGBA_Map_Point *p, int smooth, Eina_Bool anti_alias, int level) +evas_common_map_rgba_draw(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 mul_col, int render_op, int npoints EINA_UNUSED, RGBA_Map_Point *p, int smooth, Eina_Bool anti_alias, int level, RGBA_Image *mask_ie, int mask_x, int mask_y) { #ifdef BUILD_MMX int mmx, sse, sse2; @@ -873,7 +876,8 @@ evas_common_map_rgba_draw(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip _evas_common_map_rgba_internal_mmx(src, dst, clip_x, clip_y, clip_w, clip_h, mul_col, render_op, - p, smooth, anti_alias, level); + p, smooth, anti_alias, level, + mask_ie, mask_x, mask_y); else #endif #ifdef BUILD_NEON @@ -881,13 +885,15 @@ evas_common_map_rgba_draw(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip _evas_common_map_rgba_internal_neon(src, dst, clip_x, clip_y, clip_w, clip_h, mul_col, render_op, - p, smooth, anti_alias, level); + p, smooth, anti_alias, level, + mask_ie, mask_x, mask_y); else #endif _evas_common_map_rgba_internal(src, dst, clip_x, clip_y, clip_w, clip_h, mul_col, render_op, - p, smooth, anti_alias, level); + p, smooth, anti_alias, level, + mask_ie, mask_x, mask_y); } EAPI void diff --git a/src/lib/evas/common/evas_map_image.h b/src/lib/evas/common/evas_map_image.h index ff83650fe9..2bca78b0a2 100644 --- a/src/lib/evas/common/evas_map_image.h +++ b/src/lib/evas/common/evas_map_image.h @@ -19,7 +19,7 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst, int npoints, RGBA_Map_Point *points, int smooth, int level); -EAPI void evas_common_map_rgba_draw(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 mul_col, int render_op, int npoints, RGBA_Map_Point *p, int smooth, Eina_Bool anti_alias, int level); +EAPI void evas_common_map_rgba_draw(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 mul_col, int render_op, int npoints, RGBA_Map_Point *p, int smooth, Eina_Bool anti_alias, int level, RGBA_Image *mask_ie, int mask_x, int mask_y); EAPI Eina_Bool evas_common_map_rgba_prepare(RGBA_Image *src, RGBA_Image *dst, diff --git a/src/lib/evas/common/evas_map_image_core.c b/src/lib/evas/common/evas_map_image_core.c index d514612998..14c46aa141 100644 --- a/src/lib/evas/common/evas_map_image_core.c +++ b/src/lib/evas/common/evas_map_image_core.c @@ -117,7 +117,16 @@ { d = dst->image.data; d += (y * dst->cache_entry.w) + x; - func(buf, NULL, mul_col, d, w); + if (!mask_ie) + func(buf, NULL, mul_col, d, w); + else + { + DATA8 *mask = mask_ie->image.data8 + + (y - mask_y) * mask_ie->cache_entry.w + + (x - mask_x); + if (mul_col != 0xffffffff) func2(buf, NULL, mul_col, buf, w); + func(buf, mask, 0, d, w); + } } } } @@ -226,7 +235,16 @@ { d = dst->image.data; d += (y * dst->cache_entry.w) + x; - func(buf, NULL, mul_col, d, w); + if (!mask_ie) + func(buf, NULL, mul_col, d, w); + else + { + DATA8 *mask = mask_ie->image.data8 + + (y - mask_y) * mask_ie->cache_entry.w + + (x - mask_x); + if (mul_col != 0xffffffff) func2(buf, NULL, mul_col, buf, w); + func(buf, mask, 0, d, w); + } } } } diff --git a/src/lib/evas/common/evas_map_image_internal.c b/src/lib/evas/common/evas_map_image_internal.c index ba00981319..f3238b2420 100644 --- a/src/lib/evas/common/evas_map_image_internal.c +++ b/src/lib/evas/common/evas_map_image_internal.c @@ -4,15 +4,17 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 mul_col, int render_op, RGBA_Map_Point *p, - int smooth, int anti_alias, int level EINA_UNUSED) // level unused for now - for future use + int smooth, int anti_alias, int level EINA_UNUSED, // level unused for now - for future use + RGBA_Image *mask_ie, int mask_x, int mask_y) { int i; int cx, cy, cw, ch; int ytop, ybottom, ystart, yend, y, sw, shp, swp, direct; Line *spans; DATA32 *buf = NULL, *sp; - RGBA_Gfx_Func func = NULL; + RGBA_Gfx_Func func = NULL, func2 = NULL; Eina_Bool havea = EINA_FALSE; + Eina_Bool sa, ssa, da; int havecol = 4; cx = clip_x; @@ -57,6 +59,10 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst, swp = sw << (FP + FPI); shp = src->cache_entry.h << (FP + FPI); + sa = src->cache_entry.flags.alpha; + ssa = src->cache_entry.flags.alpha_sparse; + da = dst->cache_entry.flags.alpha; + // limit u,v coords of points to be within the source image for (i = 0; i < 4; i++) { @@ -88,8 +94,8 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst, /* FIXME: even if anti-alias is enabled, only edges may require the pixels composition. we can optimize it. */ - if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha) && - (mul_col == 0xffffffff) && (!havea) && (!anti_alias)) + if ((!sa) && (!dst->cache_entry.flags.alpha) && + (mul_col == 0xffffffff) && (!havea) && (!anti_alias) && (!mask_ie)) { direct = 1; } @@ -98,12 +104,20 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst, int pa; buf = alloca(cw * sizeof(DATA32)); - pa = src->cache_entry.flags.alpha; - if (havea) src->cache_entry.flags.alpha = 1; - if (mul_col != 0xffffffff) - func = evas_common_gfx_func_composite_pixel_color_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, mul_col, dst->cache_entry.flags.alpha, cw, render_op); + if (havea) sa = 1; + if (!mask_ie) + { + if (mul_col != 0xffffffff) + func = evas_common_gfx_func_composite_pixel_color_span_get(sa, ssa, mul_col, da, cw, render_op); + else + func = evas_common_gfx_func_composite_pixel_span_get(sa, ssa, da, cw, render_op); + } else - 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, cw, render_op); + { + func = evas_common_gfx_func_composite_pixel_mask_span_get(sa, ssa, da, cw, render_op); + if (mul_col != 0xffffffff) + func2 = evas_common_gfx_func_composite_pixel_color_span_get(sa, ssa, mul_col, da, cw, render_op); + } if (anti_alias) src->cache_entry.flags.alpha = EINA_TRUE; else src->cache_entry.flags.alpha = pa; @@ -128,12 +142,17 @@ FUNC_NAME_DO(RGBA_Image *src, RGBA_Image *dst, { Line *spans; DATA32 *buf = NULL, *sp; - RGBA_Gfx_Func func = NULL; + RGBA_Gfx_Func func = NULL, func2 = NULL; int cx, cy, cw, ch; DATA32 mul_col; int ystart, yend, y, sw, shp, swp, direct; int havecol; int i; + Eina_Bool sa, ssa, da; + + RGBA_Image *mask_ie = dc->clip.mask; + int mask_x = dc->clip.mask_x; + int mask_y = dc->clip.mask_y; cx = dc->clip.x; cy = dc->clip.y; @@ -155,6 +174,10 @@ FUNC_NAME_DO(RGBA_Image *src, RGBA_Image *dst, havecol = ms->havecol; direct = ms->direct; + sa = src->cache_entry.flags.alpha; + ssa = src->cache_entry.flags.alpha_sparse; + da = dst->cache_entry.flags.alpha; + // allocate some s to hold out span list spans = alloca((yend - ystart + 1) * sizeof(Line)); memcpy(spans, &ms->spans[ystart - ms->ystart], @@ -167,13 +190,20 @@ FUNC_NAME_DO(RGBA_Image *src, RGBA_Image *dst, int pa; buf = alloca(cw * sizeof(DATA32)); - pa = src->cache_entry.flags.alpha; - if (ms->havea) src->cache_entry.flags.alpha = 1; - if (dc->mul.use) - func = evas_common_gfx_func_composite_pixel_color_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dc->mul.col, dst->cache_entry.flags.alpha, cw, dc->render_op); + if (ms->havea) sa = 1; + if (mask_ie) + { + if (mul_col != 0xffffffff) + func = evas_common_gfx_func_composite_pixel_color_span_get(sa, ssa, dc->mul.col, da, cw, dc->render_op); + else + func = evas_common_gfx_func_composite_pixel_span_get(sa, ssa, da, cw, dc->render_op); + } else - 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, cw, dc->render_op); - src->cache_entry.flags.alpha = pa; + { + func = evas_common_gfx_func_composite_pixel_mask_span_get(sa, ssa, da, cw, dc->render_op); + if (mul_col != 0xffffffff) + func2 = evas_common_gfx_func_composite_pixel_color_span_get(sa, ssa, dc->mul.col, da, cw, dc->render_op); + } } if (havecol == 0) diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 4bd1fd2b35..17ed7f3d44 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -367,6 +367,8 @@ struct _Evas_Thread_Command_Map RGBA_Map *map; int smooth, level, offset; Eina_Bool anti_alias; + void *mask; + int mask_x, mask_y; }; struct _Evas_Thread_Command_Multi_Font @@ -1626,7 +1628,8 @@ _draw_thread_map_draw(void *data) (im, map->surface, map->clip.x, map->clip.y, map->clip.w, map->clip.h, map->mul_col, map->render_op, m->count - offset, &m->pts[offset], - map->smooth, map->anti_alias, map->level); + map->smooth, map->anti_alias, map->level, + map->mask, map->mask_x, map->mask_y); } evas_common_cpu_end_opt(); @@ -1689,6 +1692,10 @@ _map_draw_thread_cmd(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, RG cm->level = level; cm->offset = offset; + cm->mask = dc->clip.mask; + cm->mask_x = dc->clip.mask_x; + cm->mask_y = dc->clip.mask_y; + evas_thread_cmd_enqueue(_draw_thread_map_draw, cm); return EINA_TRUE;