Lags caused by shape (not size - num points) of Path


in my plugin I have Path myPath; that has about 700 points. And if myPath is smoothly-curved line, it works great, very fast and fluently.

But unfortunately when myPath is some crazy, distracted graph with many shredded points, everything start lagging, and work slowly and unfluently.
“Everything” I mean my plugin, whole host, and other plugins also.

I don’t understand why it is like that, because it’s still the same size path, and which is more important I have created separated Thread exclusively for stroke my path.

So why is that? How to avoid that? But please notice that I can’t just ensure smooth pline all the time, there will be sometimes situations that will draw shredded, crazy graph, so how to avoid then lagging?
For any help thanks in advance

for example such shape works perfect:

But that one causes lags in whol system:

but it’s still the same Path, with the same number of points. So why it’s much slower? How to fix that?

you should google “xcode profile c++” or “visual studio profile c++”

1 Like

Hey thanks, I’ve just googled it.
It’s interesting I’ve never heard about it before. But I’ve watched some tutorials and not sure how it could help in that exact case. As I understand it will show me where there is most CPU usage. But how to fix it for that case I still have no idea. I don’t thing (hopefully I am wrong) there is any method that allows me to return; from stroking path wheb CPU is too much in use.

First you have to find the problem, then you can fix it. Profile it and find the part if the drawing or path-preprocessing which uses the biggest amount of CPU. Then you can see what you can do about it. I can imagine that slicing the path into linear segments in order to draw it could be quite intensive. If that’s the case, you could do that in your thread, which hopefully doesn’t have a real-time priority, otherwise itself might be the culprit which stalls everything else.

What do you mean by:

real-time priority,

As I know thread can have low or high priority or something between - from 0 (low) to high (10). But “real-time priority” sounds for me like some special priority, that’s why I am asking.

By the way, my Thread which strokes myPath, has priority set to 0 by calling startThread(0); due to fact I don’t need it to be in high priority. And in run() I call wait(1000), and in other thread (which prepares data for Path) I use notify() when data is ready. I wonder maybe I better should use wait(-1) due to fact that I don’t want to draw and stroke my path if there is no data.

If that’s the case, you could do that in your thread,

Also I wonder what I could do? That’s what about that topic I created.

To understand what’s going on you really have to understand how path rasterisation works, and I’m not going to attempt that here… The TL;DR is that paths which have many vertical up/down jaggies will be much slower that smooth lines. (It’s all down to the number of sections per horizontal scan-line)

How to work around that is tricky… Simply chopping up the path into multiple tall thin sections may be an approach that works. (If it does then ideally you’d make it smart enough to only do that when needed)

So as the path is representing magnitude or phase data vs. frequency, rotating the path by 90 degrees (or creating it that way), drawing and rotating back should improve things? Then in theory there should be only one point per horizontal line.

Well… sure, that’d make the path rendering faster, but would add a ton of overhead in drawing the image. Wouldn’t want to predict which is faster.

Also worth noting that I can only talk about juce’s path renderer in our GL and software rendering engines.

When you run it on some other engine like CoreGraphics, it may have entirely different performance characteristics (maybe even different for particular OS versions and GPUs), as we have no idea what might be going on inside there.

So as the path is representing magnitude or phase data vs. frequency, rotating the path by 90 degrees (or creating it that way), drawing and rotating back should improve things? Then in theory there should be only one point per horizontal line.

I’ve read that tones of time in other threads on that forum. But I don’t get the idea. Do you mean to draw exacty the same what is now but vertical - instead horizontal? Freq should go from down to up? And then all rotate of 90 degree? But what’s the sense of it?

Just read the answers and suggestions above.

Don’t spend a second about drawing 90 degree rotated. This is for the last optimisation, when you did everything else.
That is a whole different ballpark.

Since you managed to stall your host drawing with your code, you have most likely a problem with priority inversion, a thread is waiting for another one, that is actually less important and therefore slower running. That is my strong hunch anyway.

To draw what you’ve shown above much faster, just draw individual line segments instead of a path. That will make rasterization much faster and more consistent… it’ll scale with total length of the segments instead of complexity of the path.

Also you should reduce your resolution to be closer to screen resolution by merging points (on the high frequency side). It won’t look at nice, but will draw much faster.

No, that’s not true. Making separate calls to drawLine will avoid the complex paths, but will add the overhead of hundreds of calls into the graphics stack. For a simple graph, a single path will be faster and look better; for a very jagged graph then breaking it up into lines may start to become faster, but you could achieve the same thing by dividing it into vertical strips like I suggested above, which would also look good.

Sorry for ask again, but I don’t get the idea. What does mean „doviding into vertical strips”? Could you explain please? And please believe me, I tried to search in google about that, and on that forum, I found a lot of threads where people mention that technique of drawing. But no one explain that.

Just read the answers and suggestions above.

I’ve read it about 50 times. Can you believe? Still don’t understanding. I also read other threads about rotating Path 90 degree. Each thread I read min 2 times. Ok maybe I just should give up.

The 90degree-idea is rotating the path by 90 degree, so per horizontal line only one section will appear, which - for the rasterization - would result in a performance boost. However, you have to rotate the rasterized result back again to match your desired visualization. So it might/will end up in poor performance.

What you can do is what jules suggested:

That means: don’t draw one path from 20Hz to 20kHz, but draw several paths maybe one from 20 to 1kHz (as it might be smooth there), one from 1kHz to 3kHz and so on… These are the vertical strips. Each strip isn’t as wide as the whole path, so the number of sections per horizontal scanline will be smaller. And if your algorithm is clever, it will control the number and width’s of the strips depending on your actual data. However, first try some static strips, and optionally add some data dependent processing.