This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch span-gl-clean
in repository efl.

View the commit online.

commit 9421b4009e3bb4ab2d279deb42520152da2370b2
Author: Cedric BAIL <[email protected]>
AuthorDate: Fri Aug 14 10:38:10 2026 -0600

    perf(evas_ector_gl): grow the raster pixel buffer on a high-water mark
    
    A profile of expedite test 125 "VG Scaled" put 14.4% of the frame in
    eng_ector_begin, all of it libc memory work, for a function that should
    be doing almost nothing.
    
    The cause is in how it sizes the shared raster pixel buffer:
    
        size_t needed = (size_t)bbd->stride * h;
        size_t have   = (size_t)bbd->stride * bbd->generic->h;
    
    generic->h is the height currently in use, not the height the buffer
    was allocated at. Every vector object on the canvas shares one ector
    surface, so that field carries whatever the previous object set, and
    their sizes change independently. A shrink followed by a growth
    therefore reallocates and zeroes a buffer that was already large
    enough, and with 128 objects whose sizes move independently every
    frame that happened for roughly half of them - hundreds of kilobytes
    of realloc and memset many times a frame, which is also where the
    mremap time in the profile came from.
    
    Track the real allocation on the ector surface data and grow only when
    the request exceeds it.
    
    Test 125, best of three 400-frame runs: 86.9 -> 93.5 FPS, +7.5%. Test
    121 gains 2.1%. Test 122 is unaffected, as expected - it has a single
    object of constant size, so the branch never fires (its apparent -6%
    in a first measurement was that test's own variance; interleaved over
    five runs it is 178.0 against 177.4).
    
    Note for later: bbd->stride is set once by the initial pixels_set and
    never revised, so a later object wider than the first leaves the buffer
    too narrow for its rows. Nothing writes pixels through it on the span
    path, where the rasterizer emits spans rather than pixels, so this is
    latent rather than live, and it is left alone here.
    
    All ten VG expedite tests render byte-identical frames; ector-suite and
    evas-suite pass.
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
 src/lib/ector/software/ector_software_private.h   |  5 +++++
 src/modules/evas/engines/gl_generic/evas_engine.c | 20 +++++++++++++++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/src/lib/ector/software/ector_software_private.h b/src/lib/ector/software/ector_software_private.h
index 283394549e..9700f6c470 100644
--- a/src/lib/ector/software/ector_software_private.h
+++ b/src/lib/ector/software/ector_software_private.h
@@ -160,6 +160,11 @@ struct _Ector_Software_Surface_Data
    int    span_collectors_stroke_count;
    int    span_collectors_stroke_alloc;
 
+   /* Bytes currently allocated for the shared raster pixel buffer.  The
+    * buffer's own descriptor only records the height in use, which is not
+    * the height it was allocated at, so growth has to be tracked here. */
+   size_t span_pixels_alloc;
+
    /* GL composite mask for the current eng_ector_begin/end window.
     * Set by _efl_canvas_vg_container_render_pre() when a container has a
     * composite target whose mask was rendered into an FBO via _prepare_comp().
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c
index fb9890684a..f86cbf40f4 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -2828,17 +2828,34 @@ eng_ector_begin(void *engine, void *surface,
          * the pixel buffer with realloc if needed (high-water mark)
          * to avoid the per-frame free+calloc cycle in pixels_set. */
         {
+           Ector_Software_Surface_Data *spd =
+              efl_data_scope_get(ector, ECTOR_SOFTWARE_SURFACE_CLASS);
            Ector_Software_Buffer_Base_Data *bbd =
               efl_data_scope_get(ector, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
            if (!bbd || !bbd->pixels.u8)
              {
                 ector_buffer_pixels_set(ector, NULL, w, h, 0,
                                         EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
+                if (spd)
+                  {
+                     Ector_Software_Buffer_Base_Data *nbd =
+                        efl_data_scope_get(ector, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
+                     spd->span_pixels_alloc = nbd ? (size_t)nbd->stride * h : 0;
+                  }
              }
            else if (bbd->generic && (bbd->generic->w != (unsigned)w || bbd->generic->h != (unsigned)h))
              {
                 size_t needed = (size_t)bbd->stride * h;
-                size_t have = (size_t)bbd->stride * bbd->generic->h;
+                size_t have   = spd ? spd->span_pixels_alloc
+                                    : (size_t)bbd->stride * bbd->generic->h;
+
+                /* Grow on a high-water mark.  generic->h is the height in
+                 * use, not the height allocated, so deriving the current
+                 * allocation from it makes every shrink-then-grow realloc a
+                 * buffer that was already large enough.  With one surface
+                 * shared by every vector object on the canvas and their
+                 * sizes changing independently, that was reallocating and
+                 * zeroing hundreds of kilobytes many times a frame. */
                 if (needed > have)
                   {
                      uint8_t *p = realloc(bbd->pixels.u8, needed);
@@ -2846,6 +2863,7 @@ eng_ector_begin(void *engine, void *surface,
                        {
                           bbd->pixels.u8 = p;
                           memset(p + have, 0, needed - have);
+                          if (spd) spd->span_pixels_alloc = needed;
                        }
                   }
                 bbd->generic->w = w;

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to