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.

Reply via email to