This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository expedite.
View the commit online.
commit 7e8aee462377dc99708ef0c910f07f883616f48c
Author: [email protected] <[email protected]>
AuthorDate: Sat Mar 28 13:49:37 2026 -0600
test(expedite): add VG network traffic graph benchmark
Add a network traffic graph VG benchmark that simulates a real-world
scrolling graph with three curves and two filled areas. Paths are
fully rebuilt each frame from scrolling data, exercising per-frame
VG path update and re-rasterization performance.
Uses the legacy evas_vg_shape_* API which properly triggers
efl_canvas_vg_node_change — the Eo efl_gfx_path_* API does not
propagate change notifications to the VG object.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---
src/bin/Makefile.am | 1 +
src/bin/meson.build | 1 +
src/bin/tests.h | 1 +
src/bin/vg_basic_network.c | 248 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 251 insertions(+)
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index 7949e79..c84619c 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -134,6 +134,7 @@ vg_basic_rect.c \
vg_basic_circle.c \
vg_basic_gradient.c \
vg_basic_radial_gradient.c \
+vg_basic_network.c \
vg_scaled.c \
snapshot_widgets_file_icons.c
# \
diff --git a/src/bin/meson.build b/src/bin/meson.build
index 267ef53..0d7fb31 100644
--- a/src/bin/meson.build
+++ b/src/bin/meson.build
@@ -124,6 +124,7 @@ expedite_sources = [ 'main.c',
'vg_basic_gradient.c',
'vg_basic_radial_gradient.c',
'vg_basic_batman.c',
+ 'vg_basic_network.c',
'vg_scaled.c',
'snapshot_widgets_file_icons.c' ]
diff --git a/src/bin/tests.h b/src/bin/tests.h
index 817d099..a85c1be 100644
--- a/src/bin/tests.h
+++ b/src/bin/tests.h
@@ -117,6 +117,7 @@
#include "vg_basic_gradient.c"
#include "vg_basic_radial_gradient.c"
#include "vg_basic_batman.c"
+#include "vg_basic_network.c"
#include "vg_scaled.c"
#include "snapshot_widgets_file_icons.c"
#if 0 // test disabled - evas having code disabled
diff --git a/src/bin/vg_basic_network.c b/src/bin/vg_basic_network.c
new file mode 100644
index 0000000..b367c37
--- /dev/null
+++ b/src/bin/vg_basic_network.c
@@ -0,0 +1,248 @@
+#undef FNAME
+#undef NAME
+#undef ICON
+
+/* metadata */
+#define FNAME vg_basic_network_start
+#define NAME "VG Basic Network"
+#define ICON "vector.png"
+
+#ifndef PROTO
+# ifndef UI
+# include "main.h"
+
+/* standard var */
+static int done = 0;
+
+/* Graph dimensions */
+#define GRAPH_W 600
+#define GRAPH_H 300
+#define NUM_POINTS 120
+#define CENTER_Y (GRAPH_H / 2)
+
+/* private data */
+static Eo *o_vg;
+static Efl_VG *o_green_shape, *o_red_shape, *o_blue_shape;
+static Efl_VG *o_green_fill_shape, *o_red_fill_shape;
+
+/* Scrolling data buffers — values in pixels from center.
+ * green: 0..CENTER_Y (above center = negative y direction)
+ * red: 0..CENTER_Y (below center = positive y direction)
+ * blue: -CENTER_Y..CENTER_Y (both sides) */
+static float green_data[NUM_POINTS];
+static float red_data[NUM_POINTS];
+static float blue_data[NUM_POINTS];
+
+static float
+_smooth_random(float prev, float min_val, float max_val, float pull_to)
+{
+ float range = max_val - min_val;
+ float delta = ((float)(rnd() % 1000) / 500.0f - 1.0f) * range * 0.15f;
+ /* Mean-reversion: pull toward pull_to so curves don't stick
+ * to one side. Strength 0.05 keeps oscillation visible. */
+ delta += (pull_to - prev) * 0.05f;
+ float v = prev + delta;
+ if (v < min_val) v = min_val + (min_val - v);
+ if (v > max_val) v = max_val - (v - max_val);
+ return v;
+}
+
+/* Use the legacy evas_vg_shape_* API which calls efl_canvas_vg_node_change
+ * after each path operation, ensuring the VG object re-renders. The Eo
+ * efl_gfx_path_* API does NOT trigger change notifications. */
+static void
+_build_curve_path(Efl_VG *shape, float *data, float y_center, float y_sign)
+{
+ int i;
+ float dx = (float)GRAPH_W / (float)(NUM_POINTS - 1);
+
+ evas_vg_shape_reset(shape);
+ evas_vg_shape_append_move_to(shape, 0, y_center + data[0] * y_sign);
+ for (i = 1; i < NUM_POINTS; i++)
+ {
+ float x = i * dx;
+ float y = y_center + data[i] * y_sign;
+ float px = (i - 1) * dx;
+ float py = y_center + data[i - 1] * y_sign;
+ float cx1 = px + dx * 0.4f;
+ float cx2 = x - dx * 0.4f;
+ evas_vg_shape_append_cubic_to(shape, x, y, cx1, py, cx2, y);
+ }
+}
+
+static void
+_build_filled_path(Efl_VG *shape, float *data, float y_center, float y_sign)
+{
+ int i;
+ float dx = (float)GRAPH_W / (float)(NUM_POINTS - 1);
+
+ evas_vg_shape_reset(shape);
+ evas_vg_shape_append_move_to(shape, 0, y_center);
+ evas_vg_shape_append_line_to(shape, 0, y_center + data[0] * y_sign);
+ for (i = 1; i < NUM_POINTS; i++)
+ {
+ float x = i * dx;
+ float y = y_center + data[i] * y_sign;
+ float px = (i - 1) * dx;
+ float py = y_center + data[i - 1] * y_sign;
+ float cx1 = px + dx * 0.4f;
+ float cx2 = x - dx * 0.4f;
+ evas_vg_shape_append_cubic_to(shape, x, y, cx1, py, cx2, y);
+ }
+ evas_vg_shape_append_line_to(shape, (NUM_POINTS - 1) * dx, y_center);
+ evas_vg_shape_append_close(shape);
+}
+
+static void _setup(void)
+{
+ int i;
+
+ srnd();
+
+ /* Initialize with sinusoidal base + noise so the curves look natural
+ * from the start. The blue curve uses a sine that crosses zero,
+ * guaranteeing it visibly oscillates between the green and red zones. */
+ for (i = 0; i < NUM_POINTS; i++)
+ {
+ float t = (float)i / (float)NUM_POINTS;
+ float noise_g = ((float)(rnd() % 1000) / 500.0f - 1.0f) * 15.0f;
+ float noise_r = ((float)(rnd() % 1000) / 500.0f - 1.0f) * 15.0f;
+ float noise_b = ((float)(rnd() % 1000) / 500.0f - 1.0f) * 20.0f;
+
+ green_data[i] = (float)CENTER_Y * 0.3f
+ + sinf(t * 6.0f) * (float)CENTER_Y * 0.4f + noise_g;
+ if (green_data[i] < 5.0f) green_data[i] = 5.0f;
+ if (green_data[i] > (float)CENTER_Y * 0.9f) green_data[i] = (float)CENTER_Y * 0.9f;
+
+ red_data[i] = (float)CENTER_Y * 0.3f
+ + cosf(t * 5.0f) * (float)CENTER_Y * 0.4f + noise_r;
+ if (red_data[i] < 5.0f) red_data[i] = 5.0f;
+ if (red_data[i] > (float)CENTER_Y * 0.9f) red_data[i] = (float)CENTER_Y * 0.9f;
+
+ blue_data[i] = sinf(t * 4.0f + 1.5f) * (float)CENTER_Y * 0.6f + noise_b;
+ if (blue_data[i] < -(float)CENTER_Y * 0.9f) blue_data[i] = -(float)CENTER_Y * 0.9f;
+ if (blue_data[i] > (float)CENTER_Y * 0.9f) blue_data[i] = (float)CENTER_Y * 0.9f;
+ }
+
+ o_vg = efl_add(EFL_CANVAS_VG_OBJECT_CLASS, evas);
+ efl_gfx_entity_size_set(o_vg, EINA_SIZE2D(GRAPH_W, GRAPH_H));
+ efl_gfx_entity_position_set(o_vg,
+ EINA_POSITION2D((win_w - GRAPH_W) / 2,
+ (win_h - GRAPH_H) / 2));
+ efl_gfx_entity_visible_set(o_vg, EINA_TRUE);
+
+ /* Filled areas (drawn first, behind strokes) */
+ o_green_fill_shape = efl_add(EFL_CANVAS_VG_SHAPE_CLASS, o_vg);
+ efl_gfx_color_set(o_green_fill_shape, 0, 51, 0, 51); /* green, 20% alpha */
+
+ o_red_fill_shape = efl_add(EFL_CANVAS_VG_SHAPE_CLASS, o_vg);
+ efl_gfx_color_set(o_red_fill_shape, 51, 0, 0, 51); /* red, 20% alpha */
+
+ /* Stroke curves (drawn on top) */
+ o_green_shape = efl_add(EFL_CANVAS_VG_SHAPE_CLASS, o_vg);
+ efl_gfx_shape_stroke_width_set(o_green_shape, 2.0);
+ efl_gfx_shape_stroke_color_set(o_green_shape, 0, 200, 0, 255);
+ efl_gfx_shape_stroke_join_set(o_green_shape, EFL_GFX_JOIN_ROUND);
+ efl_gfx_shape_stroke_cap_set(o_green_shape, EFL_GFX_CAP_ROUND);
+
+ o_red_shape = efl_add(EFL_CANVAS_VG_SHAPE_CLASS, o_vg);
+ efl_gfx_shape_stroke_width_set(o_red_shape, 2.0);
+ efl_gfx_shape_stroke_color_set(o_red_shape, 200, 0, 0, 255);
+ efl_gfx_shape_stroke_join_set(o_red_shape, EFL_GFX_JOIN_ROUND);
+ efl_gfx_shape_stroke_cap_set(o_red_shape, EFL_GFX_CAP_ROUND);
+
+ o_blue_shape = efl_add(EFL_CANVAS_VG_SHAPE_CLASS, o_vg);
+ efl_gfx_shape_stroke_width_set(o_blue_shape, 2.0);
+ efl_gfx_shape_stroke_color_set(o_blue_shape, 0, 80, 255, 255);
+ efl_gfx_shape_stroke_join_set(o_blue_shape, EFL_GFX_JOIN_ROUND);
+ efl_gfx_shape_stroke_cap_set(o_blue_shape, EFL_GFX_CAP_ROUND);
+
+ /* Build the VG tree: all shapes are children of a container root.
+ * efl_add with parent automatically adds to the container's tree.
+ * Draw order follows creation order — fills first, then strokes. */
+ {
+ Efl_VG *root = efl_add(EFL_CANVAS_VG_CONTAINER_CLASS, o_vg);
+ efl_parent_set(o_green_fill_shape, root);
+ efl_parent_set(o_red_fill_shape, root);
+ efl_parent_set(o_green_shape, root);
+ efl_parent_set(o_red_shape, root);
+ efl_parent_set(o_blue_shape, root);
+ efl_canvas_vg_object_root_node_set(o_vg, root);
+ }
+
+ done = 0;
+}
+
+/* cleanup */
+static void _cleanup(void)
+{
+ efl_del(o_vg);
+}
+
+/* loop - do things */
+static void _loop(double t, int f)
+{
+ int i;
+
+ (void)t;
+
+ /* Scroll data left, add new sample on right */
+ for (i = 0; i < NUM_POINTS - 1; i++)
+ {
+ green_data[i] = green_data[i + 1];
+ red_data[i] = red_data[i + 1];
+ blue_data[i] = blue_data[i + 1];
+ }
+ green_data[NUM_POINTS - 1] = _smooth_random(green_data[NUM_POINTS - 2],
+ 5.0f, (float)CENTER_Y * 0.9f,
+ (float)CENTER_Y * 0.4f);
+ red_data[NUM_POINTS - 1] = _smooth_random(red_data[NUM_POINTS - 2],
+ 5.0f, (float)CENTER_Y * 0.9f,
+ (float)CENTER_Y * 0.4f);
+ blue_data[NUM_POINTS - 1] = _smooth_random(blue_data[NUM_POINTS - 2],
+ -(float)CENTER_Y * 0.9f,
+ (float)CENTER_Y * 0.9f,
+ 0.0f);
+
+ /* Rebuild all paths from updated data.
+ * Green: above center (negative y_sign moves upward).
+ * Red: below center (positive y_sign moves downward).
+ * Blue: both sides, stroke only. */
+ _build_filled_path(o_green_fill_shape, green_data, (float)CENTER_Y, -1.0f);
+ _build_filled_path(o_red_fill_shape, red_data, (float)CENTER_Y, 1.0f);
+ _build_curve_path(o_green_shape, green_data, (float)CENTER_Y, -1.0f);
+ _build_curve_path(o_red_shape, red_data, (float)CENTER_Y, 1.0f);
+ _build_curve_path(o_blue_shape, blue_data, (float)CENTER_Y, 1.0f);
+
+ FPS_STD(NAME);
+}
+
+/* prepend special key handlers if interactive (before STD) */
+static void _key(const char *key)
+{
+ KEY_STD;
+}
+
+/* template stuff - ignore */
+# endif
+#endif
+
+#ifdef UI
+_ui_menu_item_add(ICON, NAME, FNAME);
+#endif
+
+#ifdef PROTO
+void FNAME(void);
+#endif
+
+#ifndef PROTO
+# ifndef UI
+void FNAME(void)
+{
+ ui_func_set(_key, _loop, _setup);
+}
+# endif
+#endif
+#undef FNAME
+#undef NAME
+#undef ICON
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.