Commit: patch 9.2.0856: GTK4: undercurl rendering is inefficient

Christian Brabandt <[email protected]>
Newsgroups gmane.editors.vim.devel
Message-ID <[email protected]>
patch 9.2.0856: GTK4: undercurl rendering is inefficient

Commit: https://github.com/vim/vim/commit/06c0e88b760e62f1c44177241eb58f866c136fc6
Author: Foxe Chen <[email protected]>
Date:   Sat Jul 25 16:57:36 2026 +0000

    patch 9.2.0856: GTK4: undercurl rendering is inefficient
    
    Problem:  In the GTK4 GUI the undercurl is drawn by building a path
              across the whole width of each decorated row.  With many
              undercurls on screen this causes frame drops.
    Solution: Render a single cycle of the undercurl and tile it across the
              row with a repeating node, so the Vulkan and OpenGL
              renderers can repeat directly (Foxe Chen).
    
    closes: #20829
    
    Signed-off-by: Foxe Chen <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/gui_gtk4_da.c b/src/gui_gtk4_da.c
index 739f2e0ae..7a082cedf 100644
--- a/src/gui_gtk4_da.c
+++ b/src/gui_gtk4_da.c
@@ -914,7 +914,12 @@ draw_row_ensure_decor(DrawRow *drow, int flags)
 	int x_start = FILL_X(0);
 	int x_end = FILL_X(drow->n_cells);
 
-	// GskPath was added in GSK 4.14, otherwise use cairo
+	// Instead of rendering the entire pattern, use a repeating node to
+	// render a single cycle of the undercurl, taking advantage of the GPU
+	// (if using opengl or vulkan renderer).
+	GskRenderNode *child = NULL;
+
+	// GskPath was added in GSK 4.14, otherwise use Cairo
 #if GTK_CHECK_VERSION(4, 14, 0)
 	GskPathBuilder	*builder;
 	GskPath		*path;
@@ -924,52 +929,52 @@ draw_row_ensure_decor(DrawRow *drow, int flags)
 
 	builder = gsk_path_builder_new();
 
-	gsk_path_builder_move_to(builder,
-		x_start + 1,
-		y - 2 + 0.5);
+	// Start at X = -1 (val[7]) to ensure a fully formed stroke at X = 0
+	gsk_path_builder_move_to(builder, -1, y - val[7] + 0.5);
+	gsk_path_builder_line_to(builder, 0, y - val[0] + 0.5);
 
-	for (int i = x_start + 1; i < x_end; i++)
-	{
-	    int offset = val[i % 8];
+	for (int i = 1; i < 8; i++)
+	    gsk_path_builder_line_to(builder, i, y - val[i] + 0.5);
 
-	    gsk_path_builder_line_to(builder,
-		    i, y - offset + 0.5);
-	}
+	// Extend to X = 9 (val[1]) to ensure a fully formed stroke at X = 8
+	gsk_path_builder_line_to(builder, 8, y - val[0] + 0.5);
+	gsk_path_builder_line_to(builder, 9, y - val[1] + 0.5);
 
 	path = gsk_path_builder_free_to_path(builder);
-
 	stroke = gsk_stroke_new(1.0);
 
-	gsk_path_get_stroke_bounds (path, stroke, &bounds);
+	gsk_path_get_stroke_bounds(path, stroke, &bounds);
 	color_node = gsk_color_node_new(&white_rgba, &bounds);
+	child = gsk_stroke_node_new(color_node, path, stroke);
 
-	drow->underc_mask = gsk_stroke_node_new(color_node, path, stroke);
 	gsk_stroke_free(stroke);
 	gsk_path_unref(path);
 	gsk_render_node_unref(color_node);
 #else
-	cairo_t		*cr;
-	GskRenderNode	*node;
+	cairo_t *cr;
 
-	node = gsk_cairo_node_new(
-		&GRAPHENE_RECT_INIT(x_start, y - 3, x_end - x_start, 5));
-	cr = gsk_cairo_node_get_draw_context(node);
+	child = gsk_cairo_node_new(&GRAPHENE_RECT_INIT(-2, y - 4, 12, 7));
+	cr = gsk_cairo_node_get_draw_context(child);
 
 	cairo_set_line_width(cr, 1.0);
 	cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
 
-	cairo_move_to(cr, x_start + 1, y - 2 + 0.5);
+	cairo_move_to(cr, -1, y - val[7] + 0.5);
+	cairo_line_to(cr, 0, y - val[0] + 0.5);
 
-	for (int i = x_start + 1; i < x_end; ++i)
-	{
-	    int offset = val[i % 8];
-	    cairo_line_to(cr, i, y - offset + 0.5);
-	}
+	for (int i = 1; i < 8; ++i)
+	    cairo_line_to(cr, i, y - val[i] + 0.5);
+
+	cairo_line_to(cr, 8, y - val[0] + 0.5);
+	cairo_line_to(cr, 9, y - val[1] + 0.5);
 
 	cairo_stroke(cr);
 	cairo_destroy(cr);
-	drow->underc_mask = node;
 #endif
+	drow->underc_mask = gsk_repeat_node_new(
+		&GRAPHENE_RECT_INIT(x_start, y - 3, x_end - x_start, 5),
+		child, &GRAPHENE_RECT_INIT(0.0f, y - 3, 8.0f, 5.0f));
+	gsk_render_node_unref(child);
     }
 }
 
diff --git a/src/version.c b/src/version.c
index 7a37a44ea..b289c6800 100644
--- a/src/version.c
+++ b/src/version.c
@@ -758,6 +758,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    856,
 /**/
     855,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups "vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1wnfxn-00DZlN-OY%40256bit.org.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.