From b6df13b02448621e5264152e2db1de370c7a6529 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Tue, 17 Jan 2017 20:34:16 +0900 Subject: [PATCH] evas filters: Move curve to software generic (3/8) This moves the RGBA premul/unpremul functions to static_libs/draw. --- src/Makefile_Evas.am | 2 +- src/lib/evas/common/evas_convert_color.c | 84 +------------------- src/lib/evas/filters/evas_filter.c | 3 - src/lib/evas/filters/evas_filter_private.h | 1 - .../evas/engines/software_generic/evas_engine.c | 1 + .../engines/software_generic/evas_engine_filter.h | 2 + .../software_generic/filters/evas_filter_blend.c | 2 - .../software_generic}/filters/evas_filter_curve.c | 10 +-- .../software_generic/filters/evas_filter_mask.c | 1 - src/static_libs/draw/draw.h | 3 + src/static_libs/draw/draw_convert.c | 90 ++++++++++++++++++++++ src/static_libs/draw/draw_main_neon.c | 1 + 12 files changed, 105 insertions(+), 95 deletions(-) rename src/{lib/evas => modules/evas/engines/software_generic}/filters/evas_filter_curve.c (95%) diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index 00b8791..a2237d5 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -594,7 +594,6 @@ lib/evas/canvas/evas_filter_mixin.c \ lib/evas/filters/evas_filter.c \ lib/evas/filters/evas_filter_blur.c \ lib/evas/filters/evas_filter_bump.c \ -lib/evas/filters/evas_filter_curve.c \ lib/evas/filters/evas_filter_displace.c \ lib/evas/filters/evas_filter_fill.c \ lib/evas/filters/evas_filter_parser.c \ @@ -617,6 +616,7 @@ lib/evas/filters/blur/blur_box_rgba_neon.c GFX_FILTER_SW_FILES = \ modules/evas/engines/software_generic/evas_engine_filter.h \ modules/evas/engines/software_generic/filters/evas_filter_blend.c \ +modules/evas/engines/software_generic/filters/evas_filter_curve.c \ modules/evas/engines/software_generic/filters/evas_filter_mask.c \ $(NULL) diff --git a/src/lib/evas/common/evas_convert_color.c b/src/lib/evas/common/evas_convert_color.c index ee26638..548c8c5 100644 --- a/src/lib/evas/common/evas_convert_color.c +++ b/src/lib/evas/common/evas_convert_color.c @@ -1,9 +1,6 @@ #include "evas_common_private.h" #include "evas_convert_color.h" - -#ifdef BUILD_NEON -#include -#endif +#include "draw.h" EAPI DATA32 evas_common_convert_ag_premul(DATA16 *data, unsigned int len) @@ -57,88 +54,13 @@ evas_common_convert_ag_unpremul(DATA16 *data, unsigned int len) EAPI DATA32 evas_common_convert_argb_premul(DATA32 *data, unsigned int len) { - DATA32 *de = data + len; - DATA32 nas = 0; - -#ifdef BUILD_NEON - if (evas_common_cpu_has_feature(CPU_FEATURE_NEON)) - { - uint8x8_t mask_0x00 = vdup_n_u8(0); - uint8x8_t mask_0x01 = vdup_n_u8(1); - uint8x8_t mask_0xff = vdup_n_u8(255); - uint8x8_t cmp; - uint64x1_t tmp; - - while (data <= de - 8) - { - uint8x8x4_t rgba = vld4_u8((uint8_t *)data); - - cmp = vand_u8(vorr_u8(vceq_u8(rgba.val[3], mask_0xff), - vceq_u8(rgba.val[3], mask_0x00)), - mask_0x01); - tmp = vpaddl_u32(vpaddl_u16(vpaddl_u8(cmp))); - nas += vget_lane_u32(vreinterpret_u32_u64(tmp), 0); - - uint16x8x4_t lrgba; - lrgba.val[0] = vmovl_u8(rgba.val[0]); - lrgba.val[1] = vmovl_u8(rgba.val[1]); - lrgba.val[2] = vmovl_u8(rgba.val[2]); - lrgba.val[3] = vaddl_u8(rgba.val[3], mask_0x01); - - rgba.val[0] = vshrn_n_u16(vmlaq_u16(lrgba.val[0], lrgba.val[0], - lrgba.val[3]), 8); - rgba.val[1] = vshrn_n_u16(vmlaq_u16(lrgba.val[1], lrgba.val[1], - lrgba.val[3]), 8); - rgba.val[2] = vshrn_n_u16(vmlaq_u16(lrgba.val[2], lrgba.val[2], - lrgba.val[3]), 8); - vst4_u8((uint8_t *)data, rgba); - data += 8; - } - } -#endif - - while (data < de) - { - DATA32 a = 1 + (*data >> 24); - - *data = (*data & 0xff000000) + - (((((*data) >> 8) & 0xff) * a) & 0xff00) + - (((((*data) & 0x00ff00ff) * a) >> 8) & 0x00ff00ff); - data++; - - if ((a == 1) || (a == 256)) - nas++; - } - - return nas; + return (DATA32) efl_draw_argb_premul(data, len); } EAPI void evas_common_convert_argb_unpremul(DATA32 *data, unsigned int len) { - DATA32 *de = data + len; - DATA32 p_val = 0x00000000, p_res = 0x00000000; - - while (data < de) - { - DATA32 a = (*data >> 24); - - if (p_val == *data) *data = p_res; - else - { - p_val = *data; - if ((a > 0) && (a < 255)) - *data = ARGB_JOIN(a, - (R_VAL(data) * 255) / a, - (G_VAL(data) * 255) / a, - (B_VAL(data) * 255) / a); - else if (a == 0) - *data = 0x00000000; - p_res = *data; - } - data++; - } - + return efl_draw_argb_unpremul(data, len); } EAPI void diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index 04188d5..3f2f0d5 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c @@ -1541,9 +1541,6 @@ _filter_command_run(Evas_Filter_Command *cmd) case EVAS_FILTER_MODE_BLUR: func = evas_filter_blur_cpu_func_get(cmd); break; - case EVAS_FILTER_MODE_CURVE: - func = evas_filter_curve_cpu_func_get(cmd); - break; case EVAS_FILTER_MODE_DISPLACE: func = evas_filter_displace_cpu_func_get(cmd); break; diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h index d81bc9a..f95dd61 100644 --- a/src/lib/evas/filters/evas_filter_private.h +++ b/src/lib/evas/filters/evas_filter_private.h @@ -263,7 +263,6 @@ void evas_filter_context_source_set(Evas_Filter_Context *ctx /* FIXME: CPU filters entry points. Move these to the Evas Engine itself. */ Evas_Filter_Apply_Func evas_filter_blur_cpu_func_get(Evas_Filter_Command *cmd); Evas_Filter_Apply_Func evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd); -Evas_Filter_Apply_Func evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd); Evas_Filter_Apply_Func evas_filter_displace_cpu_func_get(Evas_Filter_Command *cmd); Evas_Filter_Apply_Func evas_filter_fill_cpu_func_get(Evas_Filter_Command *cmd); Evas_Filter_Apply_Func evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd); diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 281340a..7dd2c2e 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -4628,6 +4628,7 @@ _gfx_filter_func_get(Evas_Filter_Command *cmd) switch (cmd->mode) { case EVAS_FILTER_MODE_BLEND: func = eng_filter_blend_func_get(cmd); break; + case EVAS_FILTER_MODE_CURVE: func = eng_filter_curve_func_get(cmd); break; case EVAS_FILTER_MODE_MASK: func = eng_filter_mask_func_get(cmd); break; default: return NULL; } diff --git a/src/modules/evas/engines/software_generic/evas_engine_filter.h b/src/modules/evas/engines/software_generic/evas_engine_filter.h index 3971a6b..c6c657b 100644 --- a/src/modules/evas/engines/software_generic/evas_engine_filter.h +++ b/src/modules/evas/engines/software_generic/evas_engine_filter.h @@ -2,8 +2,10 @@ #define EVAS_ENGINE_FILTER_H #include "evas_filter_private.h" +#include "draw.h" Evas_Filter_Apply_Func eng_filter_blend_func_get(Evas_Filter_Command *cmd); +Evas_Filter_Apply_Func eng_filter_curve_func_get(Evas_Filter_Command *cmd); Evas_Filter_Apply_Func eng_filter_mask_func_get(Evas_Filter_Command *cmd); #endif // EVAS_ENGINE_FILTER_H diff --git a/src/modules/evas/engines/software_generic/filters/evas_filter_blend.c b/src/modules/evas/engines/software_generic/filters/evas_filter_blend.c index be43af9..e6ab9bf 100644 --- a/src/modules/evas/engines/software_generic/filters/evas_filter_blend.c +++ b/src/modules/evas/engines/software_generic/filters/evas_filter_blend.c @@ -1,6 +1,4 @@ #include "../evas_engine_filter.h" -#include "ector_buffer.h" -#include "draw.h" // FIXME: This should all be based on ector renderer diff --git a/src/lib/evas/filters/evas_filter_curve.c b/src/modules/evas/engines/software_generic/filters/evas_filter_curve.c similarity index 95% rename from src/lib/evas/filters/evas_filter_curve.c rename to src/modules/evas/engines/software_generic/filters/evas_filter_curve.c index 2ab9f70..6202b80 100644 --- a/src/lib/evas/filters/evas_filter_curve.c +++ b/src/modules/evas/engines/software_generic/filters/evas_filter_curve.c @@ -1,6 +1,4 @@ -#include "evas_filter.h" -#include "evas_filter_private.h" - +#include "../evas_engine_filter.h" static Eina_Bool _filter_curve_cpu_rgba(Evas_Filter_Command *cmd) @@ -43,7 +41,7 @@ _filter_curve_cpu_rgba(Evas_Filter_Command *cmd) if (src != dst) memcpy(dst, src, dst_len); - evas_data_argb_unpremul(dst, len); + efl_draw_argb_unpremul(dst, len); // One channel (R, G or B) if (offset >= 0) @@ -81,7 +79,7 @@ _filter_curve_cpu_rgba(Evas_Filter_Command *cmd) C_VAL(d) = curve[C_VAL(src)]; premul: - evas_data_argb_premul(dst, len); + efl_draw_argb_premul(dst, len); ret = EINA_TRUE; end: @@ -118,7 +116,7 @@ end: } Evas_Filter_Apply_Func -evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd) +eng_filter_curve_func_get(Evas_Filter_Command *cmd) { EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL); diff --git a/src/modules/evas/engines/software_generic/filters/evas_filter_mask.c b/src/modules/evas/engines/software_generic/filters/evas_filter_mask.c index 18acf8c..46fdc2c 100644 --- a/src/modules/evas/engines/software_generic/filters/evas_filter_mask.c +++ b/src/modules/evas/engines/software_generic/filters/evas_filter_mask.c @@ -1,7 +1,6 @@ /* Implementation of some masking functions for the software engine */ #include "../evas_engine_filter.h" -#include "draw.h" // Naming convention: _func_engine_incolor_maskcolor_outcolor() static Eina_Bool _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd); diff --git a/src/static_libs/draw/draw.h b/src/static_libs/draw/draw.h index b3393d2..f25f66d 100644 --- a/src/static_libs/draw/draw.h +++ b/src/static_libs/draw/draw.h @@ -26,6 +26,9 @@ Draw_Func_ARGB_Mix3 efl_draw_func_argb_mix3_get (Efl_Gfx_Render_Op op, uint3 Draw_Func_Alpha efl_draw_alpha_func_get (Efl_Gfx_Render_Op op, Eina_Bool has_mask); Cspace_Convert_Func efl_draw_convert_func_get (Efl_Gfx_Colorspace origcs, Efl_Gfx_Colorspace dstcs, Eina_Bool *region_can); +int efl_draw_argb_premul(uint32_t *data, unsigned int len); +void efl_draw_argb_unpremul(uint32_t *data, unsigned int len); + /* common sw draw helpers */ diff --git a/src/static_libs/draw/draw_convert.c b/src/static_libs/draw/draw_convert.c index 4e29d9e..1c65f4d 100644 --- a/src/static_libs/draw/draw_convert.c +++ b/src/static_libs/draw/draw_convert.c @@ -2,6 +2,10 @@ #include "draw_private.h" #include "../rg_etc/rg_etc1.h" +#ifdef BUILD_NEON +#include +#endif + #if DIV_USING_BITSHIFT # define DEFINE_DIVIDER(div) const int pow2 = _pow2_geq((div) << 10); const int numerator = (1 << pow2) / (div); # define DIVIDE(val) (((val) * numerator) >> pow2) @@ -526,3 +530,89 @@ efl_draw_convert_func_get(Efl_Gfx_Colorspace srccs, Efl_Gfx_Colorspace dstcs, if (region_can) *region_can = EINA_FALSE; return NULL; } + +int +efl_draw_argb_premul(uint32_t *data, unsigned int len) +{ + uint32_t *de = data + len; + int nas = 0; + +#ifdef BUILD_NEON + if (eina_cpu_features_get() & EINA_CPU_NEON) + { + uint8x8_t mask_0x00 = vdup_n_u8(0); + uint8x8_t mask_0x01 = vdup_n_u8(1); + uint8x8_t mask_0xff = vdup_n_u8(255); + uint8x8_t cmp; + uint64x1_t tmp; + + while (data <= de - 8) + { + uint8x8x4_t rgba = vld4_u8((uint8_t *) data); + + cmp = vand_u8(vorr_u8(vceq_u8(rgba.val[3], mask_0xff), + vceq_u8(rgba.val[3], mask_0x00)), + mask_0x01); + tmp = vpaddl_u32(vpaddl_u16(vpaddl_u8(cmp))); + nas += vget_lane_u32(vreinterpret_u32_u64(tmp), 0); + + uint16x8x4_t lrgba; + lrgba.val[0] = vmovl_u8(rgba.val[0]); + lrgba.val[1] = vmovl_u8(rgba.val[1]); + lrgba.val[2] = vmovl_u8(rgba.val[2]); + lrgba.val[3] = vaddl_u8(rgba.val[3], mask_0x01); + + rgba.val[0] = vshrn_n_u16(vmlaq_u16(lrgba.val[0], lrgba.val[0], + lrgba.val[3]), 8); + rgba.val[1] = vshrn_n_u16(vmlaq_u16(lrgba.val[1], lrgba.val[1], + lrgba.val[3]), 8); + rgba.val[2] = vshrn_n_u16(vmlaq_u16(lrgba.val[2], lrgba.val[2], + lrgba.val[3]), 8); + vst4_u8((uint8_t *) data, rgba); + data += 8; + } + } +#endif + + while (data < de) + { + uint32_t a = 1 + (*data >> 24); + + *data = (*data & 0xff000000) + + (((((*data) >> 8) & 0xff) * a) & 0xff00) + + (((((*data) & 0x00ff00ff) * a) >> 8) & 0x00ff00ff); + data++; + + if ((a == 1) || (a == 256)) + nas++; + } + + return nas; +} + +void +efl_draw_argb_unpremul(uint32_t *data, unsigned int len) +{ + uint32_t *de = data + len; + uint32_t p_val = 0x00000000, p_res = 0x00000000; + + while (data < de) + { + uint32_t a = (*data >> 24); + + if (p_val == *data) *data = p_res; + else + { + p_val = *data; + if ((a > 0) && (a < 255)) + *data = DRAW_ARGB_JOIN(a, + (R_VAL(data) * 255) / a, + (G_VAL(data) * 255) / a, + (B_VAL(data) * 255) / a); + else if (a == 0) + *data = 0x00000000; + p_res = *data; + } + data++; + } +} diff --git a/src/static_libs/draw/draw_main_neon.c b/src/static_libs/draw/draw_main_neon.c index 24b3d01..1c3a911 100644 --- a/src/static_libs/draw/draw_main_neon.c +++ b/src/static_libs/draw/draw_main_neon.c @@ -217,6 +217,7 @@ void efl_draw_neon_init(void) { #ifdef BUILD_NEON + if (getenv("EVAS_CPU_NO_NEON")) return; // compat with evas env vars if (eina_cpu_features_get() & EINA_CPU_NEON) { // update the comp_function table for solid color -- 2.7.4