From 077e62573493d889151ecbde4ecfc088ac9f08b1 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 11 Jun 2015 13:34:46 -0400 Subject: don't queue a callback with the idle event for waveview image generation if one is already queued. Also, hold relevant lock when waking image rendering thread. --- libs/canvas/canvas/wave_view.h | 1 + libs/canvas/wave_view.cc | 29 +++++++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/libs/canvas/canvas/wave_view.h b/libs/canvas/canvas/wave_view.h index 9f87855e54..ceb6829da2 100644 --- a/libs/canvas/canvas/wave_view.h +++ b/libs/canvas/canvas/wave_view.h @@ -310,6 +310,7 @@ public: double _amplitude_above_axis; float _region_amplitude; double _start_shift; + mutable bool idle_queued; /** The `start' value to use for the region; we can't use the region's * value as the crossfade editor needs to alter it. diff --git a/libs/canvas/wave_view.cc b/libs/canvas/wave_view.cc index 111bf73f27..6dc5c71726 100644 --- a/libs/canvas/wave_view.cc +++ b/libs/canvas/wave_view.cc @@ -87,6 +87,7 @@ WaveView::WaveView (Canvas* c, boost::shared_ptr region) , _amplitude_above_axis (1.0) , _region_amplitude (region->scale_amplitude ()) , _start_shift (0.0) + , idle_queued (false) , _region_start (region->start()) , get_image_in_thread (false) , always_get_image_in_thread (false) @@ -115,6 +116,8 @@ WaveView::WaveView (Item* parent, boost::shared_ptr region) , _gradient_depth_independent (false) , _amplitude_above_axis (1.0) , _region_amplitude (region->scale_amplitude ()) + , _start_shift (0.0) + , idle_queued (false) , _region_start (region->start()) , get_image_in_thread (false) , always_get_image_in_thread (false) @@ -1342,7 +1345,6 @@ WaveView::set_start_shift (double pixels) _start_shift = pixels; end_visual_change (); } - void WaveView::cancel_my_render_request () const @@ -1381,20 +1383,27 @@ WaveView::send_request (boost::shared_ptr req) const start_drawing_thread (); - Glib::signal_idle().connect (sigc::bind (sigc::mem_fun (*this, &WaveView::idle_send_request), req)); + /* this is always called from the GUI thread (there is only one), and + * the same thread runs the idle callback chain. thus we do not need + * any locks to protect idle_queued - it is only ever set or read in + * the unitary GUI thread. + */ + + if (!idle_queued) { + Glib::signal_idle().connect (sigc::bind (sigc::mem_fun (*this, &WaveView::idle_send_request), req)); + idle_queued = true; + } } bool WaveView::idle_send_request (boost::shared_ptr req) const { - { - Glib::Threads::Mutex::Lock lm (request_queue_lock); - /* swap requests (protected by lock) */ - current_request = req; - request_queue.insert (this); - } - - request_cond.signal (); /* wake thread */ + Glib::Threads::Mutex::Lock lm (request_queue_lock); + /* swap requests (protected by lock) */ + current_request = req; + request_queue.insert (this); + request_cond.signal (); /* wake thread - must be done while holding lock */ + idle_queued = false; return false; /* do not call from idle again */ } -- cgit v1.2.3