aboutsummaryrefslogtreecommitdiffstats
path: root/gui/fpgaviewwidget.cc
diff options
context:
space:
mode:
authorMateusz Zalega <mateusz@appliedsourcery.com>2018-08-16 21:44:37 +0200
committerMateusz Zalega <mateusz@appliedsourcery.com>2018-10-23 15:43:51 +0200
commitd03291eeb1efbb1005eba5a8a4b2c92ef66d2fd5 (patch)
tree997b4a31291efaca2d1f60c54e95b81785a9ddcc /gui/fpgaviewwidget.cc
parentb5faa7ad102b8308eeb0c73a3849909bf4b1b635 (diff)
downloadnextpnr-d03291eeb1efbb1005eba5a8a4b2c92ef66d2fd5.tar.gz
nextpnr-d03291eeb1efbb1005eba5a8a4b2c92ef66d2fd5.tar.bz2
nextpnr-d03291eeb1efbb1005eba5a8a4b2c92ef66d2fd5.zip
gui: improved FPGAViewWidget::paintGL() performance
Profiling revealed that memcpy() in QOpenGLBuffer::allocate() had been taking the most time during paintGL() calls. I've been able to take the CPU usage down to about 1/4 of its previous values by caching elements in VBOs and updating them only after subsequent calls to renderGraphicElement(). Signed-off-by: Mateusz Zalega <mateusz@appliedsourcery.com>
Diffstat (limited to 'gui/fpgaviewwidget.cc')
-rw-r--r--gui/fpgaviewwidget.cc96
1 files changed, 69 insertions, 27 deletions
diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc
index 3b0b3df7..fb5e36b2 100644
--- a/gui/fpgaviewwidget.cc
+++ b/gui/fpgaviewwidget.cc
@@ -103,8 +103,21 @@ void FPGAViewWidget::initializeGL()
log_error("Could not compile shader.\n");
}
initializeOpenGLFunctions();
- glClearColor(colors_.background.red() / 255, colors_.background.green() / 255, colors_.background.blue() / 255,
- 0.0);
+ glClearColor(colors_.background.red() / 255, colors_.background.green() / 255,
+ colors_.background.blue() / 255, 0.0);
+
+
+ {
+ QMutexLocker locker(&rendererDataLock_);
+ // Render grid.
+ auto grid = LineShaderData();
+ 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);
+ }
+ grid.last_render = 1;
+ lineShader_.update_vbos(GraphicElement::STYLE_GRID, grid);
+ }
}
float FPGAViewWidget::PickedElement::distance(Context *ctx, float wx, float wy) const
@@ -185,6 +198,8 @@ void FPGAViewWidget::renderGraphicElement(LineShaderData &out, PickQuadTree::Bou
bb.setY0(std::min(bb.y0(), y + el.y1));
bb.setX1(std::max(bb.x1(), x + el.x2));
bb.setY1(std::max(bb.y1(), y + el.y2));
+
+ out.last_render++;
return;
}
@@ -194,6 +209,8 @@ void FPGAViewWidget::renderGraphicElement(LineShaderData &out, PickQuadTree::Bou
bb.setY0(std::min(bb.y0(), y + el.y1));
bb.setX1(std::max(bb.x1(), x + el.x2));
bb.setY1(std::max(bb.y1(), y + el.y2));
+
+ out.last_render++;
return;
}
}
@@ -297,36 +314,40 @@ void FPGAViewWidget::paintGL()
float thick11Px = mouseToWorldDimensions(1.1, 0).x();
float thick2Px = mouseToWorldDimensions(2, 0).x();
- // Render grid.
- auto grid = LineShaderData();
- 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);
- }
- // Flags from pipeline.
- PassthroughFlags flags;
- // Draw grid.
- lineShader_.draw(grid, colors_.grid, thick1Px, matrix);
-
{
QMutexLocker locker(&rendererDataLock_);
+ // Must be called from a thread holding the OpenGL context
+ update_vbos();
+ }
- // Render Arch graphics.
- lineShader_.draw(rendererData_->gfxByStyle[GraphicElement::STYLE_FRAME], colors_.frame, thick11Px, matrix);
- lineShader_.draw(rendererData_->gfxByStyle[GraphicElement::STYLE_HIDDEN], colors_.hidden, thick11Px, matrix);
- lineShader_.draw(rendererData_->gfxByStyle[GraphicElement::STYLE_INACTIVE], colors_.inactive, thick11Px,
- matrix);
- lineShader_.draw(rendererData_->gfxByStyle[GraphicElement::STYLE_ACTIVE], colors_.active, thick11Px, matrix);
-
- // Draw highlighted items.
- for (int i = 0; i < 8; i++)
- lineShader_.draw(rendererData_->gfxHighlighted[i], colors_.highlight[i], thick11Px, matrix);
+ // Render the grid.
+ lineShader_.draw(GraphicElement::STYLE_GRID, colors_.grid, thick1Px,
+ matrix);
+
+ // Render Arch graphics.
+ lineShader_.draw(GraphicElement::STYLE_FRAME, colors_.frame, thick11Px,
+ matrix);
+ lineShader_.draw(GraphicElement::STYLE_HIDDEN, colors_.hidden, thick11Px,
+ matrix);
+ lineShader_.draw(GraphicElement::STYLE_INACTIVE, colors_.inactive,
+ thick11Px, matrix);
+ lineShader_.draw(GraphicElement::STYLE_ACTIVE, colors_.active, thick11Px,
+ matrix);
+
+ // Draw highlighted items.
+ for (int i = 0; i < 8; i++) {
+ GraphicElement::style_t style = (GraphicElement::style_t)(
+ GraphicElement::STYLE_HIGHLIGHTED0 + i);
+ lineShader_.draw(style, colors_.highlight[i], thick11Px, matrix);
+ }
- lineShader_.draw(rendererData_->gfxSelected, colors_.selected, thick11Px, matrix);
- lineShader_.draw(rendererData_->gfxHovered, colors_.hovered, thick2Px, matrix);
+ lineShader_.draw(GraphicElement::STYLE_SELECTED, colors_.selected,
+ thick11Px, matrix);
+ lineShader_.draw(GraphicElement::STYLE_HOVER, colors_.hovered,
+ thick2Px, matrix);
- flags = rendererData_->flags;
- }
+ // Flags from pipeline.
+ PassthroughFlags flags = rendererData_->flags;
// Check flags passed through pipeline.
if (flags.zoomOutbound) {
@@ -799,4 +820,25 @@ void FPGAViewWidget::leaveEvent(QEvent *event)
pokeRenderer();
}
+void FPGAViewWidget::update_vbos()
+{
+ for (int style = GraphicElement::STYLE_FRAME; style
+ < GraphicElement::STYLE_HIGHLIGHTED0;
+ style++) {
+ lineShader_.update_vbos((enum GraphicElement::style_t)(style),
+ rendererData_->gfxByStyle[style]);
+ }
+
+ for (int i = 0; i < 8; i++) {
+ GraphicElement::style_t style = (GraphicElement::style_t)(
+ GraphicElement::STYLE_HIGHLIGHTED0 + i);
+ lineShader_.update_vbos(style, rendererData_->gfxHighlighted[i]);
+ }
+
+ lineShader_.update_vbos(GraphicElement::STYLE_SELECTED,
+ rendererData_->gfxSelected);
+ lineShader_.update_vbos(GraphicElement::STYLE_HOVER,
+ rendererData_->gfxHovered);
+}
+
NEXTPNR_NAMESPACE_END