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 <QApplication>
#include <QCoreApplication> #include <QCoreApplication>
#include <QMouseEvent> #include <QMouseEvent>
#include <QTimer>
#include <QWidget> #include <QWidget>
#include "fpgaviewwidget.h" #include "fpgaviewwidget.h"
@ -242,7 +241,7 @@ void LineShader::draw(const LineShaderData &line, const QColor &color, float thi
} }
FPGAViewWidget::FPGAViewWidget(QWidget *parent) 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_.background = QColor("#000000");
colors_.grid = QColor("#333"); colors_.grid = QColor("#333");
@ -276,16 +275,12 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent)
printf("Could not get OpenGL 3.1 context - trying anyway...\n "); printf("Could not get OpenGL 3.1 context - trying anyway...\n ");
} }
QTimer *timer = new QTimer(this); connect(&paintTimer_, SIGNAL(timeout()), this, SLOT(update()));
connect(timer, SIGNAL(timeout()), this, SLOT(update())); paintTimer_.start(std::chrono::duration<int, std::milli>(1000/20)); // paint GL 20 times per second
timer->start(1000/20);
timer = new QTimer(this); renderRunner_ = std::unique_ptr<PeriodicRunner>(new PeriodicRunner(this, [this] { renderLines(); }));
connect(timer, SIGNAL(timeout()), this, SLOT(pokeRenderer())); renderRunner_->start();
timer->start(1000/2); renderRunner_->startTimer(std::chrono::duration<int, std::milli>(1000/2)); // render line 2 times per second
renderThread_ = std::unique_ptr<QThread>(QThread::create([this] { renderLinesWorker(); }));
renderThread_->start();
} }
FPGAViewWidget::~FPGAViewWidget() {} FPGAViewWidget::~FPGAViewWidget() {}
@ -423,19 +418,7 @@ void FPGAViewWidget::paintGL()
} }
void FPGAViewWidget::pokeRenderer(void) { void FPGAViewWidget::pokeRenderer(void) {
render_.wakeOne(); renderRunner_->poke();
}
void FPGAViewWidget::renderLinesWorker(void) {
for (;;) {
QMutex mutex;
mutex.lock();
render_.wait(&mutex);
renderLines();
mutex.unlock();
}
} }
void FPGAViewWidget::renderLines(void) void FPGAViewWidget::renderLines(void)

View File

@ -28,6 +28,7 @@
#include <QOpenGLVertexArrayObject> #include <QOpenGLVertexArrayObject>
#include <QOpenGLWidget> #include <QOpenGLWidget>
#include <QPainter> #include <QPainter>
#include <QTimer>
#include <QThread> #include <QThread>
#include <QWaitCondition> #include <QWaitCondition>
@ -209,6 +210,60 @@ class LineShader
void draw(const LineShaderData &data, const QColor &color, float thickness, const QMatrix4x4 &projection); 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 class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
{ {
Q_OBJECT Q_OBJECT
@ -245,7 +300,6 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
private: private:
void renderLines(void); void renderLines(void);
void renderLinesWorker(void);
QPoint lastPos_; QPoint lastPos_;
LineShader lineShader_; LineShader lineShader_;
@ -261,9 +315,9 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
const float zoomLvl2_ = 50.0f; const float zoomLvl2_ = 50.0f;
Context *ctx_; Context *ctx_;
QTimer paintTimer_;
QWaitCondition render_; std::unique_ptr<PeriodicRunner> renderRunner_;
std::unique_ptr<QThread> renderThread_;
struct { struct {
QColor background; QColor background;