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:
parent
1e0d14f429
commit
baa30262b8
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue