Quantitative CPU for GUI - how much is acceptible?

I am wondering, how to get quantitative numbers of how much CPU is used for GUI, and to get an idea, how much is acceptable.

I know profiling would be a good measure, but that tells me, where time is spent, but not how much. That’s understandable, since it will depend on which machine it will run.

I created a generic GUI engine (PluginGuiMagic), which allows to add many realtime analysers, oscilloscopes and LevelMeters. Typical GUIs add on average 20% on the Activity monitor when opening the GUI and have it zoomed relatively large (all not very scientific).

It is using the juce::Graphics functions and has a juce::OpenGLContext attached to the AudioProcessorEditor.

Should I be worried? What do I tell clients? How much CPU can one spend?

N.B. I started to optimise using setOpaque() everywhere where possible, but the benefit was just a few percent, so it seems to be a dead end optimisation.

1 Like

I’ve got quite better performance setting rarely updated components to bufferedToImage, when they’re transparent and overlaid with others that update a lot. It’s all still a bit heavy, around 10-15%, but I’m not using OpenGL.

1 Like

Practically, I aim for as little movement as possible on my GUI with Juce, unless I have an exact idea of how I can render something with a poly list / shader combo that the hardware can splat, which is limited to how much you’re willing to handle with polygons yourself, which can be FFTs etc like you appear to be doing anyway. What you say to potential clients can only be a guess based on your experience and abilities, and what they want, of course :slightly_smiling_face:
Sorry there is no definitive answer, but you seem to be on top of it.

Thanks for the ideas and thoughts. Yes I am aware that this probably has no yes/no answer, so I am happy to hear opinions, and also numbers what your GUIs use on average.

I am weary about Path and PathFlatteningIterator. At the moment I use paths for Analyser and Oscilloscope, but I know that AudioThumbnail avoids doing that. It uses a RectangleList instead, maybe it’s worth trying to do something similar. For the Analyser at least that might work.

Oh yes, I also added setPaintingIsUnclipped(true), which improved things by 1% or something in that range…

I try to do as much as possible with plain fillRects. I tried to do stroked graphs like scopes with vertical rects but they’re too rough, big jumps look too staircased, so I went back to paths. For filled graphs with low contrast I still use RectLists. I dropped OpenGL because I got weird glitches in some computers -flashing tooltips, random white dots in fills. I will give it a try again some day, but without doing my own shaders it doesn’t seem like I can fix much.

1 Like

Being pragmatic, if the UI is using a ‘lot’ of CPU but it is doing something generally useful, and if all of that work is on such a low priority background thread that it does not affect audio performance, will it matter that much to most people? I don’t think so, but laptop users may disagree if they’re not close to a wall outlet. If you can add facilities to reduce CPU usage for those perhaps where it does make a difference, perhaps by including options for reducing update rates, it may be appreciated in some edge case situations.

Well even if it‘s on a low priority thread and it‘s on a wall socket, the fan will speed up and annoy the user (especially on mobile rigs), so there‘s a legitimate reason to keep the CPU usage in check.

Well, sometimes it matters. If you have many editors open with visualizations, you can start to lose frames. Nothing terrible, but not nice. Also, seemingly simple things can clog the message queue in some situations. I’ve had a process which updated labels at 30 fps make the UI totally unresponsive on offline renders. Dropping to 5 fps fixed it -it seems glyph stuff is heavy.

Btw, I’ve been reading some old posts where Jules said that filling areas with vertical lines can be worse than using paths. I don’t know if this is still the case, but I moved to paths and it doesn’t seem worse at least, though I also tightened some previous calculations.

I agree 100%, but in reality there is a limit. What I want to know is when I can relax, since if I listen to every user, it will always be too much.

You can always fire up a few reference plugins that have a similar UI workload and compare it on your system. Plus you can do proper profiling of the message thread and not just look at the activity monitor as this can be just considered as rough indicator what’s going on.

Also be aware of Timers. If you have a generic UI framework that might use a timer for each UI control to update its value, you will run into really nasty freeze issues if you increase the instance count (the first version of our plugin froze the UI when more than 10 instances were open because it used about 30-50 timers per instance.