changeset 131:eaae73b6bd28

* Suspend/resume fft data server write activity while reading from a server to repaint the spectrogram display. Makes a significant improvement to the otherwise dreadful responsiveness of spectrogram display.
author Chris Cannam
date Thu, 03 Aug 2006 12:42:15 +0000
parents 10eec0da9efe
children 5d3a483856ff
files layer/Layer.cpp layer/Layer.h layer/SpectrogramLayer.cpp view/View.cpp
diffstat 4 files changed, 46 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/layer/Layer.cpp	Mon Jul 31 17:05:18 2006 +0000
+++ b/layer/Layer.cpp	Thu Aug 03 12:42:15 2006 +0000
@@ -19,7 +19,9 @@
 
 #include <iostream>
 
-#include "LayerFactory.h" //!!! shouldn't be including this here -- does that suggest we need to move this into layer/ ?
+#include <QMutexLocker>
+
+#include "LayerFactory.h"
 #include "base/PlayParameterRepository.h"
 
 Layer::Layer()
@@ -92,6 +94,23 @@
 }
 
 void
+Layer::setLayerDormant(const View *v, bool dormant)
+{
+    const void *vv = (const void *)v;
+    QMutexLocker locker(&m_dormancyMutex);
+    m_dormancy[vv] = dormant;
+}
+
+bool
+Layer::isLayerDormant(const View *v) const
+{
+    const void *vv = (const void *)v;
+    QMutexLocker locker(&m_dormancyMutex);
+    if (m_dormancy.find(vv) == m_dormancy.end()) return false;
+    return m_dormancy.find(vv)->second;
+}
+
+void
 Layer::showLayer(View *view, bool show)
 {
     setLayerDormant(view, !show);
--- a/layer/Layer.h	Mon Jul 31 17:05:18 2006 +0000
+++ b/layer/Layer.h	Thu Aug 03 12:42:15 2006 +0000
@@ -24,6 +24,7 @@
 #include <QObject>
 #include <QRect>
 #include <QXmlAttributes>
+#include <QMutex>
 
 #include <map>
 
@@ -226,19 +227,17 @@
      * it).  The layer may respond by (for example) freeing any cache
      * memory it is using, until next time its paint method is called,
      * when it should set itself un-dormant again.
+     *
+     * A layer class that overrides this function must also call this
+     * class's implementation.
      */
-    virtual void setLayerDormant(const View *v, bool dormant) {
-	m_dormancy[v] = dormant;
-    }
+    virtual void setLayerDormant(const View *v, bool dormant);
 
     /**
      * Return whether the layer is dormant (i.e. hidden) in the given
      * view.
      */
-    virtual bool isLayerDormant(const View *v) const {
-	if (m_dormancy.find(v) == m_dormancy.end()) return false;
-	return m_dormancy.find(v)->second;
-    }
+    virtual bool isLayerDormant(const View *v) const;
 
     virtual PlayParameters *getPlayParameters();
 
@@ -293,7 +292,8 @@
     void layerParametersChanged();
     void layerNameChanged();
 
-protected:
+private:
+    mutable QMutex m_dormancyMutex;
     mutable std::map<const void *, bool> m_dormancy;
 };
 
--- a/layer/SpectrogramLayer.cpp	Mon Jul 31 17:05:18 2006 +0000
+++ b/layer/SpectrogramLayer.cpp	Thu Aug 03 12:42:15 2006 +0000
@@ -544,6 +544,7 @@
 {
     for (ViewPixmapCache::iterator i = m_pixmapCaches.begin();
          i != m_pixmapCaches.end(); ++i) {
+
         //!!! when are views removed from the map? on setLayerDormant?
         const View *v = i->first;
 
@@ -878,11 +879,13 @@
 void
 SpectrogramLayer::setLayerDormant(const View *v, bool dormant)
 {
-    if (dormant == m_dormancy[v]) return;
-
     if (dormant) {
 
-	m_dormancy[v] = true;
+        if (isLayerDormant(v)) {
+            return;
+        }
+
+        Layer::setLayerDormant(v, true);
 
 	invalidatePixmapCaches();
         m_pixmapCaches.erase(v);
@@ -894,7 +897,7 @@
 	
     } else {
 
-	m_dormancy[v] = false;
+        Layer::setLayerDormant(v, false);
     }
 }
 
@@ -1647,7 +1650,7 @@
 	v->setLightBackground(false);
     }
 
-//    Profiler profiler("SpectrogramLayer::paint", true);
+    Profiler profiler("SpectrogramLayer::paint", true);
 #ifdef DEBUG_SPECTROGRAM_REPAINT
     std::cerr << "SpectrogramLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", m_updateTimer " << m_updateTimer << std::endl;
     
@@ -1670,7 +1673,8 @@
     // is not in the dormancy map at all -- we need it to be present
     // and accountable for when determining whether we need the cache
     // in the cache-fill thread above.
-    m_dormancy[v] = false;
+    //!!! no longer use cache-fill thread
+    const_cast<SpectrogramLayer *>(this)->Layer::setLayerDormant(v, false);
 
     size_t fftSize = getFFTSize(v);
     FFTModel *fft = getFFTModel(v);
@@ -1937,6 +1941,8 @@
     MagnitudeRange overallMag = m_viewMags[v];
     bool overallMagChanged = false;
 
+    fft->suspend();
+
     for (int x = 0; x < w; ++x) {
 
 	for (int y = 0; y < h; ++y) {
@@ -2116,6 +2122,8 @@
 #ifdef DEBUG_SPECTROGRAM_REPAINT
     std::cerr << "SpectrogramLayer::paint() returning" << std::endl;
 #endif
+
+    fft->resume();
 }
 
 void
--- a/view/View.cpp	Mon Jul 31 17:05:18 2006 +0000
+++ b/view/View.cpp	Thu Aug 03 12:42:15 2006 +0000
@@ -923,6 +923,10 @@
     bool metUnscrollable = false;
 
     for (LayerList::const_iterator i = m_layers.begin(); i != m_layers.end(); ++i) {
+        std::cerr << "View::getScrollableBackLayers: calling isLayerDormant on layer " << *i << std::endl;
+        std::cerr << "(name is " << (*i)->objectName().toStdString() << ")"
+                  << std::endl;
+        std::cerr << "View::getScrollableBackLayers: I am " << this << std::endl;
 	if ((*i)->isLayerDormant(this)) continue;
 	if ((*i)->isLayerOpaque()) {
 	    // You can't see anything behind an opaque layer!