From 67ce4058b12e8ab219055ce21b6184f9fd7c785e Mon Sep 17 00:00:00 2001 From: m0dB Date: Mon, 9 Dec 2024 17:51:11 +0100 Subject: [PATCH 1/5] use geometrynode for waveformrendererpreroll --- .../allshader/waveformrendererpreroll.cpp | 148 ++++++++---------- .../allshader/waveformrendererpreroll.h | 28 ++-- .../renderers/waveformwidgetrenderer.cpp | 18 +-- .../renderers/waveformwidgetrenderer.h | 21 ++- 4 files changed, 104 insertions(+), 111 deletions(-) diff --git a/src/waveform/renderers/allshader/waveformrendererpreroll.cpp b/src/waveform/renderers/allshader/waveformrendererpreroll.cpp index 89948347d87..47caa6f3300 100644 --- a/src/waveform/renderers/allshader/waveformrendererpreroll.cpp +++ b/src/waveform/renderers/allshader/waveformrendererpreroll.cpp @@ -1,12 +1,13 @@ #include "waveform/renderers/allshader/waveformrendererpreroll.h" #include -#include #include #include +#include "rendergraph/geometry.h" +#include "rendergraph/material/patternmaterial.h" +#include "rendergraph/vertexupdaters/texturedvertexupdater.h" #include "skin/legacy/skincontext.h" -#include "waveform/renderers/allshader/matrixforwidgetgeometry.h" #include "waveform/renderers/waveformwidgetrenderer.h" #include "widget/wskincolor.h" @@ -20,7 +21,7 @@ QImage drawPrerollImage(float markerLength, const float imageW = static_cast(imagePixelW) / devicePixelRatio; const float imageH = static_cast(imagePixelH) / devicePixelRatio; - QImage image(imagePixelW, imagePixelH, QImage::Format_ARGB32_Premultiplied); + QImage image(imagePixelW, imagePixelH, QImage::Format_RGBA8888_Premultiplied); image.setDevicePixelRatio(devicePixelRatio); const float penWidth = 1.5f; @@ -47,7 +48,7 @@ QImage drawPrerollImage(float markerLength, path.lineTo(p0); path.closeSubpath(); QColor fillColor = color; - fillColor.setAlphaF(0.5f); + fillColor.setAlphaF(0.25f); painter.fillPath(path, QBrush(fillColor)); painter.drawPath(path); @@ -57,31 +58,52 @@ QImage drawPrerollImage(float markerLength, } } // anonymous namespace +using namespace rendergraph; + namespace allshader { WaveformRendererPreroll::WaveformRendererPreroll( WaveformWidgetRenderer* waveformWidget, ::WaveformRendererAbstract::PositionSource type) - : WaveformRenderer(waveformWidget), + : ::WaveformRendererAbstract(waveformWidget), m_isSlipRenderer(type == ::WaveformRendererAbstract::Slip) { + setGeometry(std::make_unique(PatternMaterial::attributes(), 0)); + setMaterial(std::make_unique()); + setUsePreprocess(true); + geometry().setDrawingMode(Geometry::DrawingMode::Triangles); } WaveformRendererPreroll::~WaveformRendererPreroll() = default; void WaveformRendererPreroll::setup( - const QDomNode& node, const SkinContext& context) { - m_color = QColor(context.selectString(node, "SignalColor")); + const QDomNode& node, const SkinContext& skinContext) { + m_color = QColor(skinContext.selectString(node, "SignalColor")); m_color = WSkinColor::getCorrectColor(m_color); } -void WaveformRendererPreroll::initializeGL() { - m_shader.init(); +void WaveformRendererPreroll::draw(QPainter* painter, QPaintEvent* event) { + Q_UNUSED(painter); + Q_UNUSED(event); + DEBUG_ASSERT(false); +} + +void WaveformRendererPreroll::preprocess() { + if (!preprocessInner()) { + if (geometry().vertexCount() != 0) { + geometry().allocate(0); + markDirtyGeometry(); + } + } else { + markDirtyMaterial(); + markDirtyGeometry(); + } } -void WaveformRendererPreroll::paintGL() { - const TrackPointer track = m_waveformRenderer->getTrackInfo(); - if (!track || (m_isSlipRenderer && !m_waveformRenderer->isSlipActive())) { - return; +bool WaveformRendererPreroll::preprocessInner() { + const TrackPointer trackInfo = m_waveformRenderer->getTrackInfo(); + + if (!trackInfo || (m_isSlipRenderer && !m_waveformRenderer->isSlipActive())) { + return false; } auto positionType = m_isSlipRenderer ? ::WaveformRendererAbstract::Slip @@ -95,11 +117,15 @@ void WaveformRendererPreroll::paintGL() { // to indicate the respective zones. const bool preRollVisible = firstDisplayedPosition < 0; const bool postRollVisible = lastDisplayedPosition > 1; + const int numVerticesPerRectangle = 6; - if (!(preRollVisible || postRollVisible)) { - return; + if (!preRollVisible && !postRollVisible) { + return false; } + const int reserved = (preRollVisible ? numVerticesPerRectangle : 0) + + (postRollVisible ? numVerticesPerRectangle : 0); + const double playMarkerPosition = m_waveformRenderer->getPlayMarkerPosition(); const double vSamplesPerPixel = m_waveformRenderer->getVisualSamplePerPixel(); const double numberOfVSamples = m_waveformRenderer->getLength() * vSamplesPerPixel; @@ -125,36 +151,20 @@ void WaveformRendererPreroll::paintGL() { // has changed size last time. m_markerLength = markerLength; m_markerBreadth = markerBreadth; - m_texture.setData(drawPrerollImage(m_markerLength, - m_markerBreadth, - m_waveformRenderer->getDevicePixelRatio(), - m_color)); + dynamic_cast(material()) + .setTexture(std::make_unique(m_waveformRenderer->getContext(), + drawPrerollImage(m_markerLength, + m_markerBreadth, + m_waveformRenderer->getDevicePixelRatio(), + m_color))); } - if (!m_texture.isStorageAllocated()) { - return; - } - - const int matrixLocation = m_shader.matrixLocation(); - const int textureLocation = m_shader.textureLocation(); - const int positionLocation = m_shader.positionLocation(); - const int texcoordLocation = m_shader.texcoordLocation(); - - // Set up the shader - m_shader.bind(); - - m_shader.enableAttributeArray(positionLocation); - m_shader.enableAttributeArray(texcoordLocation); - - const QMatrix4x4 matrix = matrixForWidgetGeometry(m_waveformRenderer, false); - - m_shader.setUniformValue(matrixLocation, matrix); - m_shader.setUniformValue(textureLocation, 0); - - m_texture.bind(); + geometry().allocate(reserved); const float end = m_waveformRenderer->getLength(); + TexturedVertexUpdater vertexUpdater{geometry().vertexDataAs()}; + if (preRollVisible) { // VSample position of the right-most triangle's tip const double triangleTipVSamplePosition = @@ -168,11 +178,14 @@ void WaveformRendererPreroll::paintGL() { x -= std::ceil((x - limit) / markerLength) * markerLength; } - drawPattern(x, - halfBreadth - halfMarkerBreadth, - 0.f, - m_isSlipRenderer ? halfBreadth : halfBreadth + halfMarkerBreadth, - x / markerLength); + const float repetitions = x / markerLength; + + vertexUpdater.addRectangle({x, halfBreadth - halfMarkerBreadth}, + {0, + m_isSlipRenderer ? halfBreadth + : halfBreadth + halfMarkerBreadth}, + {0.f, 0.f}, + {repetitions, m_isSlipRenderer ? 0.5f : 1.f}); } if (postRollVisible) { @@ -189,44 +202,19 @@ void WaveformRendererPreroll::paintGL() { x += std::ceil((limit - x) / markerLength) * markerLength; } - drawPattern(x, - halfBreadth - halfMarkerBreadth, - end, - m_isSlipRenderer ? halfBreadth : halfBreadth + halfMarkerBreadth, - (end - x) / markerLength); - } + const float repetitions = (end - x) / markerLength; - m_texture.release(); + vertexUpdater.addRectangle({x, halfBreadth - halfMarkerBreadth}, + {end, + m_isSlipRenderer ? halfBreadth + : halfBreadth + halfMarkerBreadth}, + {0.f, 0.f}, + {repetitions, m_isSlipRenderer ? 0.5f : 1.f}); + } - m_shader.disableAttributeArray(positionLocation); - m_shader.disableAttributeArray(texcoordLocation); - m_shader.release(); -} + DEBUG_ASSERT(reserved == vertexUpdater.index()); -void WaveformRendererPreroll::drawPattern( - float x1, float y1, float x2, float y2, float repetitions) { - // Draw a large rectangle with a repeating pattern of the texture - const int repetitionsLocation = m_shader.repetitionsLocation(); - const int positionLocation = m_shader.positionLocation(); - const int texcoordLocation = m_shader.texcoordLocation(); - - const std::array positionArray = {x1, y1, x2, y1, x1, y2, x2, y2}; - const std::array texcoordArray = {0.f, - 0.f, - 1.f, - 0.f, - 0.f, - m_isSlipRenderer ? 0.5f : 1.f, - 1.f, - m_isSlipRenderer ? 0.5f : 1.f}; - m_shader.setUniformValue(repetitionsLocation, QVector2D(repetitions, 1.0)); - - m_shader.setAttributeArray( - positionLocation, GL_FLOAT, positionArray.data(), 2); - m_shader.setAttributeArray( - texcoordLocation, GL_FLOAT, texcoordArray.data(), 2); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + return true; } } // namespace allshader diff --git a/src/waveform/renderers/allshader/waveformrendererpreroll.h b/src/waveform/renderers/allshader/waveformrendererpreroll.h index 0fd2cc59942..eb28459ef96 100644 --- a/src/waveform/renderers/allshader/waveformrendererpreroll.h +++ b/src/waveform/renderers/allshader/waveformrendererpreroll.h @@ -1,27 +1,22 @@ #pragma once #include -#include #include -#include "rendergraph/openglnode.h" -#include "shaders/patternshader.h" +#include "rendergraph/geometrynode.h" #include "util/class.h" -#include "util/opengltexture2d.h" -#include "waveform/renderers/allshader/vertexdata.h" -#include "waveform/renderers/allshader/waveformrenderer.h" +#include "waveform/renderers/waveformrendererabstract.h" class QDomNode; class SkinContext; -class QOpenGLTexture; namespace allshader { class WaveformRendererPreroll; } class allshader::WaveformRendererPreroll final - : public allshader::WaveformRenderer, - public rendergraph::OpenGLNode { + : public ::WaveformRendererAbstract, + public rendergraph::GeometryNode { public: explicit WaveformRendererPreroll( WaveformWidgetRenderer* waveformWidget, @@ -29,20 +24,21 @@ class allshader::WaveformRendererPreroll final ::WaveformRendererAbstract::Play); ~WaveformRendererPreroll() override; + // Pure virtual from WaveformRendererAbstract, not used + void draw(QPainter* painter, QPaintEvent* event) override final; + void setup(const QDomNode& node, const SkinContext& skinContext) override; - void paintGL() override; - void initializeGL() override; - private: - void drawPattern(float x1, float y1, float x2, float y2, float repetitions); + // Virtual for rendergraph::Node + void preprocess() override; - mixxx::PatternShader m_shader; + private: QColor m_color; float m_markerBreadth{}; float m_markerLength{}; - OpenGLTexture2D m_texture; - bool m_isSlipRenderer; + bool preprocessInner(); + DISALLOW_COPY_AND_ASSIGN(WaveformRendererPreroll); }; diff --git a/src/waveform/renderers/waveformwidgetrenderer.cpp b/src/waveform/renderers/waveformwidgetrenderer.cpp index 8059711b8a2..1fb0ad27834 100644 --- a/src/waveform/renderers/waveformwidgetrenderer.cpp +++ b/src/waveform/renderers/waveformwidgetrenderer.cpp @@ -39,13 +39,11 @@ WaveformWidgetRenderer::WaveformWidgetRenderer(const QString& group) // Really create some to manage those; m_visualPlayPosition(nullptr), m_totalVSamples(0), - m_pRateRatioCO(nullptr), - m_pGainControlObject(nullptr), m_gain(1.0), - m_pTrackSamplesControlObject(nullptr), - m_trackSamples(0), + m_trackSamples(0.0), m_scaleFactor(1.0), m_playMarkerPosition(s_defaultPlayMarkerPosition), + m_pContext(nullptr), m_passthroughEnabled(false) { //qDebug() << "WaveformWidgetRenderer"; for (int type = ::WaveformRendererAbstract::Play; @@ -79,10 +77,6 @@ WaveformWidgetRenderer::~WaveformWidgetRenderer() { delete m_rendererStack[i]; } - delete m_pRateRatioCO; - delete m_pGainControlObject; - delete m_pTrackSamplesControlObject; - #ifdef WAVEFORMWIDGETRENDERER_DEBUG delete m_timer; #endif @@ -93,11 +87,11 @@ bool WaveformWidgetRenderer::init() { m_visualPlayPosition = VisualPlayPosition::getVisualPlayPosition(m_group); - m_pRateRatioCO = new ControlProxy( + m_pRateRatioCO = std::make_unique( m_group, "rate_ratio"); - m_pGainControlObject = new ControlProxy( + m_pGainControlObject = std::make_unique( m_group, "total_gain"); - m_pTrackSamplesControlObject = new ControlProxy( + m_pTrackSamplesControlObject = std::make_unique( m_group, "track_samples"); for (int i = 0; i < m_rendererStack.size(); ++i) { @@ -428,7 +422,7 @@ void WaveformWidgetRenderer::selectStem(mixxx::StemChannelSelection stemMask) { void WaveformWidgetRenderer::setTrack(TrackPointer track) { m_pTrack = track; //used to postpone first display until track sample is actually available - m_trackSamples = -1; + m_trackSamples = -1.0; for (int i = 0; i < m_rendererStack.size(); ++i) { m_rendererStack[i]->onSetTrack(); diff --git a/src/waveform/renderers/waveformwidgetrenderer.h b/src/waveform/renderers/waveformwidgetrenderer.h index 33a948bca65..42d02f49e0c 100644 --- a/src/waveform/renderers/waveformwidgetrenderer.h +++ b/src/waveform/renderers/waveformwidgetrenderer.h @@ -15,6 +15,10 @@ class VSyncThread; class QPainter; class WaveformRendererAbstract; +namespace rendergraph { +class Context; +} + class WaveformWidgetRenderer { public: static const double s_waveformMinZoom; @@ -201,6 +205,14 @@ class WaveformWidgetRenderer { return m_trackSamples <= 0.0 || m_pos[::WaveformRendererAbstract::Play] == -1; } + void setContext(rendergraph::Context* pContext) { + m_pContext = pContext; + } + + rendergraph::Context* getContext() const { + return m_pContext; + } + protected: const QString m_group; TrackPointer m_pTrack; @@ -231,14 +243,17 @@ class WaveformWidgetRenderer { QSharedPointer m_visualPlayPosition; int m_posVSample[2]; int m_totalVSamples; - ControlProxy* m_pRateRatioCO; - ControlProxy* m_pGainControlObject; + std::unique_ptr m_pRateRatioCO; + std::unique_ptr m_pGainControlObject; + std::unique_ptr m_pTrackSamplesControlObject; double m_gain; - ControlProxy* m_pTrackSamplesControlObject; double m_trackSamples; double m_scaleFactor; double m_playMarkerPosition; // 0.0 - left, 0.5 - center, 1.0 - right + // used by allshader waveformrenderers when used with rendergraph nodes + rendergraph::Context* m_pContext; + #ifdef WAVEFORMWIDGETRENDERER_DEBUG PerformanceTimer* m_timer; int m_lastFrameTime; From 6004cc809e7a03cf2c43feb426ed7b4d849040b7 Mon Sep 17 00:00:00 2001 From: m0dB <79429057+m0dB@users.noreply.github.com> Date: Tue, 21 Jan 2025 00:44:42 +0100 Subject: [PATCH 2/5] Update src/waveform/renderers/allshader/waveformrendererpreroll.cpp qstringliteral Co-authored-by: Antoine Colombier <7086688+acolombier@users.noreply.github.com> --- src/waveform/renderers/allshader/waveformrendererpreroll.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/waveform/renderers/allshader/waveformrendererpreroll.cpp b/src/waveform/renderers/allshader/waveformrendererpreroll.cpp index 47caa6f3300..3b7636c5864 100644 --- a/src/waveform/renderers/allshader/waveformrendererpreroll.cpp +++ b/src/waveform/renderers/allshader/waveformrendererpreroll.cpp @@ -77,7 +77,7 @@ WaveformRendererPreroll::~WaveformRendererPreroll() = default; void WaveformRendererPreroll::setup( const QDomNode& node, const SkinContext& skinContext) { - m_color = QColor(skinContext.selectString(node, "SignalColor")); + m_color = QColor(skinContext.selectString(node, QStringLiteral("SignalColor"))); m_color = WSkinColor::getCorrectColor(m_color); } From 863f665ef2f8cc407c283d5c1e79e1201ad92f26 Mon Sep 17 00:00:00 2001 From: m0dB <79429057+m0dB@users.noreply.github.com> Date: Tue, 21 Jan 2025 00:44:58 +0100 Subject: [PATCH 3/5] Update src/waveform/renderers/waveformwidgetrenderer.cpp qstringliteral Co-authored-by: Antoine Colombier <7086688+acolombier@users.noreply.github.com> --- src/waveform/renderers/waveformwidgetrenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/waveform/renderers/waveformwidgetrenderer.cpp b/src/waveform/renderers/waveformwidgetrenderer.cpp index 1fb0ad27834..d7a74321dff 100644 --- a/src/waveform/renderers/waveformwidgetrenderer.cpp +++ b/src/waveform/renderers/waveformwidgetrenderer.cpp @@ -88,7 +88,7 @@ bool WaveformWidgetRenderer::init() { m_visualPlayPosition = VisualPlayPosition::getVisualPlayPosition(m_group); m_pRateRatioCO = std::make_unique( - m_group, "rate_ratio"); + m_group, QStringLiteral("rate_ratio")); m_pGainControlObject = std::make_unique( m_group, "total_gain"); m_pTrackSamplesControlObject = std::make_unique( From 3e4dd30c5cf24991d34fd6d13ab0180ea315c544 Mon Sep 17 00:00:00 2001 From: m0dB <79429057+m0dB@users.noreply.github.com> Date: Tue, 21 Jan 2025 00:45:13 +0100 Subject: [PATCH 4/5] Update src/waveform/renderers/waveformwidgetrenderer.cpp qstringliteral Co-authored-by: Antoine Colombier <7086688+acolombier@users.noreply.github.com> --- src/waveform/renderers/waveformwidgetrenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/waveform/renderers/waveformwidgetrenderer.cpp b/src/waveform/renderers/waveformwidgetrenderer.cpp index d7a74321dff..4cd244df849 100644 --- a/src/waveform/renderers/waveformwidgetrenderer.cpp +++ b/src/waveform/renderers/waveformwidgetrenderer.cpp @@ -90,7 +90,7 @@ bool WaveformWidgetRenderer::init() { m_pRateRatioCO = std::make_unique( m_group, QStringLiteral("rate_ratio")); m_pGainControlObject = std::make_unique( - m_group, "total_gain"); + m_group, QStringLiteral("total_gain")); m_pTrackSamplesControlObject = std::make_unique( m_group, "track_samples"); From 6fb20675f964792728c1e8c017fad6ebdab88a44 Mon Sep 17 00:00:00 2001 From: m0dB <79429057+m0dB@users.noreply.github.com> Date: Tue, 21 Jan 2025 00:45:35 +0100 Subject: [PATCH 5/5] Update src/waveform/renderers/waveformwidgetrenderer.cpp qstringliteral Co-authored-by: Antoine Colombier <7086688+acolombier@users.noreply.github.com> --- src/waveform/renderers/waveformwidgetrenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/waveform/renderers/waveformwidgetrenderer.cpp b/src/waveform/renderers/waveformwidgetrenderer.cpp index 4cd244df849..7e50cf35741 100644 --- a/src/waveform/renderers/waveformwidgetrenderer.cpp +++ b/src/waveform/renderers/waveformwidgetrenderer.cpp @@ -92,7 +92,7 @@ bool WaveformWidgetRenderer::init() { m_pGainControlObject = std::make_unique( m_group, QStringLiteral("total_gain")); m_pTrackSamplesControlObject = std::make_unique( - m_group, "track_samples"); + m_group, QStringLiteral("track_samples")); for (int i = 0; i < m_rendererStack.size(); ++i) { if (!m_rendererStack[i]->init()) {