From bd2059fc2f67af6ed2c740f5c56ee88ad1dd84d6 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Wed, 30 Jul 2025 10:38:13 +0100 Subject: [PATCH 01/19] Start This Month In Linebender for July --- content/blog/2025-08-05-tmil-19/index.md | 86 ++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 content/blog/2025-08-05-tmil-19/index.md diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md new file mode 100644 index 00000000..fe5caadd --- /dev/null +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -0,0 +1,86 @@ ++++ +title = "Linebender in July 2025" +authors = ["Daniel McNab"] ++++ + +Linebender is an informal open-source organization working on various projects to advance the state of the art in GUI for [the Rust programming language](https://rust-lang.org). + +## Vello + +Vello is our GPU vector renderer. +It can draw large 2D scenes with high performance, using GPU compute shaders for most of the work. + + +- [vello#...][]: + +This month's progress on the sparse strips renderers, a collaborative evolution of Vello, has been centered around applying SIMD . + + +- [vello#...][]: + +Our [working roadmap](https://docs.google.com/document/d/1ZquH-53j2OedTbgEKCJBKTh4WLE11UveM10mNdnVARY/edit?tab=t.0#heading=h.j3duh9pgdm94) outlines the planned timeline for work on the renderers into next year. + +An integration of Vello as the backend for Servo's canvas rendering has landed in (and also Vello CPU in ). + + + +### Fearless SIMD + +TODO: A new blurb here? + +## Masonry + +Masonry is the widget system developed by Linebender. +It provides a non-opinionated retained widget tree, designed as a base layer for high-level GUI frameworks. + +- [xilem#...][]: + + + + +## Xilem + +Xilem is our flagship GUI project, inspired by SwiftUI, which uses Masonry for its widgets. +It lets you build user interfaces declaratively by composing lightweight views together, and will diff them to provide minimal updates to a retained layer. +Our work on Placehero, which is the working name for our Mastodon client example, has inspired several significant architectural improvements in Xilem. + +- [xilem#...][]: + + +## Anymore + +We have factored a shared utility for use in both Xilem and Masonry... + + +## Parley + +Parley is a text layout library. +It handles text layout, mostly at the level of line breaking and resolving glyph positions. + +- [parley#...][]: + + + +## Get Involved + +We welcome collaboration on any of our crates. +This can include improving the documentation, implementing new features, improving our test coverage, or using them within your own code. + +We host an hour long office hours meeting each week where we discuss what's going on in our projects. +We're also running a separate office hours time dedicated to the renderer collaboration, details also available at that link. +See [#office hours in Zulip](https://xi.zulipchat.com/#narrow/channel/359642-office-hours) for details. + +If you wish to discuss the Linebender project individually, Daniel is offering ["office hours" appointments](https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ32eQYJ9DtZ_wJaYNtT36YioETiloZDIdImFpBFRo5-XsqGzpikgkg47LPsiHhpiwiQ1orOwwW2), which are free to book. +It really helps us to learn what aspects our users care about the most. + + From 56bb17919af8f6450de9071ba979e2ad4173c8a2 Mon Sep 17 00:00:00 2001 From: Laurenz Stampfl <47084093+LaurenzV@users.noreply.github.com> Date: Fri, 1 Aug 2025 10:43:36 +0000 Subject: [PATCH 02/19] Add charts to vello-cpu performance --- content/blog/2025-08-05-tmil-19/index.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index fe5caadd..cd65f80d 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -13,7 +13,17 @@ It can draw large 2D scenes with high performance, using GPU compute shaders for - [vello#...][]: -This month's progress on the sparse strips renderers, a collaborative evolution of Vello, has been centered around applying SIMD . +This month's progress on the sparse strips renderers, a collaborative evolution of Vello, has been centered around adding support for NEON and WASM SIMD, as well as making further improvements to multi-threaded rendering. + +In order to get a better understanding of where we lie performance-wise, we included `tiny-skia` and `vello-cpu` in the [Blend2D benchmark harness](https://blend2d.com/performance.html), a comprehensive benchmarking tool that tests the performance of different parts of a 2D renderer and compares it against other renderers. In order to do so, a [fork](https://github.com/LaurenzV/blend2d-apps/tree/benching) of the benchmark harness was created that uses C bindings to both libraries to include them in the harness. To visualize the results, we created a chart, similar to how it is available on the official Blend2D website. We do want to emphasize again that full credit for building this benchmark tool goes to the Blend2D team, and we merely extended it to also include `tiny-skia` and `vello-cpu`. + +The results can be viewed [here](https://laurenzv.github.io/vello_chart/), the source code for generating the charts is available [here](https://github.com/LaurenzV/vello_chart). + +Some things that should be noted here: +- Note that these are only preliminary results, and there are plans for making further improvements, especially for multi-threading. +- We currently do not support x86 SIMD, which is why they are currently not included in the chart. It should be noted that the [README](https://github.com/linebender/tiny-skia?tab=readme-ov-file#performance) of `tiny-skia` explicitly mentions that performance on ARM is worse than on x86, so we expect the performance gap to be smaller on x86. + +Nevertheless, by looking at this chart, it is clear that `vello-cpu` has very impressive performance and on track to become the fastest CPU-based renderer in the Rust ecosystem! When taking all renderers into consideration, Blend2D is still the clear winner in terms of raw performance, but `vello-cpu` does end up taking the second place in many of the benchmarks and beating other renderers such as Skia and Cairo, especially as the size of the geometry gets larger. Similarly to Blend2D, `vello-cpu` also offers a multi-threaded rendering mode, which is especially effective when drawing larger geometries with curves or when using complex paints such as gradients or patterns. - [vello#...][]: From 29250b3202a1fff50caeb9ac9655457ebd14c765 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Fri, 1 Aug 2025 18:22:17 +0100 Subject: [PATCH 03/19] One sentence per line --- content/blog/2025-08-05-tmil-19/index.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index cd65f80d..bf44fe17 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -15,19 +15,24 @@ It can draw large 2D scenes with high performance, using GPU compute shaders for This month's progress on the sparse strips renderers, a collaborative evolution of Vello, has been centered around adding support for NEON and WASM SIMD, as well as making further improvements to multi-threaded rendering. -In order to get a better understanding of where we lie performance-wise, we included `tiny-skia` and `vello-cpu` in the [Blend2D benchmark harness](https://blend2d.com/performance.html), a comprehensive benchmarking tool that tests the performance of different parts of a 2D renderer and compares it against other renderers. In order to do so, a [fork](https://github.com/LaurenzV/blend2d-apps/tree/benching) of the benchmark harness was created that uses C bindings to both libraries to include them in the harness. To visualize the results, we created a chart, similar to how it is available on the official Blend2D website. We do want to emphasize again that full credit for building this benchmark tool goes to the Blend2D team, and we merely extended it to also include `tiny-skia` and `vello-cpu`. + +- [vello#...][]: + +In order to get a better understanding of where we lie performance-wise, we included `tiny-skia` and `vello-cpu` in the [Blend2D benchmark harness](https://blend2d.com/performance.html), a comprehensive benchmarking tool that tests the performance of different parts of a 2D renderer and compares it against other renderers. +In order to do so, a [fork](https://github.com/LaurenzV/blend2d-apps/tree/benching) of the benchmark harness was created that uses C bindings to both libraries to include them in the harness. +To visualize the results, we created a chart, similar to how it is available on the official Blend2D website. +We do want to emphasize again that full credit for building this benchmark tool goes to the Blend2D team, and we merely extended it to also include `tiny-skia` and `vello-cpu`. The results can be viewed [here](https://laurenzv.github.io/vello_chart/), the source code for generating the charts is available [here](https://github.com/LaurenzV/vello_chart). Some things that should be noted here: + - Note that these are only preliminary results, and there are plans for making further improvements, especially for multi-threading. -- We currently do not support x86 SIMD, which is why they are currently not included in the chart. It should be noted that the [README](https://github.com/linebender/tiny-skia?tab=readme-ov-file#performance) of `tiny-skia` explicitly mentions that performance on ARM is worse than on x86, so we expect the performance gap to be smaller on x86. +- We currently do not support x86 SIMD, which is why they are currently not included in the chart. + It should be noted that the [README](https://github.com/linebender/tiny-skia?tab=readme-ov-file#performance) of `tiny-skia` explicitly mentions that performance on ARM is worse than on x86, so we expect the performance gap to be smaller on x86. Nevertheless, by looking at this chart, it is clear that `vello-cpu` has very impressive performance and on track to become the fastest CPU-based renderer in the Rust ecosystem! When taking all renderers into consideration, Blend2D is still the clear winner in terms of raw performance, but `vello-cpu` does end up taking the second place in many of the benchmarks and beating other renderers such as Skia and Cairo, especially as the size of the geometry gets larger. Similarly to Blend2D, `vello-cpu` also offers a multi-threaded rendering mode, which is especially effective when drawing larger geometries with curves or when using complex paints such as gradients or patterns. - -- [vello#...][]: - Our [working roadmap](https://docs.google.com/document/d/1ZquH-53j2OedTbgEKCJBKTh4WLE11UveM10mNdnVARY/edit?tab=t.0#heading=h.j3duh9pgdm94) outlines the planned timeline for work on the renderers into next year. An integration of Vello as the backend for Servo's canvas rendering has landed in (and also Vello CPU in ). From 9d179cf4e7952f5654d78db67c922557fa87eda0 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Fri, 1 Aug 2025 19:52:00 +0100 Subject: [PATCH 04/19] Add Vello section --- content/blog/2025-08-05-tmil-19/index.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index bf44fe17..109357a6 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -10,14 +10,22 @@ Linebender is an informal open-source organization working on various projects t Vello is our GPU vector renderer. It can draw large 2D scenes with high performance, using GPU compute shaders for most of the work. - -- [vello#...][]: +- [vello#785][]: Strokes with a width of zero are no longer treated as fills. +- [vello#908][]: Updates to wgpu 25 release. +- [vello#1093][]: Disabled runtime checks in shaders using wgpu's new `create_shader_module_trusted` API, by sagudev. This month's progress on the sparse strips renderers, a collaborative evolution of Vello, has been centered around adding support for NEON and WASM SIMD, as well as making further improvements to multi-threaded rendering. - -- [vello#...][]: +- [vello#1064][], [vello#1086][]: Image rendering in Vello Hybrid. +- [vello#1078][]: Rewrote Vello CPU to be more SIMD-friendly. +- [vello#1092][]: Adds support for SIMD flattening. +- [vello#1103][]: Optimises alpha coverage calculation in strip rendering. +- [vello#1105][]: Ignores paths containing NaN points, giving a warning. +- [vello#1122][]: Adds opacity layers to Vello Hybrid. +- [vello#1134][]: Reuses FlattenCtx for paths. +- [kurbo#427][]: Contains a new stroke expander with significant performance improvements. + In order to get a better understanding of where we lie performance-wise, we included `tiny-skia` and `vello-cpu` in the [Blend2D benchmark harness](https://blend2d.com/performance.html), a comprehensive benchmarking tool that tests the performance of different parts of a 2D renderer and compares it against other renderers. In order to do so, a [fork](https://github.com/LaurenzV/blend2d-apps/tree/benching) of the benchmark harness was created that uses C bindings to both libraries to include them in the harness. To visualize the results, we created a chart, similar to how it is available on the official Blend2D website. @@ -35,7 +43,7 @@ Nevertheless, by looking at this chart, it is clear that `vello-cpu` has very im Our [working roadmap](https://docs.google.com/document/d/1ZquH-53j2OedTbgEKCJBKTh4WLE11UveM10mNdnVARY/edit?tab=t.0#heading=h.j3duh9pgdm94) outlines the planned timeline for work on the renderers into next year. -An integration of Vello as the backend for Servo's canvas rendering has landed in (and also Vello CPU in ). +An integration of Vello as the backend for Servo's canvas rendering has landed in [servo#36821][] (and also Vello CPU in [servo#38282][]). From 8b5d98c9c7fd7d79fe619e3d46d40010c53fb33a Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Fri, 1 Aug 2025 19:52:19 +0100 Subject: [PATCH 05/19] Add Fearless SIMD section --- content/blog/2025-08-05-tmil-19/index.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index 109357a6..9dc048d4 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -45,11 +45,16 @@ Our [working roadmap](https://docs.google.com/document/d/1ZquH-53j2OedTbgEKCJBKT An integration of Vello as the backend for Servo's canvas rendering has landed in [servo#36821][] (and also Vello CPU in [servo#38282][]). - + ### Fearless SIMD -TODO: A new blurb here? + + +Fearless SIMD is our experimental SIMD infrastructure library, developed for Vello sparse strips. + +- [fearless_simd#24][], [fearless_simd#26][], [fearless_simd#27][]: Implement all WASM SIMD methods. + ## Masonry From 490d73616ef5ae09fff2fb3b52e9eb3c33edca23 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Fri, 1 Aug 2025 19:52:35 +0100 Subject: [PATCH 06/19] Add Anymore section --- content/blog/2025-08-05-tmil-19/index.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index 9dc048d4..9d0e29ae 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -84,10 +84,15 @@ Our work on Placehero, which is the working name for our Mastodon client example - [xilem#...][]: + + ## Anymore -We have factored a shared utility for use in both Xilem and Masonry... - +You might have noticed mentions of [Anymore](https://github.com/linebender/anymore) in both the Xilem and Masonry sections. +This is a new crate which we've created for the `AnyDebug` trait. +This allows creating dynamically typed values which can be inspected, making debugging downcasting failures much easier. +This crate is designed for stability, so that it can be used for interoperability between projects (without allocation). +We plan to release version 1.0 in early August. ## Parley From 4c28aa8fa9ab3fa9dd7eeacb5cf6660a312e213b Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Fri, 1 Aug 2025 19:52:50 +0100 Subject: [PATCH 07/19] Add Parley section --- content/blog/2025-08-05-tmil-19/index.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index 9d0e29ae..6b3417aa 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -99,7 +99,10 @@ We plan to release version 1.0 in early August. Parley is a text layout library. It handles text layout, mostly at the level of line breaking and resolving glyph positions. -- [parley#...][]: +- [parley#378][]: Reimplements the fontconfig backend using FFI, improving font matching. +- [parley#378][]: Implements shift-click selection extension, by kekelp. +- [parley#389][]: Renames variants to more closely match CSS. +- [parley#395][]: Adds a method to unregister a loaded font. From 3ad9fdca858c50b026e366e5e85f49dbc25a824d Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Mon, 4 Aug 2025 18:50:03 +0100 Subject: [PATCH 08/19] Add first pass at Xilem/Masonry sections --- content/blog/2025-08-05-tmil-19/index.md | 30 ++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index 6b3417aa..7fae296b 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -61,8 +61,27 @@ Fearless SIMD is our experimental SIMD infrastructure library, developed for Vel Masonry is the widget system developed by Linebender. It provides a non-opinionated retained widget tree, designed as a base layer for high-level GUI frameworks. -- [xilem#...][]: - + +- [xilem#1077][]: Added the accessibility integration for VirtualScroll. +- [xilem#1096][]: Improved the default styles in Masonry, by Marco Melorio. +- [xilem#1124][]: Make Checkbox support keyboard interaction, by tannal. +- [xilem#1130][]: Rename `Textbox` to `TextInput`. +- [xilem#1163][]: Make text color controlled through properties. +- [xilem#1168][]: Add `IndexedStack` widget, by Kiran Wells. +- [xilem#1170][], [xilem#1178][]: Use [Anymore](#anymore) for all actions. +- [xilem#1189][]: Add the active status. +- [xilem#1200][]: Simplify both exclusive and immutable raw access to child widgets. +- [xilem#1212][]: Add a convenience associated type for the action type generated by each widget. +- [xilem#1213][]: Add a post_paint pass, designed for box shadows. +- [xilem#1215][]: Create a `NewWidget` type, which encapsulates the metadata associated with new widgets. +- [xilem#1223][]: Add cache to avoid relayouts when constraints haven't changed. +- [xilem#1237][]: Add rudimentary clipboard support. +- [xilem#1239][]: Add pixel snapping to layout pass. +- [xilem#1246][]: Use properties in `ProgressBar`, by Pufferfish. +- [xilem#1248][]: Make all widget associated properties be stored in the same arena. +- [xilem#1253][]: Let Masonry's button have any, by Nixon. + + +- [xilem#1117][], [xilem#1122][]: Make `DynMessage` not require `Send`, and remove the `Message` generic from View. +- [xilem#1142][]: Add an environment system. +- [xilem#1170][]: Use [Anymore](#anymore) for messages. +- [xilem#1220][], [xilem#1256][]: Use the environment system for avatars in Placehero. +- [xilem#1257][]: Avoid per-frame potential allocations in views with multiple children (i.e. Flex, Grid). From 6bf3953aa74f793f2d84db5e7bded387ba87b3ef Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Mon, 4 Aug 2025 11:23:17 -0700 Subject: [PATCH 09/19] Add Raph job change section --- content/blog/2025-08-05-tmil-19/index.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index 7fae296b..cf7d4069 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -128,6 +128,16 @@ It handles text layout, mostly at the level of line breaking and resolving glyph +## Raph's job change + +Raph Levien has decided to take a voluntary exit offer from Google. +He is very grateful for the opportunity and the support from Google Fonts of Linebender and Rust UI projects. +His last day there will be October 12. +He has a new gig lined up, as well – he plans to join Canva in January, working on rendering and Rust. +That also involves a move to Australia, an exciting new adventure. +Through all the changes, he intends to continue his work on Linebender and Rust UI, though towards the end of the year he will be taking things a bit easy. +The timing of office hours will also need to change, to accommodate the time zone; more updates will be forthcoming. + ## Get Involved We welcome collaboration on any of our crates. From 75a843cb9272c9bad1b043f7888f5b719d52ce4d Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 5 Aug 2025 10:59:27 +0100 Subject: [PATCH 10/19] Link to Vello tracking issue in Servo --- content/blog/2025-08-05-tmil-19/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index cf7d4069..1ca1fec6 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -44,6 +44,7 @@ Nevertheless, by looking at this chart, it is clear that `vello-cpu` has very im Our [working roadmap](https://docs.google.com/document/d/1ZquH-53j2OedTbgEKCJBKTh4WLE11UveM10mNdnVARY/edit?tab=t.0#heading=h.j3duh9pgdm94) outlines the planned timeline for work on the renderers into next year. An integration of Vello as the backend for Servo's canvas rendering has landed in [servo#36821][] (and also Vello CPU in [servo#38282][]). +You can follow this work at [servo#38345][]. From 2ce64ad8a1069bdb621d835a46f47aa875a9a0ae Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 5 Aug 2025 11:40:16 +0100 Subject: [PATCH 11/19] Add section on Fearless SIMD --- content/blog/2025-08-05-tmil-19/index.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index 1ca1fec6..4659ed41 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -50,12 +50,15 @@ You can follow this work at [servo#38345][]. ### Fearless SIMD - - -Fearless SIMD is our experimental SIMD infrastructure library, developed for Vello sparse strips. +Fearless SIMD is our SIMD infrastructure library. +We are developing it in concert with the Vello sparse strips renderers, particularly `vello_cpu`. + +To support the significant Vello CPU refactor using SIMD, this month saw the addition of more methods implemented in both Neon and WebAssembly. +Thanks to new contributions from Benjamin Saunders we've started on SSE 4.2 support for `x86` architectures. - [fearless_simd#24][], [fearless_simd#26][], [fearless_simd#27][]: Implement all WASM SIMD methods. - +- [fearless_simd#31][]: Introduce semantic conversion traits, by Benjamin Saunders. +- [fearless_simd#42][] (not yet merged): SSE 4.2 support, by Benjamin Saunders. ## Masonry From d21a1d4d1bc7f2fb078581b9e9faf1f6367ceaf6 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 5 Aug 2025 11:44:32 +0100 Subject: [PATCH 12/19] Add Laurenz as co-author --- content/blog/2025-08-05-tmil-19/index.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index 4659ed41..4a682fa4 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -1,6 +1,6 @@ +++ title = "Linebender in July 2025" -authors = ["Daniel McNab"] +authors = ["Daniel McNab", " Laurenz Stampfl"] +++ Linebender is an informal open-source organization working on various projects to advance the state of the art in GUI for [the Rust programming language](https://rust-lang.org). @@ -130,8 +130,6 @@ It handles text layout, mostly at the level of line breaking and resolving glyph - [parley#389][]: Renames variants to more closely match CSS. - [parley#395][]: Adds a method to unregister a loaded font. - - ## Raph's job change Raph Levien has decided to take a voluntary exit offer from Google. From c405111dcebc384b1078e162d788c8aa2475e65d Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 5 Aug 2025 14:02:52 +0100 Subject: [PATCH 13/19] Misc cleanups --- content/blog/2025-08-05-tmil-19/index.md | 27 +++++++++--------- .../2025-08-05-tmil-19/masonry_new_style.png | Bin 0 -> 12770 bytes 2 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 content/blog/2025-08-05-tmil-19/masonry_new_style.png diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index 4a682fa4..2af3dbc3 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -10,8 +10,8 @@ Linebender is an informal open-source organization working on various projects t Vello is our GPU vector renderer. It can draw large 2D scenes with high performance, using GPU compute shaders for most of the work. -- [vello#785][]: Strokes with a width of zero are no longer treated as fills. -- [vello#908][]: Updates to wgpu 25 release. +- [vello#785][]: Fixed strokes with a width of zero being treated as fills. +- [vello#908][]: Updated to wgpu version 25. - [vello#1093][]: Disabled runtime checks in shaders using wgpu's new `create_shader_module_trusted` API, by sagudev. This month's progress on the sparse strips renderers, a collaborative evolution of Vello, has been centered around adding support for NEON and WASM SIMD, as well as making further improvements to multi-threaded rendering. @@ -25,6 +25,13 @@ This month's progress on the sparse strips renderers, a collaborative evolution - [vello#1134][]: Reuses FlattenCtx for paths. - [kurbo#427][]: Contains a new stroke expander with significant performance improvements. +Our [working roadmap](https://docs.google.com/document/d/1ZquH-53j2OedTbgEKCJBKTh4WLE11UveM10mNdnVARY/edit?tab=t.0#heading=h.j3duh9pgdm94) outlines the planned timeline for work on the renderers into next year. + +An integration of Vello as the backend for Servo's canvas rendering has landed in [servo#36821][] (and also Vello CPU in [servo#38282][]). +You can follow this work at [servo#38345][]. + +### Benchmarking + In order to get a better understanding of where we lie performance-wise, we included `tiny-skia` and `vello-cpu` in the [Blend2D benchmark harness](https://blend2d.com/performance.html), a comprehensive benchmarking tool that tests the performance of different parts of a 2D renderer and compares it against other renderers. In order to do so, a [fork](https://github.com/LaurenzV/blend2d-apps/tree/benching) of the benchmark harness was created that uses C bindings to both libraries to include them in the harness. @@ -41,13 +48,6 @@ Some things that should be noted here: Nevertheless, by looking at this chart, it is clear that `vello-cpu` has very impressive performance and on track to become the fastest CPU-based renderer in the Rust ecosystem! When taking all renderers into consideration, Blend2D is still the clear winner in terms of raw performance, but `vello-cpu` does end up taking the second place in many of the benchmarks and beating other renderers such as Skia and Cairo, especially as the size of the geometry gets larger. Similarly to Blend2D, `vello-cpu` also offers a multi-threaded rendering mode, which is especially effective when drawing larger geometries with curves or when using complex paints such as gradients or patterns. -Our [working roadmap](https://docs.google.com/document/d/1ZquH-53j2OedTbgEKCJBKTh4WLE11UveM10mNdnVARY/edit?tab=t.0#heading=h.j3duh9pgdm94) outlines the planned timeline for work on the renderers into next year. - -An integration of Vello as the backend for Servo's canvas rendering has landed in [servo#36821][] (and also Vello CPU in [servo#38282][]). -You can follow this work at [servo#38345][]. - - - ### Fearless SIMD Fearless SIMD is our SIMD infrastructure library. @@ -87,16 +87,17 @@ It provides a non-opinionated retained widget tree, designed as a base layer for - + ## Xilem diff --git a/content/blog/2025-08-05-tmil-19/masonry_new_style.png b/content/blog/2025-08-05-tmil-19/masonry_new_style.png new file mode 100644 index 0000000000000000000000000000000000000000..8e4dad48f6d0e2c13022efbfc46decda4d8a5785 GIT binary patch literal 12770 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 JOxz^ke*oB=>(&4O literal 0 HcmV?d00001 From f54368bdeee2145a25feeb716e1de7131adb8b3c Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 5 Aug 2025 16:11:17 +0100 Subject: [PATCH 14/19] Cleanup section on benchmarking --- content/blog/2025-08-05-tmil-19/index.md | 79 +++++++++++++++++++----- 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index 2af3dbc3..116c72a7 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -32,21 +32,61 @@ You can follow this work at [servo#38345][]. ### Benchmarking - -In order to get a better understanding of where we lie performance-wise, we included `tiny-skia` and `vello-cpu` in the [Blend2D benchmark harness](https://blend2d.com/performance.html), a comprehensive benchmarking tool that tests the performance of different parts of a 2D renderer and compares it against other renderers. -In order to do so, a [fork](https://github.com/LaurenzV/blend2d-apps/tree/benching) of the benchmark harness was created that uses C bindings to both libraries to include them in the harness. -To visualize the results, we created a chart, similar to how it is available on the official Blend2D website. -We do want to emphasize again that full credit for building this benchmark tool goes to the Blend2D team, and we merely extended it to also include `tiny-skia` and `vello-cpu`. - -The results can be viewed [here](https://laurenzv.github.io/vello_chart/), the source code for generating the charts is available [here](https://github.com/LaurenzV/vello_chart). +We have performed some benchmarking to understand where Vello CPU's performance lies in the available 2d renderers. +We did this by creating [a fork of the Blend2D benchmark harness](https://github.com/LaurenzV/blend2d-apps/tree/benching) with the addition of Vello CPU. +We also added Tiny Skia, which is also stewarded by Linebender and is another popular renderer written in Rust. +You can read more about the benchmark methodology on [Blend2D's performance page](https://blend2d.com/performance.html). +We wish to thank the Blend2D team for creating this excellent suite of tests. + + + + +The [benchmark results page](https://laurenzv.github.io/vello_chart/) shows the results of running this suite on an Apple M1 Pro. +This shows the results for Blend2D, Agg, Tiny Skia, Vello CPU, Cairo, Skia, and JUCE. +The source for this results page is available on GitHub at . Some things that should be noted here: -- Note that these are only preliminary results, and there are plans for making further improvements, especially for multi-threading. -- We currently do not support x86 SIMD, which is why they are currently not included in the chart. - It should be noted that the [README](https://github.com/linebender/tiny-skia?tab=readme-ov-file#performance) of `tiny-skia` explicitly mentions that performance on ARM is worse than on x86, so we expect the performance gap to be smaller on x86. +- Vello CPU is still under active development, so these are only preliminary results. +- We currently do not support x86-64 SIMD, which is why these charts currently only show an ARM machine. + As noted below, we're actively working on x86-64 support. +- Tiny Skia's relative performance [is documented](https://github.com/linebender/tiny-skia?tab=readme-ov-file#performance) to be worse on ARM than on x86-64. + We therefore expect the performance gap between Vello CPU and Tiny Skia to be smaller on x86-64. -Nevertheless, by looking at this chart, it is clear that `vello-cpu` has very impressive performance and on track to become the fastest CPU-based renderer in the Rust ecosystem! When taking all renderers into consideration, Blend2D is still the clear winner in terms of raw performance, but `vello-cpu` does end up taking the second place in many of the benchmarks and beating other renderers such as Skia and Cairo, especially as the size of the geometry gets larger. Similarly to Blend2D, `vello-cpu` also offers a multi-threaded rendering mode, which is especially effective when drawing larger geometries with curves or when using complex paints such as gradients or patterns. +It is clear that `vello-cpu` has very impressive performance and on track to become the fastest CPU-only renderer in the Rust ecosystem! +Blend2D is still the clear winner in these tests, but `vello-cpu` takes second place in many of the benchmarks, beating other mature renderers such as Skia and Cairo. +This is especially the case as the size of the geometry gets larger. +Blend2D and `vello-cpu` both offer multi-threaded rendering modes (marked by the 2T/4T/8T suffices, as opposed to ST for single threaded). +Vello CPU's multithreading is especially effective when drawing larger geometries with curves or when using complex paints such as gradients or patterns. ### Fearless SIMD @@ -65,7 +105,7 @@ Thanks to new contributions from Benjamin Saunders we've started on SSE 4.2 supp Masonry is the widget system developed by Linebender. It provides a non-opinionated retained widget tree, designed as a base layer for high-level GUI frameworks. - + - [xilem#1077][]: Added the accessibility integration for VirtualScroll. - [xilem#1096][]: Improved the default styles in Masonry, by Marco Melorio. - [xilem#1124][]: Make Checkbox support keyboard interaction, by tannal. @@ -85,8 +125,6 @@ It provides a non-opinionated retained widget tree, designed as a base layer for - [xilem#1248][]: Make all widget associated properties be stored in the same arena. - [xilem#1253][]: Let Masonry's button have any, by Nixon. - -
A todo list app, with items referring to aspects of the new design language, namely 'New Colours', 'Increased Consistency', and 'More Rounded Corners'. The item labelled 'A full design system' is unchecked. @@ -111,7 +149,18 @@ Our work on Placehero, which is the working name for our Mastodon client example - [xilem#1220][], [xilem#1256][]: Use the environment system for avatars in Placehero. - [xilem#1257][]: Avoid per-frame potential allocations in views with multiple children (i.e. Flex, Grid). - +
+ + + + +
+ +For July, we would like to showcase this Chess GUI developed using Xilem by Dr. Salewski. +It can be found in its repository at . + +
+
## Anymore From d3e41004560fc05b73580185e4bc2902b26d8b37 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 5 Aug 2025 16:26:38 +0100 Subject: [PATCH 15/19] Add Chess GUI image --- content/blog/2025-08-05-tmil-19/index.md | 5 ++--- content/blog/2025-08-05-tmil-19/xilem_chess.png | Bin 0 -> 71789 bytes 2 files changed, 2 insertions(+), 3 deletions(-) create mode 100644 content/blog/2025-08-05-tmil-19/xilem_chess.png diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index 116c72a7..e2586aa0 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -83,7 +83,7 @@ Some things that should be noted here: We therefore expect the performance gap between Vello CPU and Tiny Skia to be smaller on x86-64. It is clear that `vello-cpu` has very impressive performance and on track to become the fastest CPU-only renderer in the Rust ecosystem! -Blend2D is still the clear winner in these tests, but `vello-cpu` takes second place in many of the benchmarks, beating other mature renderers such as Skia and Cairo. +Blend2D is still the clear winner in these tests, but `vello-cpu` takes second place in many of the benchmarks, often beating other mature renderers such as Skia and Cairo. This is especially the case as the size of the geometry gets larger. Blend2D and `vello-cpu` both offer multi-threaded rendering modes (marked by the 2T/4T/8T suffices, as opposed to ST for single threaded). Vello CPU's multithreading is especially effective when drawing larger geometries with curves or when using complex paints such as gradients or patterns. @@ -151,8 +151,7 @@ Our work on Placehero, which is the working name for our Mastodon client example
- - +A chess board, with several controls to the left. The white queen is highlighted, and all its valid moves are also highlighted.
diff --git a/content/blog/2025-08-05-tmil-19/xilem_chess.png b/content/blog/2025-08-05-tmil-19/xilem_chess.png new file mode 100644 index 0000000000000000000000000000000000000000..4b583bc861dc3d8d965731036b74d16e32e3ae79 GIT binary patch literal 71789 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 Date: Tue, 5 Aug 2025 16:29:32 +0100 Subject: [PATCH 16/19] Fixup links --- content/blog/2025-08-05-tmil-19/index.md | 55 +++++++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index e2586aa0..fb4d7f71 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -201,5 +201,56 @@ See [#office hours in Zulip](https://xi.zulipchat.com/#narrow/channel/359642-off If you wish to discuss the Linebender project individually, Daniel is offering ["office hours" appointments](https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ32eQYJ9DtZ_wJaYNtT36YioETiloZDIdImFpBFRo5-XsqGzpikgkg47LPsiHhpiwiQ1orOwwW2), which are free to book. It really helps us to learn what aspects our users care about the most. - +[vello#1064]: https://github.com/linebender/vello/pull/1064 +[vello#1078]: https://github.com/linebender/vello/pull/1078 +[vello#1086]: https://github.com/linebender/vello/pull/1086 +[vello#1092]: https://github.com/linebender/vello/pull/1092 +[vello#1093]: https://github.com/linebender/vello/pull/1093 +[vello#1103]: https://github.com/linebender/vello/pull/1103 +[vello#1105]: https://github.com/linebender/vello/pull/1105 +[vello#1122]: https://github.com/linebender/vello/pull/1122 +[vello#1134]: https://github.com/linebender/vello/pull/1134 +[vello#785]: https://github.com/linebender/vello/pull/785 +[vello#908]: https://github.com/linebender/vello/pull/908 + +[kurbo#427]: https://github.com/linebender/kurbo/pull/427 + +[servo#36821]: https://github.com/servo/servo/pull/36821 +[servo#38282]: https://github.com/servo/servo/pull/38282 +[servo#38345]: https://github.com/servo/servo/pull/38345 + +[fearless_simd#24]: https://github.com/linebender/fearless_simd/pull/24 +[fearless_simd#26]: https://github.com/linebender/fearless_simd/pull/26 +[fearless_simd#27]: https://github.com/linebender/fearless_simd/pull/27 +[fearless_simd#31]: https://github.com/linebender/fearless_simd/pull/31 +[fearless_simd#42]: https://github.com/linebender/fearless_simd/pull/42 + +[parley#378]: https://github.com/linebender/parley/pull/378 +[parley#389]: https://github.com/linebender/parley/pull/389 +[parley#395]: https://github.com/linebender/parley/pull/395 + +[xilem#1077]: https://github.com/linebender/xilem/pull/1077 +[xilem#1096]: https://github.com/linebender/xilem/pull/1096 +[xilem#1117]: https://github.com/linebender/xilem/pull/1117 +[xilem#1122]: https://github.com/linebender/xilem/pull/1122 +[xilem#1124]: https://github.com/linebender/xilem/pull/1124 +[xilem#1130]: https://github.com/linebender/xilem/pull/1130 +[xilem#1142]: https://github.com/linebender/xilem/pull/1142 +[xilem#1163]: https://github.com/linebender/xilem/pull/1163 +[xilem#1168]: https://github.com/linebender/xilem/pull/1168 +[xilem#1170]: https://github.com/linebender/xilem/pull/1170 +[xilem#1178]: https://github.com/linebender/xilem/pull/1178 +[xilem#1189]: https://github.com/linebender/xilem/pull/1189 +[xilem#1200]: https://github.com/linebender/xilem/pull/1200 +[xilem#1212]: https://github.com/linebender/xilem/pull/1212 +[xilem#1213]: https://github.com/linebender/xilem/pull/1213 +[xilem#1215]: https://github.com/linebender/xilem/pull/1215 +[xilem#1220]: https://github.com/linebender/xilem/pull/1220 +[xilem#1223]: https://github.com/linebender/xilem/pull/1223 +[xilem#1237]: https://github.com/linebender/xilem/pull/1237 +[xilem#1239]: https://github.com/linebender/xilem/pull/1239 +[xilem#1246]: https://github.com/linebender/xilem/pull/1246 +[xilem#1248]: https://github.com/linebender/xilem/pull/1248 +[xilem#1253]: https://github.com/linebender/xilem/pull/1253 +[xilem#1256]: https://github.com/linebender/xilem/pull/1256 +[xilem#1257]: https://github.com/linebender/xilem/pull/1257 From 06783265895fdf56f98d4f47f6356886fa41eca4 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Wed, 6 Aug 2025 09:53:26 +0100 Subject: [PATCH 17/19] Fix plural --- content/blog/2025-08-05-tmil-19/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index fb4d7f71..646130ab 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -85,7 +85,7 @@ Some things that should be noted here: It is clear that `vello-cpu` has very impressive performance and on track to become the fastest CPU-only renderer in the Rust ecosystem! Blend2D is still the clear winner in these tests, but `vello-cpu` takes second place in many of the benchmarks, often beating other mature renderers such as Skia and Cairo. This is especially the case as the size of the geometry gets larger. -Blend2D and `vello-cpu` both offer multi-threaded rendering modes (marked by the 2T/4T/8T suffices, as opposed to ST for single threaded). +Blend2D and `vello-cpu` both offer multi-threaded rendering modes (marked by the 2T/4T/8T suffixes, as opposed to ST for single threaded). Vello CPU's multithreading is especially effective when drawing larger geometries with curves or when using complex paints such as gradients or patterns. ### Fearless SIMD From 4286feaccbad17e26481590e5d6517e9a34b937c Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Wed, 6 Aug 2025 11:26:30 -0700 Subject: [PATCH 18/19] Add kurbo section --- content/blog/2025-08-05-tmil-19/index.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-05-tmil-19/index.md index 646130ab..6a72897c 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-05-tmil-19/index.md @@ -179,6 +179,13 @@ It handles text layout, mostly at the level of line breaking and resolving glyph - [parley#389][]: Renames variants to more closely match CSS. - [parley#395][]: Adds a method to unregister a loaded font. +## Kurbo + +We released [Kurbo 0.11.3][], with some ergonomics and performance improvements, calculation of moments using Green's theorem, and other methods. + +As mentioned in teh Vello section, the new, faster stroke expansion logic ([kurbo#427][]) has landed in main. +This will be in the upcoming 0.12 release, which is semver-breaking because of changes to the API to reduce memory allocation. + ## Raph's job change Raph Levien has decided to take a voluntary exit offer from Google. @@ -254,3 +261,5 @@ It really helps us to learn what aspects our users care about the most. [xilem#1253]: https://github.com/linebender/xilem/pull/1253 [xilem#1256]: https://github.com/linebender/xilem/pull/1256 [xilem#1257]: https://github.com/linebender/xilem/pull/1257 + +[Kurbo 0.11.3]: https://github.com/linebender/kurbo/releases/tag/v0.11.3 From 28ccf211f16a2dd415ce434bc16cd1a4cb3bc00f Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Wed, 6 Aug 2025 11:53:02 -0700 Subject: [PATCH 19/19] Fix typo, update date --- .../index.md | 2 +- .../masonry_new_style.png | Bin .../xilem_chess.png | Bin 3 files changed, 1 insertion(+), 1 deletion(-) rename content/blog/{2025-08-05-tmil-19 => 2025-08-06-tmil-19}/index.md (99%) rename content/blog/{2025-08-05-tmil-19 => 2025-08-06-tmil-19}/masonry_new_style.png (100%) rename content/blog/{2025-08-05-tmil-19 => 2025-08-06-tmil-19}/xilem_chess.png (100%) diff --git a/content/blog/2025-08-05-tmil-19/index.md b/content/blog/2025-08-06-tmil-19/index.md similarity index 99% rename from content/blog/2025-08-05-tmil-19/index.md rename to content/blog/2025-08-06-tmil-19/index.md index 6a72897c..5ea1cc7f 100644 --- a/content/blog/2025-08-05-tmil-19/index.md +++ b/content/blog/2025-08-06-tmil-19/index.md @@ -183,7 +183,7 @@ It handles text layout, mostly at the level of line breaking and resolving glyph We released [Kurbo 0.11.3][], with some ergonomics and performance improvements, calculation of moments using Green's theorem, and other methods. -As mentioned in teh Vello section, the new, faster stroke expansion logic ([kurbo#427][]) has landed in main. +As mentioned in the Vello section, the new, faster stroke expansion logic ([kurbo#427][]) has landed in main. This will be in the upcoming 0.12 release, which is semver-breaking because of changes to the API to reduce memory allocation. ## Raph's job change diff --git a/content/blog/2025-08-05-tmil-19/masonry_new_style.png b/content/blog/2025-08-06-tmil-19/masonry_new_style.png similarity index 100% rename from content/blog/2025-08-05-tmil-19/masonry_new_style.png rename to content/blog/2025-08-06-tmil-19/masonry_new_style.png diff --git a/content/blog/2025-08-05-tmil-19/xilem_chess.png b/content/blog/2025-08-06-tmil-19/xilem_chess.png similarity index 100% rename from content/blog/2025-08-05-tmil-19/xilem_chess.png rename to content/blog/2025-08-06-tmil-19/xilem_chess.png