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 f87512bc84aa7445d75f82a17aff492918e990e9
Author: [email protected] <[email protected]>
AuthorDate: Mon Apr 6 09:59:18 2026 -0600

    feat(ector_gl): composite mask support and VG canvas integration
    
    Add composite/mask rendering support to the GL span-buffer pipeline
    and integrate with the Evas VG canvas layer.
    
    Composite mask rendering:
    - Mask container shapes render through the span-buffer pipeline into
      a dedicated non-atlas FBO (prevents GL texture feedback loop)
    - ector_mask_surface_create engine function forces standalone GL texture
      via evas_gl_common_image_surface_noscale_noatlas_new
    - Mask FBO texture sampled by source shapes' fragment shader on unit 4
    - All 6 Efl_Gfx_Vg_Composite_Method values GPU-accelerated:
      MATTE_ALPHA, MATTE_ALPHA_INVERSE (branchless mix),
      MASK_INTERSECT, MASK_SUBSTRACT (same math, different init),
      MASK_ADD (additive alpha), MASK_DIFFERENCE (abs difference)
    
    VG container integration (_prepare_comp):
    - GL path creates/reuses mask FBO, renders mask shapes via nested
      eng_ector_begin/end during render_pre (before main VG begin)
    - gl_comp_surface propagated via ector_software_surface_gl_comp_set
      accessor (bridges canvas code and ector private header)
    - Per-frame propagation in _evas_vg_render (draw phase, always runs)
      rather than render_pre (only runs on changes)
    
    VG object rendering fixes:
    - Composite target containers (comp.src) skipped in _evas_vg_render
      to prevent unmasked duplicate draws
    - Gradient fill objects skipped in composite containers (they are
      shape properties, not standalone renderable nodes)
    
    Software engine compatibility:
    - NULL slot for ector_mask_surface_create in software_generic
    - GL path guarded by ENFN->gl_surface_read_pixels (NULL on SW engine)
    - ECTOR_BACKEND=software fallback preserved
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---
 src/lib/ector/software/ector_software_surface.c    |  34 +++++
 src/lib/evas/canvas/efl_canvas_vg_container.c      | 161 ++++++++++++++++++++-
 src/lib/evas/canvas/efl_canvas_vg_object.c         |  45 +++++-
 src/lib/evas/canvas/evas_vg_private.h              |   9 ++
 src/lib/evas/include/evas_private.h                |   1 +
 src/modules/evas/engines/gl_common/evas_gl_image.c |  23 ++-
 .../evas/engines/gl_common/evas_gl_texture.c       |  30 ++++
 src/modules/evas/engines/gl_generic/meson.build    |  10 +-
 .../evas/engines/software_generic/evas_engine.c    |   1 +
 9 files changed, 308 insertions(+), 6 deletions(-)

diff --git a/src/lib/ector/software/ector_software_surface.c b/src/lib/ector/software/ector_software_surface.c
index ba64445ba3..152758f745 100644
--- a/src/lib/ector/software/ector_software_surface.c
+++ b/src/lib/ector/software/ector_software_surface.c
@@ -284,5 +284,39 @@ _ector_software_surface_ector_surface_draw_image(Eo *obj EINA_UNUSED,
      }
    return EINA_TRUE;
 }
+
+/* GL composite mask accessors.
+ *
+ * Called by efl_canvas_vg_container.c during render_pre to store the mask FBO
+ * surface and composite method so that eng_ector_end() (in the GL engine) can
+ * look them up via _gl_comp_get and populate Span_Pipe_Params.mask_tex.
+ *
+ * These are the only way for canvas code (which cannot include
+ * ector_software_private.h) to reach Ector_Software_Surface_Data fields. */
+ECTOR_API void
+ector_software_surface_gl_comp_set(Ector_Surface *obj,
+                                   void *gl_surface, int comp_method)
+{
+   Ector_Software_Surface_Data *pd = efl_data_scope_get(obj, ECTOR_SOFTWARE_SURFACE_CLASS);
+   if (!pd) return;
+   pd->gl_comp_surface = gl_surface;
+   pd->gl_comp_method  = comp_method;
+}
+
+ECTOR_API void
+ector_software_surface_gl_comp_get(Ector_Surface *obj,
+                                   void **gl_surface_out, int *comp_method_out)
+{
+   Ector_Software_Surface_Data *pd = efl_data_scope_get(obj, ECTOR_SOFTWARE_SURFACE_CLASS);
+   if (!pd)
+     {
+        if (gl_surface_out)  *gl_surface_out  = NULL;
+        if (comp_method_out) *comp_method_out = 0;
+        return;
+     }
+   if (gl_surface_out)  *gl_surface_out  = pd->gl_comp_surface;
+   if (comp_method_out) *comp_method_out = pd->gl_comp_method;
+}
+
 #include "ector_software_surface.eo.c"
 #include "ector_renderer_software.eo.c"
diff --git a/src/lib/evas/canvas/efl_canvas_vg_container.c b/src/lib/evas/canvas/efl_canvas_vg_container.c
index 76a67f4eee..d1450ac901 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_container.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_container.c
@@ -75,6 +75,99 @@ _prepare_comp(Evas_Object_Protected_Data *obj,     //vector object
        pd->comp.method == EFL_GFX_VG_COMPOSITE_METHOD_MASK_INTERSECT)
      init_buffer = 0xFFFFFFFF;
 
+   /* GL span-buffer path: render the mask shapes into a dedicated FBO surface
+    * through the same span-buffer pipeline.  This runs during render_pre,
+    * which is BEFORE the main VG object's eng_ector_begin(), so the shared
+    * ector surface is free and the nested begin/end does not conflict with
+    * any outer begin/end for the main VG render.
+    *
+    * The mask FBO surface is kept alive on pd->comp.gl_surface across frames
+    * and reused when the size matches.  eng_ector_end() of the main VG object
+    * reads espd->gl_comp_surface (set by render_pre after we return) to fill
+    * the mask texture params on each shape's Span_Pipe_Params. */
+   if (ENFN->gl_surface_read_pixels)  /* GL engine only — SW engine sets this to NULL */
+     {
+        int err = 0;
+        void *mask_surface = pd->comp.gl_surface;
+
+        /* Create or resize mask FBO. */
+        if (mask_surface)
+          {
+             int mw = 0, mh = 0;
+             ENFN->image_size_get(ENC, mask_surface, &mw, &mh);
+             if (mw != size.w || mh != size.h)
+               {
+                  ENFN->ector_surface_destroy(ENC, mask_surface);
+                  mask_surface = NULL;
+               }
+          }
+        if (!mask_surface)
+          {
+             /* Use ector_mask_surface_create when available so the mask FBO
+              * gets a dedicated GL texture that cannot be atlas-shared with the
+              * main VG FBO, preventing a read/write feedback loop in the shader. */
+             if (ENFN->ector_mask_surface_create)
+               mask_surface = ENFN->ector_mask_surface_create(ENC, size.w, size.h, &err);
+             else
+               mask_surface = ENFN->ector_surface_create(ENC, size.w, size.h, &err);
+             if (err || !mask_surface) goto gl_mask_fallback;
+          }
+        pd->comp.gl_surface = mask_surface;
+        pd->comp.size.w = size.w;
+        pd->comp.size.h = size.h;
+        pd->comp.vg_pd = obj;
+
+        /* Prepare mask shapes via render_pre.
+         * The nested composite chain (MASK_ADD) is handled first, exactly as
+         * in the CPU path below, but using NULL as the comp buffer since the
+         * GL path does not create a CPU comp buffer here. */
+        if (pd->comp.method >= EFL_GFX_VG_COMPOSITE_METHOD_MASK_ADD)
+          {
+             Efl_Canvas_Vg_Container_Data *target_pd = pd;
+             for (Efl_VG *ct = pd->comp_target; ct; ct = target_pd->comp_target)
+               {
+                  Efl_Canvas_Vg_Container_Data *src_pd = NULL;
+                  target_pd = efl_data_scope_get(ct, MY_CLASS);
+                  src_pd = efl_data_scope_get(eina_list_nth(target_pd->comp.src, 0), MY_CLASS);
+                  _evas_vg_render_pre(obj, ct,
+                                      engine, output, context, surface,
+                                      ctransform, c_opacity, NULL, src_pd->comp.method);
+               }
+          }
+
+        _evas_vg_render_pre(obj, comp_target,
+                            engine, output, context, surface,
+                            ptransform, p_opacity, NULL, comp_method);
+
+        /* Render mask shapes into the FBO via span-buffer pipeline.
+         * eng_ector_begin installs span collectors on the shared ector surface;
+         * _draw_comp drives ector_renderer_draw to populate them;
+         * eng_ector_end uploads and draws them to mask_surface's FBO. */
+        {
+           RGBA_Draw_Context *dc = evas_common_draw_context_new();
+           evas_common_draw_context_set_render_op(dc, _EVAS_RENDER_COPY);
+           evas_common_draw_context_set_color(dc, 255, 255, 255, 255);
+
+           if (ENFN->ector_begin(ENC, mask_surface, dc, surface, 0, 0, EINA_FALSE))
+             {
+                _draw_comp(obj, comp_target, surface, engine, output, context);
+                ENFN->image_dirty_region(ENC, mask_surface, 0, 0, size.w, size.h);
+                ENFN->ector_end(ENC, mask_surface, dc, surface, EINA_FALSE);
+             }
+
+           evas_common_draw_context_free(dc);
+        }
+
+        /* Signal to the caller that there is no CPU comp buffer.
+         * The mask FBO reference lives on pd->comp.gl_surface; render_pre
+         * propagates it to the ector surface data for eng_ector_end to pick up. */
+        return NULL;
+     }
+
+gl_mask_fallback:
+   /* Fallback: original CPU pixel buffer path (software backend or GL surface
+    * creation failure). */
+
    //2. Reusable ector buffer?
    if (pd->comp.buffer &&
        ((pd->comp.size.w != size.w) ||
@@ -171,6 +264,23 @@ _efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd,
    Efl_VG *child;
    Efl_Gfx_Change_Flag flag;
 
+   /* Even when the container's flags are NONE (nothing changed), we must
+    * still propagate the GL composite mask reference to the ector surface
+    * every frame — eng_ector_end clears it after use. */
+   if (pd->comp_target &&
+       (pd->comp.method == EFL_GFX_VG_COMPOSITE_METHOD_MATTE_ALPHA ||
+        pd->comp.method == EFL_GFX_VG_COMPOSITE_METHOD_MATTE_ALPHA_INVERSE ||
+        pd->comp.method == EFL_GFX_VG_COMPOSITE_METHOD_MASK_INTERSECT ||
+        pd->comp.method == EFL_GFX_VG_COMPOSITE_METHOD_MASK_SUBSTRACT))
+     {
+        Efl_Canvas_Vg_Container_Data *cpd =
+           efl_data_scope_get(pd->comp_target, MY_CLASS);
+        if (cpd && cpd->comp.gl_surface)
+          ector_software_surface_gl_comp_set(surface,
+                                             cpd->comp.gl_surface,
+                                             (int)pd->comp.method);
+     }
+
    if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return;
 
    flag = nd->flags;
@@ -184,12 +294,27 @@ _efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd,
    // This condition is valid because the masking use same type as matte.
    if (pd->comp_target &&
        (pd->comp.method == EFL_GFX_VG_COMPOSITE_METHOD_MATTE_ALPHA ||
-        pd->comp.method == EFL_GFX_VG_COMPOSITE_METHOD_MATTE_ALPHA_INVERSE))
+        pd->comp.method == EFL_GFX_VG_COMPOSITE_METHOD_MATTE_ALPHA_INVERSE ||
+        pd->comp.method == EFL_GFX_VG_COMPOSITE_METHOD_MASK_INTERSECT ||
+        pd->comp.method == EFL_GFX_VG_COMPOSITE_METHOD_MASK_SUBSTRACT))
      {
         comp_method = pd->comp.method;
         comp = _prepare_comp(vg_pd, pd->comp_target,
                              engine, output, context, surface,
                              ptransform, ctransform, p_opacity, c_a, comp, comp_method);
+
+        /* GL span-buffer path: _prepare_comp returns NULL but stores the
+         * mask FBO on pd->comp.gl_surface.  Propagate it to the shared ector
+         * surface so eng_ector_end() can find it when building pipe params. */
+        if (!comp && pd->comp_target)
+          {
+             Efl_Canvas_Vg_Container_Data *cpd =
+                efl_data_scope_get(pd->comp_target, MY_CLASS);
+             if (cpd && cpd->comp.gl_surface)
+               ector_software_surface_gl_comp_set(surface,
+                                                  cpd->comp.gl_surface,
+                                                  (int)pd->comp.method);
+          }
      }
 
    //If the container has transparency, it internally alpha blends with ector buffer.
@@ -225,7 +350,20 @@ _efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd,
         //       However, if there is a composition target, the child must refer to the parent's opacity.
         //       Because _evas_vg_render does not support opacity calculation for containers that need to be composited.
         //       These things need to be refactored in a better way later.
-        c_a = !comp ? 255 : c_a;
+        /* If there is a composite (CPU buffer or GL FBO mask), children must
+         * inherit the container's opacity.  In the GL span-buffer path,
+         * comp is NULL even when a mask FBO was prepared, so also check for
+         * gl_surface on the comp_target's pd. */
+        {
+           Eina_Bool has_comp = comp != NULL;
+           if (!has_comp && pd->comp_target)
+             {
+                Efl_Canvas_Vg_Container_Data *cpd =
+                   efl_data_scope_get(pd->comp_target, MY_CLASS);
+                if (cpd && cpd->comp.gl_surface) has_comp = EINA_TRUE;
+             }
+           c_a = !has_comp ? 255 : c_a;
+        }
 
         _evas_vg_render_pre(vg_pd, child,
                             engine, output, context, surface,
@@ -267,6 +405,25 @@ _efl_canvas_vg_container_efl_object_destructor(Eo *obj,
         efl_unref(pd->comp.buffer);
      }
 
+   /* Destroy GL FBO mask surface (GL span-buffer path).
+    * pd->comp.gl_surface is an Evas_GL_Image* allocated via
+    * ENFN->ector_surface_create.  We need the engine handle to free it.
+    * Retrieve the engine and output from the VG object's Evas layer if
+    * available.  If the engine context has already been torn down, skip
+    * the free to avoid use-after-free (minor leak on shutdown). */
+   if (pd->comp.gl_surface && pd->comp.vg_pd)
+     {
+        Evas_Object_Protected_Data *vg_pd = pd->comp.vg_pd;
+        if (vg_pd->layer && vg_pd->layer->evas)
+          {
+             Evas_Public_Data *evas = vg_pd->layer->evas;
+             if (evas->engine.func && evas->engine.func->ector_surface_destroy)
+               evas->engine.func->ector_surface_destroy(
+                  _evas_engine_context(evas), pd->comp.gl_surface);
+          }
+        pd->comp.gl_surface = NULL;
+     }
+
    efl_unref(pd->comp_target);
    eina_list_free(pd->comp.src);
    eina_hash_free(pd->names);
diff --git a/src/lib/evas/canvas/efl_canvas_vg_object.c b/src/lib/evas/canvas/efl_canvas_vg_object.c
index fe25ead344..f4001fdcc8 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_object.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_object.c
@@ -430,6 +430,20 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
 
         if (cd->comp.src) return;   //Don't draw composite target itself.
 
+        /* GL composite mask: propagate the mask FBO to the shared ector
+         * surface every frame.  render_pre only runs on changes, but the
+         * draw phase runs every frame.  eng_ector_end clears gl_comp_surface
+         * after use, so it must be re-set here. */
+        if (cd->comp_target)
+          {
+             Efl_Canvas_Vg_Container_Data *cpd =
+                efl_data_scope_get(cd->comp_target, EFL_CANVAS_VG_CONTAINER_CLASS);
+             if (cpd && cpd->comp.gl_surface)
+               ector_software_surface_gl_comp_set(ector,
+                                                  cpd->comp.gl_surface,
+                                                  (int)cd->comp.method);
+          }
+
         int alpha = 255;
         efl_gfx_color_get(node, NULL, NULL, NULL, &alpha);
 
@@ -484,7 +498,17 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
 
              // Draw child node to changed buffer
              EINA_LIST_FOREACH(cd->children, l, child)
-                _evas_vg_render(obj, pd, engine, output, context, child, clips, w, h, ector, do_async);
+               {
+                  if (efl_isa(child, EFL_CANVAS_VG_CONTAINER_CLASS))
+                    {
+                       Efl_Canvas_Vg_Container_Data *child_cd =
+                          efl_data_scope_get(child, EFL_CANVAS_VG_CONTAINER_CLASS);
+                       if (child_cd && child_cd->comp.src) continue;
+                    }
+                  if (cd->comp_target && efl_isa(child, EFL_CANVAS_VG_GRADIENT_CLASS))
+                    continue;
+                  _evas_vg_render(obj, pd, engine, output, context, child, clips, w, h, ector, do_async);
+               }
 
              // Recover original surface
              ector_buffer_pixels_set(ector, ppixels, pw, ph, pstride, pcspace, EINA_TRUE);
@@ -499,7 +523,24 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
              efl_canvas_vg_container_blend_buffer_clear(node, cd);
 
              EINA_LIST_FOREACH(cd->children, l, child)
-                _evas_vg_render(obj, pd, engine, output, context, child, clips, w, h, ector, do_async);
+               {
+                  /* Skip composite target containers — their shapes were
+                   * already rendered to the mask FBO during render_pre.
+                   * Drawing them again would overwrite the masked result. */
+                  if (efl_isa(child, EFL_CANVAS_VG_CONTAINER_CLASS))
+                    {
+                       Efl_Canvas_Vg_Container_Data *child_cd =
+                          efl_data_scope_get(child, EFL_CANVAS_VG_CONTAINER_CLASS);
+                       if (child_cd && child_cd->comp.src) continue;
+                    }
+                  /* Skip gradient objects in composite containers — they are
+                   * fill properties of shapes, not standalone renderable
+                   * nodes.  Only skip when comp_target is set to avoid
+                   * affecting non-composite containers. */
+                  if (cd->comp_target && efl_isa(child, EFL_CANVAS_VG_GRADIENT_CLASS))
+                    continue;
+                  _evas_vg_render(obj, pd, engine, output, context, child, clips, w, h, ector, do_async);
+               }
           }
      }
    else
diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h
index beb5854253..e68f82b155 100644
--- a/src/lib/evas/canvas/evas_vg_private.h
+++ b/src/lib/evas/canvas/evas_vg_private.h
@@ -89,6 +89,7 @@ typedef struct _Vg_Composite
    void *pixels;                           //Composite pixel buffer (actual data)
    unsigned int length;                    //pixel buffer data size
    unsigned int stride;                    //pixel buffer stride
+   void *gl_surface;                       /* GL FBO surface for mask (Evas_GL_Image* in GL path, NULL for SW) */
    Eina_Size2D size;                       //Composite boundary
    Eina_List *src;                         //Composite Sources
    Efl_Gfx_Vg_Composite_Method method;     //Composite Method
@@ -147,6 +148,14 @@ Eina_Bool                   evas_cache_vg_anim_sector_get(const Vg_Cache_Entry*
 unsigned int                evas_cache_vg_anim_frame_count_get(const Vg_Cache_Entry *vg_entry);
 Eina_Size2D                 evas_cache_vg_entry_default_size_get(const Vg_Cache_Entry *vg_entry);
 void *                      evas_cache_vg_surface_key_get(Efl_Canvas_Vg_Node *root, int w, int h, int frame_idx);
+/* Forward declarations for ector software surface GL composite accessors.
+ * The implementations live in src/lib/ector/software/ector_software_surface.c.
+ * These allow canvas code (which cannot include ector_software_private.h) to
+ * store and retrieve the GL FBO mask surface reference on the shared ector
+ * surface during render_pre, so that eng_ector_end() can find it. */
+ECTOR_API void ector_software_surface_gl_comp_set(Ector_Surface *obj, void *gl_surface, int comp_method);
+ECTOR_API void ector_software_surface_gl_comp_get(Ector_Surface *obj, void **gl_surface_out, int *comp_method_out);
+
 void                        efl_canvas_vg_node_vg_obj_set(Efl_VG *node, Efl_VG *vg_obj, Efl_Canvas_Vg_Object_Data *vd);
 void                        efl_canvas_vg_node_change(Efl_VG *node);
 void                        efl_canvas_vg_container_vg_obj_update(Efl_VG *obj, Efl_Canvas_Vg_Node_Data *nd);
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 5a4b447ee9..dd643a0c89 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1073,6 +1073,7 @@ struct _Evas_Func
    void  (*ector_end)                    (void *engine, void *output, void *context, Ector_Surface *ector, Eina_Bool do_async);
 
    void *(*ector_surface_create)         (void *engine, int w, int h, int *error);
+   void *(*ector_mask_surface_create)    (void *engine, int w, int h, int *error);
    void  (*ector_surface_destroy)        (void *engine, void *surface);
    void  (*ector_surface_cache_set)      (void *engine, void *key, void *surface);
    void *(*ector_surface_cache_get)      (void *engine, void *key);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c
index f52691f6c5..da9a67ff24 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_image.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_image.c
@@ -775,6 +775,28 @@ evas_gl_common_image_surface_noscale_new(Evas_Engine_GL_Context *gc, unsigned in
    return im;
 }
 
+EMODAPI Evas_GL_Image *
+evas_gl_common_image_surface_noscale_noatlas_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha)
+{
+   Evas_GL_Image *im;
+
+   if (((int)w > gc->shared->info.max_texture_size) ||
+       ((int)h > gc->shared->info.max_texture_size))
+     return NULL;
+
+   im = calloc(1, sizeof(Evas_GL_Image));
+   if (!im) return NULL;
+   im->references = 1;
+   im->gc = gc;
+   im->cs.space = EVAS_COLORSPACE_ARGB8888;
+   im->alpha = alpha;
+   im->w = w;
+   im->h = h;
+   im->tex = evas_gl_common_texture_render_noscale_noatlas_new(gc, w, h, alpha);
+   im->tex_only = 1;
+   return im;
+}
+
 void
 evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
 {
@@ -1331,7 +1353,6 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
         evas_gl_common_rect_draw(gc, dx, dy, dw, dh);
         return;
      }
-
    mask = gc->dc->clip.mask;
 
    switch (im->cs.space)
diff --git a/src/modules/evas/engines/gl_common/evas_gl_texture.c b/src/modules/evas/engines/gl_common/evas_gl_texture.c
index 317905e9a7..76ea5f8b2e 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_texture.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_texture.c
@@ -1151,6 +1151,36 @@ evas_gl_common_texture_render_noscale_new(Evas_Engine_GL_Context *gc, unsigned i
    return tex;
 }
 
+Evas_GL_Texture *
+evas_gl_common_texture_render_noscale_noatlas_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha)
+{
+   Evas_GL_Texture *tex;
+   int u = 0, v = 0;
+   int lformat;
+
+   lformat = _evas_gl_texture_search_format(alpha, gc->shared->info.bgra, EVAS_COLORSPACE_ARGB8888);
+   if (lformat < 0) return NULL;
+
+   tex = evas_gl_common_texture_alloc(gc, w, h, alpha);
+   if (!tex) return NULL;
+   tex->pt = _pool_tex_render_find(gc, w, h,
+                                   *matching_format[lformat].intformat,
+                                   *matching_format[lformat].format,
+                                   &u, &v, &tex->apt,
+                                   gc->shared->info.tune.atlas.max_alloc_size * 8,
+                                   EINA_TRUE);
+   if (!tex->pt)
+     {
+        evas_gl_common_texture_light_free(tex);
+        return NULL;
+     }
+   tex->x = u;
+   tex->y = v;
+
+   tex->pt->references++;
+   return tex;
+}
+
 Evas_GL_Texture *
 evas_gl_common_texture_dynamic_new(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
 {
diff --git a/src/modules/evas/engines/gl_generic/meson.build b/src/modules/evas/engines/gl_generic/meson.build
index 0464ea43a8..40ae5d46b0 100644
--- a/src/modules/evas/engines/gl_generic/meson.build
+++ b/src/modules/evas/engines/gl_generic/meson.build
@@ -5,6 +5,8 @@ engine_src = files([
   'evas_ector_gl.h',
   'evas_ector_gl_buffer.c',
   'evas_ector_gl_image_buffer.c',
+  'evas_ector_gl_span.c',
+  'evas_ector_gl_span_shader.c',
   join_paths('filters','gl_engine_filter.h'),
   join_paths('filters','gl_filter_blend.c'),
   join_paths('filters','gl_filter_blur.c'),
@@ -65,7 +67,13 @@ endforeach
 
 engine_deps += [gl_deps]
 
-engine_include_dir = include_directories(join_paths('..','software_generic'), join_paths('..', 'gl_common'))
+engine_include_dir = include_directories(
+  join_paths('..','software_generic'),
+  join_paths('..', 'gl_common'),
+  join_paths('..', '..', '..', '..', 'static_libs', 'freetype'),
+  join_paths('..', '..', '..', '..', 'static_libs', 'draw'),
+  join_paths('..', '..', '..', '..', 'lib', 'ector', 'software'),
+)
 
 shared_module(mod_full_name, engine_src,
   include_directories : config_dir + [engine_include_dir],
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c
index 83630e5818..77455962a2 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -4839,6 +4839,7 @@ static Evas_Func func =
      eng_ector_renderer_draw,
      eng_ector_end,
      eng_ector_surface_create,
+     NULL, // ector_mask_surface_create — software engine has no atlas; regular path suffices
      eng_ector_surface_destroy,
      eng_ector_surface_cache_set,
      eng_ector_surface_cache_get,

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

Reply via email to