Comment by Animats
6 months ago
I use Egui, in a game-type application.
I'm a bit concerned with Egui gaining in popularity for general purpose GUI applications. It's leading to feature bloat, and probably more overhead. The stated goal originally was that Egui should use less than 1% of main thread frame time.
Originally, Egui was completely one pass. The API looks more general than that; you can align things against the bottom or right, and get things above or to the left to adjust. But originally, that didn't work. You pretty much had to lay out widgets down and to the right. This is fast and simple. Lots of stuff didn't work, such as scrolling text boxes with line wrap.
But users doing ordinary GUI work are demanding more and more layout features, and won't stop until they get browser level layout. Overhead is increasing.[1] This is a problem in Rust game land, which is tiny. At some point, someone may need to fork Egui and create Egui-lite.
Not a rust developer, but this seems like an opportunity for Egui to have switchable layout engines.
If you want a simple, one pass layout that super fast, you use the fast-and-dumb-on-purpose-engine. If you want a fancy dynamic scaling layout with breakpoints and blah blah blah, you use the whole-damn-browser-engine.
Thinking along the lines of geometry managers in Tk. Or wxWidgets Sizers.
https://wiki.tcl-lang.org/page/Geometry+Managers
Maybe I am missing something basic and this won't work/doesn't address the problem.
But maybe there's good prior art to learn from here.
While I agree that the maintainers of any project have to know when to say no.
If your UI lib is not doing scrolling text boxes with line wrap, can't have different alignments, doesn't have a solution for context menus, then what good is it?
I remember that I essentially had to code it myself a few years ago, but I can't remember if it was egui or imgui.
Hmm. It seems to me that one of the features of an immediate mode library is that if you don't call something, you won't suffer overhead consequences. If you aren't trying to align things in a manner that triggers the two-pass rendering, then you shouldn't be affected by the associated performance hit.
I guess you worry that the feature creep dilutes the maintainers' focus, but opening it up to a broader audience might get access to more contributors.
> I guess you worry that the feature creep dilutes the maintainers' focus, but opening it up to a broader audience might get access to more contributors.
To some extent, yes. Here's an example.[1] So many features have been added that the unit tests were taking too long. So tests were switched to use a faster allocator. That won't even compile for cross-compilation from Linux to Windows.
Because tests won't run, chasing down other cross-compilation bugs got much harder.[2]
This is the price of feature bloat. Core stuff is breaking and not getting fixed as cool features are bolted on. Currently, 799 open bugs. The technical debt is building up.
[1] https://github.com/emilk/egui/issues/7033
[2] https://github.com/emilk/egui/issues/6847
It reminds me a little bit of the inescapable lifecycle of a ticketing system:
2 replies →
Two-pass rendering was considered and rejected by the Egui developer. What they have is sort of one and a half pass rendering. Sometimes, things are wrong on the first draw, but correct on the next draw because info is retained from the previous frame.
Back in 2023, this created a bug where a text box was misaligned on alternate frames.[1] Amusingly, I tried to capture a video of this, and the 30 FPS video looked perfect, because it was capturing only alternate frames of 60 FPS refresh.
Bugs in layout can be very strange in Egui.
[1] https://github.com/emilk/egui/issues/2810
I don't see how the bug you linked is relevant? It's a bug that will be presumably fixed; not an increase in overhead due to layout.
Did you just search for bugs containing "CPU usage" and not actually read it?
> Originally, Egui was completely one pass.
Originally HTML was one-pass. Until they added tables. And tables require at least two passes to lay out.
There's only so far that you can take one pass rendering
> There's only so far that you can take one pass rendering
Right. The whole point of Egui was supposed to be that it was a game renderer, a text and button overlay on the game graphics. Not the entire screen. That's why it's immediate mode. It's supposed to redraw on every game frame. Most UI programs don't need or want that.
But it was better at the basics than anything else in Rust, so it caught on for routine non-game programs. And here we are.
> But it was better at the basics than anything else in Rust, so it caught on for routine non-game programs. And here we are.
Seriously. The main tale I think is how awful Rust's story on GUIs are such that most Rust users prefer a pretty awful GUI library because it's somehow better than everything else. And that's coming from someone who's favorite language is easily Rust.
Consider me ignorant: why do you need two passes for table layout?
In a HTML table, unless given a fixed width, the width of each column depends on the natural widths of all the columns, and those widths depend on the content of every cell in the column, and those cell natural widths depend on word-wrapped layout as well as other layout of content in each cell, including nested tables recursively.
In other words, with default styling you have to calculate natural widths of every cell in the whole table before you can begjn layout out even the first cell of the table.
There are style settings you can use which change this, and allow layout of early cells or rows to complete without depending on later cells.
(Also the height of each row can depend on the height of the content of every cell in the row. But that's local to each row so it's a relatively small dependency.)