0
votes

I am currently developing a real-time data plotting solution that is able to receive new data frequently (up to 1kHz) and performing a redraw at a lower rate (e.g. 50hz). I made a first implementation using FLTK but I wanted to give a try to GTK because I never used it before and it looked promising to me.

To keep the story short, I noticed that calls to cairo_stroke() take a lot of time when drawing lines compared to what I measure using FLTK (there's no stroke in FLTK, fust an fl_line() function). I tried to limit as much as possible the strokes but I still get a rendering time 5-7x longer with GTK.

Has anyone noticed such performance issues when using GTK/Cairo during draws on a DrawingArea? Any lead on where to look to decrease the drawing duration?

Note: the back-end (the computation of the lines and texts to draw) is exactly the same since it is performed in a common base class.

2
Maybe showing your rendering code would help, mind you? Are you redrawing each time the whole thing or are you using clipping? Are you using gtk_widget_queue_draw_area?liberforce
It's not finished yet so I haven't pushed it to Github. You can already find this repo containing links to the core library and current implementations. I'll add the link to the GTK version in the upcoming days once everything is ready. But yes, I am redrawing the whole thing each time because everything changes at each redraw (new points so new lines and probably new scales for the axes)Benjamin Navarro
Redrawing the whole thing is expensive and may not be needed. If you do too much work at high speed, you will indeed have performance problems. In response to which signal do you call gtk_widget_queue_draw?liberforce
Either manuals calls or some timer (preferred solution), running at 50Hz top. So no, I don't redraw everything for each data that arrives.Benjamin Navarro

2 Answers

1
votes

Cairo drawing is indeed not very fast. There are 2 main bottlenecks: how often the "draw" signal is emitted and how cairo draws lines under the hood.

  1. On my work PC widget redraw is called about 25 times per second, that is 25fps. In my own expirience I haven't seen fps much more than that, maybe 30 or 40. Giving more priority to redraw funcion may result in other mainloop functions being called too seldom.
  2. cairo_line_to is quite smart drawing which draws lines with antialiasing, color mixing, transparency etc, and in exact pixel (coordinates are double, thus a 1px vertical line can occupy two pixels)

And as far as I know, there are two ways to make drawing faster:

  1. Use OpenGL
  2. Custom line drawing on image surfaces (cairo_image_surface_get_data and draw the image pixel by pixel)

And, of course, optimising the number of draws you perform, but this is not quite scalable.

0
votes

I have a Gtk/Cairo plotting library in https://github.com/pchilds/GtkPlot

At the time I made it, I designed it for plotting large data sets (10k+). Downside is the code is painfully unmaintainable being optimised ad nauseum. But it did the job. I didn't look into refresh rate but it may be up to it. From what I remember I didn''t stroke for each line but I may be wrong. If the points are connected you can create a path and stroke them all in the one go.

I haven't looked into FLTK for comparison.

Alexander's mention of OpenGL is a good one. You could also look into the wayland backend for cairo. Wayland is an alternative to X that uses OpenGL instead.