fix threaded state restore (duplicate calls to restore during init)
authorRobin Gareus <robin@gareus.org>
Tue, 23 Aug 2016 11:40:42 +0000 (13:40 +0200)
committerRobin Gareus <robin@gareus.org>
Tue, 23 Aug 2016 11:46:11 +0000 (13:46 +0200)
and also allow immediate work during use latency-compute runs.

At session load, Ardour calls a plugins "set default" state (GUI thread).
Some plugins may schedule work during state-restore. Ardour immediately
proceeded to restore the actual session plugin state without processing
the already scheduled work and without calling run() for a plugin
to apply state synchronously.

libs/ardour/ardour/lv2_plugin.h
libs/ardour/lv2_plugin.cc

index 27ed9bbd29d94000600f78bee48021ea863bf51e..269c158714e0ed56126883888335a280dfa5e1d8 100644 (file)
@@ -312,7 +312,7 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
 
        void init (const void* c_plugin, framecnt_t rate);
        void allocate_atom_event_buffers ();
-       void run (pframes_t nsamples);
+       void run (pframes_t nsamples, bool sync_work = false);
 
        void load_supported_properties(PropertyDescriptors& descs);
 
index 2992dd65c1671509bd3431362e0715d5b1af7716..e0498b7d3c8a8eb8234eddefadb48c4e3dfb02b2 100644 (file)
@@ -558,6 +558,13 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
 
 #ifdef HAVE_LILV_0_16_0
        // Load default state
+       if (_worker) {
+               /* immediately schedule any work,
+                * so that state restore later will not find a busy
+                * worker.  latency_compute_run() flushes any replies
+                */
+               _worker->set_synchronous(true);
+       }
        LilvState* state = lilv_state_new_from_world(
                _world.world, _uri_map.urid_map(), lilv_plugin_get_uri(_impl->plugin));
        if (state && _has_state_interface) {
@@ -2830,7 +2837,7 @@ LV2Plugin::get_scale_points(uint32_t port_index) const
 }
 
 void
-LV2Plugin::run(pframes_t nframes)
+LV2Plugin::run(pframes_t nframes, bool sync_work)
 {
        uint32_t const N = parameter_count();
        for (uint32_t i = 0; i < N; ++i) {
@@ -2841,7 +2848,7 @@ LV2Plugin::run(pframes_t nframes)
 
        if (_worker) {
                // Execute work synchronously if we're freewheeling (export)
-               _worker->set_synchronous(session().engine().freewheeling());
+               _worker->set_synchronous(sync_work || session().engine().freewheeling());
        }
 
        // Run the plugin for this cycle
@@ -2902,7 +2909,7 @@ LV2Plugin::latency_compute_run()
                port_index++;
        }
 
-       run(bufsize);
+       run(bufsize, true);
        deactivate();
        if (was_activated) {
                activate();