Fix VST parameter automation performance#8253
Conversation
It didn't make sense for the special behavior of volume knobs to be implemented in `FloatModelEditorBase`, so I moved it to a new `VolumeKnob` class which inherits from `Knob`. This significantly reduces the size of the `FloatModelEditorBase` class and all classes which inherit from it, while also simplifying calling code.
|
Why the complication with the timers, And I don't get why we have a separate |
|
@sakertooth I agree the design was pretty ugly and convoluted. I just finished refactoring the PR, and now it's much cleaner and more straightforward. I no longer have any unease about the design.
When I tested it without a timer to limit the rate of updates, it caused the CPU to spike whenever I rapidly adjusted the value of a parameter while the text float was visible. This is even after all the other optimizations. But with some simple rate limiting using a timer, there's no such problem. Before I reworked the PR, the timer stuff was cluttering up the |
|
@messmerd, nice, I'll try to review again when I have time.
Isn't this a bandage fix (and if so, should we make note of that)? Rate limiting wouldn't be necessary if the messages to update the parameters were sent on another queue for communication between the UI and the plugin, such that the audio thread wouldn't be blocked on messages it doesn't care about, right? Perhaps this is a more suitable approach to solving this problem, but if its too much to ask for here, we shouldn't need to worry much about the ideal. |
|
@sakertooth For main/GUI thread messages, such as the messages for updating parameter text that this PR uses, maybe there shouldn't be a queue and the messages should just be sent synchronously as soon as possible. Of course, main/GUI thread messages and audio thread messages would be sent concurrently and not interfere with each other. For the parameter text updates, it's different from other more important messages because it happens regularly and there is no significant penalty if it fails, so it makes sense to me to place a limit on how often it can be called. Even after an IPC rewrite, I think rate limiting could still be good for performance. Whether the rate limiting should be implemented in a generic fashion in But for now, rate limiting for VST parameter text updates makes a noticeable improvement to performance, and the implementation is confined to |
sakertooth
left a comment
There was a problem hiding this comment.
Tested it with some VST plugins. The CPU meter barely budged! This is awesome.
|
|
||
| void SimpleTextFloat::show() | ||
| { | ||
| m_hideTimer->start(); |
There was a problem hiding this comment.
I was thinking all the rate limiting/timer logic would be in VstPluginKnob.
There was a problem hiding this comment.
This isn't related to rate limiting - it just makes the floating text visible and starts the timer to hide it if it hasn't already been started. I added this method while refactoring how FloatModelEditorBase uses SimpleTextFloat, but it may not be necessary anymore. I'll have to check.
There was a problem hiding this comment.
On a separate note, a part of me questions why the code isn't just a simple call to setTooltip (i.e., why the SimpleTextFloat classes and such). I don't spend too much time in this part of the codebase, but it feels different than from what I was expecting.
There was a problem hiding this comment.
Our SimpleTextFloat allows specifying both a delay before the tooltip is shown and a display duration, while setToolTip/QToolTip only supports a display duration. And looking at QToolTip's documentation, it looks like it would be more difficult to adapt to our use cases than SimpleTextFloat.
One thing I don't like about SimpleTextFloat though, is how it's not a static class. We should probably look into changing that in a separate PR. And maybe rename it to ToolTip.
|
I just realized this PR also fixes a bug where the tooltip text displayed by a knob when you hover over it without clicking it remains static and unchanging even when the knob is being automated or controlled. |
Fixes #8066
The cause
Every time any VST parameter was modified, Vestige and VST effects would update the parameter labels and display text for all of their parameters.
This is bad because the parameter labels/display are only used by the text floats for parameter knobs, and exactly 0 or 1 text floats for knobs are visible at any given time globally. So it was making expensive calls into RemotePlugin to update the text for all parameters, even though this is only needed for at most 1 parameter and most of the time is not needed at all.
This performance regression was introduced by #5321, as @sakertooth explained here.
A solution
RemotePluginFloatModelEditorBase, replacing thedisplayValue()method with two methods for setting/updating the value of the SimpleTextFloat:VstPluginKnobclass which implementsKnobfor Vestige/VST Effects.RemotePlugin, not something that affects other knobs, so putting it in aKnobimplementation for VSTs is appropriate.)CustomTextKnobsince a superset of its functionality is now supported byKnobas well as every other class that inherits fromFloatModelEditorBase.Bonus:
FloatModelEditorBaseinto a new class calledVolumeKnobwhich inherits fromKnob. This isn't strictly necessary for this PR, but it makesFloatModelEditorBasesignificantly smaller in size (and thereforeKnobas well). These changes are self-contained in this commit: 1e5ca51