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 6b673f4a4ff4d04867e6b4e433e709ea872c25ea
Author: [email protected] <[email protected]>
AuthorDate: Sun Sep 13 19:47:39 2026 -0600
evas_ector_gl: order new struct fields by size and use the smallest types
The review pointed out that the structs this branch adds do not follow
the usual EFL layout: fields ordered by size, the smallest type that
holds each value, and fields that only ever hold 0 or 1 written as
Eina_Bool name : 1 at the end.
Apply that to the new structs where it changes something:
- Span_Collector (one per shape): pointers and the Eina_Matrix3 first,
then the 4-byte fields and split_points[]. type, comp_method,
texture_count and split_count become unsigned char, flush_prev_ti a
signed char (it holds -1), and max_spans and actual_max_spans an
unsigned short. span_collector_new() now rejects a max_spans that
does not fit 16 bits. 192 -> 168 bytes on LP64.
- Span_Channel_Params: type and grad_spread become unsigned char.
68 -> 64 bytes.
- Span_Pipe_Params (one per quad, two channels): comp_method becomes
unsigned char and max_spans unsigned short. 204 -> 192 bytes.
- Span_Texture: dirty becomes Eina_Bool dirty : 1 after the 4-byte
fields (56 bytes either way).
- Span_Grad_Atlas and Span_Grad_Atlas_Row: pointers first; occupied,
disabled and test_skip_gl become Eina_Bool : 1 at the end, set with
EINA_TRUE. The header now includes Eina.h itself.
- Span_Shader: samplers_bound becomes a 1-bit Eina_Bool.
- Span_Page_Entry: both pointers ahead of the ints.
Left unchanged: texture sizes and coordinates (Span_Page w/h, pool_w/h,
page_x/page_y) are bounded only by the GPU's maximum texture size;
canvas coordinates, heights and strides stay int; GLuint and GLint
fields follow the GL API; colours and hashes are real 32-bit values;
Span_Page_Entry and Span_Attr_Desc only live briefly on the stack; the
Span_Vertex_* structs mirror the GPU vertex layout used through
offsetof(); the test-build Span_Data copy follows the real ector
struct; structs that exist on master are not touched.
Nothing depends on the old field order or widths: the only initializer
is Span_Pipe_Params _spp = { 0 }, no code copies, compares or hashes
these structs as raw bytes, and no narrowed field has its address taken.
Sizes were measured with a probe built with the engine's compile flags.
VG expedite tests 117-126 render pixel-identical GL frames before and
after, and parity against the software engine is unchanged. The build is
clean, and ector_suite and evas_suite pass.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
.../evas/engines/gl_common/evas_gl_common.h | 13 ++--
.../engines/gl_generic/evas_ector_gl_grad_atlas.c | 6 +-
.../engines/gl_generic/evas_ector_gl_grad_atlas.h | 15 ++---
.../evas/engines/gl_generic/evas_ector_gl_span.c | 3 +-
.../evas/engines/gl_generic/evas_ector_gl_span.h | 72 +++++++++++-----------
.../engines/gl_generic/evas_ector_gl_span_shader.c | 4 +-
6 files changed, 57 insertions(+), 56 deletions(-)
diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h
index 0a827703c6..0e2feaeedf 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -284,33 +284,32 @@ typedef struct _Span_Channel_Params {
float off_tx; // texel x-offset in pool
float off_ty; // texel y-offset in pool
uint32_t col; // base color (premultiplied ARGB)
- int type; // SPAN_FILL_TYPE_* (ector's Span_Data_Type)
int x_min; // spatial split x_min
// Gradient parameters (unused for Solid type)
float grad_a, grad_b, grad_c; // linear: t = a*px + b*py + c
- int grad_spread; // 0=PAD, 1=REFLECT, 2=REPEAT
float grad_ramp_y; // atlas V coordinate: (row+0.5)/SPAN_GRAD_ATLAS_H
float grad_d, grad_e, grad_f; // radial: 2nd affine row
float grad_ra, grad_rdx, grad_rdy; // radial: quadratic params
+ unsigned char type; // SPAN_FILL_TYPE_* (ector's Span_Data_Type)
+ unsigned char grad_spread; // 0=PAD, 1=REFLECT, 2=REPEAT
} Span_Channel_Params;
// Full parameter set for one span quad; see span_pass_draw().
typedef struct _Span_Pipe_Params {
- int pool_w, pool_h;
- // pool texture dimensions
- int max_spans; // max spans per row
+ int pool_w, pool_h; // pool texture dimensions
int x, y, w, h; // draw rect in canvas space
uint32_t mul_col; // multiply color
float fbo_off_x, fbo_off_y; // atlas FBO sub-region offset
// Gradient ramp atlas (0 = atlas unavailable, gradient shapes are skipped)
GLuint grad_atlas_tex; // GL texture name of the shared gradient ramp atlas
- // Composite mask parameters (0/NULL = no mask)
+ // Composite mask parameters (0/NULL = no mask); comp_method is at the end
GLuint mask_tex; // GL texture name of mask FBO (0 = no mask)
- int comp_method; // Efl_Gfx_Vg_Composite_Method
float mask_w, mask_h; // mask texture dimensions
float mask_off_x, mask_off_y; // atlas offset of mask texture
Span_Channel_Params fill;
Span_Channel_Params stroke;
+ unsigned short max_spans; // max spans per row
+ unsigned char comp_method; // Efl_Gfx_Vg_Composite_Method
} Span_Pipe_Params;
struct _Evas_Engine_GL_Context
diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_grad_atlas.c b/src/modules/evas/engines/gl_generic/evas_ector_gl_grad_atlas.c
index ac31227bae..bcd6644ead 100644
--- a/src/modules/evas/engines/gl_generic/evas_ector_gl_grad_atlas.c
+++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_grad_atlas.c
@@ -99,7 +99,7 @@ _ensure_gl(Span_Grad_Atlas *a)
GLuint t = 0;
glGenTextures(1, &t);
- if (!t) { a->disabled = 1; return 0; }
+ if (!t) { a->disabled = EINA_TRUE; return 0; }
glBindTexture(GL_TEXTURE_2D, t);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
SPAN_GRAD_ATLAS_W, SPAN_GRAD_ATLAS_H, 0,
@@ -287,7 +287,7 @@ span_grad_atlas_lookup(Span_Grad_Atlas *a, void *grad_id,
a->rows[row].version = version;
a->rows[row].grad_id = grad_id;
a->rows[row].last_used = a->current_frame;
- a->rows[row].occupied = 1;
+ a->rows[row].occupied = EINA_TRUE;
return row;
}
@@ -296,6 +296,6 @@ void
span_grad_atlas_test_enable(Span_Grad_Atlas *a)
{
if (!a) return;
- a->test_skip_gl = 1;
+ a->test_skip_gl = EINA_TRUE;
}
#endif
diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_grad_atlas.h b/src/modules/evas/engines/gl_generic/evas_ector_gl_grad_atlas.h
index c5b7167ac9..ec1259e3fb 100644
--- a/src/modules/evas/engines/gl_generic/evas_ector_gl_grad_atlas.h
+++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_grad_atlas.h
@@ -2,6 +2,7 @@
#define EVAS_ECTOR_GL_GRAD_ATLAS_H
#include <stdint.h>
+#include <Eina.h>
// In the normal engine build GLuint is provided by the system GL headers
// pulled in by evas_gl_private.h (the .c file includes that before this
@@ -31,26 +32,26 @@ typedef unsigned int GLuint;
typedef struct _Span_Grad_Atlas_Row
{
+ void *grad_id; // gradient pointer for fast-path identity match
uint32_t hash; // hash of 4096-byte ramp
uint32_t version; // last_uploaded_version, piggybacks gradient counter
- void *grad_id; // gradient pointer for fast-path identity match
uint32_t last_used; // render-frame counter for LRU
- int occupied; // 0 = free row, 1 = occupied
+ Eina_Bool occupied : 1; // EINA_FALSE = free row
} Span_Grad_Atlas_Row;
typedef struct _Span_Grad_Atlas Span_Grad_Atlas;
struct _Span_Grad_Atlas
{
- GLuint tex; // GL texture handle, 0 until allocated
uint8_t *cpu_mirror; // H * ROW_BYTES = 256 KB
- Span_Grad_Atlas_Row rows[SPAN_GRAD_ATLAS_H];
- uint32_t current_frame; // monotonic, incremented per render pass
- int disabled; // 1 if alloc failed; gradient path skips
void (*flush_cb)(void *data); // drains pending draws
void *flush_data;
+ Span_Grad_Atlas_Row rows[SPAN_GRAD_ATLAS_H];
+ GLuint tex; // GL texture handle, 0 until allocated
+ uint32_t current_frame; // monotonic, incremented per render pass
+ Eina_Bool disabled : 1; // alloc failed; gradient path skips
#ifdef SPAN_GRAD_ATLAS_TEST_BUILD
- int test_skip_gl; // bypass GL; uploads are no-ops
+ Eina_Bool test_skip_gl : 1; // bypass GL; uploads are no-ops
#endif
};
diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_span.c b/src/modules/evas/engines/gl_generic/evas_ector_gl_span.c
index cd294219db..bf912b2b19 100644
--- a/src/modules/evas/engines/gl_generic/evas_ector_gl_span.c
+++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_span.c
@@ -88,7 +88,8 @@ span_collector_new(int h, int max_spans, Span_Data_Type type)
{
Span_Collector *sc;
- if ((h <= 0) || (max_spans <= 0)) return NULL;
+ // max_spans is stored in 16 bits.
+ if ((h <= 0) || (max_spans <= 0) || (max_spans > 0xffff)) return NULL;
sc = calloc(1, sizeof(Span_Collector));
if (!sc) return NULL;
diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_span.h b/src/modules/evas/engines/gl_generic/evas_ector_gl_span.h
index 4c5e6125ab..d5bd5858f3 100644
--- a/src/modules/evas/engines/gl_generic/evas_ector_gl_span.h
+++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_span.h
@@ -157,13 +157,13 @@ struct _Span_Texture
uint8_t *buffer; // row-major span buffer, height * stride bytes
int *span_counts; // per-row count of packed spans, height ints
int *last_x_end; // per-row: x coord where last span ended (for gap calc)
- Eina_Bool dirty; // EINA_TRUE if span data changed since last upload
uint32_t prev_hash; // hash of buffer content at last upload, for change detection
uint32_t rolling_hash; // accumulated during span collection
int x_min; // inclusive left edge of the x-range covered
int x_max; // inclusive right edge of the x-range covered
int page_x; // texel offset of these rows inside the shared page
int page_y;
+ Eina_Bool dirty : 1; // EINA_TRUE if span data changed since last upload
};
// ------------------------------------------------------------------
@@ -177,32 +177,7 @@ struct _Span_Texture
// (or cleared and reused) at eng_ector_end().
struct _Span_Collector
{
- Span_Texture *textures; // dynamic array of texture slots
- int texture_count; // number of active entries in textures[]
-
- // X-coordinates at which the canvas is split into separate textures.
- // split_points[i] is the x_min of texture i+1 (i.e., the exclusive
- // right boundary of texture i). split_count is the number of splits
- // recorded so far, up to SPAN_COLLECTOR_MAX_SPLITS.
- int split_points[SPAN_COLLECTOR_MAX_SPLITS];
- int split_count;
-
- int max_spans; // max spans per row per texture (default 32)
- int h; // active height this frame (VG object height)
- int alloc_h; // allocated buffer height (high-water mark, never shrinks)
- int stride; // bytes per row = (max_spans + 1) * 4
- // The +1 reserves a dedicated sentinel slot.
- int actual_max_spans; // max span_counts[y] seen during collection this frame
-
- // Row-tail flush state - tracked across multiple _collect_spans_solid
- // invocations (e.g., when _span_fill_clipRect calls the callback in
- // chunks). Reset in span_collector_clear.
- int flush_prev_y; // last row flushed (-1 = none)
- int flush_prev_ti; // texture index of last flushed row
-
- // Fill parameters captured at span_collector_new() time or during collection
- Span_Data_Type type; // Solid, LinearGradient, or RadialGradient
- uint32_t color; // premultiplied ARGB (0xAARRGGBB) for Solid fills
+ Span_Texture *textures; // dynamic array of texture slots
// Gradient data pointer set during _collect_spans_gradient().
// Points into the active Ector_Renderer_Software_Gradient_Data for this
@@ -210,22 +185,47 @@ struct _Span_Collector
// Used by eng_ector_end() to upload the color ramp and compute t-coefficients.
void *gradient_data; // Ector_Renderer_Software_Gradient_Data* or NULL
- // Ector surface offset captured during _collect_spans_gradient().
- // These are the x/y values passed to ector_surface_reference_point_set().
- // Needed to fold the local->canvas translation into the t-coefficients.
- int grad_offx;
- int grad_offy;
+ // Composite/mask parameters set by _collect_spans_composite() when a shape
+ // has an active composite mask. Both default to 0/NULL for non-masked
+ // shapes; comp_method is at the end of the struct.
+ void *mask_surface; // Evas_GL_Image* for the mask FBO (NULL = no mask)
// Per-shape inverse transform matrix captured during gradient/composite collection.
// Copy of sd->inv from the current shape being rasterized. Used by
// eng_ector_end() to compute gradient t-coefficients with the correct transform.
Eina_Matrix3 inv;
- // Composite/mask parameters set by _collect_spans_composite() when a shape
- // has an active composite mask. Both default to 0/NULL for non-masked shapes.
- void *mask_surface; // Evas_GL_Image* for the mask FBO (NULL = no mask)
- int comp_method; // Efl_Gfx_Vg_Composite_Method (0 = NONE)
+ int h; // active height this frame (VG object height)
+ int alloc_h; // allocated buffer height (high-water mark, never shrinks)
+ int stride; // bytes per row = (max_spans + 1) * 4
+ // The +1 reserves a dedicated sentinel slot.
+ uint32_t color; // premultiplied ARGB (0xAARRGGBB) for Solid fills
+ // Ector surface offset captured during _collect_spans_gradient().
+ // These are the x/y values passed to ector_surface_reference_point_set().
+ // Needed to fold the local->canvas translation into the t-coefficients.
+ int grad_offx;
+ int grad_offy;
+
+ // Row-tail flush state - tracked across multiple _collect_spans_solid
+ // invocations (e.g., when _span_fill_clipRect calls the callback in
+ // chunks). Reset in span_collector_clear. flush_prev_ti is at the end.
+ int flush_prev_y; // last row flushed (-1 = none)
+
+ // X-coordinates at which the canvas is split into separate textures.
+ // split_points[i] is the x_min of texture i+1 (i.e., the exclusive
+ // right boundary of texture i). split_count is the number of splits
+ // recorded so far, up to SPAN_COLLECTOR_MAX_SPLITS.
+ int split_points[SPAN_COLLECTOR_MAX_SPLITS];
+
+ unsigned short max_spans; // max spans per row per texture (default 64)
+ unsigned short actual_max_spans; // max span_counts[y] seen this frame
+
+ unsigned char texture_count; // active entries in textures[], at most 1 + MAX_SPLITS
+ unsigned char split_count;
+ signed char flush_prev_ti; // texture index of last flushed row (-1 = none)
+ unsigned char type; // Span_Data_Type: Solid, LinearGradient, RadialGradient
+ unsigned char comp_method; // Efl_Gfx_Vg_Composite_Method (0 = NONE)
};
// ------------------------------------------------------------------
diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_span_shader.c b/src/modules/evas/engines/gl_generic/evas_ector_gl_span_shader.c
index 6635d36f38..a2f4be721f 100644
--- a/src/modules/evas/engines/gl_generic/evas_ector_gl_span_shader.c
+++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_span_shader.c
@@ -795,7 +795,7 @@ typedef struct
// Mask sampler - valid only in mask variants (-1 otherwise).
int loc_mask_tex;
// Sampler uniforms are program state; assign the texture units once.
- Eina_Bool samplers_bound;
+ Eina_Bool samplers_bound : 1;
} Span_Shader;
// [kind][bind][mask] - kind 0=solid 1=gradient, bind in Span_Bind_Set, mask 0/1.
@@ -1395,11 +1395,11 @@ _span_page_ensure(Span_Page *page, Evas_Engine_GL_Context *gc, int w, int h)
typedef struct
{
Span_Texture *tex;
+ int *counts;
int w; // columns the shader will actually read
int rows;
int stride; // source row stride in bytes
int max_spans;
- int *counts;
} Span_Page_Entry;
static int
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.