aboutsummaryrefslogtreecommitdiffstats
path: root/gui/lineshader.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/lineshader.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/lineshader.cc')
-rw-r--r--gui/lineshader.cc123
1 files changed, 81 insertions, 42 deletions
diff --git a/gui/lineshader.cc b/gui/lineshader.cc
index eba96020..0f762b38 100644
--- a/gui/lineshader.cc
+++ b/gui/lineshader.cc
@@ -162,75 +162,114 @@ bool LineShader::compile(void)
return false;
}
- if (!vao_.create())
- log_abort();
- vao_.bind();
-
- if (!buffers_.position.create())
- log_abort();
- if (!buffers_.normal.create())
- log_abort();
- if (!buffers_.miter.create())
- log_abort();
- if (!buffers_.index.create())
- log_abort();
-
+ program_->bind();
attributes_.position = program_->attributeLocation("position");
attributes_.normal = program_->attributeLocation("normal");
attributes_.miter = program_->attributeLocation("miter");
uniforms_.thickness = program_->uniformLocation("thickness");
uniforms_.projection = program_->uniformLocation("projection");
uniforms_.color = program_->uniformLocation("color");
+ program_->release();
+
+ for (int style = 0; style < GraphicElement::STYLE_MAX; style++) {
+ buffers_[style].position = QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
+ buffers_[style].normal = QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
+ buffers_[style].miter = QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
+ buffers_[style].index = QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
+
+ if (!buffers_[style].vao.create())
+ log_abort();
+ buffers_[style].vao.bind();
+
+ if (!buffers_[style].position.create())
+ log_abort();
+ if (!buffers_[style].normal.create())
+ log_abort();
+ if (!buffers_[style].miter.create())
+ log_abort();
+ if (!buffers_[style].index.create())
+ log_abort();
+
+ buffers_[style].position.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ buffers_[style].normal.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ buffers_[style].miter.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ buffers_[style].index.setUsagePattern(QOpenGLBuffer::StaticDraw);
+
+ buffers_[style].position.bind();
+ buffers_[style].normal.bind();
+ buffers_[style].miter.bind();
+ buffers_[style].index.bind();
+
+ buffers_[style].vao.release();
+ }
- vao_.release();
return true;
}
-void LineShader::draw(const LineShaderData &line, const QColor &color, float thickness, const QMatrix4x4 &projection)
+void LineShader::update_vbos(enum GraphicElement::style_t style,
+ const LineShaderData &line)
{
- auto gl = QOpenGLContext::currentContext()->functions();
- if (line.vertices.size() == 0)
+ if (buffers_[style].last_vbo_update == line.last_render)
return;
- vao_.bind();
- program_->bind();
+ buffers_[style].last_vbo_update = line.last_render;
+
+ buffers_[style].indices = line.indices.size();
+ if (buffers_[style].indices == 0) {
+ // invalidate buffers
+ buffers_[style].position.allocate(nullptr, 0);
+ buffers_[style].normal.allocate(nullptr, 0);
+ buffers_[style].miter.allocate(nullptr, 0);
+ buffers_[style].index.allocate(nullptr, 0);
+ return;
+ }
+
+ buffers_[style].position.bind();
+ buffers_[style].position.allocate(&line.vertices[0], sizeof(Vertex2DPOD) * line.vertices.size());
- buffers_.position.bind();
- buffers_.position.allocate(&line.vertices[0], sizeof(Vertex2DPOD) * line.vertices.size());
+ buffers_[style].normal.bind();
+ buffers_[style].normal.allocate(&line.normals[0], sizeof(Vertex2DPOD) * line.normals.size());
- buffers_.normal.bind();
- buffers_.normal.allocate(&line.normals[0], sizeof(Vertex2DPOD) * line.normals.size());
+ buffers_[style].miter.bind();
+ buffers_[style].miter.allocate(&line.miters[0], sizeof(GLfloat) * line.miters.size());
- buffers_.miter.bind();
- buffers_.miter.allocate(&line.miters[0], sizeof(GLfloat) * line.miters.size());
+ buffers_[style].index.bind();
+ buffers_[style].index.allocate(&line.indices[0], sizeof(GLuint) * line.indices.size());
+}
- buffers_.index.bind();
- buffers_.index.allocate(&line.indices[0], sizeof(GLuint) * line.indices.size());
+void LineShader::draw(enum GraphicElement::style_t style, const QColor &color,
+ float thickness, const QMatrix4x4 &projection)
+{
+ auto gl = QOpenGLContext::currentContext()->functions();
+ if (buffers_[style].indices == 0)
+ return;
+ program_->bind();
+ buffers_[style].vao.bind();
program_->setUniformValue(uniforms_.projection, projection);
program_->setUniformValue(uniforms_.thickness, thickness);
program_->setUniformValue(uniforms_.color, color.redF(), color.greenF(), color.blueF(), color.alphaF());
- buffers_.position.bind();
- program_->enableAttributeArray("position");
- gl->glVertexAttribPointer(attributes_.position, 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
+ buffers_[style].position.bind();
+ program_->enableAttributeArray(attributes_.position);
+ program_->setAttributeBuffer(attributes_.position, GL_FLOAT, 0, 2);
- buffers_.normal.bind();
- program_->enableAttributeArray("normal");
- gl->glVertexAttribPointer(attributes_.normal, 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
+ buffers_[style].normal.bind();
+ program_->enableAttributeArray(attributes_.normal);
+ program_->setAttributeBuffer(attributes_.normal, GL_FLOAT, 0, 2);
- buffers_.miter.bind();
- program_->enableAttributeArray("miter");
- gl->glVertexAttribPointer(attributes_.miter, 1, GL_FLOAT, GL_FALSE, 0, (void *)0);
+ buffers_[style].miter.bind();
+ program_->enableAttributeArray(attributes_.miter);
+ program_->setAttributeBuffer(attributes_.miter, GL_FLOAT, 0, 1);
- buffers_.index.bind();
- gl->glDrawElements(GL_TRIANGLES, line.indices.size(), GL_UNSIGNED_INT, (void *)0);
+ buffers_[style].index.bind();
+ gl->glDrawElements(GL_TRIANGLES, buffers_[style].indices, GL_UNSIGNED_INT, (void *)0);
- program_->disableAttributeArray("miter");
- program_->disableAttributeArray("normal");
- program_->disableAttributeArray("position");
+ program_->disableAttributeArray(attributes_.position);
+ program_->disableAttributeArray(attributes_.normal);
+ program_->disableAttributeArray(attributes_.miter);
+ buffers_[style].vao.release();
program_->release();
- vao_.release();
}
NEXTPNR_NAMESPACE_END