4 ms·
> The problem with Cairo is that it's painfully slow. It really isn't though... it's just painfully easy to fall onto slow paths, and not obvious how not to. T
by awalton 9y ago
> The problem with Cairo is that it's painfully slow.
It really isn't though... it's just painfully easy to fall onto slow paths, and not obvious how not to. Time and again I've seen people stack benchmarks of cairo where they're only benchmarking the image surface; of course that's slow, it's CPU rendering! If your realtime graphics app is ever creating a new surface and it's not using cairo_surface_create_similar() or cairo_{xlib,xcb}_surface_create(), you've probably fucked up.
Nearly 100% of the time, when someone's fallen into a slow path using cairo, it's because they've managed to get cairo to copy something back from the graphics server, do some operations on the CPU, and then reupload back to the server. And surprise, that's very slow. After that, the majority of remaining slow cases are due to creating too many clipping regions (which is common in lots of complex rendering applications, but usually caught by the application developers themselves since Cairo's actually remarkably good at debugging these kinds of rendering issues with tools like the script surface and cairo-perf-trace).
Meanwhile, Firefox has managed to pretty much stamp out all of the rest of the actual painfully slow Cairo paths...
Part of this perceived slowness in Cairo is because the example code is pretty bleak and abysmal (just look at https://www.cairographics.org/documentation/ https://www.cairographics.org/documentation/ if you don't believe me), part of it is because everyone who used to maintain cairo (before they ran off and are now doing VR at Valve, or Wayland, or Tizen, or whatever) were Xorg developers and Xorg things were "so trivially obvious" to them that isn't trivially obvious to... basically everyone else, and part of it is because of "stack-overflow-itis" - "I'm just going to copy this example code because this guy got it working and I don't care to understand the mechanics of how/why it works/why it's slow in my code."
tl;dr: cairo's not slow, stop creating/rendering against image surfaces, use the perf tools to keep clear of bad application behaviors.
- yetihehe 9y agoYeah, I was actually surprised at how fast cairo can be. I had some ideas as to optimize things like prerender map markers into some tiles and then render those tiles, but it seems for my use case (rendering less than 10k small images on single surface) I didn't even need to optimise it, with 2k images I had over 40fps which felt more snappy than google maps, which was enough. Of course if someone needs something better, hw accelerated opengl is the way to go. Current processors are fast, but they have their limits.
- hawski 9y agoThere is cairo-gl. AFAIR it's still considered experimental, but good enough. I did not try it yet.
- bjourne 9y agoTypically condescending answer, "you fucked up." There are times when you absolutely DO want to use image surfaces, such as when you need raw access to the pixel data, or if you want to combine cairo rendering with something else. It was a looong while since I used cairo so I don't know if my information is correct, but at that time it was slow. The slowness originated in cairo's use of libpixman's not very well optimized functions for interpolation. I actually didn't just complain -- I wrote patches to libpixman to make it faster. They lingered on that stupid freedesktop.org site for a few years before being marked as WONTFIX. Back then, the project wasn't friendly to new contributors at all. But Federico is a very friendly and active developer so I'm sure the situation is much better nowadays.
- awalton 9y agoTypical hackernews half-off-topic reposte. Not even sure why I bother... > There are times when you absolutely DO want to use image surfaces, such as when you need raw access to the pixel data, or if you want to combine cairo rendering with something else. And at that point, you really can't complain about Cairo being slow, can you? You're not even doing vector graphics at this point, you're back in raster graphics territory. Cairo would have been a better library if the image surface was only public in debug builds, forcing developers to learn and understand the implications of using it or reinventing it yourself with some combination of calls that end in XGetImage or XPutImage which has plenty of neon lights around it reminding people that it's slow to do these operations. Literally any raster API that has to download the image from the server, change a pixel, and put the image back on the server is going to be slow. This is precisely why X extensions like Xdamage and Xrender exist to attempt to mitigate the damage by manipulating smaller image regions (less data to download/upload) and pushing operations server-side, and why X APIs like "XPutPixel" exist. But there are limits to just how good these things can ever be; they're going to be limited by GPU-to-main-memory bandwidth and CPU rendering speeds _always_. These raster problems are why UI toolkits have moved on to using OpenGL( ES) and Wayland and similar architectures on other OSes; OpenGL, despite its flaws, makes it very explicit when you're doing obviously slow things like download/modify/upload and has tools that make it easy to avoid the need to do these roundtrips, and Wayland doesn't know so much what a "pixel" is, just how to move buffers around and notionally where those buffers are in space - it's up to the compositor's implementation to figure out how to put together the actual images in buffers and put them on output devices. > It was a looong while since I used cairo so I don't know if my information is correct, And this seems to be the recurring problem... everyone's moved on, cairo's now "infrastructure", nobody gives a damn about infrastructure until it's crumbling, and then it's hard to find anyone to devote resources to repairing and maintaining infrastructure... Luckily, Federico's good at these things, and has historically been good at finding devs to give him a hand. I can't really tell you anything about your pixman patches though, besides the fact that pixman's practically unmaintained too (see my first post about how the devs moved on), it's shared infrastructure with the X server, and nobody really wants to touch it because it's "stable" and was mostly written before the era of unit tests and CI/CD so it's hard to prove changes to it are correct across all of the various platforms and use cases it has to support... It's like trying to change Win32 APIs, only worse because people are still building Xorg on bizarro platforms and architectures you won't have access to test on. Your best bet is to actually bug developers with commit access to review/push your patches and then work your way up to commit access and start actually maintaining this stuff.
- _ph_ 9y agoAs I am just getting into gtk-based UI programming, I have not found any good overviews how to do things "right" to get the best performance. Could you give a pointer to where I could find information how to efficiently draw with cairo, including some pixel data?
- awalton 9y agoI don't think that documentation truly exists. You can read the Gtk+ documentation and the Cairo documentation, but that really only tells you what the APIs do in the grand scheme, not why they were added, what problems they solve, or the gist of how to get best perf. Most of the time when you're writing new widgets you only care about drawing lines, placing icons and laying out text, for which Gtk+ has fast higher level mechanisms and you should use those (see gtk_render_line(), gtk_render_icon(), gtk_render_layout() and their friends). When in doubt, use the newer widgets and functions (the ones with the latest "Since:" annotations), since they have usually replaced older functions with worse performance or behavior. If you're lucky, those new functions will even document why you shouldn't use the old function anymore... The general theme of working with Gtk+ is "do as the library does", as it's mostly been written and maintained by people who know these things through decades of experience and that code can help guide you towards avoiding bad behaviors (like the famously bad StackOverflow-style toy example code that creates an image surface, renders some clock or gears vector image to it imperatively, and then setting that image surface as your widget cairo context's source and rendering the whole image to your widget and wondering why you can only get 10 fps vs using gdk_window_create_similar_surface() to make your offscreen rendering target, splitting your drawing up into the "clock face background" and the "clock hands foreground" pieces, and only re-rendering the hands as they move or even prerendering all of the different hand positions to another offscreen buffer and blitting the pieces as necessary and suddenly realizing you can get hundreds of FPS easily.) Sadly all of this means source diving a lot of the time. And it can be hard, especially in cases where you want to stray off the beaten path and do a completely new widget design - you will want to find and make friends with great GNOME people as they can really mentor you through these more complicated widgets until you get your legs under you. The toolkit as a whole is moving towards a model more like that of modern browsers, where widgets are conceptually smaller and simpler and composite widgets and layouts are more of what you actually have to maintain. (A good example of the latter is looking how complicated the current code in GtkSpinButton was, compared to how conceptually it could be a much simpler composite widget that only handles the key/button events between a pair of buttons and a text entry). This shift in design is a boon for many application developers, but it can mean really struggling if you want to write or maintain complex applications with components such as drawing canvases (e.g. the GIMP) and layered cross-process rendering (I used to work on VMware Workstation...) You can help! Document your findings as you learn, write patches against these libraries and their documentation, get it reviewed and committed. The Gtk+ folks are not scary to work with, just very opinionated.