diff options
Diffstat (limited to 'gui')
-rw-r--r-- | gui/application.cc | 20 | ||||
-rw-r--r-- | gui/fpgaviewwidget.cc | 220 | ||||
-rw-r--r-- | gui/fpgaviewwidget.h | 62 |
3 files changed, 207 insertions, 95 deletions
diff --git a/gui/application.cc b/gui/application.cc index 58dc23eb..12453b57 100644 --- a/gui/application.cc +++ b/gui/application.cc @@ -37,17 +37,17 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) bool Application::notify(QObject *receiver, QEvent *event) { bool retVal = true; - try { + //try { retVal = QApplication::notify(receiver, event); - } catch (assertion_failure ex) { - QString msg; - QTextStream out(&msg); - out << ex.filename.c_str() << " at " << ex.line << "\n"; - out << ex.msg.c_str(); - QMessageBox::critical(0, "Error", msg); - } catch (...) { - QMessageBox::critical(0, "Error", "Fatal error !!!"); - } + //} catch (assertion_failure ex) { + // QString msg; + // QTextStream out(&msg); + // out << ex.filename.c_str() << " at " << ex.line << "\n"; + // out << ex.msg.c_str(); + // QMessageBox::critical(0, "Error", msg); + //} catch (...) { + // QMessageBox::critical(0, "Error", "Fatal error !!!"); + //} return retVal; } diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc index c926e5fa..f4bd2b97 100644 --- a/gui/fpgaviewwidget.cc +++ b/gui/fpgaviewwidget.cc @@ -23,6 +23,7 @@ #include <QApplication> #include <QCoreApplication> #include <QMouseEvent> +#include <QTimer> #include <QWidget> #include "fpgaviewwidget.h" @@ -241,26 +242,25 @@ void LineShader::draw(const LineShaderData &line, const QColor &color, float thi } FPGAViewWidget::FPGAViewWidget(QWidget *parent) - : QOpenGLWidget(parent), lineShader_(this), zoom_(500.f), ctx_(nullptr), selectedItemsChanged_(false) + : QOpenGLWidget(parent), lineShader_(this), zoom_(500.f), ctx_(nullptr), rendererData_(new FPGAViewWidget::RendererData), rendererArgs_(new FPGAViewWidget::RendererArgs) { - backgroundColor_ = QColor("#000000"); - gridColor_ = QColor("#333"); - gFrameColor_ = QColor("#d0d0d0"); - gHiddenColor_ = QColor("#606060"); - gInactiveColor_ = QColor("#303030"); - gActiveColor_ = QColor("#f0f0f0"); - gSelectedColor_ = QColor("#ff6600"); - frameColor_ = QColor("#0066ba"); - highlightColors[0] = QColor("#6495ed"); - highlightColors[1] = QColor("#7fffd4"); - highlightColors[2] = QColor("#98fb98"); - highlightColors[3] = QColor("#ffd700"); - highlightColors[4] = QColor("#cd5c5c"); - highlightColors[5] = QColor("#fa8072"); - highlightColors[6] = QColor("#ff69b4"); - highlightColors[7] = QColor("#da70d6"); - for (int i = 0; i < 8; i++) - highlightItemsChanged_[i] = false; + colors_.background = QColor("#000000"); + colors_.grid = QColor("#333"); + colors_.frame = QColor("#d0d0d0"); + colors_.hidden = QColor("#606060"); + colors_.inactive = QColor("#303030"); + colors_.active = QColor("#f0f0f0"); + colors_.selected = QColor("#ff6600"); + colors_.highlight[0] = QColor("#6495ed"); + colors_.highlight[1] = QColor("#7fffd4"); + colors_.highlight[2] = QColor("#98fb98"); + colors_.highlight[3] = QColor("#ffd700"); + colors_.highlight[4] = QColor("#cd5c5c"); + colors_.highlight[5] = QColor("#fa8072"); + colors_.highlight[6] = QColor("#ff69b4"); + colors_.highlight[7] = QColor("#da70d6"); + + rendererArgs_->highlightedOrSelectedChanged = false; auto fmt = format(); fmt.setMajorVersion(3); @@ -268,7 +268,6 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent) setFormat(fmt); fmt = format(); - // printf("FPGAViewWidget running on OpenGL %d.%d\n", fmt.majorVersion(), fmt.minorVersion()); if (fmt.majorVersion() < 3) { printf("Could not get OpenGL 3.0 context. Aborting.\n"); log_abort(); @@ -276,6 +275,17 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent) if (fmt.minorVersion() < 1) { 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); + + 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(); } FPGAViewWidget::~FPGAViewWidget() {} @@ -283,8 +293,7 @@ FPGAViewWidget::~FPGAViewWidget() {} void FPGAViewWidget::newContext(Context *ctx) { ctx_ = ctx; - selectedItems_.clear(); - update(); + pokeRenderer(); } QSize FPGAViewWidget::minimumSizeHint() const { return QSize(640, 480); } @@ -297,7 +306,7 @@ void FPGAViewWidget::initializeGL() log_error("Could not compile shader.\n"); } initializeOpenGLFunctions(); - glClearColor(backgroundColor_.red() / 255, backgroundColor_.green() / 255, backgroundColor_.blue() / 255, 0.0); + glClearColor(colors_.background.red() / 255, colors_.background.green() / 255, colors_.background.blue() / 255, 0.0); } void FPGAViewWidget::drawDecal(LineShaderData &out, const DecalXY &decal) @@ -398,67 +407,158 @@ void FPGAViewWidget::paintGL() PolyLine(-100.0f, i, 100.0f, i).build(grid); PolyLine(i, -100.0f, i, 100.0f).build(grid); } - lineShader_.draw(grid, gridColor_, thick1Px, matrix); + lineShader_.draw(grid, colors_.grid, thick1Px, matrix); - LineShaderData shaders[4] = {LineShaderData(), LineShaderData(), LineShaderData(), LineShaderData()}; + rendererDataLock_.lock(); + lineShader_.draw(rendererData_->decals[0], colors_.frame, thick11Px, matrix); + lineShader_.draw(rendererData_->decals[1], colors_.hidden, thick11Px, matrix); + lineShader_.draw(rendererData_->decals[2], colors_.inactive, thick11Px, matrix); + lineShader_.draw(rendererData_->decals[3], colors_.active, thick11Px, matrix); - if (ctx_) { - // Draw Bels. + for (int i = 0; i < 8; i++) + lineShader_.draw(rendererData_->highlighted[i], colors_.highlight[i], thick11Px, matrix); + + lineShader_.draw(rendererData_->selected, colors_.selected, thick11Px, matrix); + rendererDataLock_.unlock(); +} + +void FPGAViewWidget::pokeRenderer(void) { + render_.wakeOne(); +} + +void FPGAViewWidget::renderLinesWorker(void) { + for (;;) { + QMutex mutex; + mutex.lock(); + render_.wait(&mutex); + + renderLines(); + + mutex.unlock(); + } +} + +void FPGAViewWidget::renderLines(void) +{ + if (ctx_ == nullptr) + return; + + ctx_->lock(); + + // For now, collapse any decal changes into change of all decals. + // TODO(q3k): fix this + bool decalsChanged = false; + if (ctx_->allUiReload) { + ctx_->allUiReload = false; + decalsChanged = true; + } + if (ctx_->frameUiReload) { + ctx_->frameUiReload = false; + decalsChanged = true; + } + if (ctx_->belUiReload.size() > 0){ + ctx_->belUiReload.clear(); + decalsChanged = true; + } + if (ctx_->wireUiReload.size() > 0) { + ctx_->wireUiReload.clear(); + decalsChanged = true; + } + if (ctx_->pipUiReload.size() > 0) { + ctx_->pipUiReload.clear(); + decalsChanged = true; + } + if (ctx_->groupUiReload.size() > 0) { + ctx_->groupUiReload.clear(); + decalsChanged = true; + } + + // Local copy of decals, taken as fast as possible to not block the P&R. + std::vector<DecalXY> belDecals; + std::vector<DecalXY> wireDecals; + std::vector<DecalXY> pipDecals; + std::vector<DecalXY> groupDecals; + if (decalsChanged) { for (auto bel : ctx_->getBels()) { - drawDecal(shaders, ctx_->getBelDecal(bel)); + belDecals.push_back(ctx_->getBelDecal(bel)); } - // Draw Wires. for (auto wire : ctx_->getWires()) { - drawDecal(shaders, ctx_->getWireDecal(wire)); + wireDecals.push_back(ctx_->getWireDecal(wire)); } - // Draw Pips. for (auto pip : ctx_->getPips()) { - drawDecal(shaders, ctx_->getPipDecal(pip)); + pipDecals.push_back(ctx_->getPipDecal(pip)); } - // Draw Groups. for (auto group : ctx_->getGroups()) { - drawDecal(shaders, ctx_->getGroupDecal(group)); + groupDecals.push_back(ctx_->getGroupDecal(group)); } + } + ctx_->unlock(); - if (selectedItemsChanged_) { - selectedItemsChanged_ = false; - selectedShader_.clear(); - for (auto decal : selectedItems_) { - drawDecal(selectedShader_, decal); - } + rendererArgsLock_.lock(); + auto selectedItems = rendererArgs_->selectedItems; + auto highlightedItems = rendererArgs_->highlightedItems; + auto highlightedOrSelectedChanged = rendererArgs_->highlightedOrSelectedChanged; + rendererArgs_->highlightedOrSelectedChanged = false; + rendererArgsLock_.unlock(); + + if (decalsChanged) { + auto data = std::unique_ptr<FPGAViewWidget::RendererData>(new FPGAViewWidget::RendererData); + // Draw Bels. + for (auto const &decal : belDecals) { + drawDecal(data->decals, decal); + } + // Draw Wires. + for (auto const &decal : wireDecals) { + drawDecal(data->decals, decal); + } + // Draw Pips. + for (auto const &decal : pipDecals) { + drawDecal(data->decals, decal); + } + // Draw Groups. + for (auto const &decal : groupDecals) { + drawDecal(data->decals, decal); + } + + // Swap over. + rendererDataLock_.lock(); + rendererData_ = std::move(data); + rendererDataLock_.unlock(); + } + + rendererDataLock_.lock(); + if (decalsChanged || highlightedOrSelectedChanged) { + rendererData_->selected.clear(); + for (auto &decal : selectedItems) { + drawDecal(rendererData_->selected, decal); } for (int i = 0; i < 8; i++) { - if (highlightItemsChanged_[i]) { - highlightItemsChanged_[i] = false; - highlightShader_[i].clear(); - for (auto decal : highlightItems_[i]) { - drawDecal(highlightShader_[i], decal); - } + rendererData_->highlighted[i].clear(); + for (auto &decal : highlightedItems[i]) { + drawDecal(rendererData_->highlighted[i], decal); } } } - - lineShader_.draw(shaders[0], gFrameColor_, thick11Px, matrix); - lineShader_.draw(shaders[1], gHiddenColor_, thick11Px, matrix); - lineShader_.draw(shaders[2], gInactiveColor_, thick11Px, matrix); - lineShader_.draw(shaders[3], gActiveColor_, thick11Px, matrix); - for (int i = 0; i < 8; i++) - lineShader_.draw(highlightShader_[i], highlightColors[i], thick11Px, matrix); - lineShader_.draw(selectedShader_, gSelectedColor_, thick11Px, matrix); + rendererDataLock_.unlock(); } + void FPGAViewWidget::onSelectedArchItem(std::vector<DecalXY> decals) { - selectedItems_ = decals; - selectedItemsChanged_ = true; - update(); + rendererArgsLock_.lock(); + rendererArgs_->selectedItems = decals; + rendererArgs_->highlightedOrSelectedChanged = true; + rendererArgsLock_.unlock(); + pokeRenderer(); } void FPGAViewWidget::onHighlightGroupChanged(std::vector<DecalXY> decals, int group) { - highlightItems_[group] = decals; - highlightItemsChanged_[group] = true; - update(); + rendererArgsLock_.lock(); + rendererArgs_->highlightedItems[group] = decals; + rendererArgs_->highlightedOrSelectedChanged = true; + rendererArgsLock_.unlock(); + pokeRenderer(); } void FPGAViewWidget::resizeGL(int width, int height) {} diff --git a/gui/fpgaviewwidget.h b/gui/fpgaviewwidget.h index 33eb2800..19440054 100644 --- a/gui/fpgaviewwidget.h +++ b/gui/fpgaviewwidget.h @@ -21,12 +21,15 @@ #define MAPGLWIDGET_H #include <QMainWindow> +#include <QMutex> #include <QOpenGLBuffer> #include <QOpenGLFunctions> #include <QOpenGLShaderProgram> #include <QOpenGLVertexArrayObject> #include <QOpenGLWidget> #include <QPainter> +#include <QThread> +#include <QWaitCondition> #include "nextpnr.h" @@ -209,14 +212,6 @@ class LineShader class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT - Q_PROPERTY(QColor backgroundColor MEMBER backgroundColor_ DESIGNABLE true) - Q_PROPERTY(QColor gridColor MEMBER gridColor_ DESIGNABLE true) - Q_PROPERTY(QColor gFrameColor MEMBER gFrameColor_ DESIGNABLE true) - Q_PROPERTY(QColor gHiddenColor MEMBER gHiddenColor_ DESIGNABLE true) - Q_PROPERTY(QColor gInactiveColor MEMBER gInactiveColor_ DESIGNABLE true) - Q_PROPERTY(QColor gActiveColor MEMBER gActiveColor_ DESIGNABLE true) - Q_PROPERTY(QColor gSelectedColor MEMBER gSelectedColor_ DESIGNABLE true) - Q_PROPERTY(QColor frameColor MEMBER frameColor_ DESIGNABLE true) public: FPGAViewWidget(QWidget *parent = 0); @@ -246,8 +241,12 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions void newContext(Context *ctx); void onSelectedArchItem(std::vector<DecalXY> decals); void onHighlightGroupChanged(std::vector<DecalXY> decals, int group); + void pokeRenderer(void); private: + void renderLines(void); + void renderLinesWorker(void); + QPoint lastPos_; LineShader lineShader_; QMatrix4x4 viewMove_; @@ -263,23 +262,36 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions Context *ctx_; - QColor backgroundColor_; - QColor gridColor_; - QColor gFrameColor_; - QColor gHiddenColor_; - QColor gInactiveColor_; - QColor gActiveColor_; - QColor gSelectedColor_; - QColor frameColor_; - - LineShaderData selectedShader_; - std::vector<DecalXY> selectedItems_; - bool selectedItemsChanged_; - - LineShaderData highlightShader_[8]; - std::vector<DecalXY> highlightItems_[8]; - bool highlightItemsChanged_[8]; - QColor highlightColors[8]; + QWaitCondition render_; + std::unique_ptr<QThread> renderThread_; + + struct { + QColor background; + QColor grid; + QColor frame; + QColor hidden; + QColor inactive; + QColor active; + QColor selected; + QColor highlight[8]; + } colors_; + + struct RendererData { + LineShaderData decals[4]; + LineShaderData selected; + LineShaderData highlighted[8]; + }; + + struct RendererArgs { + std::vector<DecalXY> selectedItems; + std::vector<DecalXY> highlightedItems[8]; + bool highlightedOrSelectedChanged; + }; + + std::unique_ptr<RendererData> rendererData_; + QMutex rendererDataLock_; + std::unique_ptr<RendererArgs> rendererArgs_; + QMutex rendererArgsLock_; }; NEXTPNR_NAMESPACE_END |