From 5786ac12f0a9901b0ddf7ee3c74cd1e87095306c Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Wed, 20 May 2020 11:05:17 +0200 Subject: [PATCH] Fix hellowindow example It seems this example never worked as expected. It has a 'multiple' option which should show extra windows with rendering taking place in different thread, however although render is moved to other thread render() function was never called in that thread. Fix following things: * make rendering in other thread * stop requestUpdate if nothing is exposed * add timer so animation works at the same speed despite of number of windows (renderer B renders two windows) * wait for render to finish before triggering requestUdpate * remove mutex where not needed Pick-to: 5.15 Change-Id: I420436bd28d0357534332dd55b088d634d906c14 Reviewed-by: Laszlo Agocs --- examples/opengl/hellowindow/hellowindow.cpp | 65 +++++++-------------- examples/opengl/hellowindow/hellowindow.h | 24 +++----- 2 files changed, 30 insertions(+), 59 deletions(-) diff --git a/examples/opengl/hellowindow/hellowindow.cpp b/examples/opengl/hellowindow/hellowindow.cpp index 1c1259de137..bde763dd708 100644 --- a/examples/opengl/hellowindow/hellowindow.cpp +++ b/examples/opengl/hellowindow/hellowindow.cpp @@ -54,11 +54,11 @@ #include #include #include +#include Renderer::Renderer(const QSurfaceFormat &format, Renderer *share, QScreen *screen) : m_initialized(false) , m_format(format) - , m_currentWindow(0) { m_context = new QOpenGLContext(this); if (screen) @@ -89,24 +89,33 @@ HelloWindow::HelloWindow(const QSharedPointer &renderer, QScreen *scre create(); updateColor(); + + connect(renderer.data(), &Renderer::requestUpdate, this, &QWindow::requestUpdate); } void HelloWindow::exposeEvent(QExposeEvent *) { - m_renderer->setAnimating(this, isExposed()); if (isExposed()) - m_renderer->render(); + render(); } bool HelloWindow::event(QEvent *ev) { - if (ev->type() == QEvent::UpdateRequest) { - m_renderer->render(); - requestUpdate(); - } + if (ev->type() == QEvent::UpdateRequest && isExposed()) + render(); return QWindow::event(ev); } +void HelloWindow::render() +{ + static QElapsedTimer timer; + if (!timer.isValid()) + timer.start(); + qreal a = (qreal)(((timer.elapsed() * 3) % 36000) / 100.0); + auto call = [this, r = m_renderer.data(), a, c = color()]() { r->render(this, a, c); }; + QMetaObject::invokeMethod(m_renderer.data(), call); +} + void HelloWindow::mousePressEvent(QMouseEvent *) { updateColor(); @@ -114,14 +123,11 @@ void HelloWindow::mousePressEvent(QMouseEvent *) QColor HelloWindow::color() const { - QMutexLocker locker(&m_colorLock); return m_color; } void HelloWindow::updateColor() { - QMutexLocker locker(&m_colorLock); - QColor colors[] = { QColor(100, 255, 0), @@ -132,41 +138,13 @@ void HelloWindow::updateColor() m_colorIndex = 1 - m_colorIndex; } -void Renderer::setAnimating(HelloWindow *window, bool animating) +void Renderer::render(HelloWindow *surface, qreal angle, const QColor &color) { - QMutexLocker locker(&m_windowLock); - if (m_windows.contains(window) == animating) - return; - - if (animating) { - m_windows << window; - if (m_windows.size() == 1) - window->requestUpdate(); - } else { - m_currentWindow = 0; - m_windows.removeOne(window); - } -} - -void Renderer::render() -{ - QMutexLocker locker(&m_windowLock); - - if (m_windows.isEmpty()) - return; - - HelloWindow *surface = m_windows.at(m_currentWindow); - QColor color = surface->color(); - - m_currentWindow = (m_currentWindow + 1) % m_windows.size(); - if (!m_context->makeCurrent(surface)) return; QSize viewSize = surface->size(); - locker.unlock(); - if (!m_initialized) { initialize(); m_initialized = true; @@ -192,9 +170,9 @@ void Renderer::render() m_program->setAttributeBuffer(normalAttr, GL_FLOAT, verticesSize, 3); QMatrix4x4 modelview; - modelview.rotate(m_fAngle, 0.0f, 1.0f, 0.0f); - modelview.rotate(m_fAngle, 1.0f, 0.0f, 0.0f); - modelview.rotate(m_fAngle, 0.0f, 0.0f, 1.0f); + modelview.rotate(angle, 0.0f, 1.0f, 0.0f); + modelview.rotate(angle, 1.0f, 0.0f, 0.0f); + modelview.rotate(angle, 0.0f, 0.0f, 1.0f); modelview.translate(0.0f, -0.2f, 0.0f); m_program->setUniformValue(matrixUniform, modelview); @@ -204,7 +182,7 @@ void Renderer::render() m_context->swapBuffers(surface); - m_fAngle += 1.0f; + emit requestUpdate(); } Q_GLOBAL_STATIC(QMutex, initMutex) @@ -250,7 +228,6 @@ void Renderer::initialize() matrixUniform = m_program->uniformLocation("matrix"); colorUniform = m_program->uniformLocation("sourceColor"); - m_fAngle = 0; createGeometry(); m_vbo.create(); diff --git a/examples/opengl/hellowindow/hellowindow.h b/examples/opengl/hellowindow/hellowindow.h index 938c6409a4f..76f2afb549b 100644 --- a/examples/opengl/hellowindow/hellowindow.h +++ b/examples/opengl/hellowindow/hellowindow.h @@ -52,7 +52,7 @@ #include #include -#include +#include #include #include #include @@ -64,14 +64,16 @@ class Renderer : public QObject Q_OBJECT public: - explicit Renderer(const QSurfaceFormat &format, Renderer *share = 0, QScreen *screen = 0); + explicit Renderer(const QSurfaceFormat &format, Renderer *share = nullptr, + QScreen *screen = nullptr); QSurfaceFormat format() const { return m_format; } - void setAnimating(HelloWindow *window, bool animating); - public slots: - void render(); + void render(HelloWindow *surface, qreal angle, const QColor &color); + +signals: + void requestUpdate(); private: void initialize(); @@ -81,8 +83,6 @@ private: void quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4); void extrude(qreal x1, qreal y1, qreal x2, qreal y2); - qreal m_fAngle; - QVector vertices; QVector normals; int vertexAttr; @@ -95,19 +95,13 @@ private: QOpenGLContext *m_context; QOpenGLShaderProgram *m_program; QOpenGLBuffer m_vbo; - - QList m_windows; - int m_currentWindow; - - QMutex m_windowLock; - QColor m_backgroundColor; }; class HelloWindow : public QWindow { public: - explicit HelloWindow(const QSharedPointer &renderer, QScreen *screen = 0); + explicit HelloWindow(const QSharedPointer &renderer, QScreen *screen = nullptr); QColor color() const; void updateColor(); @@ -116,10 +110,10 @@ protected: bool event(QEvent *ev) override; void exposeEvent(QExposeEvent *event) override; void mousePressEvent(QMouseEvent *) override; + void render(); private: int m_colorIndex; QColor m_color; const QSharedPointer m_renderer; - mutable QMutex m_colorLock; };