From 2edbd967b1494ce7c0dd4e15f1d9482c5062a8d7 Mon Sep 17 00:00:00 2001 From: m0dB Date: Sun, 1 Dec 2024 21:14:24 +0100 Subject: [PATCH 01/21] use rendergraph in allshader/waveformwidget, derive allshader waveformrenderer classes from rendergraph::openglnode --- CMakeLists.txt | 2 + .../allshader/waveformrenderbackground.cpp | 4 +- .../allshader/waveformrenderbackground.h | 7 +- .../allshader/waveformrenderbeat.cpp | 1 - .../renderers/allshader/waveformrenderbeat.h | 7 +- .../renderers/allshader/waveformrenderer.h | 16 +-- .../allshader/waveformrendererabstract.h | 26 ---- .../allshader/waveformrendererendoftrack.cpp | 1 - .../allshader/waveformrendererendoftrack.h | 7 +- .../allshader/waveformrendererfiltered.cpp | 1 - .../allshader/waveformrendererfiltered.h | 5 +- .../allshader/waveformrendererhsv.cpp | 1 - .../renderers/allshader/waveformrendererhsv.h | 5 +- .../allshader/waveformrendererpreroll.cpp | 1 - .../allshader/waveformrendererpreroll.h | 10 +- .../allshader/waveformrendererrgb.cpp | 1 - .../renderers/allshader/waveformrendererrgb.h | 5 +- .../allshader/waveformrenderersignalbase.cpp | 12 +- .../allshader/waveformrenderersignalbase.h | 15 +-- .../allshader/waveformrenderersimple.cpp | 1 - .../allshader/waveformrenderersimple.h | 5 +- .../allshader/waveformrendererslipmode.cpp | 1 - .../allshader/waveformrendererslipmode.h | 7 +- .../allshader/waveformrendererstem.cpp | 1 - .../allshader/waveformrendererstem.h | 5 +- .../allshader/waveformrenderertextured.cpp | 2 - .../allshader/waveformrenderertextured.h | 6 +- .../allshader/waveformrendermark.cpp | 7 +- .../renderers/allshader/waveformrendermark.h | 17 +-- .../allshader/waveformrendermarkrange.cpp | 1 - .../allshader/waveformrendermarkrange.h | 7 +- .../renderers/waveformrendererabstract.h | 7 -- .../widgets/allshader/waveformwidget.cpp | 111 ++++++++++-------- .../widgets/allshader/waveformwidget.h | 27 ++++- 34 files changed, 173 insertions(+), 159 deletions(-) delete mode 100644 src/waveform/renderers/allshader/waveformrendererabstract.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7283ed6a7da..8df0b2f393e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4574,6 +4574,8 @@ endif() # rendergraph add_subdirectory(src/rendergraph/opengl) +target_link_libraries(mixxx-lib PUBLIC rendergraph_gl) +target_compile_definitions(mixxx-lib PRIVATE rendergraph=rendergraph_gl) # WavPack audio file support find_package(wavpack) diff --git a/src/waveform/renderers/allshader/waveformrenderbackground.cpp b/src/waveform/renderers/allshader/waveformrenderbackground.cpp index beddbc000a5..504beade43c 100644 --- a/src/waveform/renderers/allshader/waveformrenderbackground.cpp +++ b/src/waveform/renderers/allshader/waveformrenderbackground.cpp @@ -11,10 +11,10 @@ WaveformRenderBackground::WaveformRenderBackground( } void WaveformRenderBackground::setup(const QDomNode& node, - const SkinContext& context) { + const SkinContext& skinContext) { m_backgroundColor = m_waveformRenderer->getWaveformSignalColors()->getBgColor(); - QString backgroundPixmapPath = context.selectString(node, "BgPixmap"); + QString backgroundPixmapPath = skinContext.selectString(node, "BgPixmap"); if (!backgroundPixmapPath.isEmpty()) { qWarning() << "WaveformView BgPixmap is not supported by " "allshader::WaveformRenderBackground"; diff --git a/src/waveform/renderers/allshader/waveformrenderbackground.h b/src/waveform/renderers/allshader/waveformrenderbackground.h index 8a913e27742..7567d2da7df 100644 --- a/src/waveform/renderers/allshader/waveformrenderbackground.h +++ b/src/waveform/renderers/allshader/waveformrenderbackground.h @@ -2,6 +2,7 @@ #include +#include "rendergraph/openglnode.h" #include "util/class.h" #include "waveform/renderers/allshader/waveformrenderer.h" @@ -9,11 +10,13 @@ namespace allshader { class WaveformRenderBackground; } -class allshader::WaveformRenderBackground final : public allshader::WaveformRenderer { +class allshader::WaveformRenderBackground final + : public allshader::WaveformRenderer, + public rendergraph::OpenGLNode { public: explicit WaveformRenderBackground(WaveformWidgetRenderer* waveformWidgetRenderer); - void setup(const QDomNode& node, const SkinContext& context) override; + void setup(const QDomNode& node, const SkinContext& skinContext) override; void paintGL() override; private: diff --git a/src/waveform/renderers/allshader/waveformrenderbeat.cpp b/src/waveform/renderers/allshader/waveformrenderbeat.cpp index 3f793efd706..39da6e21401 100644 --- a/src/waveform/renderers/allshader/waveformrenderbeat.cpp +++ b/src/waveform/renderers/allshader/waveformrenderbeat.cpp @@ -17,7 +17,6 @@ WaveformRenderBeat::WaveformRenderBeat(WaveformWidgetRenderer* waveformWidget, } void WaveformRenderBeat::initializeGL() { - WaveformRenderer::initializeGL(); m_shader.init(); } diff --git a/src/waveform/renderers/allshader/waveformrenderbeat.h b/src/waveform/renderers/allshader/waveformrenderbeat.h index d3b2b79d1bc..9433ac6e39e 100644 --- a/src/waveform/renderers/allshader/waveformrenderbeat.h +++ b/src/waveform/renderers/allshader/waveformrenderbeat.h @@ -2,6 +2,7 @@ #include +#include "rendergraph/openglnode.h" #include "shaders/unicolorshader.h" #include "util/class.h" #include "waveform/renderers/allshader/vertexdata.h" @@ -14,13 +15,15 @@ namespace allshader { class WaveformRenderBeat; } -class allshader::WaveformRenderBeat final : public allshader::WaveformRenderer { +class allshader::WaveformRenderBeat final + : public allshader::WaveformRenderer, + public rendergraph::OpenGLNode { public: explicit WaveformRenderBeat(WaveformWidgetRenderer* waveformWidget, ::WaveformRendererAbstract::PositionSource type = ::WaveformRendererAbstract::Play); - void setup(const QDomNode& node, const SkinContext& context) override; + void setup(const QDomNode& node, const SkinContext& skinContext) override; void paintGL() override; void initializeGL() override; diff --git a/src/waveform/renderers/allshader/waveformrenderer.h b/src/waveform/renderers/allshader/waveformrenderer.h index 04b4b427935..b619bae71ec 100644 --- a/src/waveform/renderers/allshader/waveformrenderer.h +++ b/src/waveform/renderers/allshader/waveformrenderer.h @@ -1,6 +1,5 @@ #pragma once -#include "waveform/renderers/allshader/waveformrendererabstract.h" #include "waveform/renderers/waveformrendererabstract.h" class WaveformWidgetRenderer; @@ -9,8 +8,7 @@ namespace allshader { class WaveformRenderer; } -class allshader::WaveformRenderer : public ::WaveformRendererAbstract, - public allshader::WaveformRendererAbstract { +class allshader::WaveformRenderer : public ::WaveformRendererAbstract { public: explicit WaveformRenderer(WaveformWidgetRenderer* widget); @@ -21,16 +19,4 @@ class allshader::WaveformRenderer : public ::WaveformRendererAbstract, // QOpenGLWindow has bad performance), we leave this empty. // Should never be called. void draw(QPainter* painter, QPaintEvent* event) override final; - - allshader::WaveformRendererAbstract* allshaderWaveformRenderer() override final { - // This class is indirectly derived from - // WaveformWidgetRenderer, which has a member - // QList m_rendererStack; - // In the case of allshader::WaveformRenderer widgets, - // all the items on this stack are derived from - // allshader::WaveformRendererAbstract and we use this method to - // access them as such. (We could also have used a - // dynamic cast (or even static cast instead) - return this; - } }; diff --git a/src/waveform/renderers/allshader/waveformrendererabstract.h b/src/waveform/renderers/allshader/waveformrendererabstract.h deleted file mode 100644 index 5c530a00e22..00000000000 --- a/src/waveform/renderers/allshader/waveformrendererabstract.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include - -namespace allshader { -class WaveformRendererAbstract; -} - -class allshader::WaveformRendererAbstract : public QOpenGLFunctions { - public: - /// This interface class is called by class allshader::WaveformWidget. - /// Class allshader::WaveformWidget is derived from the allshader-based - /// class WGLWidget and, in its implementation of the WGLWidget virtual - /// methods, calls a stack of allshader::WaveformRendererAbstract instances, for - /// the different layers of the waveform graphics (background, beat - /// markers, the actual waveform, etc). In other word, this interface - /// mimics the WGLWidget virtuals, but to be called as layers of an - /// actual WGLWidget. - virtual ~WaveformRendererAbstract() = default; - virtual void initializeGL() { - initializeOpenGLFunctions(); - } - virtual void resizeGL(int /* w */, int /* h */) { - } - virtual void paintGL() = 0; -}; diff --git a/src/waveform/renderers/allshader/waveformrendererendoftrack.cpp b/src/waveform/renderers/allshader/waveformrendererendoftrack.cpp index 10df7121020..b0c15678701 100644 --- a/src/waveform/renderers/allshader/waveformrendererendoftrack.cpp +++ b/src/waveform/renderers/allshader/waveformrendererendoftrack.cpp @@ -47,7 +47,6 @@ void WaveformRendererEndOfTrack::setup(const QDomNode& node, const SkinContext& } void WaveformRendererEndOfTrack::initializeGL() { - WaveformRenderer::initializeGL(); m_shader.init(); } diff --git a/src/waveform/renderers/allshader/waveformrendererendoftrack.h b/src/waveform/renderers/allshader/waveformrendererendoftrack.h index 664a2cac16e..46b8a2a677b 100644 --- a/src/waveform/renderers/allshader/waveformrendererendoftrack.h +++ b/src/waveform/renderers/allshader/waveformrendererendoftrack.h @@ -3,6 +3,7 @@ #include #include +#include "rendergraph/openglnode.h" #include "shaders/endoftrackshader.h" #include "util/class.h" #include "util/performancetimer.h" @@ -16,12 +17,14 @@ namespace allshader { class WaveformRendererEndOfTrack; } -class allshader::WaveformRendererEndOfTrack final : public allshader::WaveformRenderer { +class allshader::WaveformRendererEndOfTrack final + : public allshader::WaveformRenderer, + public rendergraph::OpenGLNode { public: explicit WaveformRendererEndOfTrack( WaveformWidgetRenderer* waveformWidget); - void setup(const QDomNode& node, const SkinContext& context) override; + void setup(const QDomNode& node, const SkinContext& skinContext) override; bool init() override; diff --git a/src/waveform/renderers/allshader/waveformrendererfiltered.cpp b/src/waveform/renderers/allshader/waveformrendererfiltered.cpp index 0ddf164cc3e..f48b1136f59 100644 --- a/src/waveform/renderers/allshader/waveformrendererfiltered.cpp +++ b/src/waveform/renderers/allshader/waveformrendererfiltered.cpp @@ -19,7 +19,6 @@ void WaveformRendererFiltered::onSetup(const QDomNode& node) { } void WaveformRendererFiltered::initializeGL() { - WaveformRendererSignalBase::initializeGL(); m_shader.init(); } diff --git a/src/waveform/renderers/allshader/waveformrendererfiltered.h b/src/waveform/renderers/allshader/waveformrendererfiltered.h index 158ff880c01..43441adafa5 100644 --- a/src/waveform/renderers/allshader/waveformrendererfiltered.h +++ b/src/waveform/renderers/allshader/waveformrendererfiltered.h @@ -1,5 +1,6 @@ #pragma once +#include "rendergraph/openglnode.h" #include "shaders/unicolorshader.h" #include "util/class.h" #include "waveform/renderers/allshader/vertexdata.h" @@ -9,7 +10,9 @@ namespace allshader { class WaveformRendererFiltered; } -class allshader::WaveformRendererFiltered final : public allshader::WaveformRendererSignalBase { +class allshader::WaveformRendererFiltered final + : public allshader::WaveformRendererSignalBase, + public rendergraph::OpenGLNode { public: explicit WaveformRendererFiltered(WaveformWidgetRenderer* waveformWidget, bool rgbStacked); diff --git a/src/waveform/renderers/allshader/waveformrendererhsv.cpp b/src/waveform/renderers/allshader/waveformrendererhsv.cpp index 31b9785acdf..75b34dbae00 100644 --- a/src/waveform/renderers/allshader/waveformrendererhsv.cpp +++ b/src/waveform/renderers/allshader/waveformrendererhsv.cpp @@ -19,7 +19,6 @@ void WaveformRendererHSV::onSetup(const QDomNode& node) { } void WaveformRendererHSV::initializeGL() { - WaveformRendererSignalBase::initializeGL(); m_shader.init(); } diff --git a/src/waveform/renderers/allshader/waveformrendererhsv.h b/src/waveform/renderers/allshader/waveformrendererhsv.h index 0fa0b6bf863..a6fdbe95f51 100644 --- a/src/waveform/renderers/allshader/waveformrendererhsv.h +++ b/src/waveform/renderers/allshader/waveformrendererhsv.h @@ -1,5 +1,6 @@ #pragma once +#include "rendergraph/openglnode.h" #include "shaders/rgbshader.h" #include "util/class.h" #include "waveform/renderers/allshader/rgbdata.h" @@ -10,7 +11,9 @@ namespace allshader { class WaveformRendererHSV; } -class allshader::WaveformRendererHSV final : public allshader::WaveformRendererSignalBase { +class allshader::WaveformRendererHSV final + : public allshader::WaveformRendererSignalBase, + public rendergraph::OpenGLNode { public: explicit WaveformRendererHSV(WaveformWidgetRenderer* waveformWidget); diff --git a/src/waveform/renderers/allshader/waveformrendererpreroll.cpp b/src/waveform/renderers/allshader/waveformrendererpreroll.cpp index eea01c5bdad..89948347d87 100644 --- a/src/waveform/renderers/allshader/waveformrendererpreroll.cpp +++ b/src/waveform/renderers/allshader/waveformrendererpreroll.cpp @@ -75,7 +75,6 @@ void WaveformRendererPreroll::setup( } void WaveformRendererPreroll::initializeGL() { - WaveformRenderer::initializeGL(); m_shader.init(); } diff --git a/src/waveform/renderers/allshader/waveformrendererpreroll.h b/src/waveform/renderers/allshader/waveformrendererpreroll.h index 742320424c5..0fd2cc59942 100644 --- a/src/waveform/renderers/allshader/waveformrendererpreroll.h +++ b/src/waveform/renderers/allshader/waveformrendererpreroll.h @@ -4,6 +4,7 @@ #include #include +#include "rendergraph/openglnode.h" #include "shaders/patternshader.h" #include "util/class.h" #include "util/opengltexture2d.h" @@ -16,18 +17,19 @@ class QOpenGLTexture; namespace allshader { class WaveformRendererPreroll; -class WaveformRendererSlipPreroll; } -class allshader::WaveformRendererPreroll : public allshader::WaveformRenderer { +class allshader::WaveformRendererPreroll final + : public allshader::WaveformRenderer, + public rendergraph::OpenGLNode { public: explicit WaveformRendererPreroll( - WaveformWidgetRenderer* waveformWidgetRenderer, + WaveformWidgetRenderer* waveformWidget, ::WaveformRendererAbstract::PositionSource type = ::WaveformRendererAbstract::Play); ~WaveformRendererPreroll() override; - void setup(const QDomNode& node, const SkinContext& context) override; + void setup(const QDomNode& node, const SkinContext& skinContext) override; void paintGL() override; void initializeGL() override; diff --git a/src/waveform/renderers/allshader/waveformrendererrgb.cpp b/src/waveform/renderers/allshader/waveformrendererrgb.cpp index 54cea537640..31cd94f1a5d 100644 --- a/src/waveform/renderers/allshader/waveformrendererrgb.cpp +++ b/src/waveform/renderers/allshader/waveformrendererrgb.cpp @@ -27,7 +27,6 @@ void WaveformRendererRGB::onSetup(const QDomNode& node) { } void WaveformRendererRGB::initializeGL() { - WaveformRendererSignalBase::initializeGL(); m_shader.init(); } diff --git a/src/waveform/renderers/allshader/waveformrendererrgb.h b/src/waveform/renderers/allshader/waveformrendererrgb.h index e9c12b52a42..10f2262a751 100644 --- a/src/waveform/renderers/allshader/waveformrendererrgb.h +++ b/src/waveform/renderers/allshader/waveformrendererrgb.h @@ -1,5 +1,6 @@ #pragma once +#include "rendergraph/openglnode.h" #include "shaders/rgbshader.h" #include "util/class.h" #include "waveform/renderers/allshader/rgbdata.h" @@ -10,7 +11,9 @@ namespace allshader { class WaveformRendererRGB; } -class allshader::WaveformRendererRGB final : public allshader::WaveformRendererSignalBase { +class allshader::WaveformRendererRGB final + : public allshader::WaveformRendererSignalBase, + public rendergraph::OpenGLNode { public: explicit WaveformRendererRGB(WaveformWidgetRenderer* waveformWidget, ::WaveformRendererAbstract::PositionSource type = diff --git a/src/waveform/renderers/allshader/waveformrenderersignalbase.cpp b/src/waveform/renderers/allshader/waveformrenderersignalbase.cpp index 853a3f2e47d..620db520fd0 100644 --- a/src/waveform/renderers/allshader/waveformrenderersignalbase.cpp +++ b/src/waveform/renderers/allshader/waveformrenderersignalbase.cpp @@ -1,8 +1,16 @@ #include "waveform/renderers/allshader/waveformrenderersignalbase.h" -using namespace allshader; +namespace allshader { -allshader::WaveformRendererSignalBase::WaveformRendererSignalBase( +WaveformRendererSignalBase::WaveformRendererSignalBase( WaveformWidgetRenderer* waveformWidget) : ::WaveformRendererSignalBase(waveformWidget) { } + +void WaveformRendererSignalBase::draw(QPainter* painter, QPaintEvent* event) { + Q_UNUSED(painter); + Q_UNUSED(event); + DEBUG_ASSERT(false); +} + +} // namespace allshader diff --git a/src/waveform/renderers/allshader/waveformrenderersignalbase.h b/src/waveform/renderers/allshader/waveformrenderersignalbase.h index 0e72d9364c7..dafa41cd79b 100644 --- a/src/waveform/renderers/allshader/waveformrenderersignalbase.h +++ b/src/waveform/renderers/allshader/waveformrenderersignalbase.h @@ -4,7 +4,6 @@ #include #include "util/class.h" -#include "waveform/renderers/allshader/waveformrendererabstract.h" #include "waveform/renderers/waveformrenderersignalbase.h" class WaveformWidgetRenderer; @@ -13,8 +12,7 @@ namespace allshader { class WaveformRendererSignalBase; } -class allshader::WaveformRendererSignalBase : public ::WaveformRendererSignalBase, - public allshader::WaveformRendererAbstract { +class allshader::WaveformRendererSignalBase : public ::WaveformRendererSignalBase { public: enum class Option { None = 0b0, @@ -24,6 +22,8 @@ class allshader::WaveformRendererSignalBase : public ::WaveformRendererSignalBas }; Q_DECLARE_FLAGS(Options, Option) + void draw(QPainter* painter, QPaintEvent* event) override final; + static constexpr float m_maxValue{static_cast(std::numeric_limits::max())}; explicit WaveformRendererSignalBase(WaveformWidgetRenderer* waveformWidget); @@ -32,14 +32,5 @@ class allshader::WaveformRendererSignalBase : public ::WaveformRendererSignalBas return false; } - void draw(QPainter* painter, QPaintEvent* event) override { - Q_UNUSED(painter); - Q_UNUSED(event); - } - - allshader::WaveformRendererAbstract* allshaderWaveformRenderer() override { - return this; - } - DISALLOW_COPY_AND_ASSIGN(WaveformRendererSignalBase); }; diff --git a/src/waveform/renderers/allshader/waveformrenderersimple.cpp b/src/waveform/renderers/allshader/waveformrenderersimple.cpp index 02e9453afdf..90a707d2373 100644 --- a/src/waveform/renderers/allshader/waveformrenderersimple.cpp +++ b/src/waveform/renderers/allshader/waveformrenderersimple.cpp @@ -18,7 +18,6 @@ void WaveformRendererSimple::onSetup(const QDomNode& node) { } void WaveformRendererSimple::initializeGL() { - WaveformRendererSignalBase::initializeGL(); m_shader.init(); } diff --git a/src/waveform/renderers/allshader/waveformrenderersimple.h b/src/waveform/renderers/allshader/waveformrenderersimple.h index a1e92c8d2f0..ba79752539c 100644 --- a/src/waveform/renderers/allshader/waveformrenderersimple.h +++ b/src/waveform/renderers/allshader/waveformrenderersimple.h @@ -1,5 +1,6 @@ #pragma once +#include "rendergraph/openglnode.h" #include "shaders/unicolorshader.h" #include "util/class.h" #include "waveform/renderers/allshader/vertexdata.h" @@ -9,7 +10,9 @@ namespace allshader { class WaveformRendererSimple; } -class allshader::WaveformRendererSimple final : public allshader::WaveformRendererSignalBase { +class allshader::WaveformRendererSimple final + : public allshader::WaveformRendererSignalBase, + public rendergraph::OpenGLNode { public: explicit WaveformRendererSimple(WaveformWidgetRenderer* waveformWidget); diff --git a/src/waveform/renderers/allshader/waveformrendererslipmode.cpp b/src/waveform/renderers/allshader/waveformrendererslipmode.cpp index 4311f00a4ce..8ddf0be80e5 100644 --- a/src/waveform/renderers/allshader/waveformrendererslipmode.cpp +++ b/src/waveform/renderers/allshader/waveformrendererslipmode.cpp @@ -63,7 +63,6 @@ void WaveformRendererSlipMode::setup(const QDomNode& node, const SkinContext& co } void WaveformRendererSlipMode::initializeGL() { - WaveformRenderer::initializeGL(); m_shader.init(); } diff --git a/src/waveform/renderers/allshader/waveformrendererslipmode.h b/src/waveform/renderers/allshader/waveformrendererslipmode.h index 5e7b189ca57..b481142797f 100644 --- a/src/waveform/renderers/allshader/waveformrendererslipmode.h +++ b/src/waveform/renderers/allshader/waveformrendererslipmode.h @@ -3,6 +3,7 @@ #include #include +#include "rendergraph/openglnode.h" #include "shaders/slipmodeshader.h" #include "util/class.h" #include "util/performancetimer.h" @@ -16,12 +17,14 @@ namespace allshader { class WaveformRendererSlipMode; } -class allshader::WaveformRendererSlipMode final : public allshader::WaveformRenderer { +class allshader::WaveformRendererSlipMode final + : public allshader::WaveformRenderer, + public rendergraph::OpenGLNode { public: explicit WaveformRendererSlipMode( WaveformWidgetRenderer* waveformWidget); - void setup(const QDomNode& node, const SkinContext& context) override; + void setup(const QDomNode& node, const SkinContext& skinContext) override; bool init() override; diff --git a/src/waveform/renderers/allshader/waveformrendererstem.cpp b/src/waveform/renderers/allshader/waveformrendererstem.cpp index 5827904f513..80612f99470 100644 --- a/src/waveform/renderers/allshader/waveformrendererstem.cpp +++ b/src/waveform/renderers/allshader/waveformrendererstem.cpp @@ -26,7 +26,6 @@ void WaveformRendererStem::onSetup(const QDomNode& node) { } void WaveformRendererStem::initializeGL() { - WaveformRendererSignalBase::initializeGL(); m_shader.init(); m_textureShader.init(); auto group = m_pEQEnabled->getKey().group; diff --git a/src/waveform/renderers/allshader/waveformrendererstem.h b/src/waveform/renderers/allshader/waveformrendererstem.h index 757bfe763d3..99728194574 100644 --- a/src/waveform/renderers/allshader/waveformrendererstem.h +++ b/src/waveform/renderers/allshader/waveformrendererstem.h @@ -2,6 +2,7 @@ #include +#include "rendergraph/openglnode.h" #include "shaders/rgbashader.h" #include "shaders/textureshader.h" #include "util/class.h" @@ -15,7 +16,9 @@ namespace allshader { class WaveformRendererStem; } -class allshader::WaveformRendererStem final : public allshader::WaveformRendererSignalBase { +class allshader::WaveformRendererStem final + : public allshader::WaveformRendererSignalBase, + public rendergraph::OpenGLNode { public: explicit WaveformRendererStem(WaveformWidgetRenderer* waveformWidget, ::WaveformRendererAbstract::PositionSource type = diff --git a/src/waveform/renderers/allshader/waveformrenderertextured.cpp b/src/waveform/renderers/allshader/waveformrenderertextured.cpp index dc137b73208..de21a013259 100644 --- a/src/waveform/renderers/allshader/waveformrenderertextured.cpp +++ b/src/waveform/renderers/allshader/waveformrenderertextured.cpp @@ -219,8 +219,6 @@ void WaveformRendererTextured::createFrameBuffers() { } void WaveformRendererTextured::initializeGL() { - WaveformRendererSignalBase::initializeGL(); - m_textureRenderedWaveformCompletion = 0; if (!m_frameShaderProgram) { diff --git a/src/waveform/renderers/allshader/waveformrenderertextured.h b/src/waveform/renderers/allshader/waveformrenderertextured.h index 16680f1bc5d..ccd82ae5a67 100644 --- a/src/waveform/renderers/allshader/waveformrenderertextured.h +++ b/src/waveform/renderers/allshader/waveformrenderertextured.h @@ -2,6 +2,7 @@ #ifndef QT_OPENGL_ES_2 +#include "rendergraph/openglnode.h" #include "shaders/rgbshader.h" #include "track/track_decl.h" #include "util/class.h" @@ -19,8 +20,9 @@ class WaveformRendererTextured; } // Based on GLSLWaveformRendererSignal (waveform/renderers/glslwaveformrenderersignal.h) -class allshader::WaveformRendererTextured : public QObject, - public allshader::WaveformRendererSignalBase { +class allshader::WaveformRendererTextured final : public QObject, + public allshader::WaveformRendererSignalBase, + public rendergraph::OpenGLNode { Q_OBJECT public: explicit WaveformRendererTextured(WaveformWidgetRenderer* waveformWidget, diff --git a/src/waveform/renderers/allshader/waveformrendermark.cpp b/src/waveform/renderers/allshader/waveformrendermark.cpp index 3505e60519a..7dacb73279b 100644 --- a/src/waveform/renderers/allshader/waveformrendermark.cpp +++ b/src/waveform/renderers/allshader/waveformrendermark.cpp @@ -79,8 +79,13 @@ bool allshader::WaveformRenderMark::init() { return true; } +void allshader::WaveformRenderMark::draw(QPainter* painter, QPaintEvent* event) { + Q_UNUSED(painter); + Q_UNUSED(event); + DEBUG_ASSERT(false); +} + void allshader::WaveformRenderMark::initializeGL() { - allshader::WaveformRendererAbstract::initializeGL(); m_digitsRenderer.init(); m_rgbaShader.init(); m_textureShader.init(); diff --git a/src/waveform/renderers/allshader/waveformrendermark.h b/src/waveform/renderers/allshader/waveformrendermark.h index 5f4b812388a..eba21888e3c 100644 --- a/src/waveform/renderers/allshader/waveformrendermark.h +++ b/src/waveform/renderers/allshader/waveformrendermark.h @@ -2,11 +2,11 @@ #include +#include "rendergraph/openglnode.h" #include "shaders/rgbashader.h" #include "shaders/textureshader.h" #include "util/opengltexture2d.h" #include "waveform/renderers/allshader/digitsrenderer.h" -#include "waveform/renderers/allshader/waveformrendererabstract.h" #include "waveform/renderers/waveformrendermarkbase.h" class QDomNode; @@ -17,23 +17,16 @@ namespace allshader { class WaveformRenderMark; } -class allshader::WaveformRenderMark : public ::WaveformRenderMarkBase, - public allshader::WaveformRendererAbstract { +class allshader::WaveformRenderMark final + : public ::WaveformRenderMarkBase, + public rendergraph::OpenGLNode { public: explicit WaveformRenderMark(WaveformWidgetRenderer* waveformWidget, ::WaveformRendererAbstract::PositionSource type = ::WaveformRendererAbstract::Play); - void draw(QPainter* painter, QPaintEvent* event) override { - Q_UNUSED(painter); - Q_UNUSED(event); - } - - allshader::WaveformRendererAbstract* allshaderWaveformRenderer() override { - return this; - } - bool init() override; + void draw(QPainter* painter, QPaintEvent* event) override; void initializeGL() override; void paintGL() override; diff --git a/src/waveform/renderers/allshader/waveformrendermarkrange.cpp b/src/waveform/renderers/allshader/waveformrendermarkrange.cpp index 6b3a33d4936..eaacffdbdba 100644 --- a/src/waveform/renderers/allshader/waveformrendermarkrange.cpp +++ b/src/waveform/renderers/allshader/waveformrendermarkrange.cpp @@ -9,7 +9,6 @@ allshader::WaveformRenderMarkRange::WaveformRenderMarkRange(WaveformWidgetRender } void allshader::WaveformRenderMarkRange::initializeGL() { - WaveformRenderer::initializeGL(); m_shader.init(); } diff --git a/src/waveform/renderers/allshader/waveformrendermarkrange.h b/src/waveform/renderers/allshader/waveformrendermarkrange.h index 0c46a8dd5b8..ac2cb7ac24b 100644 --- a/src/waveform/renderers/allshader/waveformrendermarkrange.h +++ b/src/waveform/renderers/allshader/waveformrendermarkrange.h @@ -3,6 +3,7 @@ #include #include +#include "rendergraph/openglnode.h" #include "shaders/unicolorshader.h" #include "util/class.h" #include "waveform/renderers/allshader/waveformrenderer.h" @@ -15,11 +16,13 @@ namespace allshader { class WaveformRenderMarkRange; } -class allshader::WaveformRenderMarkRange final : public allshader::WaveformRenderer { +class allshader::WaveformRenderMarkRange final + : public allshader::WaveformRenderer, + public rendergraph::OpenGLNode { public: explicit WaveformRenderMarkRange(WaveformWidgetRenderer* waveformWidget); - void setup(const QDomNode& node, const SkinContext& context) override; + void setup(const QDomNode& node, const SkinContext& skinContext) override; void initializeGL() override; void paintGL() override; diff --git a/src/waveform/renderers/waveformrendererabstract.h b/src/waveform/renderers/waveformrendererabstract.h index 6c15dd523d5..7fc2b78529d 100644 --- a/src/waveform/renderers/waveformrendererabstract.h +++ b/src/waveform/renderers/waveformrendererabstract.h @@ -9,10 +9,6 @@ QT_FORWARD_DECLARE_CLASS(QPainter) class SkinContext; class WaveformWidgetRenderer; -namespace allshader { -class WaveformRendererAbstract; -} - class WaveformRendererAbstract { public: /// The type of cursor for which the waveform is rendered @@ -32,9 +28,6 @@ class WaveformRendererAbstract { virtual void onResize() {} virtual void onSetTrack() {} - virtual allshader::WaveformRendererAbstract* allshaderWaveformRenderer() { - return nullptr; - } protected: bool isDirty() const { diff --git a/src/waveform/widgets/allshader/waveformwidget.cpp b/src/waveform/widgets/allshader/waveformwidget.cpp index 2b507ff7afc..87e5d0d829e 100644 --- a/src/waveform/widgets/allshader/waveformwidget.cpp +++ b/src/waveform/widgets/allshader/waveformwidget.cpp @@ -6,7 +6,6 @@ #include "waveform/renderers/allshader/waveformrenderbackground.h" #include "waveform/renderers/allshader/waveformrenderbeat.h" -#include "waveform/renderers/allshader/waveformrendererabstract.h" #include "waveform/renderers/allshader/waveformrendererendoftrack.h" #include "waveform/renderers/allshader/waveformrendererfiltered.h" #include "waveform/renderers/allshader/waveformrendererhsv.h" @@ -27,52 +26,67 @@ WaveformWidget::WaveformWidget(QWidget* parent, const QString& group, WaveformRendererSignalBase::Options options) : WGLWidget(parent), WaveformWidgetAbstract(group) { - addRenderer(); - addRenderer(); - addRenderer(); - addRenderer(); + auto pTopNode = std::make_unique(); + auto pOpacityNode = std::make_unique(); + + pTopNode->appendChildNode(addRendererNode()); + pOpacityNode->appendChildNode(addRendererNode()); + pOpacityNode->appendChildNode(addRendererNode()); + pOpacityNode->appendChildNode(addRendererNode()); + m_pWaveformRenderMarkRange = static_cast(pOpacityNode->lastChild()); #ifdef __STEM__ // The following two renderers work in tandem: if the rendered waveform is // for a stem track, WaveformRendererSignalBase will skip rendering and let // WaveformRendererStem do the rendering, and vice-versa. - addRenderer(); + pOpacityNode->appendChildNode(addRendererNode()); #endif - allshader::WaveformRendererSignalBase* waveformSignalRenderer = - addWaveformSignalRenderer( - type, options, ::WaveformRendererAbstract::Play); - - addRenderer(); - addRenderer(); - - // if the signal renderer supports slip, we add it again, now for slip, together with the - // other slip renderers - if (waveformSignalRenderer && waveformSignalRenderer->supportsSlip()) { + pOpacityNode->appendChildNode(addWaveformSignalRendererNode( + type, options, ::WaveformRendererAbstract::Play)); + pOpacityNode->appendChildNode(addRendererNode()); + pOpacityNode->appendChildNode(addRendererNode()); + m_pWaveformRenderMark = static_cast(pOpacityNode->lastChild()); + + // if the added signal renderer supports slip, we add it again, now for + // slip, together with the other slip renderers + if (m_pWaveformRendererSignal && m_pWaveformRendererSignal->supportsSlip()) { // The following renderer will add an overlay waveform if a slip is in progress - addRenderer(); - addRenderer(::WaveformRendererAbstract::Slip); + pOpacityNode->appendChildNode(addRendererNode()); + pOpacityNode->appendChildNode( + addRendererNode( + ::WaveformRendererAbstract::Slip)); #ifdef __STEM__ - addRenderer(::WaveformRendererAbstract::Slip); + pOpacityNode->appendChildNode( + addRendererNode( + ::WaveformRendererAbstract::Slip)); #endif - addWaveformSignalRenderer(type, options, ::WaveformRendererAbstract::Slip); - addRenderer(::WaveformRendererAbstract::Slip); - addRenderer(::WaveformRendererAbstract::Slip); + pOpacityNode->appendChildNode(addWaveformSignalRendererNode( + type, options, ::WaveformRendererAbstract::Slip)); + pOpacityNode->appendChildNode( + addRendererNode( + ::WaveformRendererAbstract::Slip)); + pOpacityNode->appendChildNode( + addRendererNode( + ::WaveformRendererAbstract::Slip)); } m_initSuccess = init(); + + pTopNode->appendChildNode(std::move(pOpacityNode)); + m_pOpacityNode = static_cast(pTopNode->lastChild()); + + m_pEngine = std::make_unique(std::move(pTopNode)); } WaveformWidget::~WaveformWidget() { makeCurrentIfNeeded(); - for (auto* pRenderer : std::as_const(m_rendererStack)) { - delete pRenderer; - } m_rendererStack.clear(); + m_pEngine.reset(); doneCurrent(); } -allshader::WaveformRendererSignalBase* -WaveformWidget::addWaveformSignalRenderer(WaveformWidgetType::Type type, +std::unique_ptr +WaveformWidget::addWaveformSignalRendererNode(WaveformWidgetType::Type type, WaveformRendererSignalBase::Options options, ::WaveformRendererAbstract::PositionSource positionSource) { #ifndef QT_OPENGL_ES_2 @@ -81,7 +95,8 @@ WaveformWidget::addWaveformSignalRenderer(WaveformWidgetType::Type type, case ::WaveformWidgetType::RGB: case ::WaveformWidgetType::Filtered: case ::WaveformWidgetType::Stacked: - return addRenderer(type, positionSource, options); + return addWaveformSignalRendererNode( + type, positionSource, options); default: break; } @@ -90,15 +105,16 @@ WaveformWidget::addWaveformSignalRenderer(WaveformWidgetType::Type type, switch (type) { case ::WaveformWidgetType::Simple: - return addRenderer(); + return addWaveformSignalRendererNode(); case ::WaveformWidgetType::RGB: - return addRenderer(positionSource, options); + return addWaveformSignalRendererNode(positionSource, options); case ::WaveformWidgetType::HSV: - return addRenderer(); + return addWaveformSignalRendererNode(); case ::WaveformWidgetType::Filtered: - return addRenderer(false); + return addWaveformSignalRendererNode(false); case ::WaveformWidgetType::Stacked: - return addRenderer(true); // true for RGB Stacked + return addWaveformSignalRendererNode( + true); // true for RGB Stacked default: break; } @@ -117,15 +133,11 @@ mixxx::Duration WaveformWidget::render() { } void WaveformWidget::paintGL() { - if (shouldOnlyDrawBackground()) { - if (!m_rendererStack.empty()) { - m_rendererStack[0]->allshaderWaveformRenderer()->paintGL(); - } - } else { - for (auto* pRenderer : std::as_const(m_rendererStack)) { - pRenderer->allshaderWaveformRenderer()->paintGL(); - } - } + // opacity of 0.f effectively skips the subtree rendering + m_pOpacityNode->setOpacity(shouldOnlyDrawBackground() ? 0.f : 1.f); + + m_pEngine->preprocess(); + m_pEngine->render(); } void WaveformWidget::castToQWidget() { @@ -133,15 +145,18 @@ void WaveformWidget::castToQWidget() { } void WaveformWidget::initializeGL() { - for (auto* pRenderer : std::as_const(m_rendererStack)) { - pRenderer->allshaderWaveformRenderer()->initializeGL(); - } +} + +void WaveformWidget::resizeRenderer(int, int, float) { + // defer to resizeGL } void WaveformWidget::resizeGL(int w, int h) { - for (auto* pRenderer : std::as_const(m_rendererStack)) { - pRenderer->allshaderWaveformRenderer()->resizeGL(w, h); - } + w = static_cast(std::lroundf(static_cast(w) / devicePixelRatio())); + h = static_cast(std::lroundf(static_cast(h) / devicePixelRatio())); + + m_pEngine->resize(w, h); + WaveformWidgetRenderer::resizeRenderer(w, h, devicePixelRatio()); } void WaveformWidget::paintEvent(QPaintEvent* event) { diff --git a/src/waveform/widgets/allshader/waveformwidget.h b/src/waveform/widgets/allshader/waveformwidget.h index f6c0877975e..bf0b3a18267 100644 --- a/src/waveform/widgets/allshader/waveformwidget.h +++ b/src/waveform/widgets/allshader/waveformwidget.h @@ -1,5 +1,7 @@ #pragma once +#include "rendergraph/engine.h" +#include "rendergraph/opacitynode.h" #include "waveform/renderers/allshader/waveformrenderersignalbase.h" #include "waveform/widgets/waveformwidgetabstract.h" #include "waveform/widgets/waveformwidgetvars.h" @@ -7,6 +9,8 @@ namespace allshader { class WaveformWidget; +class WaveformRenderMark; +class WaveformRenderMarkRange; } class allshader::WaveformWidget final : public ::WGLWidget, @@ -23,6 +27,8 @@ class allshader::WaveformWidget final : public ::WGLWidget, return m_type; } + void resizeRenderer(int width, int height, float devicePixelRatio) override; + // override for WaveformWidgetAbstract mixxx::Duration render() override; @@ -42,12 +48,31 @@ class allshader::WaveformWidget final : public ::WGLWidget, void wheelEvent(QWheelEvent* event) override; void leaveEvent(QEvent* event) override; - allshader::WaveformRendererSignalBase* addWaveformSignalRenderer( + template + inline std::unique_ptr addRendererNode(Args&&... args) { + return std::unique_ptr(addRenderer(std::forward(args)...)); + } + + template + inline std::unique_ptr addWaveformSignalRendererNode(Args&&... args) { + auto pRenderer = addRenderer(std::forward(args)...); + if (!m_pWaveformRendererSignal) { + m_pWaveformRendererSignal = pRenderer; + } + return std::unique_ptr(pRenderer); + } + + std::unique_ptr addWaveformSignalRendererNode( WaveformWidgetType::Type type, WaveformRendererSignalBase::Options options, ::WaveformRendererAbstract::PositionSource positionSource); WaveformWidgetType::Type m_type; + std::unique_ptr m_pEngine; + rendergraph::OpacityNode* m_pOpacityNode; + WaveformRenderMark* m_pWaveformRenderMark; + WaveformRenderMarkRange* m_pWaveformRenderMarkRange; + WaveformRendererSignalBase* m_pWaveformRendererSignal; DISALLOW_COPY_AND_ASSIGN(WaveformWidget); }; From 3f9a2b184747e014ac25104ab163ad973325cc5e Mon Sep 17 00:00:00 2001 From: m0dB Date: Mon, 9 Dec 2024 17:33:18 +0100 Subject: [PATCH 02/21] avoid rendering on images with 0 or negative width or height --- .../renderers/allshader/digitsrenderer.cpp | 4 ++++ .../renderers/allshader/waveformrendermark.cpp | 14 +++++++++++--- src/waveform/renderers/waveformmark.cpp | 14 +++++++++----- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/waveform/renderers/allshader/digitsrenderer.cpp b/src/waveform/renderers/allshader/digitsrenderer.cpp index cd7d9947e5d..212613c34c8 100644 --- a/src/waveform/renderers/allshader/digitsrenderer.cpp +++ b/src/waveform/renderers/allshader/digitsrenderer.cpp @@ -70,6 +70,10 @@ float allshader::DigitsRenderer::height() const { void allshader::DigitsRenderer::updateTexture( float fontPointSize, float maxHeight, float devicePixelRatio) { + if (std::lround(maxHeight * devicePixelRatio) <= 0) { + return; + } + if (fontPointSize == m_fontPointSize && maxHeight == m_maxHeight) { return; } diff --git a/src/waveform/renderers/allshader/waveformrendermark.cpp b/src/waveform/renderers/allshader/waveformrendermark.cpp index 7dacb73279b..9e9f1632896 100644 --- a/src/waveform/renderers/allshader/waveformrendermark.cpp +++ b/src/waveform/renderers/allshader/waveformrendermark.cpp @@ -396,9 +396,17 @@ void allshader::WaveformRenderMark::updatePlayPosMarkTexture() { const float devicePixelRatio = m_waveformRenderer->getDevicePixelRatio(); const float lineX = 5.5f; - QImage image(static_cast(imgWidth * devicePixelRatio), - static_cast(imgHeight * devicePixelRatio), - QImage::Format_ARGB32_Premultiplied); + imgwidth = 11.f; + imgheight = height; + + const QSize size{static_cast(std::lround(imgwidth * devicePixelRatio)), + static_cast(std::lround(imgheight * devicePixelRatio))}; + + if (size.width() <= 0 || size.height() <= 0) { + return; + } + + QImage image(size, QImage::Format_ARGB32_Premultiplied); VERIFY_OR_DEBUG_ASSERT(!image.isNull()) { return; } diff --git a/src/waveform/renderers/waveformmark.cpp b/src/waveform/renderers/waveformmark.cpp index 5d36bfd9f88..e90f2f4e02b 100644 --- a/src/waveform/renderers/waveformmark.cpp +++ b/src/waveform/renderers/waveformmark.cpp @@ -308,8 +308,8 @@ class MarkerGeometry { } } QSize getImageSize(float devicePixelRatio) const { - return QSize{static_cast(m_imageSize.width() * devicePixelRatio), - static_cast(m_imageSize.height() * devicePixelRatio)}; + return QSize{static_cast(std::lround(m_imageSize.width() * devicePixelRatio)), + static_cast(std::lround(m_imageSize.height() * devicePixelRatio))}; } const QFont font() const { @@ -381,9 +381,13 @@ QImage WaveformMark::generateImage(float devicePixelRatio) { m_label.setAreaRect(markerGeometry.labelRect()); - // Create the image - QImage image{markerGeometry.getImageSize(devicePixelRatio), - QImage::Format_ARGB32_Premultiplied}; + const QSize size{markerGeometry.getImageSize(devicePixelRatio)}; + + if (size.width() <= 0 || size.height() <= 0) { + return QImage{}; + } + + QImage image{size, QImage::Format_ARGB32_Premultiplied}; VERIFY_OR_DEBUG_ASSERT(!image.isNull()) { return image; } From cd9d060cf33bd5c7bfbfb80868e52c841ff292be Mon Sep 17 00:00:00 2001 From: m0dB Date: Mon, 9 Dec 2024 17:00:52 +0100 Subject: [PATCH 03/21] added rendergraph shaders --- CMakeLists.txt | 2 +- src/rendergraph/CMakeLists.txt | 5 +- src/rendergraph/shaders/CMakeLists.txt | 53 +++++++++++++++ src/rendergraph/shaders/README.md | 29 ++++++++ .../shaders/generate_shaders_gl.pl | 68 +++++++++++++++++++ .../shaders/generated_shaders_gl.cmake | 13 ++++ src/rendergraph/shaders/pattern.frag | 9 +++ src/rendergraph/shaders/pattern.frag.gl | 11 +++ src/rendergraph/shaders/pattern.vert | 15 ++++ src/rendergraph/shaders/pattern.vert.gl | 19 ++++++ src/rendergraph/shaders/rgb.frag | 8 +++ src/rendergraph/shaders/rgb.frag.gl | 9 +++ src/rendergraph/shaders/rgb.vert | 15 ++++ src/rendergraph/shaders/rgb.vert.gl | 19 ++++++ src/rendergraph/shaders/rgba.frag | 8 +++ src/rendergraph/shaders/rgba.frag.gl | 9 +++ src/rendergraph/shaders/rgba.vert | 15 ++++ src/rendergraph/shaders/rgba.vert.gl | 19 ++++++ src/rendergraph/shaders/texture.frag | 9 +++ src/rendergraph/shaders/texture.frag.gl | 11 +++ src/rendergraph/shaders/texture.vert | 15 ++++ src/rendergraph/shaders/texture.vert.gl | 19 ++++++ src/rendergraph/shaders/unicolor.frag | 13 ++++ src/rendergraph/shaders/unicolor.frag.gl | 15 ++++ src/rendergraph/shaders/unicolor.vert | 13 ++++ src/rendergraph/shaders/unicolor.vert.gl | 17 +++++ 26 files changed, 436 insertions(+), 2 deletions(-) create mode 100644 src/rendergraph/shaders/CMakeLists.txt create mode 100644 src/rendergraph/shaders/README.md create mode 100755 src/rendergraph/shaders/generate_shaders_gl.pl create mode 100644 src/rendergraph/shaders/generated_shaders_gl.cmake create mode 100644 src/rendergraph/shaders/pattern.frag create mode 100644 src/rendergraph/shaders/pattern.frag.gl create mode 100644 src/rendergraph/shaders/pattern.vert create mode 100644 src/rendergraph/shaders/pattern.vert.gl create mode 100644 src/rendergraph/shaders/rgb.frag create mode 100644 src/rendergraph/shaders/rgb.frag.gl create mode 100644 src/rendergraph/shaders/rgb.vert create mode 100644 src/rendergraph/shaders/rgb.vert.gl create mode 100644 src/rendergraph/shaders/rgba.frag create mode 100644 src/rendergraph/shaders/rgba.frag.gl create mode 100644 src/rendergraph/shaders/rgba.vert create mode 100644 src/rendergraph/shaders/rgba.vert.gl create mode 100644 src/rendergraph/shaders/texture.frag create mode 100644 src/rendergraph/shaders/texture.frag.gl create mode 100644 src/rendergraph/shaders/texture.vert create mode 100644 src/rendergraph/shaders/texture.vert.gl create mode 100644 src/rendergraph/shaders/unicolor.frag create mode 100644 src/rendergraph/shaders/unicolor.frag.gl create mode 100644 src/rendergraph/shaders/unicolor.vert create mode 100644 src/rendergraph/shaders/unicolor.vert.gl diff --git a/CMakeLists.txt b/CMakeLists.txt index 8df0b2f393e..0cc13a22921 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4573,7 +4573,7 @@ if(VINYLCONTROL) endif() # rendergraph -add_subdirectory(src/rendergraph/opengl) +add_subdirectory(src/rendergraph) target_link_libraries(mixxx-lib PUBLIC rendergraph_gl) target_compile_definitions(mixxx-lib PRIVATE rendergraph=rendergraph_gl) diff --git a/src/rendergraph/CMakeLists.txt b/src/rendergraph/CMakeLists.txt index 8f14cb2f313..23569ef30ca 100644 --- a/src/rendergraph/CMakeLists.txt +++ b/src/rendergraph/CMakeLists.txt @@ -39,5 +39,8 @@ set( ) add_subdirectory(opengl) -add_subdirectory(scenegraph) +################################# +# TODO: uncomment in follow-up PR +# add_subdirectory(scenegraph) +################################# add_subdirectory(shaders) diff --git a/src/rendergraph/shaders/CMakeLists.txt b/src/rendergraph/shaders/CMakeLists.txt new file mode 100644 index 00000000000..42478758f46 --- /dev/null +++ b/src/rendergraph/shaders/CMakeLists.txt @@ -0,0 +1,53 @@ +# included from src/rendergraph/CMakeLists.txt + +set( + shaders + pattern.frag + pattern.vert + rgb.frag + rgb.vert + rgba.frag + rgba.vert + texture.frag + texture.vert + unicolor.frag + unicolor.vert +) + +qt6_add_shaders(rendergraph_sg "shaders-qsb" + BATCHABLE + PRECOMPILE + OPTIMIZED + PREFIX + /shaders/rendergraph + FILES + ${shaders} +) + +# USE_QSHADER_FOR_GL is set in src/rendergraph/CMakeLists.txt when Qt >= 6.6 +if(USE_QSHADER_FOR_GL) + # Add the .qsb shader bundles; rendergraph::MaterialShader will use + # QShader to extract the GLSL shader from the bundle. + message(STATUS "Adding qsb shaders to rendergraph_gl") + qt6_add_shaders(rendergraph_gl "shaders-qsb" + BATCHABLE + PRECOMPILE + OPTIMIZED + PREFIX + /shaders/rendergraph + FILES + ${shaders} + ) +else() + # Use GLSL shaders extracted from the .qsb shader bundles using + # generate_shaders_gl.pl + message(STATUS "Adding gl shaders to rendergraph_gl") + include(generated_shaders_gl.cmake) + + qt_add_resources(rendergraph_gl "shaders-gl" + PREFIX + /shaders/rendergraph + FILES + ${generated_shaders_gl} + ) +endif() diff --git a/src/rendergraph/shaders/README.md b/src/rendergraph/shaders/README.md new file mode 100644 index 00000000000..31f8a53fff1 --- /dev/null +++ b/src/rendergraph/shaders/README.md @@ -0,0 +1,29 @@ +# rendergraph shaders + +The CMakeLists.txt in this folder generates qsb shader bundles from spirv shaders, to +be used by `rendergraph::MaterialShader`. + +## For use with QML / Qt scene graph + +The qsb files can be used directly through `QSGShader`. This includes the scenegraph +implementation of rendergraph. + +## For use with OpenGL + +Depending on the Qt version, the opengl implementation of `rendergraph::MaterialShader` +uses either the .qsb shader bundles directly, or the extracted GLSL shaders: + +### Qt >= 6.6 + +The GLSL shaders are extracted programmatically with `QShader` and then used with +`QOpenGLShader`. + +### Qt < 6.6 + +The GLSL shader have to extracted from the qsb shader bundles to be used by `QOpenGLShader`. +This can be done using the script `generate_shaders_gl.pl`. To use this script, make sure +that the qsb and spirv commands are in your path. qsb is part of Qt. spirv is part of the +Vulkan SDK and can be downloaded from + +The script also generates the file ```generated_shaders_gl.cmake``` which sets a cmake +variable containing a list of all GLSL shaders, used by the CMakeLists.txt in this folder. diff --git a/src/rendergraph/shaders/generate_shaders_gl.pl b/src/rendergraph/shaders/generate_shaders_gl.pl new file mode 100755 index 00000000000..c528eb94747 --- /dev/null +++ b/src/rendergraph/shaders/generate_shaders_gl.pl @@ -0,0 +1,68 @@ +#!/usr/bin/perl + +my @files = (glob("*.vert"),glob("*.frag")); + +open(GENERATED,">generated_shaders_gl.cmake"); +print(GENERATED "set(generated_shaders_gl\n"); +for $file (@files) +{ + system("qsb","--glsl","120",$file,"-o","/tmp/$$-$file.qsb"); + open(INFILE,"qsb --dump /tmp/$$-$file.qsb|"); + open(OUTFILE,">$file.gl"); + $ok = 0; + $comment_added = 0; + print "Generating $file.gl from $file\n"; + while () + { + if ($in_shader_block == 2) + { + if (m/^\*\*/) + { + $in_shader_block = 0; + $ok = 1; + } + else + { + if (!$comment_added) + { + if (!m/^#/) + { + print(OUTFILE "//// GENERATED - EDITS WILL BE OVERWRITTEN\n"); + $comment_added = 1; + } + } + print OUTFILE "$_"; + } + } + elsif ($in_shader_block == 1) + { + chomp($_); + if ($_ eq "Contents:") + { + $in_shader_block = 2; + } + } + else + { + chomp($_); + if ($_ eq "Shader 1: GLSL 120 [Standard]") + { + $in_shader_block = 1; + } + } + } + close INFILE; + close OUTFILE; + if($ok) + { + print(GENERATED " $file.gl\n"); + } + else + { + print STDERR "Failed to generated $file.gl"; + unlink("$file.gl") + } + unlink("/tmp/$$-$file.qsb"); +} +print(GENERATED ")\n"); +close GENERATED; diff --git a/src/rendergraph/shaders/generated_shaders_gl.cmake b/src/rendergraph/shaders/generated_shaders_gl.cmake new file mode 100644 index 00000000000..f3f89002e51 --- /dev/null +++ b/src/rendergraph/shaders/generated_shaders_gl.cmake @@ -0,0 +1,13 @@ +set( + generated_shaders_gl + pattern.vert.gl + rgb.vert.gl + rgba.vert.gl + texture.vert.gl + unicolor.vert.gl + pattern.frag.gl + rgb.frag.gl + rgba.frag.gl + texture.frag.gl + unicolor.frag.gl +) diff --git a/src/rendergraph/shaders/pattern.frag b/src/rendergraph/shaders/pattern.frag new file mode 100644 index 00000000000..5aa3d1556b1 --- /dev/null +++ b/src/rendergraph/shaders/pattern.frag @@ -0,0 +1,9 @@ +#version 440 + +layout(binding = 1) uniform sampler2D texture1; +layout(location = 0) in vec2 vTexcoord; +layout(location = 0) out vec4 fragColor; + +void main() { + fragColor = texture(texture1, fract(vTexcoord)); +} diff --git a/src/rendergraph/shaders/pattern.frag.gl b/src/rendergraph/shaders/pattern.frag.gl new file mode 100644 index 00000000000..376c71668ba --- /dev/null +++ b/src/rendergraph/shaders/pattern.frag.gl @@ -0,0 +1,11 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +uniform sampler2D texture1; + +varying vec2 vTexcoord; + +void main() +{ + gl_FragData[0] = texture2D(texture1, fract(vTexcoord)); +} diff --git a/src/rendergraph/shaders/pattern.vert b/src/rendergraph/shaders/pattern.vert new file mode 100644 index 00000000000..07b3d7f1f3b --- /dev/null +++ b/src/rendergraph/shaders/pattern.vert @@ -0,0 +1,15 @@ +#version 440 + +layout(std140, binding = 0) uniform buf { + mat4 matrix; +} +ubuf; + +layout(location = 0) in vec4 position; +layout(location = 1) in vec2 texcoord; +layout(location = 0) out vec2 vTexcoord; + +void main() { + vTexcoord = texcoord; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/pattern.vert.gl b/src/rendergraph/shaders/pattern.vert.gl new file mode 100644 index 00000000000..a3d58014be3 --- /dev/null +++ b/src/rendergraph/shaders/pattern.vert.gl @@ -0,0 +1,19 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +struct buf +{ + mat4 matrix; +}; + +uniform buf ubuf; + +varying vec2 vTexcoord; +attribute vec2 texcoord; +attribute vec4 position; + +void main() +{ + vTexcoord = texcoord; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rgb.frag b/src/rendergraph/shaders/rgb.frag new file mode 100644 index 00000000000..0a808489f5b --- /dev/null +++ b/src/rendergraph/shaders/rgb.frag @@ -0,0 +1,8 @@ +#version 440 + +layout(location = 0) in vec3 vColor; +layout(location = 0) out vec4 fragColor; + +void main() { + fragColor = vec4(vColor, 1.0); +} diff --git a/src/rendergraph/shaders/rgb.frag.gl b/src/rendergraph/shaders/rgb.frag.gl new file mode 100644 index 00000000000..b8a61f8682f --- /dev/null +++ b/src/rendergraph/shaders/rgb.frag.gl @@ -0,0 +1,9 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +varying vec3 vColor; + +void main() +{ + gl_FragData[0] = vec4(vColor, 1.0); +} diff --git a/src/rendergraph/shaders/rgb.vert b/src/rendergraph/shaders/rgb.vert new file mode 100644 index 00000000000..6568d01f187 --- /dev/null +++ b/src/rendergraph/shaders/rgb.vert @@ -0,0 +1,15 @@ +#version 440 + +layout(std140, binding = 0) uniform buf { + mat4 matrix; +} +ubuf; + +layout(location = 0) in vec4 position; +layout(location = 1) in vec3 color; +layout(location = 0) out vec3 vColor; + +void main() { + vColor = color; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rgb.vert.gl b/src/rendergraph/shaders/rgb.vert.gl new file mode 100644 index 00000000000..53e86e4501c --- /dev/null +++ b/src/rendergraph/shaders/rgb.vert.gl @@ -0,0 +1,19 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +struct buf +{ + mat4 matrix; +}; + +uniform buf ubuf; + +varying vec3 vColor; +attribute vec3 color; +attribute vec4 position; + +void main() +{ + vColor = color; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rgba.frag b/src/rendergraph/shaders/rgba.frag new file mode 100644 index 00000000000..5cf90a770ea --- /dev/null +++ b/src/rendergraph/shaders/rgba.frag @@ -0,0 +1,8 @@ +#version 440 + +layout(location = 0) in vec4 vColor; +layout(location = 0) out vec4 fragColor; + +void main() { + fragColor = vec4(vColor.xyz * vColor.w, vColor.w); // premultiple alpha +} diff --git a/src/rendergraph/shaders/rgba.frag.gl b/src/rendergraph/shaders/rgba.frag.gl new file mode 100644 index 00000000000..a831457b968 --- /dev/null +++ b/src/rendergraph/shaders/rgba.frag.gl @@ -0,0 +1,9 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +varying vec4 vColor; + +void main() +{ + gl_FragData[0] = vec4(vColor.xyz * vColor.w, vColor.w); +} diff --git a/src/rendergraph/shaders/rgba.vert b/src/rendergraph/shaders/rgba.vert new file mode 100644 index 00000000000..d5ce8b2d9db --- /dev/null +++ b/src/rendergraph/shaders/rgba.vert @@ -0,0 +1,15 @@ +#version 440 + +layout(std140, binding = 0) uniform buf { + mat4 matrix; +} +ubuf; + +layout(location = 0) in vec4 position; +layout(location = 1) in vec4 color; +layout(location = 0) out vec4 vColor; + +void main() { + vColor = color; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rgba.vert.gl b/src/rendergraph/shaders/rgba.vert.gl new file mode 100644 index 00000000000..df2bcf93236 --- /dev/null +++ b/src/rendergraph/shaders/rgba.vert.gl @@ -0,0 +1,19 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +struct buf +{ + mat4 matrix; +}; + +uniform buf ubuf; + +varying vec4 vColor; +attribute vec4 color; +attribute vec4 position; + +void main() +{ + vColor = color; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/texture.frag b/src/rendergraph/shaders/texture.frag new file mode 100644 index 00000000000..bbe37bccd69 --- /dev/null +++ b/src/rendergraph/shaders/texture.frag @@ -0,0 +1,9 @@ +#version 440 + +layout(binding = 1) uniform sampler2D texture1; +layout(location = 0) in vec2 vTexcoord; +layout(location = 0) out vec4 fragColor; + +void main() { + fragColor = texture(texture1, vTexcoord); +} diff --git a/src/rendergraph/shaders/texture.frag.gl b/src/rendergraph/shaders/texture.frag.gl new file mode 100644 index 00000000000..b2d03f1352c --- /dev/null +++ b/src/rendergraph/shaders/texture.frag.gl @@ -0,0 +1,11 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +uniform sampler2D texture1; + +varying vec2 vTexcoord; + +void main() +{ + gl_FragData[0] = texture2D(texture1, vTexcoord); +} diff --git a/src/rendergraph/shaders/texture.vert b/src/rendergraph/shaders/texture.vert new file mode 100644 index 00000000000..07b3d7f1f3b --- /dev/null +++ b/src/rendergraph/shaders/texture.vert @@ -0,0 +1,15 @@ +#version 440 + +layout(std140, binding = 0) uniform buf { + mat4 matrix; +} +ubuf; + +layout(location = 0) in vec4 position; +layout(location = 1) in vec2 texcoord; +layout(location = 0) out vec2 vTexcoord; + +void main() { + vTexcoord = texcoord; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/texture.vert.gl b/src/rendergraph/shaders/texture.vert.gl new file mode 100644 index 00000000000..a3d58014be3 --- /dev/null +++ b/src/rendergraph/shaders/texture.vert.gl @@ -0,0 +1,19 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +struct buf +{ + mat4 matrix; +}; + +uniform buf ubuf; + +varying vec2 vTexcoord; +attribute vec2 texcoord; +attribute vec4 position; + +void main() +{ + vTexcoord = texcoord; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/unicolor.frag b/src/rendergraph/shaders/unicolor.frag new file mode 100644 index 00000000000..7099bb8f3dd --- /dev/null +++ b/src/rendergraph/shaders/unicolor.frag @@ -0,0 +1,13 @@ +#version 440 + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + vec4 color; +} +ubuf; + +layout(location = 0) out vec4 fragColor; + +void main() { + fragColor = vec4(ubuf.color.xyz * ubuf.color.w, ubuf.color.w); // premultiply alpha +} diff --git a/src/rendergraph/shaders/unicolor.frag.gl b/src/rendergraph/shaders/unicolor.frag.gl new file mode 100644 index 00000000000..bfef503120b --- /dev/null +++ b/src/rendergraph/shaders/unicolor.frag.gl @@ -0,0 +1,15 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +struct buf +{ + mat4 matrix; + vec4 color; +}; + +uniform buf ubuf; + +void main() +{ + gl_FragData[0] = vec4(ubuf.color.xyz * ubuf.color.w, ubuf.color.w); +} diff --git a/src/rendergraph/shaders/unicolor.vert b/src/rendergraph/shaders/unicolor.vert new file mode 100644 index 00000000000..9e268c18fba --- /dev/null +++ b/src/rendergraph/shaders/unicolor.vert @@ -0,0 +1,13 @@ +#version 440 + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + vec4 color; +} +ubuf; + +layout(location = 0) in vec4 position; + +void main() { + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/unicolor.vert.gl b/src/rendergraph/shaders/unicolor.vert.gl new file mode 100644 index 00000000000..d126f3dab58 --- /dev/null +++ b/src/rendergraph/shaders/unicolor.vert.gl @@ -0,0 +1,17 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +struct buf +{ + mat4 matrix; + vec4 color; +}; + +uniform buf ubuf; + +attribute vec4 position; + +void main() +{ + gl_Position = ubuf.matrix * position; +} From efb9535e7c0d5f64daa89ee9d9913cca646b7de1 Mon Sep 17 00:00:00 2001 From: m0dB Date: Sat, 14 Dec 2024 19:34:53 +0100 Subject: [PATCH 04/21] fixed double/float conversions --- src/waveform/widgets/allshader/waveformwidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/waveform/widgets/allshader/waveformwidget.cpp b/src/waveform/widgets/allshader/waveformwidget.cpp index 87e5d0d829e..e6f5536a71d 100644 --- a/src/waveform/widgets/allshader/waveformwidget.cpp +++ b/src/waveform/widgets/allshader/waveformwidget.cpp @@ -152,11 +152,11 @@ void WaveformWidget::resizeRenderer(int, int, float) { } void WaveformWidget::resizeGL(int w, int h) { - w = static_cast(std::lroundf(static_cast(w) / devicePixelRatio())); - h = static_cast(std::lroundf(static_cast(h) / devicePixelRatio())); + w = static_cast(std::lround(static_cast(w) / devicePixelRatioF())); + h = static_cast(std::lround(static_cast(h) / devicePixelRatioF())); m_pEngine->resize(w, h); - WaveformWidgetRenderer::resizeRenderer(w, h, devicePixelRatio()); + WaveformWidgetRenderer::resizeRenderer(w, h, static_cast(devicePixelRatio())); } void WaveformWidget::paintEvent(QPaintEvent* event) { From 1fe28155ae8024c80493bce4604f91348b2d8577 Mon Sep 17 00:00:00 2001 From: m0dB Date: Sat, 14 Dec 2024 20:20:07 +0100 Subject: [PATCH 05/21] play nice with precompiled headers --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cc13a22921..a70b1266dcd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4575,7 +4575,7 @@ endif() # rendergraph add_subdirectory(src/rendergraph) target_link_libraries(mixxx-lib PUBLIC rendergraph_gl) -target_compile_definitions(mixxx-lib PRIVATE rendergraph=rendergraph_gl) +target_compile_definitions(mixxx-lib PUBLIC rendergraph=rendergraph_gl) # WavPack audio file support find_package(wavpack) From 31c99f6d9a6caf20aaa3e45701df4fc6340f5016 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 17 Dec 2024 22:29:36 +0100 Subject: [PATCH 06/21] chore(rendergraph): Port `generate_shaders_gl.pl` to Python --- .../shaders/generate_shaders_gl.pl | 68 -------- tools/rg_generate_shaders_gl.py | 159 ++++++++++++++++++ 2 files changed, 159 insertions(+), 68 deletions(-) delete mode 100755 src/rendergraph/shaders/generate_shaders_gl.pl create mode 100755 tools/rg_generate_shaders_gl.py diff --git a/src/rendergraph/shaders/generate_shaders_gl.pl b/src/rendergraph/shaders/generate_shaders_gl.pl deleted file mode 100755 index c528eb94747..00000000000 --- a/src/rendergraph/shaders/generate_shaders_gl.pl +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/perl - -my @files = (glob("*.vert"),glob("*.frag")); - -open(GENERATED,">generated_shaders_gl.cmake"); -print(GENERATED "set(generated_shaders_gl\n"); -for $file (@files) -{ - system("qsb","--glsl","120",$file,"-o","/tmp/$$-$file.qsb"); - open(INFILE,"qsb --dump /tmp/$$-$file.qsb|"); - open(OUTFILE,">$file.gl"); - $ok = 0; - $comment_added = 0; - print "Generating $file.gl from $file\n"; - while () - { - if ($in_shader_block == 2) - { - if (m/^\*\*/) - { - $in_shader_block = 0; - $ok = 1; - } - else - { - if (!$comment_added) - { - if (!m/^#/) - { - print(OUTFILE "//// GENERATED - EDITS WILL BE OVERWRITTEN\n"); - $comment_added = 1; - } - } - print OUTFILE "$_"; - } - } - elsif ($in_shader_block == 1) - { - chomp($_); - if ($_ eq "Contents:") - { - $in_shader_block = 2; - } - } - else - { - chomp($_); - if ($_ eq "Shader 1: GLSL 120 [Standard]") - { - $in_shader_block = 1; - } - } - } - close INFILE; - close OUTFILE; - if($ok) - { - print(GENERATED " $file.gl\n"); - } - else - { - print STDERR "Failed to generated $file.gl"; - unlink("$file.gl") - } - unlink("/tmp/$$-$file.qsb"); -} -print(GENERATED ")\n"); -close GENERATED; diff --git a/tools/rg_generate_shaders_gl.py b/tools/rg_generate_shaders_gl.py new file mode 100755 index 00000000000..a591bbc9fed --- /dev/null +++ b/tools/rg_generate_shaders_gl.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 +""" +Converts a fragment or vertex shader file into a GL shader file. + +You can use it like this: + + $ ./rg_generate_shaders_gl.py --cmake-output \\ + ../src/rendergraph/shaders/generated_shaders_gl.cmake \\ + ../src/rendergraph/shaders/*.{vert,frag} +""" +import argparse +import logging +import os +import pathlib +import re +import shutil +import subprocess +import tempfile +import typing + + +def find_executable( + executable_name: str, additional_paths: list[str] | None = None +) -> pathlib.Path: + """Find an executable by name in $PATH and in the additional paths.""" + if executable_path := shutil.which(executable_name): + return pathlib.Path(executable_path) + + if additional_paths: + if executable_path := shutil.which( + executable_name, path=os.pathsep.join(additional_paths) + ): + return pathlib.Path(executable_path) + + raise OSError(f"Executable {executable_name!r} not found!") + + +QSB_EXECUTABLE = find_executable( + "qsb", + additional_paths=[ + "/usr/lib/qt6/bin", + "/lib/qt6/bin", + "/usr/local/lib/qt6/bin", + ], +) + + +def parse_shader(input_filepath: pathlib.Path) -> typing.Iterator[str]: + """Parse a Fragment/Vertex shader file and yield lines for a GL file.""" + with tempfile.NamedTemporaryFile() as fp: + subprocess.check_call( + [ + QSB_EXECUTABLE, + "--glsl", + "120", + "--output", + fp.name, + input_filepath, + ] + ) + output = subprocess.check_output( + [QSB_EXECUTABLE, "--dump", fp.name], + encoding="utf-8", + universal_newlines=True, + ) + + comment_added = False + ok = False + in_shader_block = 0 + buffered_blank_line = False + for line in output.splitlines(): + if in_shader_block == 2: + if re.match(r"^\*\*", line): + ok = True + else: + if not comment_added and not re.match(r"^#", line): + yield "//// GENERATED - EDITS WILL BE OVERWRITTEN" + comment_added = True + if line: + if buffered_blank_line: + yield "" + buffered_blank_line = False + yield line + else: + buffered_blank_line = True + elif in_shader_block == 1: + if line.rstrip() == "Contents:": + in_shader_block = 2 + else: + if line.rstrip() == "Shader 1: GLSL 120 [Standard]": + in_shader_block = 1 + if not ok: + raise EOFError("end of file reached before end marker reached") + + +def get_paths(paths: list[pathlib.Path]) -> typing.Iterator[pathlib.Path]: + for path in paths: + if path.is_dir(): + yield from path.glob("*.vert") + yield from path.glob("*.frag") + else: + yield path + + +def main(argv: list[str] | None = None) -> int: + logging.basicConfig(level=logging.DEBUG, format="%(message)s") + + logger = logging.getLogger(__name__) + + description, _, epilog = __doc__.strip().partition("\n\n") + parser = argparse.ArgumentParser( + description=description, + epilog=epilog, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + parser.add_argument( + "file", + nargs="+", + type=pathlib.Path, + help="Input files (.vert, .frag) or directory", + ) + parser.add_argument( + "--cmake-output", + type=argparse.FileType("w"), + required=True, + help="CMake Output files (.cmake)", + ) + args = parser.parse_args(argv) + + generated_shaders: list[pathlib.Path] = [] + + for file in sorted(get_paths(args.file)): + logger.info("Reading file: %s", file) + try: + lines = list(parse_shader(file)) + except EOFError as err: + logger.error("Failed to parse %s: %s", file, err) + continue + + output_file = file.with_suffix(f"{file.suffix}.gl") + logger.info("Writing file: %s", output_file) + with output_file.open("w") as fp: + for line in lines: + fp.write(f"{line}\n") + + generated_shaders.append(output_file) + + args.cmake_output.write("set(\n") + args.cmake_output.write(" generated_shaders_gl\n") + for generated_file in generated_shaders: + args.cmake_output.write(f" {generated_file.name}\n") + args.cmake_output.write(")\n") + logger.info("Generated %d shader files.", len(generated_shaders)) + + return 0 + + +if __name__ == "__main__": + main() From e3154772d87733316883ab012d30a9101f8559b1 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 17 Dec 2024 22:32:08 +0100 Subject: [PATCH 07/21] chore(rendergraph): Order `generated_shaders_gl.cmake` alphabetically --- src/rendergraph/shaders/generated_shaders_gl.cmake | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rendergraph/shaders/generated_shaders_gl.cmake b/src/rendergraph/shaders/generated_shaders_gl.cmake index f3f89002e51..0a5d6de030b 100644 --- a/src/rendergraph/shaders/generated_shaders_gl.cmake +++ b/src/rendergraph/shaders/generated_shaders_gl.cmake @@ -1,13 +1,13 @@ set( generated_shaders_gl - pattern.vert.gl - rgb.vert.gl - rgba.vert.gl - texture.vert.gl - unicolor.vert.gl pattern.frag.gl + pattern.vert.gl rgb.frag.gl + rgb.vert.gl rgba.frag.gl + rgba.vert.gl texture.frag.gl + texture.vert.gl unicolor.frag.gl + unicolor.vert.gl ) From 78481fc224436cf6377111f713994d072786277e Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 17 Dec 2024 23:07:55 +0100 Subject: [PATCH 08/21] ci(pre-commit): Automatically update rendergraph shaders on changes --- .pre-commit-config.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cbc896f2c40..14510090503 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -189,3 +189,10 @@ repos: additional_dependencies: - lxml==5.3.0 files: ^(res/translations/.*\.ts)$ + - id: update-rendergraph-shaders + name: update-rendergraph-shaders + description: "Regenerate GL shaders for rendergraph" + entry: python tools/rg_generate_shaders_gl.py --cmake-output src/rendergraph/shaders/generated_shaders_gl.cmake src/rendergraph/shaders/ + pass_filenames: false + language: python + files: ^src/rendergraph/shaders/.*\.(vert|frag|gl)$ From 182199f4683a2c45dded1afcf18379d139f7c755 Mon Sep 17 00:00:00 2001 From: m0dB Date: Sun, 22 Dec 2024 12:25:11 +0100 Subject: [PATCH 09/21] remove generate_shaders_gl from precommit --- .pre-commit-config.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 14510090503..cbc896f2c40 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -189,10 +189,3 @@ repos: additional_dependencies: - lxml==5.3.0 files: ^(res/translations/.*\.ts)$ - - id: update-rendergraph-shaders - name: update-rendergraph-shaders - description: "Regenerate GL shaders for rendergraph" - entry: python tools/rg_generate_shaders_gl.py --cmake-output src/rendergraph/shaders/generated_shaders_gl.cmake src/rendergraph/shaders/ - pass_filenames: false - language: python - files: ^src/rendergraph/shaders/.*\.(vert|frag|gl)$ From 4e16ade9d34465162f2b59d8708455fef321c9f6 Mon Sep 17 00:00:00 2001 From: m0dB Date: Sun, 22 Dec 2024 12:25:36 +0100 Subject: [PATCH 10/21] moved generate_shaders_gl.py script to rendergraph/tools, updated readme --- src/rendergraph/shaders/README.md | 8 ++++---- .../rendergraph/tools/generate_shaders_gl.py | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) rename tools/rg_generate_shaders_gl.py => src/rendergraph/tools/generate_shaders_gl.py (96%) diff --git a/src/rendergraph/shaders/README.md b/src/rendergraph/shaders/README.md index 31f8a53fff1..f6c2d328217 100644 --- a/src/rendergraph/shaders/README.md +++ b/src/rendergraph/shaders/README.md @@ -21,9 +21,9 @@ The GLSL shaders are extracted programmatically with `QShader` and then used wit ### Qt < 6.6 The GLSL shader have to extracted from the qsb shader bundles to be used by `QOpenGLShader`. -This can be done using the script `generate_shaders_gl.pl`. To use this script, make sure -that the qsb and spirv commands are in your path. qsb is part of Qt. spirv is part of the -Vulkan SDK and can be downloaded from +This can be done using the script `generate_shaders_gl.py` in the ../tools directory. To +use this script, make sure that the qsb and spirv commands are in your path. qsb is part of +Qt. spirv is part of the Vulkan SDK and can be downloaded from -The script also generates the file ```generated_shaders_gl.cmake``` which sets a cmake +The script also generates the file `generated_shaders_gl.cmake` which sets a cmake variable containing a list of all GLSL shaders, used by the CMakeLists.txt in this folder. diff --git a/tools/rg_generate_shaders_gl.py b/src/rendergraph/tools/generate_shaders_gl.py similarity index 96% rename from tools/rg_generate_shaders_gl.py rename to src/rendergraph/tools/generate_shaders_gl.py index a591bbc9fed..75c7f4365e1 100755 --- a/tools/rg_generate_shaders_gl.py +++ b/src/rendergraph/tools/generate_shaders_gl.py @@ -4,9 +4,9 @@ You can use it like this: - $ ./rg_generate_shaders_gl.py --cmake-output \\ - ../src/rendergraph/shaders/generated_shaders_gl.cmake \\ - ../src/rendergraph/shaders/*.{vert,frag} + $ ./generate_shaders_gl.py --cmake-output \\ + ../shaders/generated_shaders_gl.cmake \\ + ../shaders/*.{vert,frag} """ import argparse import logging From 9104a3dc82cf288bbc62e0566c155d6e3e7ebe0a Mon Sep 17 00:00:00 2001 From: m0dB Date: Sun, 22 Dec 2024 12:43:41 +0100 Subject: [PATCH 11/21] add missing pointer initialization --- src/waveform/widgets/allshader/waveformwidget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/waveform/widgets/allshader/waveformwidget.cpp b/src/waveform/widgets/allshader/waveformwidget.cpp index e6f5536a71d..c359a585c05 100644 --- a/src/waveform/widgets/allshader/waveformwidget.cpp +++ b/src/waveform/widgets/allshader/waveformwidget.cpp @@ -25,7 +25,9 @@ WaveformWidget::WaveformWidget(QWidget* parent, WaveformWidgetType::Type type, const QString& group, WaveformRendererSignalBase::Options options) - : WGLWidget(parent), WaveformWidgetAbstract(group) { + : WGLWidget(parent), + WaveformWidgetAbstract(group), + m_pWaveformRendererSignal(nullptr) { auto pTopNode = std::make_unique(); auto pOpacityNode = std::make_unique(); From efae93e68d39605a39b91e7647520dd6284b4f86 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 22 Dec 2024 15:00:00 +0100 Subject: [PATCH 12/21] fix(generate_shaders_gl): Replace new union expression with old syntax This makes it compatible with Python 3.9 (default on macOS). --- src/rendergraph/tools/generate_shaders_gl.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rendergraph/tools/generate_shaders_gl.py b/src/rendergraph/tools/generate_shaders_gl.py index 75c7f4365e1..e96d50d017a 100755 --- a/src/rendergraph/tools/generate_shaders_gl.py +++ b/src/rendergraph/tools/generate_shaders_gl.py @@ -20,7 +20,7 @@ def find_executable( - executable_name: str, additional_paths: list[str] | None = None + executable_name: str, additional_paths: typing.Optional[list[str]] = None ) -> pathlib.Path: """Find an executable by name in $PATH and in the additional paths.""" if executable_path := shutil.which(executable_name): @@ -102,7 +102,7 @@ def get_paths(paths: list[pathlib.Path]) -> typing.Iterator[pathlib.Path]: yield path -def main(argv: list[str] | None = None) -> int: +def main(argv: typing.Optional[list[str]] = None) -> int: logging.basicConfig(level=logging.DEBUG, format="%(message)s") logger = logging.getLogger(__name__) From 0d99bd6e26df9dbb87e185d55eab148c488a655c Mon Sep 17 00:00:00 2001 From: m0dB Date: Sun, 22 Dec 2024 15:46:36 +0100 Subject: [PATCH 13/21] moved script back, edited info, edited readme --- src/rendergraph/shaders/README.md | 11 ++- tools/rg_generate_shaders_gl.py | 159 ++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 3 deletions(-) create mode 100755 tools/rg_generate_shaders_gl.py diff --git a/src/rendergraph/shaders/README.md b/src/rendergraph/shaders/README.md index f6c2d328217..7ed87b03499 100644 --- a/src/rendergraph/shaders/README.md +++ b/src/rendergraph/shaders/README.md @@ -21,9 +21,14 @@ The GLSL shaders are extracted programmatically with `QShader` and then used wit ### Qt < 6.6 The GLSL shader have to extracted from the qsb shader bundles to be used by `QOpenGLShader`. -This can be done using the script `generate_shaders_gl.py` in the ../tools directory. To -use this script, make sure that the qsb and spirv commands are in your path. qsb is part of -Qt. spirv is part of the Vulkan SDK and can be downloaded from +This can be done using the script `rg_generate_shaders_gl.py` in the mixxx/tools directory: + +```console +$ ../../../tools/rg_generate_shaders_gl.py --cmake generated_shaders_gl.cmake *.vert *.frag +``` + +To use this script, make sure that the qsb and spirv commands are in your path. qsb is part +of Qt. spirv is part of the Vulkan SDK and can be downloaded from The script also generates the file `generated_shaders_gl.cmake` which sets a cmake variable containing a list of all GLSL shaders, used by the CMakeLists.txt in this folder. diff --git a/tools/rg_generate_shaders_gl.py b/tools/rg_generate_shaders_gl.py new file mode 100755 index 00000000000..6cd23fff576 --- /dev/null +++ b/tools/rg_generate_shaders_gl.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 +""" +Converts a fragment or vertex shader file into a GL shader file. + +You can use it like this: + + $ ./rg_generate_shaders_gl.py --cmake-output \\ + ../src/rendergraph/shaders/generated_shaders_gl.cmake \\ + ../src/rendergraph/shaders/*.{vert,frag} +""" +import argparse +import logging +import os +import pathlib +import re +import shutil +import subprocess +import tempfile +import typing + + +def find_executable( + executable_name: str, additional_paths: typing.Optional[list[str]] = None +) -> pathlib.Path: + """Find an executable by name in $PATH and in the additional paths.""" + if executable_path := shutil.which(executable_name): + return pathlib.Path(executable_path) + + if additional_paths: + if executable_path := shutil.which( + executable_name, path=os.pathsep.join(additional_paths) + ): + return pathlib.Path(executable_path) + + raise OSError(f"Executable {executable_name!r} not found!") + + +QSB_EXECUTABLE = find_executable( + "qsb", + additional_paths=[ + "/usr/lib/qt6/bin", + "/lib/qt6/bin", + "/usr/local/lib/qt6/bin", + ], +) + + +def parse_shader(input_filepath: pathlib.Path) -> typing.Iterator[str]: + """Parse a Fragment/Vertex shader file and yield lines for a GL file.""" + with tempfile.NamedTemporaryFile() as fp: + subprocess.check_call( + [ + QSB_EXECUTABLE, + "--glsl", + "120", + "--output", + fp.name, + input_filepath, + ] + ) + output = subprocess.check_output( + [QSB_EXECUTABLE, "--dump", fp.name], + encoding="utf-8", + universal_newlines=True, + ) + + comment_added = False + ok = False + in_shader_block = 0 + buffered_blank_line = False + for line in output.splitlines(): + if in_shader_block == 2: + if re.match(r"^\*\*", line): + ok = True + else: + if not comment_added and not re.match(r"^#", line): + yield "//// GENERATED - EDITS WILL BE OVERWRITTEN" + comment_added = True + if line: + if buffered_blank_line: + yield "" + buffered_blank_line = False + yield line + else: + buffered_blank_line = True + elif in_shader_block == 1: + if line.rstrip() == "Contents:": + in_shader_block = 2 + else: + if line.rstrip() == "Shader 1: GLSL 120 [Standard]": + in_shader_block = 1 + if not ok: + raise EOFError("end of file reached before end marker reached") + + +def get_paths(paths: list[pathlib.Path]) -> typing.Iterator[pathlib.Path]: + for path in paths: + if path.is_dir(): + yield from path.glob("*.vert") + yield from path.glob("*.frag") + else: + yield path + + +def main(argv: typing.Optional[list[str]] = None) -> int: + logging.basicConfig(level=logging.DEBUG, format="%(message)s") + + logger = logging.getLogger(__name__) + + description, _, epilog = __doc__.strip().partition("\n\n") + parser = argparse.ArgumentParser( + description=description, + epilog=epilog, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + parser.add_argument( + "file", + nargs="+", + type=pathlib.Path, + help="Input files (.vert, .frag) or directory", + ) + parser.add_argument( + "--cmake-output", + type=argparse.FileType("w"), + required=True, + help="CMake Output files (.cmake)", + ) + args = parser.parse_args(argv) + + generated_shaders: list[pathlib.Path] = [] + + for file in sorted(get_paths(args.file)): + logger.info("Reading file: %s", file) + try: + lines = list(parse_shader(file)) + except EOFError as err: + logger.error("Failed to parse %s: %s", file, err) + continue + + output_file = file.with_suffix(f"{file.suffix}.gl") + logger.info("Writing file: %s", output_file) + with output_file.open("w") as fp: + for line in lines: + fp.write(f"{line}\n") + + generated_shaders.append(output_file) + + args.cmake_output.write("set(\n") + args.cmake_output.write(" generated_shaders_gl\n") + for generated_file in generated_shaders: + args.cmake_output.write(f" {generated_file.name}\n") + args.cmake_output.write(")\n") + logger.info("Generated %d shader files.", len(generated_shaders)) + + return 0 + + +if __name__ == "__main__": + main() From 931260ccc225251cc9c7a27bce47fb6925665ba2 Mon Sep 17 00:00:00 2001 From: m0dB Date: Thu, 26 Dec 2024 04:44:48 +0100 Subject: [PATCH 14/21] removed all Q_UNUSED --- src/waveform/renderers/allshader/waveformrenderer.cpp | 4 +--- src/waveform/renderers/allshader/waveformrendererfiltered.cpp | 3 +-- src/waveform/renderers/allshader/waveformrendererhsv.cpp | 3 +-- src/waveform/renderers/allshader/waveformrendererrgb.cpp | 3 +-- .../renderers/allshader/waveformrenderersignalbase.cpp | 4 +--- src/waveform/renderers/allshader/waveformrenderersimple.cpp | 3 +-- src/waveform/renderers/allshader/waveformrendererstem.cpp | 3 +-- src/waveform/renderers/allshader/waveformrenderertextured.cpp | 3 +-- src/waveform/renderers/allshader/waveformrendermark.cpp | 4 +--- 9 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/waveform/renderers/allshader/waveformrenderer.cpp b/src/waveform/renderers/allshader/waveformrenderer.cpp index 16ee93f82ed..4c983ef583b 100644 --- a/src/waveform/renderers/allshader/waveformrenderer.cpp +++ b/src/waveform/renderers/allshader/waveformrenderer.cpp @@ -8,9 +8,7 @@ WaveformRenderer::WaveformRenderer(WaveformWidgetRenderer* widget) : ::WaveformRendererAbstract(widget) { } -void WaveformRenderer::draw(QPainter* painter, QPaintEvent* event) { - Q_UNUSED(painter); - Q_UNUSED(event); +void WaveformRenderer::draw(QPainter*, QPaintEvent*) { DEBUG_ASSERT(false); } diff --git a/src/waveform/renderers/allshader/waveformrendererfiltered.cpp b/src/waveform/renderers/allshader/waveformrendererfiltered.cpp index f48b1136f59..d7c40cd01ed 100644 --- a/src/waveform/renderers/allshader/waveformrendererfiltered.cpp +++ b/src/waveform/renderers/allshader/waveformrendererfiltered.cpp @@ -14,8 +14,7 @@ WaveformRendererFiltered::WaveformRendererFiltered( m_bRgbStacked(bRgbStacked) { } -void WaveformRendererFiltered::onSetup(const QDomNode& node) { - Q_UNUSED(node); +void WaveformRendererFiltered::onSetup(const QDomNode&) { } void WaveformRendererFiltered::initializeGL() { diff --git a/src/waveform/renderers/allshader/waveformrendererhsv.cpp b/src/waveform/renderers/allshader/waveformrendererhsv.cpp index 75b34dbae00..60ec42822be 100644 --- a/src/waveform/renderers/allshader/waveformrendererhsv.cpp +++ b/src/waveform/renderers/allshader/waveformrendererhsv.cpp @@ -14,8 +14,7 @@ WaveformRendererHSV::WaveformRendererHSV( : WaveformRendererSignalBase(waveformWidget) { } -void WaveformRendererHSV::onSetup(const QDomNode& node) { - Q_UNUSED(node); +void WaveformRendererHSV::onSetup(const QDomNode&) { } void WaveformRendererHSV::initializeGL() { diff --git a/src/waveform/renderers/allshader/waveformrendererrgb.cpp b/src/waveform/renderers/allshader/waveformrendererrgb.cpp index 31cd94f1a5d..6d7a3d7393f 100644 --- a/src/waveform/renderers/allshader/waveformrendererrgb.cpp +++ b/src/waveform/renderers/allshader/waveformrendererrgb.cpp @@ -22,8 +22,7 @@ WaveformRendererRGB::WaveformRendererRGB(WaveformWidgetRenderer* waveformWidget, m_options(options) { } -void WaveformRendererRGB::onSetup(const QDomNode& node) { - Q_UNUSED(node); +void WaveformRendererRGB::onSetup(const QDomNode&) { } void WaveformRendererRGB::initializeGL() { diff --git a/src/waveform/renderers/allshader/waveformrenderersignalbase.cpp b/src/waveform/renderers/allshader/waveformrenderersignalbase.cpp index 620db520fd0..ea906dba69e 100644 --- a/src/waveform/renderers/allshader/waveformrenderersignalbase.cpp +++ b/src/waveform/renderers/allshader/waveformrenderersignalbase.cpp @@ -7,9 +7,7 @@ WaveformRendererSignalBase::WaveformRendererSignalBase( : ::WaveformRendererSignalBase(waveformWidget) { } -void WaveformRendererSignalBase::draw(QPainter* painter, QPaintEvent* event) { - Q_UNUSED(painter); - Q_UNUSED(event); +void WaveformRendererSignalBase::draw(QPainter*, QPaintEvent*) { DEBUG_ASSERT(false); } diff --git a/src/waveform/renderers/allshader/waveformrenderersimple.cpp b/src/waveform/renderers/allshader/waveformrenderersimple.cpp index 90a707d2373..8cc06626f07 100644 --- a/src/waveform/renderers/allshader/waveformrenderersimple.cpp +++ b/src/waveform/renderers/allshader/waveformrenderersimple.cpp @@ -13,8 +13,7 @@ WaveformRendererSimple::WaveformRendererSimple( : WaveformRendererSignalBase(waveformWidget) { } -void WaveformRendererSimple::onSetup(const QDomNode& node) { - Q_UNUSED(node); +void WaveformRendererSimple::onSetup(const QDomNode&) { } void WaveformRendererSimple::initializeGL() { diff --git a/src/waveform/renderers/allshader/waveformrendererstem.cpp b/src/waveform/renderers/allshader/waveformrendererstem.cpp index 80612f99470..c73e170d397 100644 --- a/src/waveform/renderers/allshader/waveformrendererstem.cpp +++ b/src/waveform/renderers/allshader/waveformrendererstem.cpp @@ -21,8 +21,7 @@ WaveformRendererStem::WaveformRendererStem( m_isSlipRenderer(type == ::WaveformRendererAbstract::Slip) { } -void WaveformRendererStem::onSetup(const QDomNode& node) { - Q_UNUSED(node); +void WaveformRendererStem::onSetup(const QDomNode&) { } void WaveformRendererStem::initializeGL() { diff --git a/src/waveform/renderers/allshader/waveformrenderertextured.cpp b/src/waveform/renderers/allshader/waveformrenderertextured.cpp index de21a013259..97ac6a48059 100644 --- a/src/waveform/renderers/allshader/waveformrenderertextured.cpp +++ b/src/waveform/renderers/allshader/waveformrenderertextured.cpp @@ -235,8 +235,7 @@ void WaveformRendererTextured::initializeGL() { } } -void WaveformRendererTextured::onSetup(const QDomNode& node) { - Q_UNUSED(node); +void WaveformRendererTextured::onSetup(const QDomNode&) { } void WaveformRendererTextured::onSetTrack() { diff --git a/src/waveform/renderers/allshader/waveformrendermark.cpp b/src/waveform/renderers/allshader/waveformrendermark.cpp index 9e9f1632896..de797d41d05 100644 --- a/src/waveform/renderers/allshader/waveformrendermark.cpp +++ b/src/waveform/renderers/allshader/waveformrendermark.cpp @@ -79,9 +79,7 @@ bool allshader::WaveformRenderMark::init() { return true; } -void allshader::WaveformRenderMark::draw(QPainter* painter, QPaintEvent* event) { - Q_UNUSED(painter); - Q_UNUSED(event); +void allshader::WaveformRenderMark::draw(QPainter*, QPaintEvent*) { DEBUG_ASSERT(false); } From 6c21fcff57a44713f35baf862e899217bbaa0fc2 Mon Sep 17 00:00:00 2001 From: m0dB Date: Thu, 26 Dec 2024 04:47:08 +0100 Subject: [PATCH 15/21] removed copy of generate_shaders_gl.py --- src/rendergraph/tools/generate_shaders_gl.py | 159 ------------------- 1 file changed, 159 deletions(-) delete mode 100755 src/rendergraph/tools/generate_shaders_gl.py diff --git a/src/rendergraph/tools/generate_shaders_gl.py b/src/rendergraph/tools/generate_shaders_gl.py deleted file mode 100755 index e96d50d017a..00000000000 --- a/src/rendergraph/tools/generate_shaders_gl.py +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env python3 -""" -Converts a fragment or vertex shader file into a GL shader file. - -You can use it like this: - - $ ./generate_shaders_gl.py --cmake-output \\ - ../shaders/generated_shaders_gl.cmake \\ - ../shaders/*.{vert,frag} -""" -import argparse -import logging -import os -import pathlib -import re -import shutil -import subprocess -import tempfile -import typing - - -def find_executable( - executable_name: str, additional_paths: typing.Optional[list[str]] = None -) -> pathlib.Path: - """Find an executable by name in $PATH and in the additional paths.""" - if executable_path := shutil.which(executable_name): - return pathlib.Path(executable_path) - - if additional_paths: - if executable_path := shutil.which( - executable_name, path=os.pathsep.join(additional_paths) - ): - return pathlib.Path(executable_path) - - raise OSError(f"Executable {executable_name!r} not found!") - - -QSB_EXECUTABLE = find_executable( - "qsb", - additional_paths=[ - "/usr/lib/qt6/bin", - "/lib/qt6/bin", - "/usr/local/lib/qt6/bin", - ], -) - - -def parse_shader(input_filepath: pathlib.Path) -> typing.Iterator[str]: - """Parse a Fragment/Vertex shader file and yield lines for a GL file.""" - with tempfile.NamedTemporaryFile() as fp: - subprocess.check_call( - [ - QSB_EXECUTABLE, - "--glsl", - "120", - "--output", - fp.name, - input_filepath, - ] - ) - output = subprocess.check_output( - [QSB_EXECUTABLE, "--dump", fp.name], - encoding="utf-8", - universal_newlines=True, - ) - - comment_added = False - ok = False - in_shader_block = 0 - buffered_blank_line = False - for line in output.splitlines(): - if in_shader_block == 2: - if re.match(r"^\*\*", line): - ok = True - else: - if not comment_added and not re.match(r"^#", line): - yield "//// GENERATED - EDITS WILL BE OVERWRITTEN" - comment_added = True - if line: - if buffered_blank_line: - yield "" - buffered_blank_line = False - yield line - else: - buffered_blank_line = True - elif in_shader_block == 1: - if line.rstrip() == "Contents:": - in_shader_block = 2 - else: - if line.rstrip() == "Shader 1: GLSL 120 [Standard]": - in_shader_block = 1 - if not ok: - raise EOFError("end of file reached before end marker reached") - - -def get_paths(paths: list[pathlib.Path]) -> typing.Iterator[pathlib.Path]: - for path in paths: - if path.is_dir(): - yield from path.glob("*.vert") - yield from path.glob("*.frag") - else: - yield path - - -def main(argv: typing.Optional[list[str]] = None) -> int: - logging.basicConfig(level=logging.DEBUG, format="%(message)s") - - logger = logging.getLogger(__name__) - - description, _, epilog = __doc__.strip().partition("\n\n") - parser = argparse.ArgumentParser( - description=description, - epilog=epilog, - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - parser.add_argument( - "file", - nargs="+", - type=pathlib.Path, - help="Input files (.vert, .frag) or directory", - ) - parser.add_argument( - "--cmake-output", - type=argparse.FileType("w"), - required=True, - help="CMake Output files (.cmake)", - ) - args = parser.parse_args(argv) - - generated_shaders: list[pathlib.Path] = [] - - for file in sorted(get_paths(args.file)): - logger.info("Reading file: %s", file) - try: - lines = list(parse_shader(file)) - except EOFError as err: - logger.error("Failed to parse %s: %s", file, err) - continue - - output_file = file.with_suffix(f"{file.suffix}.gl") - logger.info("Writing file: %s", output_file) - with output_file.open("w") as fp: - for line in lines: - fp.write(f"{line}\n") - - generated_shaders.append(output_file) - - args.cmake_output.write("set(\n") - args.cmake_output.write(" generated_shaders_gl\n") - for generated_file in generated_shaders: - args.cmake_output.write(f" {generated_file.name}\n") - args.cmake_output.write(")\n") - logger.info("Generated %d shader files.", len(generated_shaders)) - - return 0 - - -if __name__ == "__main__": - main() From a00d35c9c0757f63f44a6b01e6cd81bfcf444f14 Mon Sep 17 00:00:00 2001 From: m0dB Date: Thu, 26 Dec 2024 05:52:11 +0100 Subject: [PATCH 16/21] added appendChildNode with templatized result as suggested by Nico, cleared up code when creating a waveformsignalrenderer, and appending it as a node --- .../opengl/rendergraph/nodeinterface.h | 7 ++- .../scenegraph/rendergraph/nodeinterface.h | 6 ++- .../allshader/waveformrendererfiltered.h | 4 ++ .../renderers/allshader/waveformrendererhsv.h | 4 ++ .../renderers/allshader/waveformrendererrgb.h | 4 ++ .../allshader/waveformrenderersignalbase.h | 3 ++ .../allshader/waveformrenderersimple.h | 4 ++ .../allshader/waveformrendererstem.h | 4 ++ .../allshader/waveformrenderertextured.h | 4 ++ .../widgets/allshader/waveformwidget.cpp | 50 ++++++++++++------- .../widgets/allshader/waveformwidget.h | 7 +-- 11 files changed, 69 insertions(+), 28 deletions(-) diff --git a/src/rendergraph/opengl/rendergraph/nodeinterface.h b/src/rendergraph/opengl/rendergraph/nodeinterface.h index 45159724c49..7781dd24237 100644 --- a/src/rendergraph/opengl/rendergraph/nodeinterface.h +++ b/src/rendergraph/opengl/rendergraph/nodeinterface.h @@ -7,14 +7,17 @@ namespace rendergraph { template class NodeInterface : public T_Node { public: - void appendChildNode(std::unique_ptr pNode) { + template + T_AppendNode* appendChildNode(std::unique_ptr pNode) { // Transfers ownership to this. - BaseNode* pRawNode = pNode.release(); + T_AppendNode* pRawNode = pNode.release(); // Note: Ideally we would use unique_ptrs internally, but // Qt uses raw pointers for QSGNode hierarchy. For simplicity // we mimic this. T_Node::appendChildNode(pRawNode); + + return pRawNode; } std::unique_ptr detachChildNode(BaseNode* pNode) { diff --git a/src/rendergraph/scenegraph/rendergraph/nodeinterface.h b/src/rendergraph/scenegraph/rendergraph/nodeinterface.h index f5c42cadf46..48ae7ad67dc 100644 --- a/src/rendergraph/scenegraph/rendergraph/nodeinterface.h +++ b/src/rendergraph/scenegraph/rendergraph/nodeinterface.h @@ -8,11 +8,13 @@ namespace rendergraph { template class NodeInterface : public T_Node { public: - void appendChildNode(std::unique_ptr pNode) { - BaseNode* pRawNode = pNode.release(); + template + T_AppendNode* appendChildNode(std::unique_ptr pNode) { + T_AppendNode* pRawNode = pNode.release(); pRawNode->setFlag(QSGNode::OwnedByParent, true); T_Node::appendChildNode(pRawNode); DEBUG_ASSERT(pRawNode->flags() & QSGNode::OwnedByParent); + return pRawNode; } std::unique_ptr detachChildNode(BaseNode* pNode) { DEBUG_ASSERT(pNode->flags() & QSGNode::OwnedByParent); diff --git a/src/waveform/renderers/allshader/waveformrendererfiltered.h b/src/waveform/renderers/allshader/waveformrendererfiltered.h index 43441adafa5..273e58585d3 100644 --- a/src/waveform/renderers/allshader/waveformrendererfiltered.h +++ b/src/waveform/renderers/allshader/waveformrendererfiltered.h @@ -22,6 +22,10 @@ class allshader::WaveformRendererFiltered final void initializeGL() override; void paintGL() override; + rendergraph::BaseNode* asNode() override { + return this; + } + private: const bool m_bRgbStacked; mixxx::UnicolorShader m_shader; diff --git a/src/waveform/renderers/allshader/waveformrendererhsv.h b/src/waveform/renderers/allshader/waveformrendererhsv.h index a6fdbe95f51..afed72306d3 100644 --- a/src/waveform/renderers/allshader/waveformrendererhsv.h +++ b/src/waveform/renderers/allshader/waveformrendererhsv.h @@ -23,6 +23,10 @@ class allshader::WaveformRendererHSV final void initializeGL() override; void paintGL() override; + rendergraph::BaseNode* asNode() override { + return this; + } + private: mixxx::RGBShader m_shader; VertexData m_vertices; diff --git a/src/waveform/renderers/allshader/waveformrendererrgb.h b/src/waveform/renderers/allshader/waveformrendererrgb.h index 10f2262a751..ec4496c4bd2 100644 --- a/src/waveform/renderers/allshader/waveformrendererrgb.h +++ b/src/waveform/renderers/allshader/waveformrendererrgb.h @@ -30,6 +30,10 @@ class allshader::WaveformRendererRGB final return true; } + rendergraph::BaseNode* asNode() override { + return this; + } + private: mixxx::RGBShader m_shader; VertexData m_vertices; diff --git a/src/waveform/renderers/allshader/waveformrenderersignalbase.h b/src/waveform/renderers/allshader/waveformrenderersignalbase.h index dafa41cd79b..b9cf0ce93a1 100644 --- a/src/waveform/renderers/allshader/waveformrenderersignalbase.h +++ b/src/waveform/renderers/allshader/waveformrenderersignalbase.h @@ -3,6 +3,7 @@ #include #include +#include "rendergraph/node.h" #include "util/class.h" #include "waveform/renderers/waveformrenderersignalbase.h" @@ -32,5 +33,7 @@ class allshader::WaveformRendererSignalBase : public ::WaveformRendererSignalBas return false; } + virtual rendergraph::BaseNode* asNode() = 0; + DISALLOW_COPY_AND_ASSIGN(WaveformRendererSignalBase); }; diff --git a/src/waveform/renderers/allshader/waveformrenderersimple.h b/src/waveform/renderers/allshader/waveformrenderersimple.h index ba79752539c..1654ff7b2de 100644 --- a/src/waveform/renderers/allshader/waveformrenderersimple.h +++ b/src/waveform/renderers/allshader/waveformrenderersimple.h @@ -22,6 +22,10 @@ class allshader::WaveformRendererSimple final void initializeGL() override; void paintGL() override; + rendergraph::BaseNode* asNode() override { + return this; + } + private: mixxx::UnicolorShader m_shader; VertexData m_vertices[2]; diff --git a/src/waveform/renderers/allshader/waveformrendererstem.h b/src/waveform/renderers/allshader/waveformrendererstem.h index 99728194574..215c4e367db 100644 --- a/src/waveform/renderers/allshader/waveformrendererstem.h +++ b/src/waveform/renderers/allshader/waveformrendererstem.h @@ -30,6 +30,10 @@ class allshader::WaveformRendererStem final void initializeGL() override; void paintGL() override; + rendergraph::BaseNode* asNode() override { + return this; + } + private: mixxx::RGBAShader m_shader; mixxx::TextureShader m_textureShader; diff --git a/src/waveform/renderers/allshader/waveformrenderertextured.h b/src/waveform/renderers/allshader/waveformrenderertextured.h index ccd82ae5a67..c2477970adc 100644 --- a/src/waveform/renderers/allshader/waveformrenderertextured.h +++ b/src/waveform/renderers/allshader/waveformrenderertextured.h @@ -42,6 +42,10 @@ class allshader::WaveformRendererTextured final : public QObject, void onSetTrack() override; + rendergraph::BaseNode* asNode() override { + return this; + } + public slots: void slotWaveformUpdated(); diff --git a/src/waveform/widgets/allshader/waveformwidget.cpp b/src/waveform/widgets/allshader/waveformwidget.cpp index c359a585c05..f8b88ed927a 100644 --- a/src/waveform/widgets/allshader/waveformwidget.cpp +++ b/src/waveform/widgets/allshader/waveformwidget.cpp @@ -21,6 +21,11 @@ namespace allshader { +std::unique_ptr convert( + std::unique_ptr&& pRenderer) { + return std::unique_ptr(pRenderer.release()->asNode()); +} + WaveformWidget::WaveformWidget(QWidget* parent, WaveformWidgetType::Type type, const QString& group, @@ -34,8 +39,8 @@ WaveformWidget::WaveformWidget(QWidget* parent, pTopNode->appendChildNode(addRendererNode()); pOpacityNode->appendChildNode(addRendererNode()); pOpacityNode->appendChildNode(addRendererNode()); - pOpacityNode->appendChildNode(addRendererNode()); - m_pWaveformRenderMarkRange = static_cast(pOpacityNode->lastChild()); + m_pWaveformRenderMarkRange = pOpacityNode->appendChildNode( + addRendererNode()); #ifdef __STEM__ // The following two renderers work in tandem: if the rendered waveform is @@ -43,11 +48,16 @@ WaveformWidget::WaveformWidget(QWidget* parent, // WaveformRendererStem do the rendering, and vice-versa. pOpacityNode->appendChildNode(addRendererNode()); #endif - pOpacityNode->appendChildNode(addWaveformSignalRendererNode( - type, options, ::WaveformRendererAbstract::Play)); + std::unique_ptr pWaveformRendererSignal = addWaveformSignalRenderer( + type, options, ::WaveformRendererAbstract::Play); + m_pWaveformRendererSignal = pWaveformRendererSignal.get(); + if (pWaveformRendererSignal) { + // convert std::unique_ptr + // to std::unique_ptr + pOpacityNode->appendChildNode(convert(std::move(pWaveformRendererSignal))); + } pOpacityNode->appendChildNode(addRendererNode()); - pOpacityNode->appendChildNode(addRendererNode()); - m_pWaveformRenderMark = static_cast(pOpacityNode->lastChild()); + m_pWaveformRenderMark = pOpacityNode->appendChildNode(addRendererNode()); // if the added signal renderer supports slip, we add it again, now for // slip, together with the other slip renderers @@ -62,8 +72,11 @@ WaveformWidget::WaveformWidget(QWidget* parent, addRendererNode( ::WaveformRendererAbstract::Slip)); #endif - pOpacityNode->appendChildNode(addWaveformSignalRendererNode( - type, options, ::WaveformRendererAbstract::Slip)); + std::unique_ptr pSlipNode = addWaveformSignalRenderer( + type, options, ::WaveformRendererAbstract::Slip); + // convert std::unique_ptr + // to std::unique_ptr + pOpacityNode->appendChildNode(convert(std::move(pSlipNode))); pOpacityNode->appendChildNode( addRendererNode( ::WaveformRendererAbstract::Slip)); @@ -74,8 +87,7 @@ WaveformWidget::WaveformWidget(QWidget* parent, m_initSuccess = init(); - pTopNode->appendChildNode(std::move(pOpacityNode)); - m_pOpacityNode = static_cast(pTopNode->lastChild()); + m_pOpacityNode = pTopNode->appendChildNode(std::move(pOpacityNode)); m_pEngine = std::make_unique(std::move(pTopNode)); } @@ -87,17 +99,17 @@ WaveformWidget::~WaveformWidget() { doneCurrent(); } -std::unique_ptr -WaveformWidget::addWaveformSignalRendererNode(WaveformWidgetType::Type type, +std::unique_ptr +WaveformWidget::addWaveformSignalRenderer(WaveformWidgetType::Type type, WaveformRendererSignalBase::Options options, ::WaveformRendererAbstract::PositionSource positionSource) { #ifndef QT_OPENGL_ES_2 - if (options & allshader::WaveformRendererSignalBase::Option::HighDetail) { + if (options & WaveformRendererSignalBase::Option::HighDetail) { switch (type) { case ::WaveformWidgetType::RGB: case ::WaveformWidgetType::Filtered: case ::WaveformWidgetType::Stacked: - return addWaveformSignalRendererNode( + return addWaveformSignalRenderer( type, positionSource, options); default: break; @@ -107,15 +119,15 @@ WaveformWidget::addWaveformSignalRendererNode(WaveformWidgetType::Type type, switch (type) { case ::WaveformWidgetType::Simple: - return addWaveformSignalRendererNode(); + return addWaveformSignalRenderer(); case ::WaveformWidgetType::RGB: - return addWaveformSignalRendererNode(positionSource, options); + return addWaveformSignalRenderer(positionSource, options); case ::WaveformWidgetType::HSV: - return addWaveformSignalRendererNode(); + return addWaveformSignalRenderer(); case ::WaveformWidgetType::Filtered: - return addWaveformSignalRendererNode(false); + return addWaveformSignalRenderer(false); case ::WaveformWidgetType::Stacked: - return addWaveformSignalRendererNode( + return addWaveformSignalRenderer( true); // true for RGB Stacked default: break; diff --git a/src/waveform/widgets/allshader/waveformwidget.h b/src/waveform/widgets/allshader/waveformwidget.h index bf0b3a18267..88a871f1fe7 100644 --- a/src/waveform/widgets/allshader/waveformwidget.h +++ b/src/waveform/widgets/allshader/waveformwidget.h @@ -54,15 +54,12 @@ class allshader::WaveformWidget final : public ::WGLWidget, } template - inline std::unique_ptr addWaveformSignalRendererNode(Args&&... args) { + inline std::unique_ptr addWaveformSignalRenderer(Args&&... args) { auto pRenderer = addRenderer(std::forward(args)...); - if (!m_pWaveformRendererSignal) { - m_pWaveformRendererSignal = pRenderer; - } return std::unique_ptr(pRenderer); } - std::unique_ptr addWaveformSignalRendererNode( + std::unique_ptr addWaveformSignalRenderer( WaveformWidgetType::Type type, WaveformRendererSignalBase::Options options, ::WaveformRendererAbstract::PositionSource positionSource); From 0084dcfa403ba5e59f6a5943162c315c8aaaddde Mon Sep 17 00:00:00 2001 From: m0dB Date: Thu, 26 Dec 2024 05:54:35 +0100 Subject: [PATCH 17/21] comment --- src/waveform/widgets/allshader/waveformwidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/waveform/widgets/allshader/waveformwidget.cpp b/src/waveform/widgets/allshader/waveformwidget.cpp index f8b88ed927a..8c54b9f861a 100644 --- a/src/waveform/widgets/allshader/waveformwidget.cpp +++ b/src/waveform/widgets/allshader/waveformwidget.cpp @@ -95,6 +95,7 @@ WaveformWidget::WaveformWidget(QWidget* parent, WaveformWidget::~WaveformWidget() { makeCurrentIfNeeded(); m_rendererStack.clear(); + // destruction of nodes needs to happen within the opengl context m_pEngine.reset(); doneCurrent(); } From d7c0af56d9e030462f869dd24be3cc8dcf84004c Mon Sep 17 00:00:00 2001 From: m0dB Date: Thu, 26 Dec 2024 06:00:52 +0100 Subject: [PATCH 18/21] comment --- src/waveform/widgets/allshader/waveformwidget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/waveform/widgets/allshader/waveformwidget.cpp b/src/waveform/widgets/allshader/waveformwidget.cpp index 8c54b9f861a..dd3727102f8 100644 --- a/src/waveform/widgets/allshader/waveformwidget.cpp +++ b/src/waveform/widgets/allshader/waveformwidget.cpp @@ -163,7 +163,9 @@ void WaveformWidget::initializeGL() { } void WaveformWidget::resizeRenderer(int, int, float) { - // defer to resizeGL + // This is called when the widget is resized, but as this is a WGLWidget, we + // also get the resizeGL call and use that instead, as it has the opengl + // context set. } void WaveformWidget::resizeGL(int w, int h) { From b6aa301f3616fe4f07dfd050aff4a2a3cbfd57b6 Mon Sep 17 00:00:00 2001 From: m0dB Date: Sat, 18 Jan 2025 21:05:07 +0100 Subject: [PATCH 19/21] fix post rebase --- src/waveform/renderers/allshader/waveformrendermark.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/waveform/renderers/allshader/waveformrendermark.cpp b/src/waveform/renderers/allshader/waveformrendermark.cpp index de797d41d05..2f85b24149c 100644 --- a/src/waveform/renderers/allshader/waveformrendermark.cpp +++ b/src/waveform/renderers/allshader/waveformrendermark.cpp @@ -394,11 +394,8 @@ void allshader::WaveformRenderMark::updatePlayPosMarkTexture() { const float devicePixelRatio = m_waveformRenderer->getDevicePixelRatio(); const float lineX = 5.5f; - imgwidth = 11.f; - imgheight = height; - - const QSize size{static_cast(std::lround(imgwidth * devicePixelRatio)), - static_cast(std::lround(imgheight * devicePixelRatio))}; + const QSize size{static_cast(std::lround(imgWidth * devicePixelRatio)), + static_cast(std::lround(imgHeight * devicePixelRatio))}; if (size.width() <= 0 || size.height() <= 0) { return; From 2635bc214f5dbacbce670023bd35715335a4e82e Mon Sep 17 00:00:00 2001 From: m0dB Date: Sat, 18 Jan 2025 21:18:40 +0100 Subject: [PATCH 20/21] remove needless convert and asNode --- .../allshader/waveformrendererfiltered.h | 4 ---- .../renderers/allshader/waveformrendererhsv.h | 4 ---- .../renderers/allshader/waveformrendererrgb.h | 4 ---- .../allshader/waveformrenderersignalbase.h | 2 -- .../allshader/waveformrenderersimple.h | 4 ---- .../renderers/allshader/waveformrendererstem.h | 4 ---- .../allshader/waveformrenderertextured.h | 4 ---- .../widgets/allshader/waveformwidget.cpp | 17 ++++++----------- 8 files changed, 6 insertions(+), 37 deletions(-) diff --git a/src/waveform/renderers/allshader/waveformrendererfiltered.h b/src/waveform/renderers/allshader/waveformrendererfiltered.h index 273e58585d3..43441adafa5 100644 --- a/src/waveform/renderers/allshader/waveformrendererfiltered.h +++ b/src/waveform/renderers/allshader/waveformrendererfiltered.h @@ -22,10 +22,6 @@ class allshader::WaveformRendererFiltered final void initializeGL() override; void paintGL() override; - rendergraph::BaseNode* asNode() override { - return this; - } - private: const bool m_bRgbStacked; mixxx::UnicolorShader m_shader; diff --git a/src/waveform/renderers/allshader/waveformrendererhsv.h b/src/waveform/renderers/allshader/waveformrendererhsv.h index afed72306d3..a6fdbe95f51 100644 --- a/src/waveform/renderers/allshader/waveformrendererhsv.h +++ b/src/waveform/renderers/allshader/waveformrendererhsv.h @@ -23,10 +23,6 @@ class allshader::WaveformRendererHSV final void initializeGL() override; void paintGL() override; - rendergraph::BaseNode* asNode() override { - return this; - } - private: mixxx::RGBShader m_shader; VertexData m_vertices; diff --git a/src/waveform/renderers/allshader/waveformrendererrgb.h b/src/waveform/renderers/allshader/waveformrendererrgb.h index ec4496c4bd2..10f2262a751 100644 --- a/src/waveform/renderers/allshader/waveformrendererrgb.h +++ b/src/waveform/renderers/allshader/waveformrendererrgb.h @@ -30,10 +30,6 @@ class allshader::WaveformRendererRGB final return true; } - rendergraph::BaseNode* asNode() override { - return this; - } - private: mixxx::RGBShader m_shader; VertexData m_vertices; diff --git a/src/waveform/renderers/allshader/waveformrenderersignalbase.h b/src/waveform/renderers/allshader/waveformrenderersignalbase.h index b9cf0ce93a1..91dbbe8046c 100644 --- a/src/waveform/renderers/allshader/waveformrenderersignalbase.h +++ b/src/waveform/renderers/allshader/waveformrenderersignalbase.h @@ -33,7 +33,5 @@ class allshader::WaveformRendererSignalBase : public ::WaveformRendererSignalBas return false; } - virtual rendergraph::BaseNode* asNode() = 0; - DISALLOW_COPY_AND_ASSIGN(WaveformRendererSignalBase); }; diff --git a/src/waveform/renderers/allshader/waveformrenderersimple.h b/src/waveform/renderers/allshader/waveformrenderersimple.h index 1654ff7b2de..ba79752539c 100644 --- a/src/waveform/renderers/allshader/waveformrenderersimple.h +++ b/src/waveform/renderers/allshader/waveformrenderersimple.h @@ -22,10 +22,6 @@ class allshader::WaveformRendererSimple final void initializeGL() override; void paintGL() override; - rendergraph::BaseNode* asNode() override { - return this; - } - private: mixxx::UnicolorShader m_shader; VertexData m_vertices[2]; diff --git a/src/waveform/renderers/allshader/waveformrendererstem.h b/src/waveform/renderers/allshader/waveformrendererstem.h index 215c4e367db..99728194574 100644 --- a/src/waveform/renderers/allshader/waveformrendererstem.h +++ b/src/waveform/renderers/allshader/waveformrendererstem.h @@ -30,10 +30,6 @@ class allshader::WaveformRendererStem final void initializeGL() override; void paintGL() override; - rendergraph::BaseNode* asNode() override { - return this; - } - private: mixxx::RGBAShader m_shader; mixxx::TextureShader m_textureShader; diff --git a/src/waveform/renderers/allshader/waveformrenderertextured.h b/src/waveform/renderers/allshader/waveformrenderertextured.h index c2477970adc..ccd82ae5a67 100644 --- a/src/waveform/renderers/allshader/waveformrenderertextured.h +++ b/src/waveform/renderers/allshader/waveformrenderertextured.h @@ -42,10 +42,6 @@ class allshader::WaveformRendererTextured final : public QObject, void onSetTrack() override; - rendergraph::BaseNode* asNode() override { - return this; - } - public slots: void slotWaveformUpdated(); diff --git a/src/waveform/widgets/allshader/waveformwidget.cpp b/src/waveform/widgets/allshader/waveformwidget.cpp index dd3727102f8..035863716f3 100644 --- a/src/waveform/widgets/allshader/waveformwidget.cpp +++ b/src/waveform/widgets/allshader/waveformwidget.cpp @@ -21,11 +21,6 @@ namespace allshader { -std::unique_ptr convert( - std::unique_ptr&& pRenderer) { - return std::unique_ptr(pRenderer.release()->asNode()); -} - WaveformWidget::WaveformWidget(QWidget* parent, WaveformWidgetType::Type type, const QString& group, @@ -52,9 +47,9 @@ WaveformWidget::WaveformWidget(QWidget* parent, type, options, ::WaveformRendererAbstract::Play); m_pWaveformRendererSignal = pWaveformRendererSignal.get(); if (pWaveformRendererSignal) { - // convert std::unique_ptr - // to std::unique_ptr - pOpacityNode->appendChildNode(convert(std::move(pWaveformRendererSignal))); + auto pNode = dynamic_cast(pWaveformRendererSignal.release()); + DEBUG_ASSERT(pNode); + pOpacityNode->appendChildNode(std::unique_ptr(pNode)); } pOpacityNode->appendChildNode(addRendererNode()); m_pWaveformRenderMark = pOpacityNode->appendChildNode(addRendererNode()); @@ -74,9 +69,9 @@ WaveformWidget::WaveformWidget(QWidget* parent, #endif std::unique_ptr pSlipNode = addWaveformSignalRenderer( type, options, ::WaveformRendererAbstract::Slip); - // convert std::unique_ptr - // to std::unique_ptr - pOpacityNode->appendChildNode(convert(std::move(pSlipNode))); + auto pNode = dynamic_cast(pSlipNode.release()); + DEBUG_ASSERT(pNode); + pOpacityNode->appendChildNode(std::unique_ptr(pNode)); pOpacityNode->appendChildNode( addRendererNode( ::WaveformRendererAbstract::Slip)); From 84f8966f79389d0f87573f20be23b7bd4f34d9fa Mon Sep 17 00:00:00 2001 From: m0dB Date: Sat, 18 Jan 2025 23:07:28 +0100 Subject: [PATCH 21/21] only build shaders for added target --- src/rendergraph/shaders/CMakeLists.txt | 72 ++++++++++++++------------ 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/src/rendergraph/shaders/CMakeLists.txt b/src/rendergraph/shaders/CMakeLists.txt index 42478758f46..3db40bb2c30 100644 --- a/src/rendergraph/shaders/CMakeLists.txt +++ b/src/rendergraph/shaders/CMakeLists.txt @@ -14,40 +14,44 @@ set( unicolor.vert ) -qt6_add_shaders(rendergraph_sg "shaders-qsb" - BATCHABLE - PRECOMPILE - OPTIMIZED - PREFIX - /shaders/rendergraph - FILES - ${shaders} -) - -# USE_QSHADER_FOR_GL is set in src/rendergraph/CMakeLists.txt when Qt >= 6.6 -if(USE_QSHADER_FOR_GL) - # Add the .qsb shader bundles; rendergraph::MaterialShader will use - # QShader to extract the GLSL shader from the bundle. - message(STATUS "Adding qsb shaders to rendergraph_gl") - qt6_add_shaders(rendergraph_gl "shaders-qsb" - BATCHABLE - PRECOMPILE - OPTIMIZED - PREFIX - /shaders/rendergraph - FILES - ${shaders} +if(TARGET rendergraph_sg) + qt6_add_shaders(rendergraph_sg "shaders-qsb" + BATCHABLE + PRECOMPILE + OPTIMIZED + PREFIX + /shaders/rendergraph + FILES + ${shaders} ) -else() - # Use GLSL shaders extracted from the .qsb shader bundles using - # generate_shaders_gl.pl - message(STATUS "Adding gl shaders to rendergraph_gl") - include(generated_shaders_gl.cmake) +endif() - qt_add_resources(rendergraph_gl "shaders-gl" - PREFIX - /shaders/rendergraph - FILES - ${generated_shaders_gl} - ) +if(TARGET rendergraph_gl) + # USE_QSHADER_FOR_GL is set in src/rendergraph/CMakeLists.txt when Qt >= 6.6 + if(USE_QSHADER_FOR_GL) + # Add the .qsb shader bundles; rendergraph::MaterialShader will use + # QShader to extract the GLSL shader from the bundle. + message(STATUS "Adding qsb shaders to rendergraph_gl") + qt6_add_shaders(rendergraph_gl "shaders-qsb" + BATCHABLE + PRECOMPILE + OPTIMIZED + PREFIX + /shaders/rendergraph + FILES + ${shaders} + ) + else() + # Use GLSL shaders extracted from the .qsb shader bundles using + # generate_shaders_gl.pl + message(STATUS "Adding gl shaders to rendergraph_gl") + include(generated_shaders_gl.cmake) + + qt_add_resources(rendergraph_gl "shaders-gl" + PREFIX + /shaders/rendergraph + FILES + ${generated_shaders_gl} + ) + endif() endif()