Revert "Make GUI nice and smooth."

This reverts commit a8c84e90a3.
This commit is contained in:
Sergiusz Bazanski 2018-07-14 18:50:50 +01:00
parent 836d8c1ef3
commit 36b4e3382d
6 changed files with 127 additions and 178 deletions

View File

@ -238,16 +238,6 @@ struct CellInfo
std::unordered_map<IdString, IdString> pins; 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 struct BaseCtx
{ {
// -------------------------------------------------------------- // --------------------------------------------------------------
@ -270,8 +260,6 @@ struct BaseCtx
idstring_idx_to_str = new std::vector<const std::string *>; idstring_idx_to_str = new std::vector<const std::string *>;
IdString::initialize_add(this, "", 0); IdString::initialize_add(this, "", 0);
IdString::initialize_arch(this); IdString::initialize_arch(this);
allUiReload = true;
} }
~BaseCtx() ~BaseCtx()
@ -304,25 +292,6 @@ struct BaseCtx
void refreshUiPip(PipId pip) { pipUiReload.insert(pip); } void refreshUiPip(PipId pip) { pipUiReload.insert(pip); }
void refreshUiGroup(GroupId group) { groupUiReload.insert(group); } 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 NEXTPNR_NAMESPACE_END

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"
@ -196,7 +195,7 @@ bool LineShader::compile(void)
return true; 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(); auto gl = QOpenGLContext::currentContext()->functions();
vao_.bind(); 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()); buffers_.index.allocate(&line.indices[0], sizeof(GLuint) * line.indices.size());
program_->setUniformValue(uniforms_.projection, projection); program_->setUniformValue(uniforms_.projection, projection);
program_->setUniformValue(uniforms_.thickness, thickness); program_->setUniformValue(uniforms_.thickness, line.thickness);
program_->setUniformValue(uniforms_.color, color.redF(), color.greenF(), color.blueF(), color.alphaF()); program_->setUniformValue(uniforms_.color, line.color.r, line.color.g, line.color.b, line.color.a);
buffers_.position.bind(); buffers_.position.bind();
program_->enableAttributeArray("position"); program_->enableAttributeArray("position");
@ -265,10 +264,6 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent) : QOpenGLWidget(parent), lineSha
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(5000);
} }
FPGAViewWidget::~FPGAViewWidget() {} FPGAViewWidget::~FPGAViewWidget() {}
@ -292,6 +287,73 @@ void FPGAViewWidget::initializeGL()
glClearColor(backgroundColor_.red() / 255, backgroundColor_.green() / 255, backgroundColor_.blue() / 255, 0.0); 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 FPGAViewWidget::getProjection(void)
{ {
QMatrix4x4 matrix; QMatrix4x4 matrix;
@ -318,59 +380,47 @@ void FPGAViewWidget::paintGL()
float thick11Px = mouseToWorldCoordinates(1.1, 0).x(); float thick11Px = mouseToWorldCoordinates(1.1, 0).x();
// Draw grid. // Draw grid.
auto grid = LineShaderData(); auto grid = LineShaderData(thick1Px, gridColor_);
for (float i = -100.0f; i < 100.0f; i += 1.0f) { for (float i = -100.0f; i < 100.0f; i += 1.0f) {
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, 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_) { if (ctx_) {
auto &&proxy = ctx_->rwproxy(); // Draw Bels.
auto updates = proxy.getUIUpdatesRequired(); for (auto bel : ctx_->getBels()) {
drawDecal(shaders, ctx_->getBelDecal(bel));
// Collapse all updates to a full redraw. }
// TODO(q3k) fix this. // Draw Wires.
for (auto wire : ctx_->getWires()) {
bool redraw = (updates.allUIReload drawDecal(shaders, ctx_->getWireDecal(wire));
|| !updates.belUIReload.empty() }
|| !updates.wireUIReload.empty() // Draw Pips.
|| !updates.pipUIReload.empty() for (auto pip : ctx_->getPips()) {
|| !updates.groupUIReload.empty() drawDecal(shaders, ctx_->getPipDecal(pip));
|| updates.frameUIReload); }
// Draw Groups.
if (redraw) { for (auto group : ctx_->getGroups()) {
shaders_[0].clear(); drawDecal(shaders, ctx_->getGroupDecal(group));
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());
} }
} }
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); // Draw Frame Graphics.
lineShader_.draw(shaders_[1], gHiddenColor_, thick11Px, matrix); auto frames = LineShaderData(thick11Px, frameColor_);
lineShader_.draw(shaders_[2], gInactiveColor_, thick11Px, matrix); if (ctx_) {
lineShader_.draw(shaders_[3], gActiveColor_, thick11Px, matrix); drawDecal(frames, ctx_->getFrameDecal());
//lineShader_.draw(frame, matrix); lineShader_.draw(frames, matrix);
}
} }
void FPGAViewWidget::resizeGL(int width, int height) {} void FPGAViewWidget::resizeGL(int width, int height) {}

View File

@ -41,6 +41,18 @@ NPNR_PACKED_STRUCT(struct Vertex2DPOD {
Vertex2DPOD(GLfloat X, GLfloat Y) : x(X), y(Y) {} 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 // LineShaderData is a built set of vertices that can be rendered by the
// LineShader. // LineShader.
// Each LineShaderData can have its' own color and thickness. // Each LineShaderData can have its' own color and thickness.
@ -51,13 +63,10 @@ struct LineShaderData
std::vector<GLfloat> miters; std::vector<GLfloat> miters;
std::vector<GLuint> indices; std::vector<GLuint> indices;
void clear(void) GLfloat thickness;
{ ColorPOD color;
vertices.clear();
normals.clear(); LineShaderData(GLfloat Thickness, QColor Color) : thickness(Thickness), color(Color) {}
miters.clear();
indices.clear();
}
}; };
// PolyLine is a set of segments defined by points, that can be built to a // PolyLine is a set of segments defined by points, that can be built to a
@ -201,7 +210,7 @@ class LineShader
bool compile(void); bool compile(void);
// Render a LineShaderData with a given M/V/P transformation. // 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 class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
@ -237,76 +246,8 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
void drawDecal(LineShaderData &data, const DecalXY &decal);
template <typename T> void drawDecal(LineShaderData out[], const DecalXY &decal);
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;
}
}
}
}
public Q_SLOTS: public Q_SLOTS:
void newContext(Context *ctx); void newContext(Context *ctx);
@ -333,8 +274,6 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
QColor gInactiveColor_; QColor gInactiveColor_;
QColor gActiveColor_; QColor gActiveColor_;
QColor frameColor_; QColor frameColor_;
LineShaderData shaders_[4];
}; };
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -534,8 +534,9 @@ DecalXY Arch::getGroupDecal(GroupId group) const
return decalxy; 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; std::vector<GraphicElement> ret;
if (decal.type == DecalId::TYPE_FRAME) { if (decal.type == DecalId::TYPE_FRAME) {
@ -567,7 +568,7 @@ std::vector<GraphicElement> ArchRProxyMethods::getDecalGraphics(DecalId decal) c
BelId bel; BelId bel;
bel.index = decal.index; bel.index = decal.index;
auto bel_type = parent_->getBelType(bel); auto bel_type = getBelType(bel);
if (bel_type == TYPE_ICESTORM_LC) { if (bel_type == TYPE_ICESTORM_LC) {
GraphicElement el; GraphicElement el;
@ -953,9 +954,4 @@ CellInfo *ArchRWProxyMethods::getCell(IdString cell)
return parent_->cells.at(cell).get(); return parent_->cells.at(cell).get();
} }
UIUpdatesRequired ArchRWProxyMethods::getUIUpdatesRequired(void)
{
return parent_->getUIUpdatesRequired();
}
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -604,6 +604,8 @@ public:
// ------------------------------------------------- // -------------------------------------------------
std::vector<GraphicElement> getDecalGraphics(DecalId decal) const;
DecalXY getFrameDecal() const; DecalXY getFrameDecal() const;
DecalXY getBelDecal(BelId bel) const; DecalXY getBelDecal(BelId bel) const;
DecalXY getWireDecal(WireId wire) const; DecalXY getWireDecal(WireId wire) const;
@ -689,8 +691,6 @@ public:
IdString getBoundBelCell(BelId bel) const; IdString getBoundBelCell(BelId bel) const;
BelId getBelByName(IdString name) 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 // 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); void bindBel(BelId bel, IdString cell, PlaceStrength strength);
// Returned pointer is valid as long as Proxy object exists. // Returned pointer is valid as long as Proxy object exists.
CellInfo *getCell(IdString cell); 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. // A proxy object that keeps an Arch readwrite lock until it goes out of scope.

View File

@ -51,8 +51,7 @@ void svg_dump_decal(const Context *ctx, const DecalXY &decal)
const float scale = 10.0, offset = 10.0; const float scale = 10.0, offset = 10.0;
const std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\""; const std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\"";
auto &&proxy = ctx->rproxy(); for (auto &el : ctx->getDecalGraphics(decal.decal)) {
for (auto &el : proxy.getDecalGraphics(decal.decal)) {
if (el.type == GraphicElement::G_BOX) { if (el.type == GraphicElement::G_BOX) {
std::cout << "<rect x=\"" << (offset + scale * (decal.x + el.x1)) << "\" y=\"" std::cout << "<rect x=\"" << (offset + scale * (decal.x + el.x1)) << "\" y=\""
<< (offset + scale * (decal.y + el.y1)) << "\" height=\"" << (scale * (el.y2 - el.y1)) << (offset + scale * (decal.y + el.y1)) << "\" height=\"" << (scale * (el.y2 - el.y1))