This commit is contained in:
Serge Bazanski 2018-07-17 19:16:26 +01:00
parent 2f5b94fe30
commit 03508faabf
7 changed files with 225 additions and 94 deletions

View File

@ -369,7 +369,7 @@ class BaseCtx : public IdStringDB, public DeterministicRNG
// -------------------------------------------------------------- // --------------------------------------------------------------
bool allUiReload = false; bool allUiReload = true;
bool frameUiReload = false; bool frameUiReload = false;
std::unordered_set<BelId> belUiReload; std::unordered_set<BelId> belUiReload;
std::unordered_set<WireId> wireUiReload; std::unordered_set<WireId> wireUiReload;

View File

@ -29,6 +29,7 @@
#include <list> #include <list>
#include <map> #include <map>
#include <ostream> #include <ostream>
#include <pthread.h>
#include <queue> #include <queue>
#include <set> #include <set>
#include <stdarg.h> #include <stdarg.h>
@ -156,6 +157,14 @@ class SAPlacer
// Main simulated annealing loop // Main simulated annealing loop
for (int iter = 1;; iter++) { for (int iter = 1;; iter++) {
// TODO(q3k): unwat
pthread_yield();
pthread_yield();
pthread_yield();
pthread_yield();
pthread_yield();
pthread_yield();
pthread_yield();
ctx->lock(); ctx->lock();
n_move = n_accept = 0; n_move = n_accept = 0;
improved = false; improved = false;

View File

@ -637,7 +637,9 @@ bool router1(Context *ctx)
log_info("Checksum: 0x%08x\n", ctx->checksum()); log_info("Checksum: 0x%08x\n", ctx->checksum());
#ifndef NDEBUG #ifndef NDEBUG
ctx->lock();
ctx->check(); ctx->check();
ctx->unlock();
#endif #endif
return true; return true;
} catch (log_execution_error_exception) { } catch (log_execution_error_exception) {

View File

@ -37,17 +37,17 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
bool Application::notify(QObject *receiver, QEvent *event) bool Application::notify(QObject *receiver, QEvent *event)
{ {
bool retVal = true; bool retVal = true;
try { //try {
retVal = QApplication::notify(receiver, event); retVal = QApplication::notify(receiver, event);
} catch (assertion_failure ex) { //} catch (assertion_failure ex) {
QString msg; // QString msg;
QTextStream out(&msg); // QTextStream out(&msg);
out << ex.filename.c_str() << " at " << ex.line << "\n"; // out << ex.filename.c_str() << " at " << ex.line << "\n";
out << ex.msg.c_str(); // out << ex.msg.c_str();
QMessageBox::critical(0, "Error", msg); // QMessageBox::critical(0, "Error", msg);
} catch (...) { //} catch (...) {
QMessageBox::critical(0, "Error", "Fatal error !!!"); // QMessageBox::critical(0, "Error", "Fatal error !!!");
} //}
return retVal; return retVal;
} }

View File

@ -23,6 +23,7 @@
#include <QApplication> #include <QApplication>
#include <QCoreApplication> #include <QCoreApplication>
#include <QMouseEvent> #include <QMouseEvent>
#include <QTimer>
#include <QWidget> #include <QWidget>
#include "fpgaviewwidget.h" #include "fpgaviewwidget.h"
@ -241,26 +242,25 @@ 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), selectedItemsChanged_(false) : QOpenGLWidget(parent), lineShader_(this), zoom_(500.f), ctx_(nullptr), rendererData_(new FPGAViewWidget::RendererData), rendererArgs_(new FPGAViewWidget::RendererArgs)
{ {
backgroundColor_ = QColor("#000000"); colors_.background = QColor("#000000");
gridColor_ = QColor("#333"); colors_.grid = QColor("#333");
gFrameColor_ = QColor("#d0d0d0"); colors_.frame = QColor("#d0d0d0");
gHiddenColor_ = QColor("#606060"); colors_.hidden = QColor("#606060");
gInactiveColor_ = QColor("#303030"); colors_.inactive = QColor("#303030");
gActiveColor_ = QColor("#f0f0f0"); colors_.active = QColor("#f0f0f0");
gSelectedColor_ = QColor("#ff6600"); colors_.selected = QColor("#ff6600");
frameColor_ = QColor("#0066ba"); colors_.highlight[0] = QColor("#6495ed");
highlightColors[0] = QColor("#6495ed"); colors_.highlight[1] = QColor("#7fffd4");
highlightColors[1] = QColor("#7fffd4"); colors_.highlight[2] = QColor("#98fb98");
highlightColors[2] = QColor("#98fb98"); colors_.highlight[3] = QColor("#ffd700");
highlightColors[3] = QColor("#ffd700"); colors_.highlight[4] = QColor("#cd5c5c");
highlightColors[4] = QColor("#cd5c5c"); colors_.highlight[5] = QColor("#fa8072");
highlightColors[5] = QColor("#fa8072"); colors_.highlight[6] = QColor("#ff69b4");
highlightColors[6] = QColor("#ff69b4"); colors_.highlight[7] = QColor("#da70d6");
highlightColors[7] = QColor("#da70d6");
for (int i = 0; i < 8; i++) rendererArgs_->highlightedOrSelectedChanged = false;
highlightItemsChanged_[i] = false;
auto fmt = format(); auto fmt = format();
fmt.setMajorVersion(3); fmt.setMajorVersion(3);
@ -268,7 +268,6 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent)
setFormat(fmt); setFormat(fmt);
fmt = format(); fmt = format();
// printf("FPGAViewWidget running on OpenGL %d.%d\n", fmt.majorVersion(), fmt.minorVersion());
if (fmt.majorVersion() < 3) { if (fmt.majorVersion() < 3) {
printf("Could not get OpenGL 3.0 context. Aborting.\n"); printf("Could not get OpenGL 3.0 context. Aborting.\n");
log_abort(); log_abort();
@ -276,6 +275,17 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent)
if (fmt.minorVersion() < 1) { if (fmt.minorVersion() < 1) {
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(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() {} FPGAViewWidget::~FPGAViewWidget() {}
@ -283,8 +293,7 @@ FPGAViewWidget::~FPGAViewWidget() {}
void FPGAViewWidget::newContext(Context *ctx) void FPGAViewWidget::newContext(Context *ctx)
{ {
ctx_ = ctx; ctx_ = ctx;
selectedItems_.clear(); pokeRenderer();
update();
} }
QSize FPGAViewWidget::minimumSizeHint() const { return QSize(640, 480); } QSize FPGAViewWidget::minimumSizeHint() const { return QSize(640, 480); }
@ -297,7 +306,7 @@ void FPGAViewWidget::initializeGL()
log_error("Could not compile shader.\n"); log_error("Could not compile shader.\n");
} }
initializeOpenGLFunctions(); 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) 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(-100.0f, i, 100.0f, i).build(grid);
PolyLine(i, -100.0f, i, 100.0f).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_) { for (int i = 0; i < 8; i++)
// Draw Bels. 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()) { for (auto bel : ctx_->getBels()) {
drawDecal(shaders, ctx_->getBelDecal(bel)); belDecals.push_back(ctx_->getBelDecal(bel));
}
for (auto wire : ctx_->getWires()) {
wireDecals.push_back(ctx_->getWireDecal(wire));
}
for (auto pip : ctx_->getPips()) {
pipDecals.push_back(ctx_->getPipDecal(pip));
}
for (auto group : ctx_->getGroups()) {
groupDecals.push_back(ctx_->getGroupDecal(group));
}
}
ctx_->unlock();
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. // Draw Wires.
for (auto wire : ctx_->getWires()) { for (auto const &decal : wireDecals) {
drawDecal(shaders, ctx_->getWireDecal(wire)); drawDecal(data->decals, decal);
} }
// Draw Pips. // Draw Pips.
for (auto pip : ctx_->getPips()) { for (auto const &decal : pipDecals) {
drawDecal(shaders, ctx_->getPipDecal(pip)); drawDecal(data->decals, decal);
} }
// Draw Groups. // Draw Groups.
for (auto group : ctx_->getGroups()) { for (auto const &decal : groupDecals) {
drawDecal(shaders, ctx_->getGroupDecal(group)); drawDecal(data->decals, decal);
} }
if (selectedItemsChanged_) { // Swap over.
selectedItemsChanged_ = false; rendererDataLock_.lock();
selectedShader_.clear(); rendererData_ = std::move(data);
for (auto decal : selectedItems_) { rendererDataLock_.unlock();
drawDecal(selectedShader_, decal);
} }
rendererDataLock_.lock();
if (decalsChanged || highlightedOrSelectedChanged) {
rendererData_->selected.clear();
for (auto &decal : selectedItems) {
drawDecal(rendererData_->selected, decal);
} }
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if (highlightItemsChanged_[i]) { rendererData_->highlighted[i].clear();
highlightItemsChanged_[i] = false; for (auto &decal : highlightedItems[i]) {
highlightShader_[i].clear(); drawDecal(rendererData_->highlighted[i], decal);
for (auto decal : highlightItems_[i]) {
drawDecal(highlightShader_[i], decal);
} }
} }
} }
rendererDataLock_.unlock();
} }
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);
}
void FPGAViewWidget::onSelectedArchItem(std::vector<DecalXY> decals) void FPGAViewWidget::onSelectedArchItem(std::vector<DecalXY> decals)
{ {
selectedItems_ = decals; rendererArgsLock_.lock();
selectedItemsChanged_ = true; rendererArgs_->selectedItems = decals;
update(); rendererArgs_->highlightedOrSelectedChanged = true;
rendererArgsLock_.unlock();
pokeRenderer();
} }
void FPGAViewWidget::onHighlightGroupChanged(std::vector<DecalXY> decals, int group) void FPGAViewWidget::onHighlightGroupChanged(std::vector<DecalXY> decals, int group)
{ {
highlightItems_[group] = decals; rendererArgsLock_.lock();
highlightItemsChanged_[group] = true; rendererArgs_->highlightedItems[group] = decals;
update(); rendererArgs_->highlightedOrSelectedChanged = true;
rendererArgsLock_.unlock();
pokeRenderer();
} }
void FPGAViewWidget::resizeGL(int width, int height) {} void FPGAViewWidget::resizeGL(int width, int height) {}

View File

@ -21,12 +21,15 @@
#define MAPGLWIDGET_H #define MAPGLWIDGET_H
#include <QMainWindow> #include <QMainWindow>
#include <QMutex>
#include <QOpenGLBuffer> #include <QOpenGLBuffer>
#include <QOpenGLFunctions> #include <QOpenGLFunctions>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject> #include <QOpenGLVertexArrayObject>
#include <QOpenGLWidget> #include <QOpenGLWidget>
#include <QPainter> #include <QPainter>
#include <QThread>
#include <QWaitCondition>
#include "nextpnr.h" #include "nextpnr.h"
@ -209,14 +212,6 @@ class LineShader
class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
{ {
Q_OBJECT 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: public:
FPGAViewWidget(QWidget *parent = 0); FPGAViewWidget(QWidget *parent = 0);
@ -246,8 +241,12 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
void newContext(Context *ctx); void newContext(Context *ctx);
void onSelectedArchItem(std::vector<DecalXY> decals); void onSelectedArchItem(std::vector<DecalXY> decals);
void onHighlightGroupChanged(std::vector<DecalXY> decals, int group); void onHighlightGroupChanged(std::vector<DecalXY> decals, int group);
void pokeRenderer(void);
private: private:
void renderLines(void);
void renderLinesWorker(void);
QPoint lastPos_; QPoint lastPos_;
LineShader lineShader_; LineShader lineShader_;
QMatrix4x4 viewMove_; QMatrix4x4 viewMove_;
@ -263,23 +262,36 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
Context *ctx_; Context *ctx_;
QColor backgroundColor_; QWaitCondition render_;
QColor gridColor_; std::unique_ptr<QThread> renderThread_;
QColor gFrameColor_;
QColor gHiddenColor_;
QColor gInactiveColor_;
QColor gActiveColor_;
QColor gSelectedColor_;
QColor frameColor_;
LineShaderData selectedShader_; struct {
std::vector<DecalXY> selectedItems_; QColor background;
bool selectedItemsChanged_; QColor grid;
QColor frame;
QColor hidden;
QColor inactive;
QColor active;
QColor selected;
QColor highlight[8];
} colors_;
LineShaderData highlightShader_[8]; struct RendererData {
std::vector<DecalXY> highlightItems_[8]; LineShaderData decals[4];
bool highlightItemsChanged_[8]; LineShaderData selected;
QColor highlightColors[8]; 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 NEXTPNR_NAMESPACE_END

View File

@ -373,6 +373,7 @@ struct Arch : BaseCtx
bel_to_cell[bel.index] = cell; bel_to_cell[bel.index] = cell;
cells[cell]->bel = bel; cells[cell]->bel = bel;
cells[cell]->belStrength = strength; cells[cell]->belStrength = strength;
refreshUiBel(bel);
} }
void unbindBel(BelId bel) void unbindBel(BelId bel)
@ -382,6 +383,7 @@ struct Arch : BaseCtx
cells[bel_to_cell[bel.index]]->bel = BelId(); cells[bel_to_cell[bel.index]]->bel = BelId();
cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE;
bel_to_cell[bel.index] = IdString(); bel_to_cell[bel.index] = IdString();
refreshUiBel(bel);
} }
bool checkBelAvail(BelId bel) const bool checkBelAvail(BelId bel) const
@ -475,6 +477,7 @@ struct Arch : BaseCtx
wire_to_net[wire.index] = net; wire_to_net[wire.index] = net;
nets[net]->wires[wire].pip = PipId(); nets[net]->wires[wire].pip = PipId();
nets[net]->wires[wire].strength = strength; nets[net]->wires[wire].strength = strength;
refreshUiWire(wire);
} }
void unbindWire(WireId wire) void unbindWire(WireId wire)
@ -494,6 +497,7 @@ struct Arch : BaseCtx
net_wires.erase(it); net_wires.erase(it);
wire_to_net[wire.index] = IdString(); wire_to_net[wire.index] = IdString();
refreshUiWire(wire);
} }
bool checkWireAvail(WireId wire) const bool checkWireAvail(WireId wire) const
@ -541,6 +545,8 @@ struct Arch : BaseCtx
wire_to_net[dst.index] = net; wire_to_net[dst.index] = net;
nets[net]->wires[dst].pip = pip; nets[net]->wires[dst].pip = pip;
nets[net]->wires[dst].strength = strength; nets[net]->wires[dst].strength = strength;
refreshUiPip(pip);
refreshUiWire(dst);
} }
void unbindPip(PipId pip) void unbindPip(PipId pip)
@ -557,6 +563,8 @@ struct Arch : BaseCtx
pip_to_net[pip.index] = IdString(); pip_to_net[pip.index] = IdString();
switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString();
refreshUiPip(pip);
refreshUiWire(dst);
} }
bool checkPipAvail(PipId pip) const bool checkPipAvail(PipId pip) const