Skip to content

Commit

Permalink
plot: Draw plot tiles in background thread
Browse files Browse the repository at this point in the history
  • Loading branch information
miek committed Apr 3, 2016
1 parent 43a77e8 commit f20d99a
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 12 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
11 changes: 10 additions & 1 deletion plotview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<SampleSource<std::complex<float>>*>(iqPlot->source().get())));
auto quadDemodPlot = createQuadratureDemodPlot(static_cast<SampleSource<std::complex<float>>*>(iqPlot->source().get()));
plots.emplace_back(quadDemodPlot);

connect(iqPlot, &TracePlot::repaint, this, &PlotView::repaint);
connect(quadDemodPlot, &TracePlot::repaint, this, &PlotView::repaint);

mainSampleSource->subscribe(this);
}
Expand Down Expand Up @@ -136,6 +140,11 @@ void PlotView::invalidateEvent()
horizontalScrollBar()->setMaximum(mainSampleSource->count());
}

void PlotView::repaint()
{
viewport()->update();
}

void PlotView::setCursorSegments(int segments)
{
cursors.setSegments(segments);
Expand Down
1 change: 1 addition & 0 deletions plotview.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
30 changes: 21 additions & 9 deletions traceplot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@

#include <QPixmapCache>
#include <QTextStream>
#include <QtConcurrent>
#include "samplesource.h"
#include "traceplot.h"

TracePlot::TracePlot(std::shared_ptr<AbstractSampleSource> source) : sampleSource(source) {

connect(this, &TracePlot::imageReady, this, &TracePlot::handleImage);
}

void TracePlot::paintMid(QPainter &painter, QRect &rect, range_t<off_t> sampleRange)
Expand Down Expand Up @@ -52,19 +53,22 @@ void TracePlot::paintMid(QPainter &painter, QRect &rect, range_t<off_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<off_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<off_t> sampleRange)
void TracePlot::drawTile(QString key, const QRect &rect, range_t<off_t> sampleRange)
{
QImage image(rect.size(), QImage::Format_ARGB32);
image.fill(Qt::transparent);
Expand All @@ -79,7 +83,7 @@ QImage TracePlot::drawTile(const QRect &rect, range_t<off_t> sampleRange)
if (auto src = dynamic_cast<SampleSource<std::complex<float>>*>(sampleSource.get())) {
auto samples = src->getSamples(firstSample, length);
if (samples == nullptr)
return image;
return;

painter.setPen(Qt::red);
plotTrace(painter, rect, reinterpret_cast<float*>(samples.get()), length, 2);
Expand All @@ -90,15 +94,23 @@ QImage TracePlot::drawTile(const QRect &rect, range_t<off_t> sampleRange)
} else if (auto src = dynamic_cast<SampleSource<float>*>(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);
} else {
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)
Expand Down
10 changes: 9 additions & 1 deletion traceplot.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,19 @@ class TracePlot : public Plot
void paintMid(QPainter &painter, QRect &rect, range_t<off_t> sampleRange);
std::shared_ptr<AbstractSampleSource> source() { return sampleSource; };

signals:
void imageReady(QString key, QImage image);
void repaint();

public slots:
void handleImage(QString key, QImage image);

private:
QSet<QString> tasks;
const int tileWidth = 1000;
std::shared_ptr<AbstractSampleSource> sampleSource;

QPixmap getTile(off_t tileID, off_t sampleCount);
QImage drawTile(const QRect &rect, range_t<off_t> sampleRange);
void drawTile(QString key, const QRect &rect, range_t<off_t> sampleRange);
void plotTrace(QPainter &painter, const QRect &rect, float *samples, off_t count, int step);
};

0 comments on commit f20d99a

Please sign in to comment.