I have a simple test application that I’ve been tinkering with trying to evaluate the performance of 2d plotting. This uses Qt Quick with a QQuickFramebufferObject (similar to https://gist.github.com/nocnokneo/c3fb01bb7ecaf437f7d6).
Each plot has it’s own framebuffer and vtkGenericOpenGLRenderWindow.
The plot is just filling data into a table with a QTimer and sine wave. I have the plots rendering at 5Hz, with the data at 100Hz (back fill every 200ms).
The performance is pretty poor, although this is a somewhat naive implementation (still new to vtk).
VTune indicates:
10% of the time is spent in vtkContext2D::DrawPoly. Mostly in vector::operator[] when trying to build the VBO.
6% of the time is vtkFreeTypeTools::GetBoundingBox for the sliding x-axis.
5% of the time is in malloc: mostly for DrawPoly, some for FreeType
It seems each plot is redrawing all of it’s line every frame instead of some sort of transform. Any hints towards more performant real-time plotting would be greatly appreciated!
What do you mean by poor performance? What do you find to be slow? How many rows do you have in your table?
In 3D Slicer, we use ctkVTKChartView to display VTK plots in real-time and rendering only starts to visibly lag (fall below 20-30fps) when you display tens of thousands of data points. But even then it may be because of other things that the application does and not due to VTK.
When drawing an XY chart consisting of 25000 points, 65% time is spent in vtkContext2D::DrawPoly. Nothing else really stands out in profiling.
The call to Render takes ~25ms per plot. Since the rendering is based on an update queue, the queue can start backing up with events since rendering all 15 plots takes ~400ms and they are trying to update at 200 ms intervals.
This also inhibits other things in the main event queue from being handled, like hover animations rendering, mouse events, etc.
I have the table removing rows if the size gets above 1000. Note that each plot gets it’s own table and render window.
It may be a significant performance hit (and may lead to memory fragmentation) that you keep allocating/freeing memory on the heap hundreds of times per second. Instead of calling InsertNextRow/RemoveRow, keep the table size constant and just copy/update the values.
Thanks for the suggestion, I wasn’t sure if the table had to be in sorted order. I will implement it as a circluar buffer then fix the extra AddAxis the Mike mentioned and report back!
With the suggested changes, I’m down to ~18ms per plot. So 270ms to render all plots.
I’ve also experimented with turning the labels/ticks off. If I turn both the x-axis and y-axis labels off, the average time to plot is ~6ms. If I turn both x and y axis ticks off, I get down to ~2ms.
Ideally, I would like to get each plot render below 5ms per plot. Labels and ticks are probably necessary for my use case.