Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Qt Widgets Rendering Pipeline (felipefarinon.com)
77 points by coffeeaddict1 on Dec 15, 2023 | hide | past | favorite | 54 comments


I know QT is a very successful graphics library that works incredibly well, so clearly they’re on their game.

However.

I’m puzzled that a software rasteriser can possibly be performant enough for modern UI applications.

If you compare it with other sophisticated UI stacks for example, WPF or chrome (1), you can see a detailed and well considered use of GPU acceleration.

Does qt not do this too? I’m very surprised.

[1] - https://www.chromium.org/developers/design-documents/gpu-acc...


Qt itself has a few "graphical frameworks" to do the rendering.

QWidgets is what you're referring to. That's what is used to build traditional desktop applications and is rendered using software by default.

QML/QtQuick is their GPU accelerated scenegraph: https://doc.qt.io/qt-6/qtquick-index.html . It is mostly used in mobile/embedded systems, but they do have desktop components too.


> It is mostly used in mobile/embedded systems, but they do have desktop components too.

This is misleading. QML was supposed to be the successor of QWidgets. Many big apps use it just fine on the desktop. Sadly many Qt dev themselves (just look at the QtCreator code, do you see any commits using QML there?) do not like QML and so it never really replaced QWigets. Now we have a community that is essentially split and every party cries if one gets more updates then the other. QML still has things like TrayIcon support as a unstable labs preview module, after nearly 10 years. Yes I'm a full time Qt/QML developer and I'm salty about this :*)


For a desktop application widgets are better than QML. QML brings things to your UI that a desktop application shouldn't use. QML is the right way to do phone applications, but there are good user interface reasons to not use most of the features QML gives you on desktop applications, but to use those features on phone applications.

Not that you cannot build good desktop applications with QML, but there will be a lot more work for questionable gain.


Please give me a single reason what QWidgets does have that qml doesn't, from a user perspective.

> lot more work

I would argue the opposite. Show me a none buggy QWidgets application that features nested collapsing menus, with animations. That being said, you can still create a modern app with fancy animations in QWidgets. The beautiful Telegram QtWidgets desktop app is the best example, it's just more work....


That you cannot do those animations is a feature! Animations are useful in places, but they also make for hard to use user interfaces. Widgets where designed in a world where user interface experts sat real humans down behind on-way mirrors and watched how they used applications: those experts had long learned fancy animations look great but typically result in it being harder to use user interfaces.


Exactly, whenever I see an animation on my desktop I instantly loose 20% confidence in the app


I don't have a lot of experience with Qt but recently was exploring both QtWidgets and QtQuick as options for simple desktop UI.

QtWidgets made creating forms massively easier thanks to QFormLayout and drag and drop designer.

There was nothing similar in QtQuick - Grid and Qt Design Studio were absolutely horrible for this.


The point of QWidgets is not to create a "modern app with fancy animations", that's what QML is better suited for. It can still be done, QWidgets supports theming and all that, but that's not what it does best.

QWidgets is for making well integrated, "boring" desktop apps. For nested menus, or any menu for that matter, use QMenu. If your OS is fully supported by Qt and the standard system behavior is to animate the menu, it will be animated in your app.


I will say that the KDE system settings application uses QML for its sidebar and it behaves terribly when resizing the window (takes around a second to resolve the layout after resizing). I haven't seen the same behavior with QWidgets programs.


> Please give me a single reason what QWidgets does have that qml doesn't, from a user perspective.

QWidgets gives you widgets that look like they're desktop widgets, QML gives you a white rectangle.



That looks worse than widgets.


Why do you NEED animations though? That has never been an important feature for users.


"modern app with fancy animations" is not a good desktop app, is the point. You're assuming a requirement of things that people simply don't want.

>Sadly many Qt dev themselves...do not like QML and so it never really replaced QWigets

Says it all, doesn't it. I'm sure everyone's wrong and it's the un-liked framework that's correct, yes?


Does QML even have any system theme support? AFAIK its more of a replacement of web technologies than of QtWidgets.


Yes, nowadays QtQuick, the GUI library that is generally associated with the QML programming language, supports native styles: https://doc.qt.io/qt-6/qtquickcontrols-styles.html


Lacks a Microsoft Fluid style for Windows 11.


It's in the roadmap afaik, they talked about it during QtWS


Doesn't look like it supports either QtWidget styles or GTK styles, which are the platform styles on Linux.


I think in our modern age, a lot of people can be surprised at just how fast the CPU is relative to GPU. Slower, yes, but compiled SIMD-enabled CPU code is bloody fast. I've seen people on HN claiming "just put it on the GPU and be 10,000x faster"; I can only assume this comes from comparing interpreted Python code with compiled kernel code or something! Basic drawing code is highly likely to be memory-bandwidth-bound; Some napkin math shows e.g. a 4070 has about a 10x performance advantage over a Zen4 CPU (500gb/s vs 50).

Rant out of the way, obviously 10x faster is still an order of magnitude faster! I've continued to be curious if there's a way to properly batch geometry in the QT backend to remove all the state-changes that the QT painter is doing that kill performance; a powerfully GPU-accelerated backend for widget based apps would be incredibly useful, although given the dominance of web/electron apps these days not a useful feature for a commercial company to build.


There has been more and more “GPU chauvinism” over the past decade. For whatever reason many people have come to see the GPU architecture as the pinnacle of modern computing, seemingly unaware of its limitations. Although CPUs are boring in comparison, they most often don’t require special toolchains, shader languages, near and far memory, etc. Moreover, SIMD instruction sets like AVX-512 or SVE2 offer extremely impressive performance, often negating the need for a GPU altogether.

Of course this isn’t to be dismissive of GPUs, they are a welcome addition to the compute stack. But the humble CPU should not be underestimated.


We at https://lekh.app wrote our own tiny UI library in C++ to implement our canvas screen UI. Here is a screenshot https://i.imgur.com/gr1ernJ.png of the canvas screen. Lekh is a whiteboarding and diagramming app.

With a single codebase, we are running on iOS, Android and web. We do not have our own Rasterizer but we depend on the platform for that. We render in the main UI thread and performance wise we are fine on these three platforms.


What about text input? That's often where this kind of solution is lacking for more general-purpose use.

Does it support selection? Cut and paste? European languages? Chinese and Arabic? Hiding and showing the virtual keyboard as appropriate?


Text input is an exception. I mean, we used the platform text input instead of implementing our own. We have our own API for text input but under the hood it uses platform text input.


https://ossia.io uses widgets and qgraphicsscene for the main UI rendering and Qt rhi for the GPU pipeline, and it's performing well enough for our use-cases - I was working on it on a 1080p screen on a Pi4 recently and it certainly felt much much faster and responsive than chrome on the same hardware.


QT uses the GPL where it makes sense. However widgets on any platform mostly do not make sense to run on the GPU.


Cahier looks interesting! A research and note gathering tool.

https://getcahier.com/


Hi! I'm glad you found Cahier interesting. I use it on a daily basis.

I've been developing the tool for 10 months, and still haven't gone full public. There's still some things to iron out before that. But I hope to publish more about it in the coming weeks.


For anyone wondering why this is here, is because it's linked at the top of the article page.


I didn’t know AGG library this article is referring to. It seems to have a big legacy yet not much is known about the author.

https://en.wikipedia.org/wiki/Anti-Grain_Geometry


As I recall, he worked at 3D Pharmaceuticals on their ABCD project. The company was then bought by Johnson and Johnson. He later went to Wall Street. My knowledge comes indirectly through Dimitris Agrafiotis, who was the head of that project.

Google Scholar lists several papers with him as co-author, like the ABCD paper at https://pubs.acs.org/doi/pdf/10.1021/ci700267w which has "3DX supports these functions through a highly finessed UI and a superb rendering engine that delivers fast antialiased graphics with subpixel accuracy." citing "Shemanarev, M. The Anti-Grain Geometry Project. http://www.anti- grain.com (accessed June 1, 2006)."


Haiku OS also uses AGG for its interface kit.


Qt Widgets was a pleasure to work with. It's very well documented, well structured, and easy to extend with your own Widget classes.


Thanks for the interesting read. Your app Cahier looks cool! I'm developing a note-taking app[1] using Qt C++ and QML and love that combo. Creating complex UIs with animation is much more straightforward with QML and since the model is still on the C++ side and most Qt Quick components are compiled to C++ the performance is close to Qt Widgets.

[1] https://www.get-plume.com


I've been enjoying working with Qt as well. I'll start publishing more about Cahier in some weeks. I wish all the best for your project!


Thanks!


In your website, you say that your code is open source but I can't find a github repo. I would love to see how you did the text manipulation code.


Hi! Thanks for your interest. I've been doing some thinking in the last couple of days and decided to close source the code for Plume.[1] I'm going to update the website now. I've contributed here[2] for text selection between different blocks if you want to take a look.

Of course, you'll have to implement yourself editing between blocks, undo & redo, copy & paste, etc. For me, a big challenge was to synchronize between the state of underlying plain text and the rendered HTML since Qt's conversion is incredibly inconsistent, it requires some annoying small modifications each time.

BTW, there's a high chance I'll open source Plume in the future. I don't fully trust any non-open source app without a transparent build process. But only after I'm sure I figure out a sustainable monetization source.

[1] https://news.ycombinator.com/item?id=38584960

[2] https://github.com/shaan7/qtdevcon2022-textarea/pull/1


Oh Carl, I just noticed it is you! Haha. Thanks for your early support with Notes!


And the repo you pointed out is from a former colleague ;) the world is small


Haha, that's awesome.


> Widgets draw different types of graphical elements one after the other, changing states rapidly. Since OpenGL excels in rendering lots of data of the same type, but is slow when changing states, this created a performance penalty for Qt Widgets applications.

Why does this not hinder QML to be GPU-accelerated? (Or any other GPU-accelerated UI such as WPF, Flutter)


One reason is in QML/WPF you use data binding instead of directly setting widget state like in classic Qt.

Data binding allows the runtime to batch and consolidate changes.

Classic Qt also encourages a bad state handling programming style which is hard to optimize. Data binding fixes that and moves more of the responsibility to the framework.


Couldn't the rendering still be batched? In Swing, for example, onDraw is invoked whenever Swing feels like it (and so could presumably be batched) regardless of when and how often the component's state is updated.


All the drawing in QWidgets is done imperatively with QPainter. Converting immediate mode painting to retained mode painting is possible, I guess... but not easy and probably full of pitfalls. Also, performance is just fine (really good actually) in practice, at least on PC-class hardware. QPainter's backend is not quite as fast as Skia, but still fast.


I wish there was a multiplatform MIT alternative or ... Qt change its license prices... it is so expensive!


LGPL is perfectly usable IMO.


LGPL3 on embedded is...tricky.


Qt also puts a lot of money into paying developers to make it good. Developers are expensive.


>it is so expensive

That's how the product is made good.


At a glance, the rendering pipeline doesn’t seem too different than rendering on the web.


There's only so many ways to approach the impossible task of rendering text.

For one, I think Harfbuzz text shaping underlies Skia, QPainter, and every other text renderer?


Or any other ui toolkit.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: