mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 14:54:56 +01:00
dramatically speed up the addition of large numbers of busses + tracks. consists of a backend part (ignore JACK graph/latency callbacks while we're adding tracks) and a GUI side (avoid O(N^N) behaviour while adding each new time axis view)
git-svn-id: svn://localhost/ardour2/branches/3.0@13595 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
1feaa65d16
commit
89d1a2fdf5
8 changed files with 64 additions and 34 deletions
|
|
@ -69,6 +69,7 @@ EditorRoutes::EditorRoutes (Editor* e)
|
||||||
: EditorComponent (e)
|
: EditorComponent (e)
|
||||||
, _ignore_reorder (false)
|
, _ignore_reorder (false)
|
||||||
, _no_redisplay (false)
|
, _no_redisplay (false)
|
||||||
|
, _adding_routes (false)
|
||||||
, _menu (0)
|
, _menu (0)
|
||||||
, old_focus (0)
|
, old_focus (0)
|
||||||
, selection_countdown (0)
|
, selection_countdown (0)
|
||||||
|
|
@ -600,9 +601,12 @@ void
|
||||||
EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
|
EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
|
||||||
{
|
{
|
||||||
TreeModel::Row row;
|
TreeModel::Row row;
|
||||||
|
PBD::Unwinder<bool> at (_adding_routes, true);
|
||||||
|
|
||||||
suspend_redisplay ();
|
suspend_redisplay ();
|
||||||
|
|
||||||
|
_display.set_model (Glib::RefPtr<ListStore>());
|
||||||
|
|
||||||
for (list<RouteTimeAxisView*>::iterator x = routes.begin(); x != routes.end(); ++x) {
|
for (list<RouteTimeAxisView*>::iterator x = routes.begin(); x != routes.end(); ++x) {
|
||||||
|
|
||||||
boost::shared_ptr<MidiTrack> midi_trk = boost::dynamic_pointer_cast<MidiTrack> ((*x)->route());
|
boost::shared_ptr<MidiTrack> midi_trk = boost::dynamic_pointer_cast<MidiTrack> ((*x)->route());
|
||||||
|
|
@ -653,6 +657,7 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
|
||||||
(*x)->route()->solo_isolated_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_isolate_display, this), gui_context());
|
(*x)->route()->solo_isolated_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_isolate_display, this), gui_context());
|
||||||
(*x)->route()->solo_safe_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_safe_display, this), gui_context());
|
(*x)->route()->solo_safe_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_safe_display, this), gui_context());
|
||||||
(*x)->route()->active_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_active_display, this), gui_context ());
|
(*x)->route()->active_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_active_display, this), gui_context ());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update_rec_display ();
|
update_rec_display ();
|
||||||
|
|
@ -662,7 +667,9 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
|
||||||
update_solo_safe_display ();
|
update_solo_safe_display ();
|
||||||
update_input_active_display ();
|
update_input_active_display ();
|
||||||
update_active_display ();
|
update_active_display ();
|
||||||
|
|
||||||
resume_redisplay ();
|
resume_redisplay ();
|
||||||
|
_display.set_model (_model);
|
||||||
|
|
||||||
/* now update route order keys from the treeview/track display order */
|
/* now update route order keys from the treeview/track display order */
|
||||||
|
|
||||||
|
|
@ -672,7 +679,9 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
|
||||||
void
|
void
|
||||||
EditorRoutes::handle_gui_changes (string const & what, void*)
|
EditorRoutes::handle_gui_changes (string const & what, void*)
|
||||||
{
|
{
|
||||||
ENSURE_GUI_THREAD (*this, &EditorRoutes::handle_gui_changes, what, src)
|
if (_adding_routes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (what == "track_height") {
|
if (what == "track_height") {
|
||||||
/* Optional :make tracks change height while it happens, instead
|
/* Optional :make tracks change height while it happens, instead
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,7 @@ private:
|
||||||
|
|
||||||
bool _ignore_reorder;
|
bool _ignore_reorder;
|
||||||
bool _no_redisplay;
|
bool _no_redisplay;
|
||||||
|
bool _adding_routes;
|
||||||
|
|
||||||
Gtk::Menu* _menu;
|
Gtk::Menu* _menu;
|
||||||
Gtk::Widget* old_focus;
|
Gtk::Widget* old_focus;
|
||||||
|
|
|
||||||
|
|
@ -689,8 +689,6 @@ EditorSummary::set_editor (double const x, double const y)
|
||||||
is merely pending but not executing. But c'est la vie.
|
is merely pending but not executing. But c'est la vie.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cerr << "Editor pending idle already queued\n";
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -311,9 +311,10 @@ Mixer_UI::add_strips (RouteList& routes)
|
||||||
{
|
{
|
||||||
MixerStrip* strip;
|
MixerStrip* strip;
|
||||||
|
|
||||||
{
|
try {
|
||||||
Unwinder<bool> uw (no_track_list_redisplay, true);
|
no_track_list_redisplay = true;
|
||||||
|
track_display.set_model (Glib::RefPtr<ListStore>());
|
||||||
|
|
||||||
for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
|
for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
|
||||||
boost::shared_ptr<Route> route = (*x);
|
boost::shared_ptr<Route> route = (*x);
|
||||||
|
|
||||||
|
|
@ -345,7 +346,7 @@ Mixer_UI::add_strips (RouteList& routes)
|
||||||
|
|
||||||
strip = new MixerStrip (*this, _session, route);
|
strip = new MixerStrip (*this, _session, route);
|
||||||
strips.push_back (strip);
|
strips.push_back (strip);
|
||||||
|
|
||||||
Config->get_default_narrow_ms() ? _strip_width = Narrow : _strip_width = Wide;
|
Config->get_default_narrow_ms() ? _strip_width = Narrow : _strip_width = Wide;
|
||||||
|
|
||||||
if (strip->width_owner() != strip) {
|
if (strip->width_owner() != strip) {
|
||||||
|
|
@ -365,8 +366,13 @@ Mixer_UI::add_strips (RouteList& routes)
|
||||||
strip->WidthChanged.connect (sigc::mem_fun(*this, &Mixer_UI::strip_width_changed));
|
strip->WidthChanged.connect (sigc::mem_fun(*this, &Mixer_UI::strip_width_changed));
|
||||||
strip->signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &Mixer_UI::strip_button_release_event), strip));
|
strip->signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &Mixer_UI::strip_button_release_event), strip));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
no_track_list_redisplay = false;
|
||||||
|
track_display.set_model (track_model);
|
||||||
|
|
||||||
sync_order_keys_from_treeview ();
|
sync_order_keys_from_treeview ();
|
||||||
redisplay_track_list ();
|
redisplay_track_list ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1269,6 +1269,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||||
SerializedRCUManager<RouteList> routes;
|
SerializedRCUManager<RouteList> routes;
|
||||||
|
|
||||||
void add_routes (RouteList&, bool input_auto_connect, bool output_auto_connect, bool save);
|
void add_routes (RouteList&, bool input_auto_connect, bool output_auto_connect, bool save);
|
||||||
|
void add_routes_inner (RouteList&, bool input_auto_connect, bool output_auto_connect);
|
||||||
|
bool _adding_routes_in_progress;
|
||||||
uint32_t destructive_index;
|
uint32_t destructive_index;
|
||||||
|
|
||||||
boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&, int);
|
boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&, int);
|
||||||
|
|
|
||||||
|
|
@ -227,8 +227,8 @@ AudioEngine::stop (bool forever)
|
||||||
disconnect_from_jack ();
|
disconnect_from_jack ();
|
||||||
} else {
|
} else {
|
||||||
jack_deactivate (_priv_jack);
|
jack_deactivate (_priv_jack);
|
||||||
Stopped(); /* EMIT SIGNAL */
|
|
||||||
MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
|
MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
|
||||||
|
Stopped(); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1162,8 +1162,8 @@ AudioEngine::halted (void *arg)
|
||||||
ae->_jack = 0;
|
ae->_jack = 0;
|
||||||
|
|
||||||
if (was_running) {
|
if (was_running) {
|
||||||
ae->Halted(""); /* EMIT SIGNAL */
|
|
||||||
MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
|
MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
|
||||||
|
ae->Halted(""); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1410,8 +1410,8 @@ AudioEngine::disconnect_from_jack ()
|
||||||
|
|
||||||
if (_running) {
|
if (_running) {
|
||||||
_running = false;
|
_running = false;
|
||||||
Stopped(); /* EMIT SIGNAL */
|
|
||||||
MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
|
MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
|
||||||
|
Stopped(); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -2135,6 +2135,31 @@ Session::new_route_from_template (uint32_t how_many, const std::string& template
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
|
Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
|
||||||
|
add_routes_inner (new_routes, input_auto_connect, output_auto_connect);
|
||||||
|
|
||||||
|
} catch (...) {
|
||||||
|
error << _("Adding new tracks/busses failed") << endmsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_reordered ();
|
||||||
|
|
||||||
|
update_latency (true);
|
||||||
|
update_latency (false);
|
||||||
|
|
||||||
|
set_dirty();
|
||||||
|
|
||||||
|
if (save) {
|
||||||
|
save_state (_current_snapshot_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
RouteAdded (new_routes); /* EMIT SIGNAL */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect)
|
||||||
{
|
{
|
||||||
ChanCount existing_inputs;
|
ChanCount existing_inputs;
|
||||||
ChanCount existing_outputs;
|
ChanCount existing_outputs;
|
||||||
|
|
@ -2191,6 +2216,7 @@ Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (input_auto_connect || output_auto_connect) {
|
if (input_auto_connect || output_auto_connect) {
|
||||||
auto_connect_route (r, existing_inputs, existing_outputs, true, input_auto_connect);
|
auto_connect_route (r, existing_inputs, existing_outputs, true, input_auto_connect);
|
||||||
}
|
}
|
||||||
|
|
@ -2199,7 +2225,7 @@ Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output
|
||||||
reasonable defaults because they also affect the remote control
|
reasonable defaults because they also affect the remote control
|
||||||
ID in most situations.
|
ID in most situations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!r->has_order_key (EditorSort)) {
|
if (!r->has_order_key (EditorSort)) {
|
||||||
if (r->is_hidden()) {
|
if (r->is_hidden()) {
|
||||||
/* use an arbitrarily high value */
|
/* use an arbitrarily high value */
|
||||||
|
|
@ -2215,31 +2241,18 @@ Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_monitor_out && IO::connecting_legal) {
|
if (_monitor_out && IO::connecting_legal) {
|
||||||
|
Glib::Threads::Mutex::Lock lm (_engine.process_lock());
|
||||||
{
|
|
||||||
Glib::Threads::Mutex::Lock lm (_engine.process_lock());
|
for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
|
||||||
|
if ((*x)->is_monitor()) {
|
||||||
for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
|
/* relax */
|
||||||
if ((*x)->is_monitor()) {
|
} else if ((*x)->is_master()) {
|
||||||
/* relax */
|
/* relax */
|
||||||
} else if ((*x)->is_master()) {
|
} else {
|
||||||
/* relax */
|
(*x)->enable_monitor_send ();
|
||||||
} else {
|
|
||||||
(*x)->enable_monitor_send ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resort_routes ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set_dirty();
|
|
||||||
|
|
||||||
if (save) {
|
|
||||||
save_state (_current_snapshot_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
RouteAdded (new_routes); /* EMIT SIGNAL */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -3551,7 +3564,7 @@ Session::graph_reordered ()
|
||||||
from a set_state() call or creating new tracks. Ditto for deletion.
|
from a set_state() call or creating new tracks. Ditto for deletion.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (_state_of_the_state & (InitialConnecting|Deletion)) {
|
if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4531,7 +4544,7 @@ Session::update_latency (bool playback)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
|
DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE")));
|
||||||
|
|
||||||
if (_state_of_the_state & (InitialConnecting|Deletion)) {
|
if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
|
||||||
_play_range = false;
|
_play_range = false;
|
||||||
_exporting = false;
|
_exporting = false;
|
||||||
pending_abort = false;
|
pending_abort = false;
|
||||||
|
_adding_routes_in_progress = false;
|
||||||
destructive_index = 0;
|
destructive_index = 0;
|
||||||
first_file_data_format_reset = true;
|
first_file_data_format_reset = true;
|
||||||
first_file_header_format_reset = true;
|
first_file_header_format_reset = true;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue