diff options
| author | Serge Bazanski <serge@bazanski.pl> | 2018-07-17 19:16:26 +0100 | 
|---|---|---|
| committer | Serge Bazanski <serge@bazanski.pl> | 2018-07-17 19:16:26 +0100 | 
| commit | 03508faabfc2f5b76039cfd13d02a341baa848a4 (patch) | |
| tree | c896745d0e1555e224d5a7c67b52e7ccfb6e30dd /gui | |
| parent | 2f5b94fe309619c221c3e1ea5aa48a4523bd3156 (diff) | |
| download | nextpnr-03508faabfc2f5b76039cfd13d02a341baa848a4.tar.gz nextpnr-03508faabfc2f5b76039cfd13d02a341baa848a4.tar.bz2 nextpnr-03508faabfc2f5b76039cfd13d02a341baa848a4.zip  | |
WIP.
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  | 
