Be more specific about RouteProcessorChange signals

Session::route_processors_changed accumulates signals emitted
in realtime and processing is delegated to a dedicated rt-safe
thread. Previously this resulted in any changed to be converted
to a `GeneralChange`, which unconditionally triggered a route-reorder.

Record-arming a track causes a MeterPointChange (meters change to "in"),
and this caused routes to be resorted and a latency-update.

While the former is reasonable (Ardour prefers to process
rec-armed routes first), the latter certainly is not.
This commit is contained in:
Robin Gareus 2022-05-24 02:13:54 +02:00
parent 1e0d14f429
commit baa30262b8
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
4 changed files with 37 additions and 19 deletions

View File

@ -686,23 +686,9 @@ public:
class ProcessorChangeBlocker {
public:
ProcessorChangeBlocker (Session* s, bool rc = true)
: _session (s)
, _reconfigure_on_delete (rc)
{
g_atomic_int_inc (&s->_ignore_route_processor_changes);
}
ProcessorChangeBlocker (Session* s, bool rc = true);
~ProcessorChangeBlocker ();
~ProcessorChangeBlocker ()
{
if (g_atomic_int_dec_and_test (&_session->_ignore_route_processor_changes)) {
if (g_atomic_int_compare_and_exchange (&_session->_ignored_a_processor_change, 1, 0)) {
if (_reconfigure_on_delete) {
_session->route_processors_changed (RouteProcessorChange ());
}
}
}
}
private:
Session* _session;
bool _reconfigure_on_delete;

View File

@ -674,12 +674,16 @@ struct CleanupReport {
/** A struct used to describe changes to processors in a route.
* This is useful because objects that respond to a change in processors
* can optimise what work they do based on details of what has changed.
*
* While the signal themselves are distinct values, the Session
* can accumulate then via ProcessorChangeBlocker and batch process
* them.
*/
struct RouteProcessorChange {
enum Type {
GeneralChange = 0x0,
MeterPointChange = 0x1,
RealTimeChange = 0x2
RealTimeChange = 0x2,
GeneralChange = 0x4
};
RouteProcessorChange () : type (GeneralChange), meter_visibly_changed (true)

View File

@ -7539,3 +7539,29 @@ Session::mixer_scenes () const
Glib::Threads::RWLock::ReaderLock lm (_mixer_scenes_lock);
return _mixer_scenes;
}
Session::ProcessorChangeBlocker::ProcessorChangeBlocker (Session* s, bool rc)
: _session (s)
, _reconfigure_on_delete (rc)
{
g_atomic_int_inc (&s->_ignore_route_processor_changes);
}
Session::ProcessorChangeBlocker::~ProcessorChangeBlocker ()
{
if (g_atomic_int_dec_and_test (&_session->_ignore_route_processor_changes)) {
gint type = g_atomic_int_and (&_session->_ignored_a_processor_change, 0);
if (_reconfigure_on_delete) {
if (type & RouteProcessorChange::GeneralChange) {
_session->route_processors_changed (RouteProcessorChange ());
} else {
if (type & RouteProcessorChange::MeterPointChange) {
_session->route_processors_changed (RouteProcessorChange (RouteProcessorChange::MeterPointChange));
}
if (type & RouteProcessorChange::RealTimeChange) {
_session->route_processors_changed (RouteProcessorChange (RouteProcessorChange::RealTimeChange));
}
}
}
}
}

View File

@ -1882,11 +1882,13 @@ void
Session::route_processors_changed (RouteProcessorChange c)
{
if (g_atomic_int_get (&_ignore_route_processor_changes) > 0) {
g_atomic_int_set (&_ignored_a_processor_change, 1);
g_atomic_int_or (&_ignored_a_processor_change, (int)c.type);
return;
}
if (c.type == RouteProcessorChange::MeterPointChange) {
/* sort rec-armed routes first */
resort_routes ();
set_dirty ();
return;
}