Skip to content

Commit

Permalink
Merge pull request #10989 from m0dB/qopengl_renderers
Browse files Browse the repository at this point in the history
qopenglwindow-based replacement of qglwidget, full glsl shader based waveforms, vumeters and spinnies
  • Loading branch information
daschuer authored May 29, 2023
2 parents bf11022 + 670d4dd commit 019a681
Show file tree
Hide file tree
Showing 150 changed files with 6,391 additions and 1,904 deletions.
70 changes: 59 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ endif()

option(QT6 "Build with Qt6" OFF)

option(QOPENGL "Use QOpenGLWindow based widget instead of QGLWidget" ON)
if(QOPENGL)
add_compile_definitions(MIXXX_USE_QOPENGL)
endif()

if(APPLE)
if(QT6)
# Minimum macOS version supported by Qt 6
Expand Down Expand Up @@ -965,6 +970,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/util/battery/battery.cpp
src/util/cache.cpp
src/util/cmdlineargs.cpp
src/util/colorcomponents.cpp
src/util/color/color.cpp
src/util/color/colorpalette.cpp
src/util/color/predefinedcolorpalettes.cpp
Expand Down Expand Up @@ -1021,7 +1027,6 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/util/valuetransformer.cpp
src/util/versionstore.cpp
src/util/widgethelper.cpp
src/util/widgetrendertimer.cpp
src/util/workerthread.cpp
src/util/workerthreadscheduler.cpp
src/util/xml.cpp
Expand Down Expand Up @@ -1095,7 +1100,6 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/widget/wtracktableviewheader.cpp
src/widget/wtracktext.cpp
src/widget/wtrackwidgetgroup.cpp
src/widget/wvumeter.cpp
src/widget/wwidget.cpp
src/widget/wwidgetgroup.cpp
src/widget/wwidgetstack.cpp
Expand Down Expand Up @@ -1127,9 +1131,6 @@ else()
src/waveform/renderers/glwaveformrendererfilteredsignal.cpp
src/waveform/renderers/glwaveformrendererrgb.cpp
src/waveform/renderers/glwaveformrenderersimplesignal.cpp
src/waveform/renderers/qtvsynctestrenderer.cpp
src/waveform/renderers/qtwaveformrendererfilteredsignal.cpp
src/waveform/renderers/qtwaveformrenderersimplesignal.cpp
src/waveform/renderers/waveformmark.cpp
src/waveform/renderers/waveformmarkrange.cpp
src/waveform/renderers/waveformmarkset.cpp
Expand Down Expand Up @@ -1157,12 +1158,8 @@ else()
src/waveform/widgets/glslwaveformwidget.cpp
src/waveform/widgets/glvsynctestwidget.cpp
src/waveform/widgets/glwaveformwidget.cpp
src/waveform/widgets/glwaveformwidgetabstract.cpp
src/waveform/widgets/hsvwaveformwidget.cpp
src/waveform/widgets/qthsvwaveformwidget.cpp
src/waveform/widgets/qtrgbwaveformwidget.cpp
src/waveform/widgets/qtsimplewaveformwidget.cpp
src/waveform/widgets/qtvsynctestwidget.cpp
src/waveform/widgets/qtwaveformwidget.cpp
src/waveform/widgets/rgbwaveformwidget.cpp
src/waveform/widgets/softwarewaveformwidget.cpp
src/waveform/widgets/waveformwidgetabstract.cpp
Expand All @@ -1171,10 +1168,61 @@ else()
src/widget/woverviewlmh.cpp
src/widget/woverviewrgb.cpp
src/widget/wspinny.cpp
src/widget/wvumetergl.cpp
src/widget/wspinnybase.cpp
src/widget/wvumeter.cpp
src/widget/wvumeterbase.cpp
src/widget/wvumeterlegacy.cpp
src/widget/wwaveformviewer.cpp
)
if(QOPENGL)
target_sources(mixxx-lib PRIVATE
src/shaders/endoftrackshader.cpp
src/shaders/rgbashader.cpp
src/shaders/rgbshader.cpp
src/shaders/shader.cpp
src/shaders/textureshader.cpp
src/shaders/unicolorshader.cpp
src/util/texture.cpp
src/waveform/renderers/allshader/matrixforwidgetgeometry.cpp
src/waveform/renderers/allshader/waveformrenderbackground.cpp
src/waveform/renderers/allshader/waveformrenderbeat.cpp
src/waveform/renderers/allshader/waveformrenderer.cpp
src/waveform/renderers/allshader/waveformrendererendoftrack.cpp
src/waveform/renderers/allshader/waveformrendererfiltered.cpp
src/waveform/renderers/allshader/waveformrendererlrrgb.cpp
src/waveform/renderers/allshader/waveformrendererpreroll.cpp
src/waveform/renderers/allshader/waveformrendererrgb.cpp
src/waveform/renderers/allshader/waveformrenderersignalbase.cpp
src/waveform/renderers/allshader/waveformrenderersimple.cpp
src/waveform/renderers/allshader/waveformrendermark.cpp
src/waveform/renderers/allshader/waveformrendermarkrange.cpp
src/waveform/widgets/allshader/filteredwaveformwidget.cpp
src/waveform/widgets/allshader/lrrgbwaveformwidget.cpp
src/waveform/widgets/allshader/rgbwaveformwidget.cpp
src/waveform/widgets/allshader/simplewaveformwidget.cpp
src/waveform/widgets/allshader/waveformwidget.cpp
src/widget/openglwindow.cpp
src/widget/tooltipqopengl.cpp
src/widget/wglwidgetqopengl.cpp
src/widget/winitialglwidget.cpp
src/widget/wspinnyglsl.cpp
src/widget/wvumeterglsl.cpp
)
else()
target_sources(mixxx-lib PRIVATE
src/waveform/renderers/qtvsynctestrenderer.cpp
src/waveform/renderers/qtwaveformrendererfilteredsignal.cpp
src/waveform/renderers/qtwaveformrenderersimplesignal.cpp
src/waveform/widgets/qthsvwaveformwidget.cpp
src/waveform/widgets/qtrgbwaveformwidget.cpp
src/waveform/widgets/qtsimplewaveformwidget.cpp
src/waveform/widgets/qtvsynctestwidget.cpp
src/waveform/widgets/qtwaveformwidget.cpp
src/widget/wglwidgetqglwidget.cpp
)
endif()
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
14 changes: 11 additions & 3 deletions src/engine/enginebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ void EngineBuffer::ejectTrack() {
TrackPointer pOldTrack = m_pCurrentTrack;
m_pause.lock();

m_visualPlayPos->set(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
m_visualPlayPos->set(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
doSeekPlayPos(mixxx::audio::kStartFramePos, SEEK_EXACT);

m_pCurrentTrack.reset();
Expand Down Expand Up @@ -1385,14 +1385,21 @@ void EngineBuffer::updateIndicators(double speed, int iBufferSize) {
m_iSamplesSinceLastIndicatorUpdate += iBufferSize;

const double fFractionalPlaypos = fractionalPlayposFromAbsolute(m_playPosition);
const double fFractionalSlipPos = fractionalPlayposFromAbsolute(m_slipPosition);

const double tempoTrackSeconds = m_trackEndPositionOld.value() /
m_trackSampleRateOld / getRateRatio();
if (speed > 0 && fFractionalPlaypos == 1.0) {
// At Track end
// Play pos at Track end
speed = 0;
}

double effectiveSlipRate = m_dSlipRate;
if (effectiveSlipRate > 0.0 && fFractionalSlipPos == 1.0) {
// Slip pos at Track end
effectiveSlipRate = 0.0;
}

// Update indicators that are only updated after every
// sampleRate/kiUpdateRate samples processed. (e.g. playposSlider)
if (m_iSamplesSinceLastIndicatorUpdate >
Expand All @@ -1409,7 +1416,8 @@ void EngineBuffer::updateIndicators(double speed, int iBufferSize) {
speed * m_baserate_old,
static_cast<int>(iBufferSize) /
m_trackEndPositionOld.toEngineSamplePos(),
fractionalPlayposFromAbsolute(m_slipPosition),
fFractionalSlipPos,
effectiveSlipRate,
tempoTrackSeconds,
iBufferSize / kSamplesPerFrame / m_sampleRate.toDouble() * 1000000.0);

Expand Down
11 changes: 11 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,15 @@ int runMixxx(MixxxApplication* pApp, const CmdlineArgs& args) {
&mainWindow,
&MixxxMainWindow::initializationProgressUpdate);
pCoreServices->initialize(pApp);

#ifdef MIXXX_USE_QOPENGL
// Will call initialize when the initial wglwidget's
// qopenglwindow has been exposed
mainWindow.initializeQOpenGL();
#else
mainWindow.initialize();
#endif

pCoreServices->getControllerManager()->setUpDevices();

// If startup produced a fatal error, then don't even start the
Expand Down Expand Up @@ -124,6 +132,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
40 changes: 39 additions & 1 deletion src/mixxxmainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@

#include <QDesktopServices>
#include <QFileDialog>

#include "widget/wglwidget.h"

#ifdef MIXXX_USE_QOPENGL
#include "widget/tooltipqopengl.h"
#include "widget/winitialglwidget.h"
#else
#include <QGLFormat>
#endif

#include <QUrl>
#ifdef __LINUX__
#include <QtDBus>
Expand Down Expand Up @@ -138,6 +147,27 @@ MixxxMainWindow::MixxxMainWindow(std::shared_ptr<mixxx::CoreServices> pCoreServi
m_pVisualsManager = new VisualsManager();
}

#ifdef MIXXX_USE_QOPENGL
void MixxxMainWindow::initializeQOpenGL() {
if (!CmdlineArgs::Instance().getSafeMode()) {
// This widget and its QOpenGLWindow will be used to query QOpenGL
// information (version, driver, etc) in WaveformWidgetFactory.
// The "SharedGLContext" terminology here doesn't really apply,
// but allows us to take advantage of the existing classes.
WInitialGLWidget* widget = new WInitialGLWidget(this);
widget->setGeometry(QRect(0, 0, 3, 3));
SharedGLContext::setWidget(widget);
// When the widget's QOpenGLWindow has been initialized, we continue
// with the actual initialization
connect(widget, &WInitialGLWidget::onInitialized, this, &MixxxMainWindow::initialize);
widget->show();
// note: the format is set in the WGLWidget's OpenGLWindow constructor
} else {
initialize();
}
}
#endif

void MixxxMainWindow::initialize() {
m_pCoreServices->getControlIndicatorTimer()->setLegacyVsyncEnabled(true);

Expand All @@ -147,6 +177,9 @@ void MixxxMainWindow::initialize() {
m_toolTipsCfg = static_cast<mixxx::TooltipsPreference>(
pConfig->getValue(ConfigKey("[Controls]", "Tooltips"),
static_cast<int>(mixxx::TooltipsPreference::TOOLTIPS_ON)));
#ifdef MIXXX_USE_QOPENGL
ToolTipQOpenGL::singleton().setActive(m_toolTipsCfg == mixxx::TooltipsPreference::TOOLTIPS_ON);
#endif

#ifdef __ENGINEPRIME__
// Initialise library exporter
Expand Down Expand Up @@ -194,6 +227,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 All @@ -218,11 +252,12 @@ void MixxxMainWindow::initialize() {
glFormat.setRgba(true);
QGLFormat::setDefaultFormat(glFormat);

QGLWidget* pContextWidget = new QGLWidget(this);
WGLWidget* pContextWidget = new WGLWidget(this);
pContextWidget->setGeometry(QRect(0, 0, 3, 3));
pContextWidget->hide();
SharedGLContext::setWidget(pContextWidget);
}
#endif

WaveformWidgetFactory::createInstance(); // takes a long time
WaveformWidgetFactory::instance()->setConfig(m_pCoreServices->getSettings());
Expand Down Expand Up @@ -1015,6 +1050,9 @@ void MixxxMainWindow::slotShowKeywheel(bool toggle) {

void MixxxMainWindow::slotTooltipModeChanged(mixxx::TooltipsPreference tt) {
m_toolTipsCfg = tt;
#ifdef MIXXX_USE_QOPENGL
ToolTipQOpenGL::singleton().setActive(m_toolTipsCfg == mixxx::TooltipsPreference::TOOLTIPS_ON);
#endif
}

void MixxxMainWindow::rebootMixxxView() {
Expand Down
3 changes: 3 additions & 0 deletions src/mixxxmainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class MixxxMainWindow : public QMainWindow {
MixxxMainWindow(std::shared_ptr<mixxx::CoreServices> pCoreServices);
~MixxxMainWindow() override;

#ifdef MIXXX_USE_QOPENGL
void initializeQOpenGL();
#endif
/// Initialize main window after creation. Should only be called once.
void initialize();
/// creates the menu_bar and inserts the file Menu
Expand Down
29 changes: 29 additions & 0 deletions src/shaders/endoftrackshader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "shaders/endoftrackshader.h"

using namespace mixxx;

void EndOfTrackShader::init() {
QString vertexShaderCode = QStringLiteral(R"--(
attribute vec4 position;
attribute float gradient;
varying float vgradient;
void main()
{
vgradient = gradient;
gl_Position = position;
}
)--");

QString fragmentShaderCode = QStringLiteral(R"--(
uniform vec4 color;
varying float vgradient;
void main()
{
float minAlpha = 0.5 * color.w;
float maxAlpha = 0.83 * color.w;
gl_FragColor = vec4(color.xyz, mix(minAlpha, maxAlpha, max(0.,vgradient)));
}
)--");

load(vertexShaderCode, fragmentShaderCode);
}
17 changes: 17 additions & 0 deletions src/shaders/endoftrackshader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include "shaders/shader.h"

namespace mixxx {
class EndOfTrackShader;
}

class mixxx::EndOfTrackShader : public mixxx::Shader {
public:
EndOfTrackShader() = default;
~EndOfTrackShader() = default;
void init();

private:
DISALLOW_COPY_AND_ASSIGN(EndOfTrackShader)
};
27 changes: 27 additions & 0 deletions src/shaders/rgbashader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "shaders/rgbashader.h"

using namespace mixxx;

void RGBAShader::init() {
QString vertexShaderCode = QStringLiteral(R"--(
uniform mat4 matrix;
attribute vec4 position;
attribute vec4 color;
varying vec4 vcolor;
void main()
{
vcolor = color;
gl_Position = matrix * position;
}
)--");

QString fragmentShaderCode = QStringLiteral(R"--(
varying vec4 vcolor;
void main()
{
gl_FragColor = vcolor;
}
)--");

load(vertexShaderCode, fragmentShaderCode);
}
17 changes: 17 additions & 0 deletions src/shaders/rgbashader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include "shaders/shader.h"

namespace mixxx {
class RGBAShader;
}

class mixxx::RGBAShader final : public mixxx::Shader {
public:
RGBAShader() = default;
~RGBAShader() = default;
void init();

private:
DISALLOW_COPY_AND_ASSIGN(RGBAShader)
};
Loading

0 comments on commit 019a681

Please sign in to comment.