Better fix for 6183.
authornick_m <mainsbridge@gmail.com>
Sat, 28 Mar 2015 15:13:40 +0000 (02:13 +1100)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 30 Mar 2015 14:18:59 +0000 (09:18 -0500)
Invalidate all source entries from the image cache when we get our
region's DropReferences signal, while ignoring any subsequent regions with
no source.

libs/canvas/canvas/wave_view.h
libs/canvas/wave_view.cc

index 4b6d6c5627e3b7cc73512ad60b3df4e83283e600..9ace1486ce2adf5eec71e727efe0454c5969dc12 100644 (file)
@@ -163,6 +163,7 @@ private:
 
        static std::map <boost::shared_ptr<ARDOUR::AudioSource>, std::vector <CacheEntry> > _image_cache;
        void consolidate_image_cache () const;
+       void invalidate_source (boost::weak_ptr<ARDOUR::AudioSource>);
        void invalidate_image_cache ();
 
        boost::shared_ptr<ARDOUR::AudioRegion> _region;
@@ -188,6 +189,7 @@ private:
        ARDOUR::frameoffset_t _region_start;
 
         PBD::ScopedConnectionList invalidation_connection;
+       PBD::ScopedConnection _source_invalidated_connection;
 
         static double _global_gradient_depth;
         static bool   _global_logscaled;
index 3521ef33cd20bc610a745ceb7196cf06c7baab64..8570d8d32c5f3a1a9f64e94e4b9f535572ccce31 100644 (file)
@@ -38,6 +38,8 @@
 
 #include <gdkmm/general.h>
 
+#include "gtk2_ardour/gui_thread.h"
+
 using namespace std;
 using namespace ARDOUR;
 using namespace ArdourCanvas;
@@ -74,6 +76,10 @@ WaveView::WaveView (Canvas* c, boost::shared_ptr<ARDOUR::AudioRegion> region)
        , _start_shift (0.0)
        , _region_start (region->start())
 {
+       _region->DropReferences.connect (_source_invalidated_connection, MISSING_INVALIDATOR,
+                                                    boost::bind (&ArdourCanvas::WaveView::invalidate_source,
+                                                                 this, boost::weak_ptr<AudioSource>(_region->audio_source())), gui_context());
+
        VisualPropertiesChanged.connect_same_thread (invalidation_connection, boost::bind (&WaveView::handle_visual_property_change, this));
        ClipLevelChanged.connect_same_thread (invalidation_connection, boost::bind (&WaveView::handle_clip_level_change, this));
 }
@@ -97,12 +103,17 @@ WaveView::WaveView (Item* parent, boost::shared_ptr<ARDOUR::AudioRegion> region)
        , _region_amplitude (_region->scale_amplitude ())
        , _region_start (region->start())
 {
+       _region->DropReferences.connect (_source_invalidated_connection, MISSING_INVALIDATOR,
+                                                    boost::bind (&ArdourCanvas::WaveView::invalidate_source,
+                                                                 this, boost::weak_ptr<AudioSource>(_region->audio_source())), gui_context());
+
        VisualPropertiesChanged.connect_same_thread (invalidation_connection, boost::bind (&WaveView::handle_visual_property_change, this));
        ClipLevelChanged.connect_same_thread (invalidation_connection, boost::bind (&WaveView::handle_clip_level_change, this));
 }
 
 WaveView::~WaveView ()
 {
+       _source_invalidated_connection.disconnect();
        invalidate_image_cache ();
 }
 
@@ -206,23 +217,32 @@ WaveView::set_clip_level (double dB)
 }
 
 void
-WaveView::invalidate_image_cache ()
+WaveView::invalidate_source (boost::weak_ptr<AudioSource> src)
 {
-       vector <uint32_t> deletion_list;
-       vector <CacheEntry> caches;
+       if (boost::shared_ptr<AudioSource> source = src.lock()) {
 
-       /* The source may have disappeared in the case of rec regions.*/
-       if (_region->n_channels() == 0) {
                std::map <boost::shared_ptr<ARDOUR::AudioSource>, std::vector <CacheEntry> >::iterator i;
-               for (i = _image_cache.begin(); i != _image_cache.end(); ++i) {
-                       if (i->first.unique()) {
-                               for (uint32_t n = 0; n < (*i).second.size (); ++n) {
-                                       (*i).second[n].image.clear ();
+               for (i = _image_cache.begin (); i != _image_cache.end (); ++i) {
+                       if (i->first == source) {
+                               for (uint32_t n = 0; n < i->second.size (); ++n) {
+                                       i->second[n].image.clear ();
                                }
-                               (*i).second.clear ();
-                               _image_cache.erase(i->first);
+                               i->second.clear ();
+                               _image_cache.erase (i->first);
                        }
                }
+       }
+}
+
+void
+WaveView::invalidate_image_cache ()
+{
+       vector <uint32_t> deletion_list;
+       vector <CacheEntry> caches;
+
+       /* The source may have disappeared.*/
+
+       if (_region->n_channels() == 0) {
                return;
        }