Skip to content

Commit

Permalink
avoid unwanted updates by ignoring the expose event on openglwindows …
Browse files Browse the repository at this point in the history
…with explicit paint and swap
  • Loading branch information
m0dB authored and m0dB committed Dec 31, 2023
1 parent 41ea0fd commit de5ebc8
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 14 deletions.
16 changes: 7 additions & 9 deletions src/widget/openglwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
#include "widget/wglwidget.h"

OpenGLWindow::OpenGLWindow(WGLWidget* pWidget)
: m_pWidget(pWidget),
m_dirty(false) {
: m_pWidget(pWidget) {
setFormat(WaveformWidgetFactory::getSurfaceFormat());
}

Expand All @@ -25,13 +24,8 @@ void OpenGLWindow::initializeGL() {
}

void OpenGLWindow::paintGL() {
// will only be called when m_pWidget useExplicitPaintAndSwap is false
if (m_pWidget && isExposed()) {
if (m_dirty) {
// Extra render and swap to avoid flickering when resizing
m_pWidget->paintGL();
m_pWidget->swapBuffers();
m_dirty = false;
}
m_pWidget->paintGL();
}
}
Expand All @@ -44,7 +38,6 @@ void OpenGLWindow::resizeGL(int w, int h) {
// QGLWidget::resizeGL has devicePixelRatio applied, so we mimic the same behaviour
m_pWidget->resizeGL(static_cast<int>(static_cast<float>(w) * devicePixelRatio()),
static_cast<int>(static_cast<float>(h) * devicePixelRatio()));
m_dirty = true;
m_pWidget->doneCurrent();
}
}
Expand All @@ -62,6 +55,11 @@ bool OpenGLWindow::event(QEvent* pEv) {
// this recursion.
const auto t = pEv->type();

if (t == QEvent::Expose && m_pWidget->useExplicitPaintAndSwap()) {
// Avoid updates for windows that use explicit swaps
return false;

Check failure on line 60 in src/widget/openglwindow.cpp

View workflow job for this annotation

GitHub Actions / clazy

Return QOpenGLWindow::event() instead of false [-Wclazy-base-class-event]
}

bool result = QOpenGLWindow::event(pEv);

if (m_pWidget) {
Expand Down
1 change: 0 additions & 1 deletion src/widget/openglwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,4 @@ class OpenGLWindow : public QOpenGLWindow {
bool event(QEvent* pEv) override;

WGLWidget* m_pWidget;
bool m_dirty;
};
19 changes: 15 additions & 4 deletions src/widget/wglwidgetqopengl.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <QDebug>
#include <QResizeEvent>

#include "widget/openglwindow.h"
Expand All @@ -8,12 +9,15 @@ WGLWidget::WGLWidget(QWidget* pParent)
: QWidget(pParent),
m_pOpenGLWindow(nullptr),
m_pContainerWidget(nullptr),
m_pTrackDropTarget(nullptr) {
m_pTrackDropTarget(nullptr),
m_useExplicitPaintAndSwap(true) {
// When the widget is resized or moved, the QOpenGLWindow visibly resizes
// or moves before the widgets do. This can be solved by calling
// setAttribute(Qt::WA_PaintOnScreen);
// here, but this comes with a clear performance penalty and drop in
// frame rate.

setAutoFillBackground(true);
}

WGLWidget::~WGLWidget() {
Expand Down Expand Up @@ -42,13 +46,16 @@ void WGLWidget::showEvent(QShowEvent* event) {
m_pContainerWidget = createWindowContainer(m_pOpenGLWindow, this);
m_pContainerWidget->resize(size());
m_pContainerWidget->show();
m_pContainerWidget->setAutoFillBackground(true);
}
QWidget::showEvent(event);
}

void WGLWidget::resizeEvent(QResizeEvent* event) {
if (m_pContainerWidget) {
// For widgets that are being used with swapBuffers, post-pone
// the resize of the containerWidget and this of the OpenGLWindow
// to the swapBuffers call to avoid flickering,
if (m_pContainerWidget && !m_useExplicitPaintAndSwap) {
// Otherwise do it here.
m_pContainerWidget->resize(event->size());
}
QWidget::resizeEvent(event);
Expand All @@ -71,7 +78,8 @@ void WGLWidget::doneCurrent() {
}

void WGLWidget::paintGL() {
// to be implemented in derived widgets if needed
// to be implemented in derived widgets if needed,
// only called on widgets with setUseExplicitSwap(false)
}

void WGLWidget::initializeGL() {
Expand All @@ -86,6 +94,9 @@ void WGLWidget::resizeGL(int w, int h) {

void WGLWidget::swapBuffers() {
if (shouldRender()) {
if (size() != m_pContainerWidget->size()) {
m_pContainerWidget->resize(size());
}
m_pOpenGLWindow->context()->swapBuffers(m_pOpenGLWindow->context()->surface());
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/widget/wglwidgetqopengl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ class WGLWidget : public QWidget {

QOpenGLWindow* getOpenGLWindow() const;

bool useExplicitPaintAndSwap() const {
return m_useExplicitPaintAndSwap;
}
void setUseExplicitPaintAndSwap(bool value) {
m_useExplicitPaintAndSwap = value;
}

protected:
void showEvent(QShowEvent* event) override;
void resizeEvent(QResizeEvent* event) override;
Expand All @@ -50,4 +57,5 @@ class WGLWidget : public QWidget {
OpenGLWindow* m_pOpenGLWindow;
QWidget* m_pContainerWidget;
TrackDropTarget* m_pTrackDropTarget;
bool m_useExplicitPaintAndSwap;
};
1 change: 1 addition & 0 deletions src/widget/winitialglwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

WInitialGLWidget::WInitialGLWidget(QWidget* pParent)
: WGLWidget(pParent) {
setUseExplicitPaintAndSwap(false);
}

void WInitialGLWidget::paintGL() {
Expand Down

0 comments on commit de5ebc8

Please sign in to comment.