Refactor renderer thread

This commit is contained in:
Sergiusz Bazanski 2018-07-20 10:58:30 +01:00
parent 03508faabf
commit 0385ad1b1c
2 changed files with 64 additions and 27 deletions

View File

@ -23,7 +23,6 @@
#include <QApplication>
#include <QCoreApplication>
#include <QMouseEvent>
#include <QTimer>
#include <QWidget>
#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<int, std::milli>(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>(QThread::create([this] { renderLinesWorker(); }));
renderThread_->start();
renderRunner_ = std::unique_ptr<PeriodicRunner>(new PeriodicRunner(this, [this] { renderLines(); }));
renderRunner_->start();
renderRunner_->startTimer(std::chrono::duration<int, std::milli>(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)

View File

@ -28,6 +28,7 @@
#include <QOpenGLVertexArrayObject>
#include <QOpenGLWidget>
#include <QPainter>
#include <QTimer>
#include <QThread>
#include <QWaitCondition>
@ -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<void()> target_;
QTimer timer_;
public:
explicit PeriodicRunner(QObject *parent, std::function<void()> 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<QThread> renderThread_;
std::unique_ptr<PeriodicRunner> renderRunner_;
struct {
QColor background;