aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergiusz Bazanski <q3k@q3k.org>2018-07-14 18:50:50 +0100
committerSergiusz Bazanski <q3k@q3k.org>2018-07-14 18:50:50 +0100
commit36b4e3382dc552fcd1b078bdd246dc14379394a1 (patch)
treedfd8c295328e7452eaec3158b98bd7b153668dcd
parent836d8c1ef3295a34c591324ef4c8ec48687279ee (diff)
downloadnextpnr-36b4e3382dc552fcd1b078bdd246dc14379394a1.tar.gz
nextpnr-36b4e3382dc552fcd1b078bdd246dc14379394a1.tar.bz2
nextpnr-36b4e3382dc552fcd1b078bdd246dc14379394a1.zip
Revert "Make GUI nice and smooth."
This reverts commit a8c84e90a39c54174dd24b5b76bd17aed8311481.
-rw-r--r--common/nextpnr.h31
-rw-r--r--gui/fpgaviewwidget.cc154
-rw-r--r--gui/fpgaviewwidget.h99
-rw-r--r--ice40/arch.cc10
-rw-r--r--ice40/arch.h8
-rw-r--r--ice40/main.cc3
6 files changed, 127 insertions, 178 deletions
diff --git a/common/nextpnr.h b/common/nextpnr.h
index efcab9fc..50465869 100644
--- a/common/nextpnr.h
+++ b/common/nextpnr.h
@@ -238,16 +238,6 @@ struct CellInfo
std::unordered_map<IdString, IdString> pins;
};
-struct UIUpdatesRequired
-{
- bool allUIReload;
- bool frameUIReload;
- std::unordered_set<BelId> belUIReload;
- std::unordered_set<WireId> wireUIReload;
- std::unordered_set<PipId> pipUIReload;
- std::unordered_set<GroupId> groupUIReload;
-};
-
struct BaseCtx
{
// --------------------------------------------------------------
@@ -270,8 +260,6 @@ struct BaseCtx
idstring_idx_to_str = new std::vector<const std::string *>;
IdString::initialize_add(this, "", 0);
IdString::initialize_arch(this);
-
- allUiReload = true;
}
~BaseCtx()
@@ -304,25 +292,6 @@ struct BaseCtx
void refreshUiPip(PipId pip) { pipUiReload.insert(pip); }
void refreshUiGroup(GroupId group) { groupUiReload.insert(group); }
-
- UIUpdatesRequired getUIUpdatesRequired(void)
- {
- UIUpdatesRequired req;
- req.allUIReload = allUiReload;
- req.frameUIReload = frameUiReload;
- req.belUIReload = belUiReload;
- req.wireUIReload = wireUiReload;
- req.pipUIReload = pipUiReload;
- req.groupUIReload = groupUiReload;
-
- allUiReload = false;
- frameUiReload = false;
- belUiReload.clear();
- wireUiReload.clear();
- pipUiReload.clear();
- groupUiReload.clear();
- return req;
- }
};
NEXTPNR_NAMESPACE_END
diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc
index 21ce5b67..6b6a2617 100644
--- a/gui/fpgaviewwidget.cc
+++ b/gui/fpgaviewwidget.cc
@@ -23,7 +23,6 @@
#include <QApplication>
#include <QCoreApplication>
#include <QMouseEvent>
-#include <QTimer>
#include <QWidget>
#include "fpgaviewwidget.h"
@@ -196,7 +195,7 @@ bool LineShader::compile(void)
return true;
}
-void LineShader::draw(const LineShaderData &line, const QColor &color, const float thickness, const QMatrix4x4 &projection)
+void LineShader::draw(const LineShaderData &line, const QMatrix4x4 &projection)
{
auto gl = QOpenGLContext::currentContext()->functions();
vao_.bind();
@@ -215,8 +214,8 @@ void LineShader::draw(const LineShaderData &line, const QColor &color, const flo
buffers_.index.allocate(&line.indices[0], sizeof(GLuint) * line.indices.size());
program_->setUniformValue(uniforms_.projection, projection);
- program_->setUniformValue(uniforms_.thickness, thickness);
- program_->setUniformValue(uniforms_.color, color.redF(), color.greenF(), color.blueF(), color.alphaF());
+ program_->setUniformValue(uniforms_.thickness, line.thickness);
+ program_->setUniformValue(uniforms_.color, line.color.r, line.color.g, line.color.b, line.color.a);
buffers_.position.bind();
program_->enableAttributeArray("position");
@@ -265,10 +264,6 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent) : QOpenGLWidget(parent), lineSha
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(5000);
}
FPGAViewWidget::~FPGAViewWidget() {}
@@ -292,6 +287,73 @@ void FPGAViewWidget::initializeGL()
glClearColor(backgroundColor_.red() / 255, backgroundColor_.green() / 255, backgroundColor_.blue() / 255, 0.0);
}
+void FPGAViewWidget::drawDecal(LineShaderData &out, const DecalXY &decal)
+{
+ const float scale = 1.0;
+ float offsetX = 0.0, offsetY = 0.0;
+
+ for (auto &el : ctx_->getDecalGraphics(decal.decal)) {
+ offsetX = decal.x;
+ offsetY = decal.y;
+
+ if (el.type == GraphicElement::G_BOX) {
+ auto line = PolyLine(true);
+ line.point(offsetX + scale * el.x1, offsetY + scale * el.y1);
+ line.point(offsetX + scale * el.x2, offsetY + scale * el.y1);
+ line.point(offsetX + scale * el.x2, offsetY + scale * el.y2);
+ line.point(offsetX + scale * el.x1, offsetY + scale * el.y2);
+ line.build(out);
+ }
+
+ if (el.type == GraphicElement::G_LINE) {
+ PolyLine(offsetX + scale * el.x1, offsetY + scale * el.y1, offsetX + scale * el.x2, offsetY + scale * el.y2)
+ .build(out);
+ }
+ }
+}
+
+void FPGAViewWidget::drawDecal(LineShaderData out[], const DecalXY &decal)
+{
+ const float scale = 1.0;
+ float offsetX = 0.0, offsetY = 0.0;
+
+ for (auto &el : ctx_->getDecalGraphics(decal.decal)) {
+ offsetX = decal.x;
+ offsetY = decal.y;
+
+ if (el.type == GraphicElement::G_BOX) {
+ auto line = PolyLine(true);
+ line.point(offsetX + scale * el.x1, offsetY + scale * el.y1);
+ line.point(offsetX + scale * el.x2, offsetY + scale * el.y1);
+ line.point(offsetX + scale * el.x2, offsetY + scale * el.y2);
+ line.point(offsetX + scale * el.x1, offsetY + scale * el.y2);
+ switch (el.style) {
+ case GraphicElement::G_FRAME:
+ case GraphicElement::G_INACTIVE:
+ case GraphicElement::G_ACTIVE:
+ line.build(out[el.style]);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (el.type == GraphicElement::G_LINE) {
+ auto line = PolyLine(offsetX + scale * el.x1, offsetY + scale * el.y1, offsetX + scale * el.x2,
+ offsetY + scale * el.y2);
+ switch (el.style) {
+ case GraphicElement::G_FRAME:
+ case GraphicElement::G_INACTIVE:
+ case GraphicElement::G_ACTIVE:
+ line.build(out[el.style]);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
QMatrix4x4 FPGAViewWidget::getProjection(void)
{
QMatrix4x4 matrix;
@@ -318,59 +380,47 @@ void FPGAViewWidget::paintGL()
float thick11Px = mouseToWorldCoordinates(1.1, 0).x();
// Draw grid.
- auto grid = LineShaderData();
+ auto grid = LineShaderData(thick1Px, gridColor_);
for (float i = -100.0f; i < 100.0f; i += 1.0f) {
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, matrix);
+
+ LineShaderData shaders[4] = {[GraphicElement::G_FRAME] = LineShaderData(thick11Px, gFrameColor_),
+ [GraphicElement::G_HIDDEN] = LineShaderData(thick11Px, gHiddenColor_),
+ [GraphicElement::G_INACTIVE] = LineShaderData(thick11Px, gInactiveColor_),
+ [GraphicElement::G_ACTIVE] = LineShaderData(thick11Px, gActiveColor_)};
if (ctx_) {
- auto &&proxy = ctx_->rwproxy();
- auto updates = proxy.getUIUpdatesRequired();
-
- // Collapse all updates to a full redraw.
- // TODO(q3k) fix this.
-
- bool redraw = (updates.allUIReload
- || !updates.belUIReload.empty()
- || !updates.wireUIReload.empty()
- || !updates.pipUIReload.empty()
- || !updates.groupUIReload.empty()
- || updates.frameUIReload);
-
- if (redraw) {
- shaders_[0].clear();
- shaders_[1].clear();
- shaders_[2].clear();
- shaders_[3].clear();
-
- // Draw Bels.
- for (auto bel : ctx_->getBels()) {
- drawDecal(proxy, shaders_, ctx_->getBelDecal(bel));
- }
- // Draw Wires.
- for (auto wire : ctx_->getWires()) {
- drawDecal(proxy, shaders_, ctx_->getWireDecal(wire));
- }
- // Draw Pips.
- for (auto pip : ctx_->getPips()) {
- drawDecal(proxy, shaders_, ctx_->getPipDecal(pip));
- }
- // Draw Groups.
- for (auto group : ctx_->getGroups()) {
- drawDecal(proxy, shaders_, ctx_->getGroupDecal(group));
- }
- // Draw Frame Graphics.
- drawDecal(proxy, shaders_, ctx_->getFrameDecal());
+ // Draw Bels.
+ for (auto bel : ctx_->getBels()) {
+ drawDecal(shaders, ctx_->getBelDecal(bel));
+ }
+ // Draw Wires.
+ for (auto wire : ctx_->getWires()) {
+ drawDecal(shaders, ctx_->getWireDecal(wire));
+ }
+ // Draw Pips.
+ for (auto pip : ctx_->getPips()) {
+ drawDecal(shaders, ctx_->getPipDecal(pip));
+ }
+ // Draw Groups.
+ for (auto group : ctx_->getGroups()) {
+ drawDecal(shaders, ctx_->getGroupDecal(group));
}
}
+ lineShader_.draw(shaders[0], matrix);
+ lineShader_.draw(shaders[1], matrix);
+ lineShader_.draw(shaders[2], matrix);
+ lineShader_.draw(shaders[3], matrix);
- 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);
- //lineShader_.draw(frame, matrix);
+ // Draw Frame Graphics.
+ auto frames = LineShaderData(thick11Px, frameColor_);
+ if (ctx_) {
+ drawDecal(frames, ctx_->getFrameDecal());
+ lineShader_.draw(frames, matrix);
+ }
}
void FPGAViewWidget::resizeGL(int width, int height) {}
diff --git a/gui/fpgaviewwidget.h b/gui/fpgaviewwidget.h
index 3652e82e..410b0582 100644
--- a/gui/fpgaviewwidget.h
+++ b/gui/fpgaviewwidget.h
@@ -41,6 +41,18 @@ NPNR_PACKED_STRUCT(struct Vertex2DPOD {
Vertex2DPOD(GLfloat X, GLfloat Y) : x(X), y(Y) {}
});
+// Vertex2DPOD is a structure of R, G, B, A values that can be passed to OpenGL
+// directly.
+NPNR_PACKED_STRUCT(struct ColorPOD {
+ GLfloat r;
+ GLfloat g;
+ GLfloat b;
+ GLfloat a;
+
+ ColorPOD(GLfloat R, GLfloat G, GLfloat B, GLfloat A) : r(R), g(G), b(B), a(A) {}
+ ColorPOD(const QColor &color) : r(color.redF()), g(color.greenF()), b(color.blueF()), a(color.alphaF()) {}
+});
+
// LineShaderData is a built set of vertices that can be rendered by the
// LineShader.
// Each LineShaderData can have its' own color and thickness.
@@ -51,13 +63,10 @@ struct LineShaderData
std::vector<GLfloat> miters;
std::vector<GLuint> indices;
- void clear(void)
- {
- vertices.clear();
- normals.clear();
- miters.clear();
- indices.clear();
- }
+ GLfloat thickness;
+ ColorPOD color;
+
+ LineShaderData(GLfloat Thickness, QColor Color) : thickness(Thickness), color(Color) {}
};
// PolyLine is a set of segments defined by points, that can be built to a
@@ -201,7 +210,7 @@ class LineShader
bool compile(void);
// Render a LineShaderData with a given M/V/P transformation.
- void draw(const LineShaderData &data, const QColor &color, const float thickness, const QMatrix4x4 &projection);
+ void draw(const LineShaderData &data, const QMatrix4x4 &projection);
};
class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
@@ -237,76 +246,8 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
-
- template <typename T>
- void drawDecal(const T &proxy, LineShaderData &out, const DecalXY &decal)
- {
- const float scale = 1.0;
- float offsetX = 0.0, offsetY = 0.0;
-
- for (auto &el : proxy.getDecalGraphics(decal.decal)) {
- offsetX = decal.x;
- offsetY = decal.y;
-
- if (el.type == GraphicElement::G_BOX) {
- auto line = PolyLine(true);
- line.point(offsetX + scale * el.x1, offsetY + scale * el.y1);
- line.point(offsetX + scale * el.x2, offsetY + scale * el.y1);
- line.point(offsetX + scale * el.x2, offsetY + scale * el.y2);
- line.point(offsetX + scale * el.x1, offsetY + scale * el.y2);
- line.build(out);
- }
-
- if (el.type == GraphicElement::G_LINE) {
- PolyLine(offsetX + scale * el.x1, offsetY + scale * el.y1, offsetX + scale * el.x2, offsetY + scale * el.y2)
- .build(out);
- }
- }
- }
-
- template <typename T>
- void drawDecal(const T &proxy, LineShaderData out[], const DecalXY &decal)
- {
- const float scale = 1.0;
- float offsetX = 0.0, offsetY = 0.0;
-
- for (auto &el : proxy.getDecalGraphics(decal.decal)) {
- offsetX = decal.x;
- offsetY = decal.y;
-
- if (el.type == GraphicElement::G_BOX) {
- auto line = PolyLine(true);
- line.point(offsetX + scale * el.x1, offsetY + scale * el.y1);
- line.point(offsetX + scale * el.x2, offsetY + scale * el.y1);
- line.point(offsetX + scale * el.x2, offsetY + scale * el.y2);
- line.point(offsetX + scale * el.x1, offsetY + scale * el.y2);
- switch (el.style) {
- case GraphicElement::G_FRAME:
- case GraphicElement::G_INACTIVE:
- case GraphicElement::G_ACTIVE:
- line.build(out[el.style]);
- break;
- default:
- break;
- }
- }
-
- if (el.type == GraphicElement::G_LINE) {
- auto line = PolyLine(offsetX + scale * el.x1, offsetY + scale * el.y1, offsetX + scale * el.x2,
- offsetY + scale * el.y2);
- switch (el.style) {
- case GraphicElement::G_FRAME:
- case GraphicElement::G_INACTIVE:
- case GraphicElement::G_ACTIVE:
- line.build(out[el.style]);
- break;
- default:
- break;
- }
- }
- }
- }
-
+ void drawDecal(LineShaderData &data, const DecalXY &decal);
+ void drawDecal(LineShaderData out[], const DecalXY &decal);
public Q_SLOTS:
void newContext(Context *ctx);
@@ -333,8 +274,6 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
QColor gInactiveColor_;
QColor gActiveColor_;
QColor frameColor_;
-
- LineShaderData shaders_[4];
};
NEXTPNR_NAMESPACE_END
diff --git a/ice40/arch.cc b/ice40/arch.cc
index 547dbcd6..af6e922c 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -534,8 +534,9 @@ DecalXY Arch::getGroupDecal(GroupId group) const
return decalxy;
};
-std::vector<GraphicElement> ArchRProxyMethods::getDecalGraphics(DecalId decal) const
+std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
{
+ boost::shared_lock_guard<boost::shared_mutex> lock(mtx_);
std::vector<GraphicElement> ret;
if (decal.type == DecalId::TYPE_FRAME) {
@@ -567,7 +568,7 @@ std::vector<GraphicElement> ArchRProxyMethods::getDecalGraphics(DecalId decal) c
BelId bel;
bel.index = decal.index;
- auto bel_type = parent_->getBelType(bel);
+ auto bel_type = getBelType(bel);
if (bel_type == TYPE_ICESTORM_LC) {
GraphicElement el;
@@ -953,9 +954,4 @@ CellInfo *ArchRWProxyMethods::getCell(IdString cell)
return parent_->cells.at(cell).get();
}
-UIUpdatesRequired ArchRWProxyMethods::getUIUpdatesRequired(void)
-{
- return parent_->getUIUpdatesRequired();
-}
-
NEXTPNR_NAMESPACE_END
diff --git a/ice40/arch.h b/ice40/arch.h
index 4311f4a5..da1e583a 100644
--- a/ice40/arch.h
+++ b/ice40/arch.h
@@ -604,6 +604,8 @@ public:
// -------------------------------------------------
+ std::vector<GraphicElement> getDecalGraphics(DecalId decal) const;
+
DecalXY getFrameDecal() const;
DecalXY getBelDecal(BelId bel) const;
DecalXY getWireDecal(WireId wire) const;
@@ -689,8 +691,6 @@ public:
IdString getBoundBelCell(BelId bel) const;
BelId getBelByName(IdString name) const;
-
- std::vector<GraphicElement> getDecalGraphics(DecalId decal) const;
};
// A proxy object that keeps an Arch shared/readonly lock until it goes out
@@ -750,10 +750,6 @@ public:
void bindBel(BelId bel, IdString cell, PlaceStrength strength);
// Returned pointer is valid as long as Proxy object exists.
CellInfo *getCell(IdString cell);
-
-
- // Methods to be used by UI for detecting whether we need to redraw.
- UIUpdatesRequired getUIUpdatesRequired(void);
};
// A proxy object that keeps an Arch readwrite lock until it goes out of scope.
diff --git a/ice40/main.cc b/ice40/main.cc
index d38c786c..e77bdd34 100644
--- a/ice40/main.cc
+++ b/ice40/main.cc
@@ -51,8 +51,7 @@ void svg_dump_decal(const Context *ctx, const DecalXY &decal)
const float scale = 10.0, offset = 10.0;
const std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\"";
- auto &&proxy = ctx->rproxy();
- for (auto &el : proxy.getDecalGraphics(decal.decal)) {
+ for (auto &el : ctx->getDecalGraphics(decal.decal)) {
if (el.type == GraphicElement::G_BOX) {
std::cout << "<rect x=\"" << (offset + scale * (decal.x + el.x1)) << "\" y=\""
<< (offset + scale * (decal.y + el.y1)) << "\" height=\"" << (scale * (el.y2 - el.y1))