comparison layer/SpectrogramLayer.cpp @ 920:e39d5d2734ed osx-retina

Fix crash caused by using proxy (of unknown lifecycle) instead of view as cache key
author Chris Cannam
date Wed, 18 Mar 2015 15:10:36 +0000
parents 4fe7a09be0fe
children 64c2b3a4435a
comparison
equal deleted inserted replaced
919:a5488775f880 920:e39d5d2734ed
1004 return; 1004 return;
1005 } 1005 }
1006 1006
1007 Layer::setLayerDormant(v, true); 1007 Layer::setLayerDormant(v, true);
1008 1008
1009 const View *view = v->getView();
1010
1009 invalidateImageCaches(); 1011 invalidateImageCaches();
1010 m_imageCaches.erase(v); 1012 m_imageCaches.erase(view);
1011 1013
1012 if (m_fftModels.find(v) != m_fftModels.end()) { 1014 if (m_fftModels.find(view) != m_fftModels.end()) {
1013 1015
1014 if (m_sliceableModel == m_fftModels[v].first) { 1016 if (m_sliceableModel == m_fftModels[view].first) {
1015 bool replaced = false; 1017 bool replaced = false;
1016 for (ViewFFTMap::iterator i = m_fftModels.begin(); 1018 for (ViewFFTMap::iterator i = m_fftModels.begin();
1017 i != m_fftModels.end(); ++i) { 1019 i != m_fftModels.end(); ++i) {
1018 if (i->second.first != m_sliceableModel) { 1020 if (i->second.first != m_sliceableModel) {
1019 emit sliceableModelReplaced(m_sliceableModel, i->second.first); 1021 emit sliceableModelReplaced(m_sliceableModel, i->second.first);
1022 } 1024 }
1023 } 1025 }
1024 if (!replaced) emit sliceableModelReplaced(m_sliceableModel, 0); 1026 if (!replaced) emit sliceableModelReplaced(m_sliceableModel, 0);
1025 } 1027 }
1026 1028
1027 delete m_fftModels[v].first; 1029 delete m_fftModels[view].first;
1028 m_fftModels.erase(v); 1030 m_fftModels.erase(view);
1029 1031
1030 delete m_peakCaches[v]; 1032 delete m_peakCaches[view];
1031 m_peakCaches.erase(v); 1033 m_peakCaches.erase(view);
1032 } 1034 }
1033 1035
1034 } else { 1036 } else {
1035 1037
1036 Layer::setLayerDormant(v, false); 1038 Layer::setLayerDormant(v, false);
1597 { 1599 {
1598 if (!m_model) return 0; 1600 if (!m_model) return 0;
1599 1601
1600 int fftSize = getFFTSize(v); 1602 int fftSize = getFFTSize(v);
1601 1603
1602 if (m_fftModels.find(v) != m_fftModels.end()) { 1604 const View *view = v->getView();
1603 if (m_fftModels[v].first == 0) { 1605
1606 if (m_fftModels.find(view) != m_fftModels.end()) {
1607 if (m_fftModels[view].first == 0) {
1604 #ifdef DEBUG_SPECTROGRAM_REPAINT 1608 #ifdef DEBUG_SPECTROGRAM_REPAINT
1605 SVDEBUG << "SpectrogramLayer::getFFTModel(" << v << "): Found null model" << endl; 1609 SVDEBUG << "SpectrogramLayer::getFFTModel(" << v << "): Found null model" << endl;
1606 #endif 1610 #endif
1607 return 0; 1611 return 0;
1608 } 1612 }
1609 if (m_fftModels[v].first->getHeight() != fftSize / 2 + 1) { 1613 if (m_fftModels[view].first->getHeight() != fftSize / 2 + 1) {
1610 #ifdef DEBUG_SPECTROGRAM_REPAINT 1614 #ifdef DEBUG_SPECTROGRAM_REPAINT
1611 SVDEBUG << "SpectrogramLayer::getFFTModel(" << v << "): Found a model with the wrong height (" << m_fftModels[v].first->getHeight() << ", wanted " << (fftSize / 2 + 1) << ")" << endl; 1615 SVDEBUG << "SpectrogramLayer::getFFTModel(" << v << "): Found a model with the wrong height (" << m_fftModels[view].first->getHeight() << ", wanted " << (fftSize / 2 + 1) << ")" << endl;
1612 #endif 1616 #endif
1613 delete m_fftModels[v].first; 1617 delete m_fftModels[view].first;
1614 m_fftModels.erase(v); 1618 m_fftModels.erase(view);
1615 delete m_peakCaches[v]; 1619 delete m_peakCaches[view];
1616 m_peakCaches.erase(v); 1620 m_peakCaches.erase(view);
1617 } else { 1621 } else {
1618 #ifdef DEBUG_SPECTROGRAM_REPAINT 1622 #ifdef DEBUG_SPECTROGRAM_REPAINT
1619 SVDEBUG << "SpectrogramLayer::getFFTModel(" << v << "): Found a good model of height " << m_fftModels[v].first->getHeight() << endl; 1623 SVDEBUG << "SpectrogramLayer::getFFTModel(" << v << "): Found a good model of height " << m_fftModels[view].first->getHeight() << endl;
1620 #endif 1624 #endif
1621 return m_fftModels[v].first; 1625 return m_fftModels[view].first;
1622 } 1626 }
1623 } 1627 }
1624 1628
1625 if (m_fftModels.find(v) == m_fftModels.end()) { 1629 if (m_fftModels.find(view) == m_fftModels.end()) {
1626 1630
1627 FFTModel *model = new FFTModel(m_model, 1631 FFTModel *model = new FFTModel(m_model,
1628 m_channel, 1632 m_channel,
1629 m_windowType, 1633 m_windowType,
1630 m_windowSize, 1634 m_windowSize,
1638 QMessageBox::critical 1642 QMessageBox::critical
1639 (0, tr("FFT cache failed"), 1643 (0, tr("FFT cache failed"),
1640 tr("Failed to create the FFT model for this spectrogram.\n" 1644 tr("Failed to create the FFT model for this spectrogram.\n"
1641 "There may be insufficient memory or disc space to continue.")); 1645 "There may be insufficient memory or disc space to continue."));
1642 delete model; 1646 delete model;
1643 m_fftModels[v] = FFTFillPair(0, 0); 1647 m_fftModels[view] = FFTFillPair(0, 0);
1644 return 0; 1648 return 0;
1645 } 1649 }
1646 1650
1647 if (!m_sliceableModel) { 1651 if (!m_sliceableModel) {
1648 #ifdef DEBUG_SPECTROGRAM 1652 #ifdef DEBUG_SPECTROGRAM
1650 #endif 1654 #endif
1651 ((SpectrogramLayer *)this)->sliceableModelReplaced(0, model); 1655 ((SpectrogramLayer *)this)->sliceableModelReplaced(0, model);
1652 m_sliceableModel = model; 1656 m_sliceableModel = model;
1653 } 1657 }
1654 1658
1655 m_fftModels[v] = FFTFillPair(model, 0); 1659 m_fftModels[view] = FFTFillPair(model, 0);
1656 1660
1657 model->resume(); 1661 model->resume();
1658 1662
1659 delete m_updateTimer; 1663 delete m_updateTimer;
1660 m_updateTimer = new QTimer((SpectrogramLayer *)this); 1664 m_updateTimer = new QTimer((SpectrogramLayer *)this);
1661 connect(m_updateTimer, SIGNAL(timeout()), 1665 connect(m_updateTimer, SIGNAL(timeout()),
1662 this, SLOT(fillTimerTimedOut())); 1666 this, SLOT(fillTimerTimedOut()));
1663 m_updateTimer->start(200); 1667 m_updateTimer->start(200);
1664 } 1668 }
1665 1669
1666 return m_fftModels[v].first; 1670 return m_fftModels[view].first;
1667 } 1671 }
1668 1672
1669 Dense3DModelPeakCache * 1673 Dense3DModelPeakCache *
1670 SpectrogramLayer::getPeakCache(const LayerGeometryProvider *v) const 1674 SpectrogramLayer::getPeakCache(const LayerGeometryProvider *v) const
1671 { 1675 {
1672 if (!m_peakCaches[v]) { 1676 const View *view = v->getView();
1677 if (!m_peakCaches[view]) {
1673 FFTModel *f = getFFTModel(v); 1678 FFTModel *f = getFFTModel(v);
1674 if (!f) return 0; 1679 if (!f) return 0;
1675 m_peakCaches[v] = new Dense3DModelPeakCache(f, 8); 1680 m_peakCaches[view] = new Dense3DModelPeakCache(f, 8);
1676 } 1681 }
1677 return m_peakCaches[v]; 1682 return m_peakCaches[view];
1678 } 1683 }
1679 1684
1680 const Model * 1685 const Model *
1681 SpectrogramLayer::getSliceableModel() const 1686 SpectrogramLayer::getSliceableModel() const
1682 { 1687 {
1805 if (!fft) { 1810 if (!fft) {
1806 cerr << "ERROR: SpectrogramLayer::paint(): No FFT model, returning" << endl; 1811 cerr << "ERROR: SpectrogramLayer::paint(): No FFT model, returning" << endl;
1807 return; 1812 return;
1808 } 1813 }
1809 */ 1814 */
1810 ImageCache &cache = m_imageCaches[v]; 1815
1816 const View *view = v->getView();
1817
1818 ImageCache &cache = m_imageCaches[view];
1811 1819
1812 #ifdef DEBUG_SPECTROGRAM_REPAINT 1820 #ifdef DEBUG_SPECTROGRAM_REPAINT
1813 SVDEBUG << "SpectrogramLayer::paint(): image cache valid area " << cache. 1821 SVDEBUG << "SpectrogramLayer::paint(): image cache valid area " << cache.
1814 1822
1815 validArea.x() << ", " << cache.validArea.y() << ", " << cache.validArea.width() << "x" << cache.validArea.height() << endl; 1823 validArea.x() << ", " << cache.validArea.y() << ", " << cache.validArea.width() << "x" << cache.validArea.height() << endl;
2877 2885
2878 int 2886 int
2879 SpectrogramLayer::getCompletion(LayerGeometryProvider *v) const 2887 SpectrogramLayer::getCompletion(LayerGeometryProvider *v) const
2880 { 2888 {
2881 if (m_updateTimer == 0) return 100; 2889 if (m_updateTimer == 0) return 100;
2882 if (m_fftModels.find(v) == m_fftModels.end()) return 100; 2890
2883 2891 const View *view = v->getView();
2884 int completion = m_fftModels[v].first->getCompletion(); 2892
2893 if (m_fftModels.find(view) == m_fftModels.end()) return 100;
2894
2895 int completion = m_fftModels[view].first->getCompletion();
2885 #ifdef DEBUG_SPECTROGRAM_REPAINT 2896 #ifdef DEBUG_SPECTROGRAM_REPAINT
2886 SVDEBUG << "SpectrogramLayer::getCompletion: completion = " << completion << endl; 2897 SVDEBUG << "SpectrogramLayer::getCompletion: completion = " << completion << endl;
2887 #endif 2898 #endif
2888 return completion; 2899 return completion;
2889 } 2900 }
2890 2901
2891 QString 2902 QString
2892 SpectrogramLayer::getError(LayerGeometryProvider *v) const 2903 SpectrogramLayer::getError(LayerGeometryProvider *v) const
2893 { 2904 {
2894 if (m_fftModels.find(v) == m_fftModels.end()) return ""; 2905 const View *view = v->getView();
2895 return m_fftModels[v].first->getError(); 2906 if (m_fftModels.find(view) == m_fftModels.end()) return "";
2907 return m_fftModels[view].first->getError();
2896 } 2908 }
2897 2909
2898 bool 2910 bool
2899 SpectrogramLayer::getValueExtents(double &min, double &max, 2911 SpectrogramLayer::getValueExtents(double &min, double &max,
2900 bool &logarithmic, QString &unit) const 2912 bool &logarithmic, QString &unit) const
2985 } 2997 }
2986 2998
2987 void 2999 void
2988 SpectrogramLayer::measureDoubleClick(LayerGeometryProvider *v, QMouseEvent *e) 3000 SpectrogramLayer::measureDoubleClick(LayerGeometryProvider *v, QMouseEvent *e)
2989 { 3001 {
2990 ImageCache &cache = m_imageCaches[v]; 3002 const View *view = v->getView();
3003 ImageCache &cache = m_imageCaches[view];
2991 3004
2992 cerr << "cache width: " << cache.image.width() << ", height: " 3005 cerr << "cache width: " << cache.image.width() << ", height: "
2993 << cache.image.height() << endl; 3006 << cache.image.height() << endl;
2994 3007
2995 QImage image = cache.image; 3008 QImage image = cache.image;
2996 3009
2997 ImageRegionFinder finder; 3010 ImageRegionFinder finder;
2998 QRect rect = finder.findRegionExtents(&image, e->pos()); 3011 QRect rect = finder.findRegionExtents(&image, e->pos());