diff --git a/CMakeLists.txt b/CMakeLists.txt index d1f9b51..783821c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,7 @@ link_directories( ) add_executable(inspectrum ${inspectrum_sources}) -qt5_use_modules(inspectrum Widgets) +qt5_use_modules(inspectrum Widgets Concurrent) target_link_libraries(inspectrum ${Boost_LIBRARIES} diff --git a/plotview.cpp b/plotview.cpp index fb66335..e7d85ab 100644 --- a/plotview.cpp +++ b/plotview.cpp @@ -46,7 +46,11 @@ PlotView::PlotView(InputSource *input) : cursors(this), tuner(this), viewRange({ iqPlot = createIQPlot(mainSampleSource); plots.emplace_back(iqPlot); - plots.emplace_back(createQuadratureDemodPlot(static_cast>*>(iqPlot->source().get()))); + auto quadDemodPlot = createQuadratureDemodPlot(static_cast>*>(iqPlot->source().get())); + plots.emplace_back(quadDemodPlot); + + connect(iqPlot, &TracePlot::repaint, this, &PlotView::repaint); + connect(quadDemodPlot, &TracePlot::repaint, this, &PlotView::repaint); mainSampleSource->subscribe(this); } @@ -136,6 +140,11 @@ void PlotView::invalidateEvent() horizontalScrollBar()->setMaximum(mainSampleSource->count()); } +void PlotView::repaint() +{ + viewport()->update(); +} + void PlotView::setCursorSegments(int segments) { cursors.setSegments(segments); diff --git a/plotview.h b/plotview.h index 6096713..2f237f9 100644 --- a/plotview.h +++ b/plotview.h @@ -47,6 +47,7 @@ public slots: void cursorsMoved(); void enableCursors(bool enable); void invalidateEvent(); + void repaint(); void setCursorSegments(int segments); void setFFTAndZoom(int fftSize, int zoomLevel); void setPowerMin(int power); diff --git a/traceplot.cpp b/traceplot.cpp index 265c76f..c88349a 100644 --- a/traceplot.cpp +++ b/traceplot.cpp @@ -19,11 +19,12 @@ #include #include +#include #include "samplesource.h" #include "traceplot.h" TracePlot::TracePlot(std::shared_ptr source) : sampleSource(source) { - + connect(this, &TracePlot::imageReady, this, &TracePlot::handleImage); } void TracePlot::paintMid(QPainter &painter, QRect &rect, range_t sampleRange) @@ -52,19 +53,22 @@ void TracePlot::paintMid(QPainter &painter, QRect &rect, range_t sampleRa QPixmap TracePlot::getTile(off_t tileID, off_t sampleCount) { - QPixmap pixmap; + QPixmap pixmap(tileWidth, height()); QString key; QTextStream(&key) << "traceplot_" << this << "_" << tileID << "_" << sampleCount; if (QPixmapCache::find(key, &pixmap)) return pixmap; - auto image = drawTile(QRect(0, 0, tileWidth, height()), {tileID * sampleCount, (tileID + 1) * sampleCount}); - pixmap = QPixmap::fromImage(image); - QPixmapCache::insert(key, pixmap); + if (!tasks.contains(key)) { + range_t sampleRange{tileID * sampleCount, (tileID + 1) * sampleCount}; + QtConcurrent::run(this, &TracePlot::drawTile, key, QRect(0, 0, tileWidth, height()), sampleRange); + tasks.insert(key); + } + pixmap.fill(Qt::transparent); return pixmap; } -QImage TracePlot::drawTile(const QRect &rect, range_t sampleRange) +void TracePlot::drawTile(QString key, const QRect &rect, range_t sampleRange) { QImage image(rect.size(), QImage::Format_ARGB32); image.fill(Qt::transparent); @@ -79,7 +83,7 @@ QImage TracePlot::drawTile(const QRect &rect, range_t sampleRange) if (auto src = dynamic_cast>*>(sampleSource.get())) { auto samples = src->getSamples(firstSample, length); if (samples == nullptr) - return image; + return; painter.setPen(Qt::red); plotTrace(painter, rect, reinterpret_cast(samples.get()), length, 2); @@ -90,7 +94,7 @@ QImage TracePlot::drawTile(const QRect &rect, range_t sampleRange) } else if (auto src = dynamic_cast*>(sampleSource.get())) { auto samples = src->getSamples(firstSample, length); if (samples == nullptr) - return image; + return; painter.setPen(Qt::green); plotTrace(painter, rect, samples.get(), length, 1); @@ -98,7 +102,15 @@ QImage TracePlot::drawTile(const QRect &rect, range_t sampleRange) throw std::runtime_error("TracePlot::paintMid: Unsupported source type"); } - return image; + emit imageReady(key, image); +} + +void TracePlot::handleImage(QString key, QImage image) +{ + auto pixmap = QPixmap::fromImage(image); + QPixmapCache::insert(key, pixmap); + tasks.remove(key); + emit repaint(); } void TracePlot::plotTrace(QPainter &painter, const QRect &rect, float *samples, off_t count, int step = 1) diff --git a/traceplot.h b/traceplot.h index 2b1bd6d..6f2da7f 100644 --- a/traceplot.h +++ b/traceplot.h @@ -33,11 +33,19 @@ public: void paintMid(QPainter &painter, QRect &rect, range_t sampleRange); std::shared_ptr source() { return sampleSource; }; +signals: + void imageReady(QString key, QImage image); + void repaint(); + +public slots: + void handleImage(QString key, QImage image); + private: + QSet tasks; const int tileWidth = 1000; std::shared_ptr sampleSource; QPixmap getTile(off_t tileID, off_t sampleCount); - QImage drawTile(const QRect &rect, range_t sampleRange); + void drawTile(QString key, const QRect &rect, range_t sampleRange); void plotTrace(QPainter &painter, const QRect &rect, float *samples, off_t count, int step); };