From 155338d168b362dd135597695aaa1e419831a277 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 22 Oct 2009 17:17:34 +0000 Subject: [PATCH] Defer plugin discovery until actually needed (significant startup time improvement, especially with LV2). git-svn-id: svn://localhost/ardour2/branches/3.0@5859 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/mixer_strip.cc | 24 ++++---- gtk2_ardour/mixer_strip.h | 5 +- gtk2_ardour/mixer_ui.cc | 21 +++++-- gtk2_ardour/mixer_ui.h | 2 +- gtk2_ardour/processor_box.cc | 12 ++-- gtk2_ardour/processor_box.h | 10 ++-- gtk2_ardour/route_params_ui.cc | 8 +-- gtk2_ardour/route_params_ui.h | 12 ++-- libs/ardour/ardour/audio_unit.h | 2 +- libs/ardour/ardour/lv2_plugin.h | 4 +- libs/ardour/ardour/plugin_manager.h | 21 +++---- libs/ardour/audio_unit.cc | 4 +- libs/ardour/lv2_plugin.cc | 10 ++-- libs/ardour/plugin_manager.cc | 91 +++++++++++++++++++++-------- 14 files changed, 141 insertions(+), 85 deletions(-) diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index c2e38a1d34..c82a621d36 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -74,20 +74,19 @@ sigc::signal > MixerStrip::SwitchIO; int MixerStrip::scrollbar_height = 0; MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, bool in_mixer) - : AxisView(sess) + : AxisView(sess) , RouteUI (sess) ,_mixer(mx) , _mixer_owned (in_mixer) - , processor_box (sess, mx.plugin_selector(), mx.selection(), this, in_mixer) + , processor_box (sess, sigc::mem_fun(*this, &MixerStrip::plugin_selector), mx.selection(), this, in_mixer) , gpm (sess) , panners (sess) , _mono_button (_("Mono")) , button_table (3, 2) , middle_button_table (1, 2) - , bottom_button_table (1, 2) + , bottom_button_table (1, 2) , meter_point_label (_("pre")) - , comment_button (_("Comments")) - + , comment_button (_("Comments")) { init (); @@ -101,19 +100,18 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, bool in_mixer) } MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr rt, bool in_mixer) - : AxisView(sess) + : AxisView(sess) , RouteUI (sess) ,_mixer(mx) , _mixer_owned (in_mixer) - , processor_box (sess, mx.plugin_selector(), mx.selection(), this, in_mixer) + , processor_box (sess, sigc::mem_fun(*this, &MixerStrip::plugin_selector), mx.selection(), this, in_mixer) , gpm (sess) , panners (sess) , button_table (3, 2) , middle_button_table (1, 2) - , bottom_button_table (1, 2) + , bottom_button_table (1, 2) , meter_point_label (_("pre")) - , comment_button (_("Comments")) - + , comment_button (_("Comments")) { init (); set_button_names (); @@ -1795,3 +1793,9 @@ MixerStrip::mono_button_clicked () { panners.set_mono (_mono_button.get_active ()); } + +PluginSelector& +MixerStrip::plugin_selector() +{ + return _mixer.plugin_selector(); +} diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h index c83c260845..891d3a4d8d 100644 --- a/gtk2_ardour/mixer_strip.h +++ b/gtk2_ardour/mixer_strip.h @@ -87,8 +87,9 @@ class MixerStrip : public RouteUI, public Gtk::EventBox Width get_width_enum () const { return _width; } void* width_owner () const { return _width_owner; } - GainMeter& gain_meter() { return gpm; } - PannerUI& panner_ui() { return panners; } + GainMeter& gain_meter() { return gpm; } + PannerUI& panner_ui() { return panners; } + PluginSelector& plugin_selector(); void fast_update (); void set_embedded (bool); diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index 51578ad2b4..9931d51ff0 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -62,6 +62,7 @@ using PBD::atoi; Mixer_UI::Mixer_UI () : Window (Gtk::WINDOW_TOPLEVEL) + , _plugin_selector (0) { session = 0; _strip_width = Config->get_default_narrow_ms() ? Narrow : Wide; @@ -76,9 +77,9 @@ Mixer_UI::Mixer_UI () Route::SyncOrderKeys.connect (mem_fun (*this, &Mixer_UI::sync_order_keys)); - scroller_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); - scroller_base.set_name ("MixerWindow"); - scroller_base.signal_button_release_event().connect (mem_fun(*this, &Mixer_UI::strip_scroller_button_release)); + scroller_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); + scroller_base.set_name ("MixerWindow"); + scroller_base.signal_button_release_event().connect (mem_fun(*this, &Mixer_UI::strip_scroller_button_release)); // add as last item of strip packer strip_packer.pack_end (scroller_base, true, true); @@ -220,8 +221,6 @@ Mixer_UI::Mixer_UI () signal_delete_event().connect (mem_fun (*this, &Mixer_UI::hide_window)); add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK); - _plugin_selector = new PluginSelector (PluginManager::the_manager()); - signal_configure_event().connect (mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::configure_handler)); _selection.RoutesChanged.connect (mem_fun(*this, &Mixer_UI::follow_strip_selection)); @@ -466,7 +465,8 @@ Mixer_UI::connect_to_session (Session* sess) route_groups_changed (); - _plugin_selector->set_session (session); + if (_plugin_selector) + _plugin_selector->set_session (session); if (_visible) { show_window(); @@ -1487,3 +1487,12 @@ Mixer_UI::set_route_group_activation (RouteGroup* g, bool a) g->set_active (a, this); } +PluginSelector& +Mixer_UI::plugin_selector() +{ + if (!_plugin_selector) { + _plugin_selector = new PluginSelector (PluginManager::the_manager()); + _plugin_selector->set_session (session); + } + return *_plugin_selector; +} diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h index c7378404ef..e96178160a 100644 --- a/gtk2_ardour/mixer_ui.h +++ b/gtk2_ardour/mixer_ui.h @@ -58,7 +58,7 @@ class Mixer_UI : public Gtk::Window void connect_to_session (ARDOUR::Session *); - PluginSelector& plugin_selector() { return *_plugin_selector; } + PluginSelector& plugin_selector(); void set_strip_width (Width); Width get_strip_width () const { return _strip_width; } diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index aba5abe294..b21ce633da 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -93,13 +93,13 @@ bool ProcessorBox::get_colors = true; Gdk::Color* ProcessorBox::active_processor_color; Gdk::Color* ProcessorBox::inactive_processor_color; -ProcessorBox::ProcessorBox (Session& sess, PluginSelector &plugsel, - RouteRedirectSelection & rsel, MixerStrip* parent, bool owner_is_mixer) +ProcessorBox::ProcessorBox (ARDOUR::Session& sess, sigc::slot get_plugin_selector, + RouteRedirectSelection& rsel, MixerStrip* parent, bool owner_is_mixer) : _session(sess) , _parent_strip (parent) , _owner_is_mixer (owner_is_mixer) + , _get_plugin_selector (get_plugin_selector) , _placement(PreFader) - , _plugin_selector(plugsel) , _rr_selection(rsel) { if (get_colors) { @@ -309,7 +309,7 @@ ProcessorBox::show_processor_menu (gint arg) Gtk::MenuItem* plugin_menu_item = dynamic_cast(ActionManager::get_widget("/processormenu/newplugin")); if (plugin_menu_item) { - plugin_menu_item->set_submenu (_plugin_selector.plugin_menu()); + plugin_menu_item->set_submenu (_get_plugin_selector().plugin_menu()); } paste_action->set_sensitive (!_rr_selection.processors.empty()); @@ -469,7 +469,7 @@ ProcessorBox::processor_button_press_event (GdkEventButton *ev) } else if (!processor && ev->button == 1 && ev->type == GDK_2BUTTON_PRESS) { choose_plugin (); - _plugin_selector.show_manager (); + _get_plugin_selector().show_manager (); } @@ -572,7 +572,7 @@ ProcessorBox::deselect_all_processors () void ProcessorBox::choose_plugin () { - _plugin_selector.set_interested_object (*this); + _get_plugin_selector().set_interested_object (*this); } void diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h index 6a80549132..075e176903 100644 --- a/gtk2_ardour/processor_box.h +++ b/gtk2_ardour/processor_box.h @@ -69,7 +69,8 @@ namespace ARDOUR { class ProcessorBox : public Gtk::HBox, public PluginInterestedObject { public: - ProcessorBox (ARDOUR::Session&, PluginSelector &, RouteRedirectSelection &, MixerStrip* parent, bool owner_is_mixer = false); + ProcessorBox (ARDOUR::Session&, sigc::slot get_plugin_selector, + RouteRedirectSelection&, MixerStrip* parent, bool owner_is_mixer = false); ~ProcessorBox (); void set_route (boost::shared_ptr); @@ -96,12 +97,13 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject bool ab_direction; std::vector connections; + sigc::slot _get_plugin_selector; + boost::shared_ptr _processor_being_created; - ARDOUR::Placement _placement; + ARDOUR::Placement _placement; - PluginSelector & _plugin_selector; - RouteRedirectSelection & _rr_selection; + RouteRedirectSelection& _rr_selection; void route_going_away (); diff --git a/gtk2_ardour/route_params_ui.cc b/gtk2_ardour/route_params_ui.cc index 80849bebe4..888e28aab0 100644 --- a/gtk2_ardour/route_params_ui.cc +++ b/gtk2_ardour/route_params_ui.cc @@ -64,7 +64,6 @@ RouteParams_UI::RouteParams_UI () : ArdourDialog ("track/bus inspector"), latency_apply_button (Stock::APPLY), track_menu(0) - { insert_box = 0; _input_iosel = 0; @@ -224,10 +223,11 @@ RouteParams_UI::setup_processor_boxes() cleanup_processor_boxes(); // construct new redirect boxes - insert_box = new ProcessorBox(*session, *_plugin_selector, _rr_selection, 0); - insert_box->set_route (_route); + insert_box = new ProcessorBox(*session, + sigc::mem_fun(*this, &RouteParams_UI::plugin_selector), _rr_selection, 0); + insert_box->set_route (_route); - redir_hpane.pack1 (*insert_box); + redir_hpane.pack1 (*insert_box); insert_box->ProcessorSelected.connect (mem_fun(*this, &RouteParams_UI::redirect_selected)); insert_box->ProcessorUnselected.connect (mem_fun(*this, &RouteParams_UI::redirect_selected)); diff --git a/gtk2_ardour/route_params_ui.h b/gtk2_ardour/route_params_ui.h index 75c0ef731d..ca582dadd3 100644 --- a/gtk2_ardour/route_params_ui.h +++ b/gtk2_ardour/route_params_ui.h @@ -78,11 +78,11 @@ class RouteParams_UI : public ArdourDialog Gtk::ScrolledWindow route_select_scroller; Gtk::Notebook notebook; - Gtk::Frame input_frame; - Gtk::Frame output_frame; + Gtk::Frame input_frame; + Gtk::Frame output_frame; Gtk::HPaned redir_hpane; - Gtk::Frame route_select_frame; + Gtk::Frame route_select_frame; Gtk::HBox route_hpacker; Gtk::VBox route_vpacker; @@ -93,9 +93,9 @@ class RouteParams_UI : public ArdourDialog Gtk::HPaned right_hpane; - Gtk::Frame route_choice_frame; + Gtk::Frame route_choice_frame; - Gtk::Frame route_param_frame; + Gtk::Frame route_param_frame; Gtk::VBox choice_vpacker; @@ -145,7 +145,7 @@ class RouteParams_UI : public ArdourDialog /* treeview */ - struct RouteDisplayModelColumns : public Gtk::TreeModel::ColumnRecord { + struct RouteDisplayModelColumns : public Gtk::TreeModel::ColumnRecord { RouteDisplayModelColumns() { add(text); add(route); diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h index a1f22a88df..d1dd92dd3d 100644 --- a/libs/ardour/ardour/audio_unit.h +++ b/libs/ardour/ardour/audio_unit.h @@ -166,7 +166,7 @@ class AUPluginInfo : public PluginInfo { AUPluginCachedInfo cache; - static PluginInfoList discover (); + static PluginInfoList* discover (); static void get_names (CAComponentDescription&, std::string& name, Glib::ustring& maker); static std::string stringify_descriptor (const CAComponentDescription&); diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h index f2773a3d6c..9705459ee1 100644 --- a/libs/ardour/ardour/lv2_plugin.h +++ b/libs/ardour/ardour/lv2_plugin.h @@ -176,7 +176,7 @@ struct LV2World { SLV2Value srate; SLV2Value gtk_gui; SLV2Value external_gui; - SLV2Value logarithmic; + SLV2Value logarithmic; }; @@ -184,7 +184,7 @@ class LV2PluginInfo : public PluginInfo { public: LV2PluginInfo (void* slv2_world, void* slv2_plugin);; ~LV2PluginInfo ();; - static PluginInfoList discover (void* slv2_world); + static PluginInfoList* discover (void* slv2_world); PluginPtr load (Session& session); diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h index c792b539a7..d564d62a87 100644 --- a/libs/ardour/ardour/plugin_manager.h +++ b/libs/ardour/ardour/plugin_manager.h @@ -46,12 +46,10 @@ class PluginManager : public boost::noncopyable { PluginManager (); ~PluginManager (); - /* realtime plugin APIs */ - - ARDOUR::PluginInfoList &vst_plugin_info () { return _vst_plugin_info; } - ARDOUR::PluginInfoList &ladspa_plugin_info () { return _ladspa_plugin_info; } - ARDOUR::PluginInfoList &lv2_plugin_info () { return _lv2_plugin_info; } - ARDOUR::PluginInfoList &au_plugin_info () { return _au_plugin_info; } + ARDOUR::PluginInfoList &vst_plugin_info (); + ARDOUR::PluginInfoList &ladspa_plugin_info (); + ARDOUR::PluginInfoList &lv2_plugin_info (); + ARDOUR::PluginInfoList &au_plugin_info (); void refresh (); @@ -85,10 +83,11 @@ class PluginManager : public boost::noncopyable { typedef std::set FavoritePluginList; FavoritePluginList favorites; - ARDOUR::PluginInfoList _vst_plugin_info; - ARDOUR::PluginInfoList _ladspa_plugin_info; - ARDOUR::PluginInfoList _lv2_plugin_info; - ARDOUR::PluginInfoList _au_plugin_info; + ARDOUR::PluginInfoList _empty_plugin_info; + ARDOUR::PluginInfoList* _vst_plugin_info; + ARDOUR::PluginInfoList* _ladspa_plugin_info; + ARDOUR::PluginInfoList* _lv2_plugin_info; + ARDOUR::PluginInfoList* _au_plugin_info; #ifdef HAVE_SLV2 LV2World* _lv2_world; @@ -107,10 +106,8 @@ class PluginManager : public boost::noncopyable { void add_vst_presets (); void add_presets (std::string domain); - int au_discover (); void au_refresh (); - int lv2_discover (); void lv2_refresh (); int vst_discover_from_path (std::string path); diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index b0ced9bdfb..cb91b34cf5 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -1444,7 +1444,7 @@ AUPluginInfo::au_cache_path () return Glib::build_filename (ARDOUR::get_user_ardour_path(), "au_cache"); } -PluginInfoList +PluginInfoList* AUPluginInfo::discover () { XMLTree tree; @@ -1453,7 +1453,7 @@ AUPluginInfo::discover () ARDOUR::BootMessage (_("Discovering AudioUnit plugins (could take some time ...)")); } - PluginInfoList plugs; + PluginInfoList* plugs = new PluginInfoList (); discover_fx (plugs); discover_music (plugs); diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index 678dfd4715..2090d18e96 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -703,15 +703,15 @@ LV2PluginInfo::load (Session& session) return PluginPtr(); } -PluginInfoList +PluginInfoList* LV2PluginInfo::discover (void* lv2_world) { - PluginInfoList plugs; + PluginInfoList* plugs = new PluginInfoList; LV2World* world = (LV2World*)lv2_world; SLV2Plugins plugins = slv2_world_get_all_plugins(world->world); - cerr << "LV2: Discovered " << slv2_plugins_size (plugins) << " plugins\n"; + cerr << "LV2: Discovering " << slv2_plugins_size (plugins) << " plugins" << endl; for (unsigned i=0; i < slv2_plugins_size(plugins); ++i) { SLV2Plugin p = slv2_plugins_get_at(plugins, i); @@ -750,9 +750,11 @@ LV2PluginInfo::discover (void* lv2_world) info->unique_id = slv2_value_as_uri(slv2_plugin_get_uri(p)); info->index = 0; // Meaningless for LV2 - plugs.push_back (info); + plugs->push_back (info); } + cerr << "Done LV2 discovery" << endl; + return plugs; } diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index 6ac57400c4..8315397fe8 100644 --- a/libs/ardour/plugin_manager.cc +++ b/libs/ardour/plugin_manager.cc @@ -74,6 +74,10 @@ using namespace std; PluginManager* PluginManager::_manager = 0; PluginManager::PluginManager () + : _vst_plugin_info(0) + , _ladspa_plugin_info(0) + , _lv2_plugin_info(0) + , _au_plugin_info(0) { char* s; string lrdf_path; @@ -135,8 +139,6 @@ PluginManager::PluginManager () #endif BootMessage (_("Discovering Plugins")); - - refresh (); } void @@ -159,7 +161,10 @@ PluginManager::refresh () void PluginManager::ladspa_refresh () { - _ladspa_plugin_info.clear (); + if (_ladspa_plugin_info) + _ladspa_plugin_info->clear (); + else + _ladspa_plugin_info = new ARDOUR::PluginInfoList (); static const char *standard_paths[] = { "/usr/local/lib64/ladspa", @@ -240,12 +245,13 @@ PluginManager::ladspa_discover_from_path (string /*path*/) return ret; } -static bool rdf_filter (const string &str, void */*arg*/) +static bool rdf_filter (const string &str, void* /*arg*/) { return str[0] != '.' && ((str.find(".rdf") == (str.length() - 4)) || (str.find(".rdfs") == (str.length() - 5)) || - (str.find(".n3") == (str.length() - 3))); + (str.find(".n3") == (str.length() - 3)) || + (str.find(".ttl") == (str.length() - 4))); } void @@ -368,22 +374,22 @@ PluginManager::ladspa_discover (string path) } } - if(_ladspa_plugin_info.empty()){ - _ladspa_plugin_info.push_back (info); + if(_ladspa_plugin_info->empty()){ + _ladspa_plugin_info->push_back (info); } //Ensure that the plugin is not already in the plugin list. bool found = false; - for (PluginInfoList::const_iterator i = _ladspa_plugin_info.begin(); i != _ladspa_plugin_info.end(); ++i) { + for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) { if(0 == info->unique_id.compare((*i)->unique_id)){ found = true; } } if(!found){ - _ladspa_plugin_info.push_back (info); + _ladspa_plugin_info->push_back (info); } } @@ -433,14 +439,8 @@ PluginManager::get_ladspa_category (uint32_t plugin_id) void PluginManager::lv2_refresh () { - lv2_discover(); -} - -int -PluginManager::lv2_discover () -{ + delete _lv2_plugin_info; _lv2_plugin_info = LV2PluginInfo::discover(_lv2_world); - return 0; } #endif @@ -448,14 +448,8 @@ PluginManager::lv2_discover () void PluginManager::au_refresh () { - au_discover(); -} - -int -PluginManager::au_discover () -{ + delete _au_plugin_info; _au_plugin_info = AUPluginInfo::discover(); - return 0; } #endif @@ -465,7 +459,10 @@ PluginManager::au_discover () void PluginManager::vst_refresh () { - _vst_plugin_info.clear (); + if (_vst_plugin_info) + _vst_plugin_info->clear (); + else + _vst_plugin_info = new ARDOUR::PluginInfoList(); if (vst_path.length() == 0) { vst_path = "/usr/local/lib/vst:/usr/lib/vst"; @@ -552,7 +549,7 @@ PluginManager::vst_discover (string path) info->n_outputs.set_audio (finfo->numOutputs); info->type = ARDOUR::VST; - _vst_plugin_info.push_back (info); + _vst_plugin_info->push_back (info); fst_free_info (finfo); return 0; @@ -663,3 +660,47 @@ PluginManager::remove_favorite (PluginType t, string id) FavoritePlugin fp (t, id); favorites.erase (fp); } + +ARDOUR::PluginInfoList& +PluginManager::vst_plugin_info () +{ +#ifdef VST_SUPPORT + if (!_vst_plugin_info) + vst_refresh(); + return *_vst_plugin_info; +#else + return _empty_plugin_info; +#endif +} + +ARDOUR::PluginInfoList& +PluginManager::ladspa_plugin_info () +{ + if (!_ladspa_plugin_info) + ladspa_refresh(); + return *_ladspa_plugin_info; +} + +ARDOUR::PluginInfoList& +PluginManager::lv2_plugin_info () +{ +#ifdef HAVE_SLV2 + if (!_lv2_plugin_info) + lv2_refresh(); + return *_lv2_plugin_info; +#else + return _empty_plugin_info; +#endif +} + +ARDOUR::PluginInfoList& +PluginManager::au_plugin_info () +{ +#ifdef HAVE_AUDIOUNITS + if (!_au_plugin_info) + au_refresh(); + return *_au_plugin_info; +#else + return _empty_plugin_info; +#endif +}