From 0385ad1b1cc3dcd4673b3c674bc28ca12a7c7450 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 20 Jul 2018 10:58:30 +0100 Subject: Refactor renderer thread --- gui/fpgaviewwidget.cc | 31 ++++++-------------------- gui/fpgaviewwidget.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 27 deletions(-) (limited to 'gui') diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc index f4bd2b97..9a03b2a5 100644 --- a/gui/fpgaviewwidget.cc +++ b/gui/fpgaviewwidget.cc @@ -23,7 +23,6 @@ #include #include #include -#include #include #include "fpgaviewwidget.h" @@ -242,7 +241,7 @@ void LineShader::draw(const LineShaderData &line, const QColor &color, float thi } FPGAViewWidget::FPGAViewWidget(QWidget *parent) - : QOpenGLWidget(parent), lineShader_(this), zoom_(500.f), ctx_(nullptr), rendererData_(new FPGAViewWidget::RendererData), rendererArgs_(new FPGAViewWidget::RendererArgs) + : QOpenGLWidget(parent), lineShader_(this), zoom_(500.f), ctx_(nullptr), paintTimer_(this), rendererData_(new FPGAViewWidget::RendererData), rendererArgs_(new FPGAViewWidget::RendererArgs) { colors_.background = QColor("#000000"); colors_.grid = QColor("#333"); @@ -276,16 +275,12 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent) printf("Could not get OpenGL 3.1 context - trying anyway...\n "); } - QTimer *timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), this, SLOT(update())); - timer->start(1000/20); + connect(&paintTimer_, SIGNAL(timeout()), this, SLOT(update())); + paintTimer_.start(std::chrono::duration(1000/20)); // paint GL 20 times per second - timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), this, SLOT(pokeRenderer())); - timer->start(1000/2); - - renderThread_ = std::unique_ptr(QThread::create([this] { renderLinesWorker(); })); - renderThread_->start(); + renderRunner_ = std::unique_ptr(new PeriodicRunner(this, [this] { renderLines(); })); + renderRunner_->start(); + renderRunner_->startTimer(std::chrono::duration(1000/2)); // render line 2 times per second } FPGAViewWidget::~FPGAViewWidget() {} @@ -423,19 +418,7 @@ void FPGAViewWidget::paintGL() } void FPGAViewWidget::pokeRenderer(void) { - render_.wakeOne(); -} - -void FPGAViewWidget::renderLinesWorker(void) { - for (;;) { - QMutex mutex; - mutex.lock(); - render_.wait(&mutex); - - renderLines(); - - mutex.unlock(); - } + renderRunner_->poke(); } void FPGAViewWidget::renderLines(void) diff --git a/gui/fpgaviewwidget.h b/gui/fpgaviewwidget.h index 19440054..f846abca 100644 --- a/gui/fpgaviewwidget.h +++ b/gui/fpgaviewwidget.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -209,6 +210,60 @@ class LineShader void draw(const LineShaderData &data, const QColor &color, float thickness, const QMatrix4x4 &projection); }; +class PeriodicRunner : public QThread +{ + Q_OBJECT +private: + QMutex mutex_; + QWaitCondition condition_; + bool abort_; + std::function target_; + QTimer timer_; +public: + explicit PeriodicRunner(QObject *parent, std::function target) : + QThread(parent), abort_(false), target_(target), timer_(this) + { + connect(&timer_, &QTimer::timeout, this, &PeriodicRunner::poke); + } + + void run(void) override + { + for (;;) { + mutex_.lock(); + condition_.wait(&mutex_); + + if (abort_) { + mutex_.unlock(); + return; + } + + target_(); + + mutex_.unlock(); + } + } + + void startTimer(std::chrono::milliseconds value) + { + timer_.start(value); + } + + ~PeriodicRunner() + { + mutex_.lock(); + abort_ = true; + condition_.wakeOne(); + mutex_.unlock(); + + wait(); + } + + void poke(void) + { + condition_.wakeOne(); + } +}; + class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT @@ -245,7 +300,6 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions private: void renderLines(void); - void renderLinesWorker(void); QPoint lastPos_; LineShader lineShader_; @@ -261,9 +315,9 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions const float zoomLvl2_ = 50.0f; Context *ctx_; + QTimer paintTimer_; - QWaitCondition render_; - std::unique_ptr renderThread_; + std::unique_ptr renderRunner_; struct { QColor background; -- cgit v1.2.3