This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch fix-release-build
in repository efl.
View the commit online.
commit 97a4cb4822ca1493660537f9f9af706a9c5f7ede
Author: Cedric BAIL <[email protected]>
AuthorDate: Sun Aug 2 19:38:15 2026 -0600
evas: add EVAS_NEON_DISABLE to bisect NEON kernels at runtime
EVAS_CPU_NO_NEON is all or nothing, so tracking a rendering artifact down
to one of the hand written NEON kernels meant rebuilding repeatedly with
individual call sites commented out.
Add a per subsystem mask instead:
EVAS_NEON_DISABLE=map,scale,blit,font,convert,ops,blur
or "all". Each named part falls back to its C path while the rest keep
using NEON, which turns "some pixels are wrong somewhere" into a couple
of runs.
evas_common_cpu_has_neon_for() replaces the bare
evas_common_cpu_has_feature(CPU_FEATURE_NEON) test at the dispatch sites.
It is checked once per span function lookup or per draw call, never per
pixel.
The box blur dispatch tested eina_cpu_features_get() directly rather than
going through evas' feature mask, so it honoured neither this variable
nor EVAS_CPU_NO_NEON - it was the one NEON user that could not be turned
off, which also meant a NEON-versus-C comparison silently kept using NEON
for blur on both sides. software_generic is compiled into libevas rather
than being a loadable module, so it can call the internal helper
directly; the eina_cpu_features_get() test looks like convention rather
than necessity.
The ector draw helpers in src/static_libs/draw still test
eina_cpu_features_get() directly. They live in a different library and
cannot reach evas' internals, so they are left alone.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
src/lib/evas/common/evas_blit_main.c | 4 +--
src/lib/evas/common/evas_convert_rgb_32.c | 4 +--
src/lib/evas/common/evas_cpu.c | 37 ++++++++++++++++++++++
src/lib/evas/common/evas_font_draw.c | 2 +-
src/lib/evas/common/evas_map_image.c | 8 ++---
src/lib/evas/common/evas_op_blend_main_.c | 10 +++---
src/lib/evas/common/evas_op_copy_main_.c | 10 +++---
src/lib/evas/common/evas_scale_smooth.c | 8 ++---
src/lib/evas/include/evas_common_private.h | 16 ++++++++++
.../software_generic/filters/evas_filter_blur.c | 8 ++---
10 files changed, 80 insertions(+), 27 deletions(-)
diff --git a/src/lib/evas/common/evas_blit_main.c b/src/lib/evas/common/evas_blit_main.c
index 2457716b47..e39bb1e0d6 100644
--- a/src/lib/evas/common/evas_blit_main.c
+++ b/src/lib/evas/common/evas_blit_main.c
@@ -598,7 +598,7 @@ evas_common_draw_func_copy_get(int pixels EINA_UNUSED, int reverse)
return evas_common_copy_pixels_rev_mmx;
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_BLIT))
return evas_common_copy_pixels_rev_neon;
#endif
return evas_common_copy_pixels_rev_c;
@@ -614,7 +614,7 @@ evas_common_draw_func_copy_get(int pixels EINA_UNUSED, int reverse)
return evas_common_copy_pixels_mmx;
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_BLIT))
return evas_common_copy_pixels_neon;
#endif
}
diff --git a/src/lib/evas/common/evas_convert_rgb_32.c b/src/lib/evas/common/evas_convert_rgb_32.c
index 68d3a95b22..46dc2133e4 100644
--- a/src/lib/evas/common/evas_convert_rgb_32.c
+++ b/src/lib/evas/common/evas_convert_rgb_32.c
@@ -50,7 +50,7 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int
#ifdef TILE_ROTATE
# ifdef BUILD_NEON
# define ROT90_QUAD_COPY_LOOP(pix_type) \
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON)) { \
+ if (evas_common_cpu_has_neon_for(NEON_PART_CONVERT)) { \
if ((w % 4) == 0) { \
int klght = 4 * src_stride; \
for (y = 0; y < h; y++) { \
@@ -84,7 +84,7 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int
} \
else
# define ROT270_QUAD_COPY_LOOP(pix_type) \
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON)) { \
+ if (evas_common_cpu_has_neon_for(NEON_PART_CONVERT)) { \
if ((w % 4) == 0) { \
int klght = 4 * src_stride; \
for (y = 0; y < h; y++) { \
diff --git a/src/lib/evas/common/evas_cpu.c b/src/lib/evas/common/evas_cpu.c
index b44cbc69f6..48e43be79c 100644
--- a/src/lib/evas/common/evas_cpu.c
+++ b/src/lib/evas/common/evas_cpu.c
@@ -1,6 +1,7 @@
#include "evas_common_private.h"
static int cpu_feature_mask = 0;
+static unsigned int neon_disabled_parts = 0;
static Eina_Bool
_cpu_check(Eina_Cpu_Features f)
@@ -9,6 +10,34 @@ _cpu_check(Eina_Cpu_Features f)
return (features & f) == f;
}
+/* EVAS_NEON_DISABLE=map,scale,blit,font,convert - see Neon_Part. Lets a
+ * rendering artifact be narrowed down to one NEON kernel without a rebuild. */
+static void
+_neon_disable_parse(void)
+{
+ static const struct { const char *name; unsigned int bit; } parts[] = {
+ { "map", NEON_PART_MAP },
+ { "scale", NEON_PART_SCALE },
+ { "blit", NEON_PART_BLIT },
+ { "font", NEON_PART_FONT },
+ { "convert", NEON_PART_CONVERT },
+ { "ops", NEON_PART_OPS },
+ { "blur", NEON_PART_BLUR },
+ { NULL, 0 }
+ };
+ const char *s = getenv("EVAS_NEON_DISABLE");
+ int i;
+
+ if (!s) return;
+ if (!strcmp(s, "all"))
+ {
+ for (i = 0; parts[i].name; i++) neon_disabled_parts |= parts[i].bit;
+ return;
+ }
+ for (i = 0; parts[i].name; i++)
+ if (strstr(s, parts[i].name)) neon_disabled_parts |= parts[i].bit;
+}
+
EVAS_API void
evas_common_cpu_init(void)
{
@@ -65,6 +94,7 @@ evas_common_cpu_init(void)
else
cpu_feature_mask |= _cpu_check(EINA_CPU_SVE) * CPU_FEATURE_SVE;
#endif
+ _neon_disable_parse();
}
int
@@ -73,6 +103,13 @@ evas_common_cpu_has_feature(unsigned int feature)
return (cpu_feature_mask & feature);
}
+int
+evas_common_cpu_has_neon_for(unsigned int part)
+{
+ if (!(cpu_feature_mask & CPU_FEATURE_NEON)) return 0;
+ return !(neon_disabled_parts & part);
+}
+
int
evas_common_cpu_have_cpuid(void)
{
diff --git a/src/lib/evas/common/evas_font_draw.c b/src/lib/evas/common/evas_font_draw.c
index 93c493df9a..60bda0f003 100644
--- a/src/lib/evas/common/evas_font_draw.c
+++ b/src/lib/evas/common/evas_font_draw.c
@@ -580,7 +580,7 @@ evas_common_font_glyph_draw(RGBA_Font_Glyph *fg,
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_FONT))
{
#define NEON 1
#include "evas_font_compress_draw.c"
diff --git a/src/lib/evas/common/evas_map_image.c b/src/lib/evas/common/evas_map_image.c
index 19eb165052..3ff5273edc 100644
--- a/src/lib/evas/common/evas_map_image.c
+++ b/src/lib/evas/common/evas_map_image.c
@@ -879,7 +879,7 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
else
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_MAP))
cb = evas_common_map_rgba_internal_neon;
else
#endif
@@ -916,7 +916,7 @@ evas_common_map_rgba_draw(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip
else
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_MAP))
_evas_common_map_rgba_internal_neon(src, dst,
clip_x, clip_y, clip_w, clip_h,
mul_col, render_op,
@@ -966,7 +966,7 @@ evas_common_map_rgba_do(const Eina_Rectangle *clip,
else
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_MAP))
evas_common_map_rgba_internal_neon_do(src, dst, dc,
&spans->spans[0], smooth,
dc->anti_alias, level);
@@ -995,7 +995,7 @@ evas_common_map_rgba_do(const Eina_Rectangle *clip,
else
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_MAP))
evas_common_map_rgba_internal_neon_do(src, dst, dc,
&spans->spans[i], smooth,
dc->anti_alias, level);
diff --git a/src/lib/evas/common/evas_op_blend_main_.c b/src/lib/evas/common/evas_op_blend_main_.c
index c7b629346d..c43daf787f 100644
--- a/src/lib/evas/common/evas_op_blend_main_.c
+++ b/src/lib/evas/common/evas_op_blend_main_.c
@@ -121,7 +121,7 @@ op_blend_init(void)
}
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_OPS))
{
init_blend_pixel_span_funcs_neon();
init_blend_pixel_color_span_funcs_neon();
@@ -176,7 +176,7 @@ blend_gfx_span_func_cpu(int s, int m, int c, int d)
}
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_OPS))
{
cpu = CPU_NEON;
func = op_blend_span_funcs[s][m][c][d][cpu];
@@ -297,7 +297,7 @@ blend_gfx_pt_func_cpu(int s, int m, int c, int d)
}
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_OPS))
{
cpu = CPU_NEON;
func = op_blend_pt_funcs[s][m][c][d][cpu];
@@ -459,7 +459,7 @@ blend_rel_gfx_span_func_cpu(int s, int m, int c, int d)
}
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_OPS))
{
cpu = CPU_NEON;
func = op_blend_rel_span_funcs[s][m][c][d][cpu];
@@ -575,7 +575,7 @@ blend_rel_gfx_pt_func_cpu(int s, int m, int c, int d)
}
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_OPS))
{
cpu = CPU_NEON;
func = op_blend_rel_pt_funcs[s][m][c][d][cpu];
diff --git a/src/lib/evas/common/evas_op_copy_main_.c b/src/lib/evas/common/evas_op_copy_main_.c
index 51428ed6d6..f1679824ba 100644
--- a/src/lib/evas/common/evas_op_copy_main_.c
+++ b/src/lib/evas/common/evas_op_copy_main_.c
@@ -117,7 +117,7 @@ op_copy_init(void)
}
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_OPS))
{
init_copy_pixel_span_funcs_neon();
init_copy_pixel_color_span_funcs_neon();
@@ -164,7 +164,7 @@ copy_gfx_span_func_cpu(int s, int m, int c, int d)
}
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_OPS))
{
cpu = CPU_NEON;
func = op_copy_span_funcs[s][m][c][d][cpu];
@@ -268,7 +268,7 @@ copy_gfx_pt_func_cpu(int s, int m, int c, int d)
}
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_OPS))
{
cpu = CPU_NEON;
func = op_copy_pt_funcs[s][m][c][d][cpu];
@@ -422,7 +422,7 @@ copy_rel_gfx_span_func_cpu(int s, int m, int c, int d)
}
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_OPS))
{
cpu = CPU_NEON;
func = op_copy_rel_span_funcs[s][m][c][d][cpu];
@@ -526,7 +526,7 @@ copy_rel_gfx_pt_func_cpu(int s, int m, int c, int d)
}
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_OPS))
{
cpu = CPU_NEON;
func = op_copy_rel_pt_funcs[s][m][c][d][cpu];
diff --git a/src/lib/evas/common/evas_scale_smooth.c b/src/lib/evas/common/evas_scale_smooth.c
index f5d8e93cd5..74b98b4a63 100644
--- a/src/lib/evas/common/evas_scale_smooth.c
+++ b/src/lib/evas/common/evas_scale_smooth.c
@@ -253,7 +253,7 @@ evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
else
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_SCALE))
cb = evas_common_scale_rgba_in_to_out_clip_smooth_neon;
else
#endif
@@ -285,7 +285,7 @@ evas_common_scale_rgba_smooth_draw(RGBA_Image *src, RGBA_Image *dst, int dst_cli
else
#endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_SCALE))
_evas_common_scale_rgba_in_to_out_clip_smooth_neon
(src, dst,
dst_clip_x, dst_clip_y, dst_clip_w, dst_clip_h,
@@ -337,7 +337,7 @@ evas_common_scale_rgba_in_to_out_clip_smooth_do(const Cutout_Rects *reuse,
else
# endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_SCALE))
evas_common_scale_rgba_in_to_out_clip_smooth_neon(src, dst, dc,
src_region_x, src_region_y,
src_region_w, src_region_h,
@@ -370,7 +370,7 @@ evas_common_scale_rgba_in_to_out_clip_smooth_do(const Cutout_Rects *reuse,
else
# endif
#ifdef BUILD_NEON
- if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+ if (evas_common_cpu_has_neon_for(NEON_PART_SCALE))
evas_common_scale_rgba_in_to_out_clip_smooth_neon(src, dst, dc,
src_region_x, src_region_y,
src_region_w, src_region_h,
diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h
index 7d7ae02ef9..0fb5d34888 100644
--- a/src/lib/evas/include/evas_common_private.h
+++ b/src/lib/evas/include/evas_common_private.h
@@ -469,6 +469,21 @@ typedef enum _CPU_Features
CPU_FEATURE_SVE = (1 << 8)
} CPU_Features;
+/* Subsystems that dispatch to a hand written NEON kernel outside of the
+ * op tables. EVAS_NEON_DISABLE=map,scale,blit,font,convert (or "all") forces
+ * any subset of them back onto the C path at runtime, which makes a rendering
+ * artifact bisectable to a single kernel without rebuilding. */
+typedef enum _Neon_Part
+{
+ NEON_PART_MAP = (1 << 0),
+ NEON_PART_SCALE = (1 << 1),
+ NEON_PART_BLIT = (1 << 2),
+ NEON_PART_FONT = (1 << 3),
+ NEON_PART_CONVERT = (1 << 4),
+ NEON_PART_OPS = (1 << 5), /* the blend/copy span and point op tables */
+ NEON_PART_BLUR = (1 << 6)
+} Neon_Part;
+
/*****************************************************************************/
struct _Image_Entry_Flags
@@ -1032,6 +1047,7 @@ EVAS_API void evas_common_cpu_init (void);
int evas_common_cpu_have_cpuid (void);
int evas_common_cpu_has_feature (unsigned int feature);
+int evas_common_cpu_has_neon_for (unsigned int part);
EVAS_API void evas_common_cpu_can_do (int *mmx, int *sse, int *sse2);
EVAS_API void evas_common_cpu_end_opt (void);
diff --git a/src/modules/evas/engines/software_generic/filters/evas_filter_blur.c b/src/modules/evas/engines/software_generic/filters/evas_filter_blur.c
index c5617d0096..b410437291 100644
--- a/src/modules/evas/engines/software_generic/filters/evas_filter_blur.c
+++ b/src/modules/evas/engines/software_generic/filters/evas_filter_blur.c
@@ -67,7 +67,7 @@ _box_blur_horiz_rgba(const uint32_t *src, int src_stride,
}
#endif
#ifdef BUILD_NEON
- if (eina_cpu_features_get() & EINA_CPU_NEON)
+ if (evas_common_cpu_has_neon_for(NEON_PART_BLUR))
{
_box_blur_rgba_horiz_step_neon(src, src_stride, dst, dst_stride, radii, region);
goto end;
@@ -103,7 +103,7 @@ _box_blur_vert_rgba(const uint32_t *src, int src_stride,
}
#endif
#ifdef BUILD_NEON
- if (eina_cpu_features_get() & EINA_CPU_NEON)
+ if (evas_common_cpu_has_neon_for(NEON_PART_BLUR))
{
_box_blur_rgba_vert_step_neon(src, src_stride, dst, dst_stride, radii, region);
goto end;
@@ -150,7 +150,7 @@ _box_blur_horiz_alpha(const uint8_t *src, int src_stride,
}
#endif
#ifdef BUILD_NEON
- if (eina_cpu_features_get() & EINA_CPU_NEON)
+ if (evas_common_cpu_has_neon_for(NEON_PART_BLUR))
{
_box_blur_alpha_horiz_step_neon(src, src_stride, dst, dst_stride, radii, region);
goto end;
@@ -186,7 +186,7 @@ _box_blur_vert_alpha(const uint8_t *src, int src_stride,
}
#endif
#ifdef BUILD_NEON
- if (eina_cpu_features_get() & EINA_CPU_NEON)
+ if (evas_common_cpu_has_neon_for(NEON_PART_BLUR))
{
_box_blur_alpha_vert_step_neon(src, src_stride, dst, dst_stride, radii, region);
goto end;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.