Skip to content

Commit

Permalink
When cmake option QOPENGL is set: use QOpenGL.. classes, use QOpenGLW…
Browse files Browse the repository at this point in the history
…indow based WGLWidget, don’t use SharedGLContext, don’t use WidgetRenderTimer, use texture-based WVuMeterGL.
  • Loading branch information
m0dB committed Oct 15, 2022
1 parent 31fa633 commit d243084
Show file tree
Hide file tree
Showing 45 changed files with 1,124 additions and 152 deletions.
23 changes: 20 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ if(NOT CMAKE_CONFIGURATION_TYPES)
endif()

option(QT6 "Build with Qt6" OFF)
option(QOPENGL "Use QOpenGL... classes instead of QGLWidget" OFF)

if(QOPENGL)
add_compile_definitions(MIXXX_USE_QOPENGL)
endif()

if(APPLE)
if(QT6)
Expand Down Expand Up @@ -1113,7 +1118,6 @@ else()
src/waveform/renderers/waveformrendermarkrange.cpp
src/waveform/renderers/waveformsignalcolors.cpp
src/waveform/renderers/waveformwidgetrenderer.cpp
src/waveform/sharedglcontext.cpp
src/waveform/visualsmanager.cpp
src/waveform/vsyncthread.cpp
src/waveform/waveformmarklabel.cpp
Expand All @@ -1133,16 +1137,29 @@ else()
src/waveform/widgets/rgbwaveformwidget.cpp
src/waveform/widgets/softwarewaveformwidget.cpp
src/waveform/widgets/waveformwidgetabstract.cpp
src/widget/wglwidgetqglwidget.cpp
src/widget/woverview.cpp
src/widget/woverviewhsv.cpp
src/widget/woverviewlmh.cpp
src/widget/woverviewrgb.cpp
src/widget/wspinny.cpp
src/widget/wvumetergl.cpp
src/widget/wwaveformviewer.cpp
)
endif()

if(QOPENGL)
target_sources(mixxx-lib PRIVATE
src/widget/openglwindow.cpp
src/widget/wglwidgetqopengl.cpp
src/widget/wvumeterglqopengl.cpp
)
else()
target_sources(mixxx-lib PRIVATE
src/waveform/sharedglcontext.cpp
src/widget/wglwidgetqglwidget.cpp
src/widget/wvumeterglqgl.cpp
)
endif()

set_target_properties(mixxx-lib PROPERTIES AUTOMOC ON AUTOUIC ON CXX_CLANG_TIDY "${CLANG_TIDY}")
target_include_directories(mixxx-lib PUBLIC src "${CMAKE_CURRENT_BINARY_DIR}/src")
if(UNIX AND NOT APPLE)
Expand Down
3 changes: 3 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ int main(int argc, char * argv[]) {
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
#ifdef MIXXX_USE_QOPENGL
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
#endif

// workaround for https://bugreports.qt.io/browse/QTBUG-84363
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) && QT_VERSION < QT_VERSION_CHECK(5, 15, 1)
Expand Down
6 changes: 6 additions & 0 deletions src/mixxxmainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

#include <QDesktopServices>
#include <QFileDialog>

#ifndef MIXXX_USE_QOPENGL
#include <QGLFormat>
#endif

#include <QUrl>
#include <QtDebug>

Expand Down Expand Up @@ -152,6 +156,7 @@ void MixxxMainWindow::initialize() {
}
});

#ifndef MIXXX_USE_QOPENGL
// Before creating the first skin we need to create a QGLWidget so that all
// the QGLWidget's we create can use it as a shared QGLContext.
if (!CmdlineArgs::Instance().getSafeMode() && QGLFormat::hasOpenGL()) {
Expand Down Expand Up @@ -181,6 +186,7 @@ void MixxxMainWindow::initialize() {
pContextWidget->hide();
SharedGLContext::setWidget(pContextWidget);
}
#endif

WaveformWidgetFactory::createInstance(); // takes a long time
WaveformWidgetFactory::instance()->setConfig(m_pCoreServices->getSettings());
Expand Down
2 changes: 1 addition & 1 deletion src/skin/legacy/legacyskinparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,7 @@ QWidget* LegacySkinParser::parseVuMeter(const QDomElement& node) {
return pVuMeterWidget;
}

// QGLWidget derived WVuMeterGL
// WGLWidget derived WVuMeterGL

if (CmdlineArgs::Instance().getSafeMode()) {
WLabel* dummy = new WLabel(m_pParent);
Expand Down
4 changes: 4 additions & 0 deletions src/util/widgetrendertimer.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "util/widgetrendertimer.h"

#ifdef USE_WIDGET_RENDER_TIMER

#include "moc_widgetrendertimer.cpp"
#include "util/time.h"

Expand Down Expand Up @@ -28,3 +30,5 @@ void WidgetRenderTimer::activity() {
m_guiTickTimer.start(m_renderFrequency);
}
}

#endif
11 changes: 11 additions & 0 deletions src/util/widgetrendertimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@
// Ironically, using this class somehow causes severe lagginess on mouse input
// with Windows, so use #ifdefs to only call activity() on macOS; just call
// QWidget::update() for other operating systems.
//
// Also when using the QOpenGLWindow based WGLWidget (when MIXXX_USE_QOPENGL is
// defined) using this seems not necessary and makes causes lagginess
#ifdef __APPLE__
#ifndef MIXXX_USE_QOPENGL
#define USE_WIDGET_RENDER_TIMER
#endif
#endif

#ifdef USE_WIDGET_RENDER_TIMER
class WidgetRenderTimer : public QObject {
Q_OBJECT
public:
Expand Down Expand Up @@ -53,3 +63,4 @@ class WidgetRenderTimer : public QObject {
mixxx::Duration m_lastActivity;
mixxx::Duration m_lastRender;
};
#endif
17 changes: 12 additions & 5 deletions src/waveform/renderers/glslwaveformrenderersignal.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#include "waveform/renderers/glslwaveformrenderersignal.h"
#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)

#ifdef MIXXX_USE_QOPENGL
#include <QOpenGLFramebufferObject>
#include <QOpenGLShaderProgram>
#else
#endif
#include <QGLFramebufferObject>
#include <QGLShaderProgram>

Expand Down Expand Up @@ -49,14 +54,16 @@ bool GLSLWaveformRendererSignal::loadShaders() {
m_frameShaderProgram->removeAllShaders();

if (!m_frameShaderProgram->addShaderFromSourceFile(
QGLShader::Vertex, ":/shaders/passthrough.vert")) {
GL_SHADER_CLASS::Vertex,
":/shaders/passthrough.vert")) {
qDebug() << "GLWaveformRendererSignalShader::loadShaders - "
<< m_frameShaderProgram->log();
return false;
}

if (!m_frameShaderProgram->addShaderFromSourceFile(
QGLShader::Fragment, m_pFragShader)) {
GL_SHADER_CLASS::Fragment,
m_pFragShader)) {
qDebug() << "GLWaveformRendererSignalShader::loadShaders - "
<< m_frameShaderProgram->log();
return false;
Expand Down Expand Up @@ -182,8 +189,8 @@ void GLSLWaveformRendererSignal::createFrameBuffers() {
static_cast<int>(
m_waveformRenderer->getHeight() * devicePixelRatio);

m_framebuffer = std::make_unique<QGLFramebufferObject>(bufferWidth,
bufferHeight);
m_framebuffer = std::make_unique<GL_FBO_CLASS>(bufferWidth,
bufferHeight);

if (!m_framebuffer->isValid()) {
qWarning() << "GLSLWaveformRendererSignal::createFrameBuffer - frame buffer not valid";
Expand All @@ -195,7 +202,7 @@ void GLSLWaveformRendererSignal::onInitializeGL() {
m_textureRenderedWaveformCompletion = 0;

if (!m_frameShaderProgram) {
m_frameShaderProgram = std::make_unique<QGLShaderProgram>();
m_frameShaderProgram = std::make_unique<GL_SHADER_PROGRAM_CLASS>();
}

if (!loadShaders()) {
Expand Down
18 changes: 14 additions & 4 deletions src/waveform/renderers/glslwaveformrenderersignal.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,18 @@
#include "util/memory.h"
#include "waveform/renderers/waveformrenderersignalbase.h"

QT_FORWARD_DECLARE_CLASS(QGLFramebufferObject)
QT_FORWARD_DECLARE_CLASS(QGLShaderProgram)
#ifdef MIXXX_USE_QOPENGL
#define GL_FBO_CLASS QOpenGLFramebufferObject
#define GL_SHADER_CLASS QOpenGLShader
#define GL_SHADER_PROGRAM_CLASS QOpenGLShaderProgram
#else
#define GL_FBO_CLASS QGLFramebufferObject
#define GL_SHADER_CLASS QGLShader
#define GL_SHADER_PROGRAM_CLASS QGLShaderProgram
#endif

QT_FORWARD_DECLARE_CLASS(GL_FBO_CLASS)
QT_FORWARD_DECLARE_CLASS(GL_SHADER_PROGRAM_CLASS)

class GLSLWaveformRendererSignal : public QObject,
public WaveformRendererSignalBase,
Expand Down Expand Up @@ -51,15 +61,15 @@ class GLSLWaveformRendererSignal : public QObject,
int m_textureRenderedWaveformCompletion;

// Frame buffer for two pass rendering.
std::unique_ptr<QGLFramebufferObject> m_framebuffer;
std::unique_ptr<GL_FBO_CLASS> m_framebuffer;

bool m_bDumpPng;

// shaders
bool m_shadersValid;
ColorType m_colorType;
const QString m_pFragShader;
std::unique_ptr<QGLShaderProgram> m_frameShaderProgram;
std::unique_ptr<GL_SHADER_PROGRAM_CLASS> m_frameShaderProgram;
};

class GLSLWaveformRendererFilteredSignal: public GLSLWaveformRendererSignal {
Expand Down
25 changes: 24 additions & 1 deletion src/waveform/renderers/glwaveformrenderer.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#pragma once

#include <QGLContext>
#include <QOpenGLFunctions_2_1>

#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
Expand All @@ -10,6 +9,28 @@
/// Note that the Qt OpenGL WaveformRendererAbstracts are not GLWaveformRenderers because
/// they do not call OpenGL functions directly. Instead, they inherit QGLWidget and use the
/// QPainter API which Qt translates to OpenGL under the hood.

#ifdef MIXXX_USE_OPENGL

class GLWaveformRenderer : protected QOpenGLFunctions_2_1 {
public:
GLWaveformRenderer() {
}

virtual void onInitializeGL() {
initializeOpenGLFunctions();
}
// Not needed when using QOpenGL classes,
// leaving empty function so calling code
// can be unchanged
void maybeInitializeGL() {
}
};

#else

#include <QGLContext>

class GLWaveformRenderer : protected QOpenGLFunctions_2_1 {
public:
GLWaveformRenderer()
Expand All @@ -35,4 +56,6 @@ class GLWaveformRenderer : protected QOpenGLFunctions_2_1 {
const QGLContext* m_pLastContext;
};

#endif

#endif // !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
7 changes: 4 additions & 3 deletions src/waveform/renderers/waveformrenderbeat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,13 @@ void WaveformRenderBeat::draw(QPainter* painter, QPaintEvent* /*event*/) {
return;
}

PainterScope PainterScope(painter);
//PainterScope PainterScope(painter);

painter->setRenderHint(QPainter::Antialiasing);
//painter->setRenderHint(QPainter::Antialiasing);

QPen beatPen(m_beatColor);
beatPen.setWidthF(std::max(1.0, scaleFactor()));
//beatPen.setWidthF(std::max(1.0, scaleFactor()));
beatPen.setWidthF(1.0);
painter->setPen(beatPen);

const Qt::Orientation orientation = m_waveformRenderer->getOrientation();
Expand Down
1 change: 0 additions & 1 deletion src/waveform/vsyncthread.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "vsyncthread.h"

#include <QGLFormat>
#include <QThread>
#include <QTime>
#include <QtDebug>
Expand Down
13 changes: 11 additions & 2 deletions src/waveform/waveformwidgetfactory.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#include "waveform/waveformwidgetfactory.h"

#ifndef MIXXX_USE_QOPENGL
#include <QGLFormat>
#include <QGLShaderProgram>
#endif

#include <QGuiApplication>
#include <QOpenGLFunctions>
#include <QStringList>
Expand Down Expand Up @@ -114,6 +117,12 @@ WaveformWidgetFactory::WaveformWidgetFactory()
m_visualGain[Mid] = 1.0;
m_visualGain[High] = 1.0;

#ifdef MIXXX_USE_QOPENGL
// TODO @m0dB We might want to check, but as this is intended for macOS
// we can be sure the OpenGL is available
m_openGlAvailable = true;
m_openGLShaderAvailable = true;
#else
QGLWidget* pGlWidget = SharedGLContext::getWidget();
if (pGlWidget && pGlWidget->isValid()) {
// will be false if SafeMode is enabled
Expand Down Expand Up @@ -254,7 +263,7 @@ WaveformWidgetFactory::WaveformWidgetFactory()

pGlWidget->hide();
}

#endif
evaluateWidgets();
m_time.start();
}
Expand Down Expand Up @@ -674,7 +683,7 @@ void WaveformWidgetFactory::render() {
}
}

// WSpinnys are also double-buffered QGLWidgets, like all the waveform
// WSpinnys are also double-buffered WGLWidgets, like all the waveform
// renderers. Render all the WSpinny widgets now.
emit renderSpinnies(m_vsyncThread);
// Same for WVuMeterGL. Note that we are either using WVuMeter or WVuMeterGL.
Expand Down
2 changes: 1 addition & 1 deletion src/waveform/widgets/glrgbwaveformwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ mixxx::Duration GLRGBWaveformWidget::render() {
timer.start();
// QPainter makes QGLContext::currentContext() == context()
// this may delayed until previous buffer swap finished
QPainter painter(this);
QPainter painter(paintDevice());
t1 = timer.restart();
draw(&painter, nullptr);
//t2 = timer.restart();
Expand Down
2 changes: 1 addition & 1 deletion src/waveform/widgets/glsimplewaveformwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ mixxx::Duration GLSimpleWaveformWidget::render() {
timer.start();
// QPainter makes QGLContext::currentContext() == context()
// this may delayed until previous buffer swap finished
QPainter painter(this);
QPainter painter(paintDevice());
t1 = timer.restart();
draw(&painter, nullptr);
//t2 = timer.restart();
Expand Down
2 changes: 1 addition & 1 deletion src/waveform/widgets/glslwaveformwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ mixxx::Duration GLSLWaveformWidget::render() {
timer.start();
// QPainter makes QGLContext::currentContext() == context()
// this may delayed until previous buffer swap finished
QPainter painter(this);
QPainter painter(paintDevice());
t1 = timer.restart();
draw(&painter, nullptr);
//t2 = timer.restart();
Expand Down
2 changes: 1 addition & 1 deletion src/waveform/widgets/glvsynctestwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ mixxx::Duration GLVSyncTestWidget::render() {
timer.start();
// QPainter makes QGLContext::currentContext() == context()
// this may delayed until previous buffer swap finished
QPainter painter(this);
QPainter painter(paintDevice());
t1 = timer.restart();
draw(&painter, nullptr);
//t2 = timer.restart();
Expand Down
2 changes: 1 addition & 1 deletion src/waveform/widgets/glwaveformwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ mixxx::Duration GLWaveformWidget::render() {
timer.start();
// QPainter makes QGLContext::currentContext() == context()
// this may delayed until previous buffer swap finished
QPainter painter(this);
QPainter painter(paintDevice());
t1 = timer.restart();
draw(&painter, nullptr);
//t2 = timer.restart();
Expand Down
Loading

0 comments on commit d243084

Please sign in to comment.