diff --git a/src/qml/qmlwaveformdisplay.cpp b/src/qml/qmlwaveformdisplay.cpp index ccd70a6ed0a8..4b15df4ac746 100644 --- a/src/qml/qmlwaveformdisplay.cpp +++ b/src/qml/qmlwaveformdisplay.cpp @@ -38,7 +38,7 @@ QmlWaveformDisplay::QmlWaveformDisplay(QQuickItem* parent) } QmlWaveformDisplay::~QmlWaveformDisplay() { - // The stack contains references to Renderer that are owned and cleared by a TreeNode + // The stack contains references to Renderer that are owned and cleared by a BaseNode m_rendererStack.clear(); } @@ -107,7 +107,7 @@ QSGNode* QmlWaveformDisplay::updatePaintNode(QSGNode* node, UpdatePaintNodeData* auto renderer = pQmlRenderer->create(this); addRenderer(renderer.renderer); - m_pTopNode->appendChildNode(std::unique_ptr(renderer.node)); + m_pTopNode->appendChildNode(std::unique_ptr(renderer.node)); auto *pWaveformRenderMark = dynamic_cast( renderer.renderer); @@ -122,7 +122,7 @@ QSGNode* QmlWaveformDisplay::updatePaintNode(QSGNode* node, UpdatePaintNodeData* } } - bgNode->appendChildNode(m_pTopNode->backendNode()); + bgNode->appendChildNode(m_pTopNode); init(); } diff --git a/src/qml/qmlwaveformrenderer.h b/src/qml/qmlwaveformrenderer.h index 5af9860fd0e9..751ff10da11d 100644 --- a/src/qml/qmlwaveformrenderer.h +++ b/src/qml/qmlwaveformrenderer.h @@ -1,17 +1,14 @@ #pragma once -#include #include +#include +#include "rendergraph/node.h" #include "waveform/renderers/waveformrendererabstract.h" #include "waveform/renderers/waveformwidgetrenderer.h" class WaveformWidgetRenderer; -namespace rendergraph { -class TreeNode; -} // namespace rendergraph - namespace allshaders { class WaveformRendererEndOfTrack; class WaveformRendererPreroll; @@ -28,7 +25,7 @@ class QmlWaveformRendererFactory : public QObject { public: struct Renderer { ::WaveformRendererAbstract* renderer{nullptr}; - rendergraph::TreeNode* node{nullptr}; + rendergraph::BaseNode* node{nullptr}; }; virtual Renderer create(WaveformWidgetRenderer* waveformWidget) const = 0; diff --git a/src/rendergraph/common/node.cpp b/src/rendergraph/common/node.cpp deleted file mode 100644 index 24f5d29d3eeb..000000000000 --- a/src/rendergraph/common/node.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "rendergraph/node.h" - -using namespace rendergraph; - -Node::Node() - : TreeNode(this) { -} diff --git a/src/rendergraph/common/opacitynode.cpp b/src/rendergraph/common/opacitynode.cpp deleted file mode 100644 index caa6526626f6..000000000000 --- a/src/rendergraph/common/opacitynode.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "rendergraph/opacitynode.h" - -using namespace rendergraph; - -OpacityNode::OpacityNode() - : TreeNode(this) { -} diff --git a/src/rendergraph/common/rendergraph/geometrynode.h b/src/rendergraph/common/rendergraph/geometrynode.h index 41292de4c7d1..fbcacba36471 100644 --- a/src/rendergraph/common/rendergraph/geometrynode.h +++ b/src/rendergraph/common/rendergraph/geometrynode.h @@ -3,21 +3,16 @@ #include "backend/basegeometrynode.h" #include "rendergraph/geometry.h" #include "rendergraph/material.h" -#include "rendergraph/treenode.h" +#include "rendergraph/nodeinterface.h" namespace rendergraph { class GeometryNode; } // namespace rendergraph -class rendergraph::GeometryNode : public rendergraph::BaseGeometryNode, - public rendergraph::TreeNode { +class rendergraph::GeometryNode : public rendergraph::NodeInterface { public: - using rendergraph::TreeNode::appendChildNode; - using rendergraph::TreeNode::firstChild; - using rendergraph::TreeNode::lastChild; - using rendergraph::TreeNode::nextSibling; - using rendergraph::TreeNode::removeChildNode; GeometryNode(); + virtual ~GeometryNode() = default; template void initForRectangles(int numRectangles) { @@ -28,6 +23,7 @@ class rendergraph::GeometryNode : public rendergraph::BaseGeometryNode, geometry().setDrawingMode(Geometry::DrawingMode::Triangles); } + void setUsePreprocess(bool value); void setMaterial(std::unique_ptr material); void setGeometry(std::unique_ptr geometry); diff --git a/src/rendergraph/common/rendergraph/node.h b/src/rendergraph/common/rendergraph/node.h index 657ef0d23427..3060648e846d 100644 --- a/src/rendergraph/common/rendergraph/node.h +++ b/src/rendergraph/common/rendergraph/node.h @@ -1,18 +1,11 @@ #pragma once #include "backend/basenode.h" -#include "rendergraph/treenode.h" +#include "rendergraph/nodeinterface.h" namespace rendergraph { class Node; } // namespace rendergraph -class rendergraph::Node : public rendergraph::BaseNode, public rendergraph::TreeNode { - public: - using rendergraph::TreeNode::appendChildNode; - using rendergraph::TreeNode::firstChild; - using rendergraph::TreeNode::lastChild; - using rendergraph::TreeNode::nextSibling; - using rendergraph::TreeNode::removeChildNode; - Node(); +class rendergraph::Node : public rendergraph::NodeInterface { }; diff --git a/src/rendergraph/common/rendergraph/nodeinterface.h b/src/rendergraph/common/rendergraph/nodeinterface.h new file mode 100644 index 000000000000..4b2d08f4d499 --- /dev/null +++ b/src/rendergraph/common/rendergraph/nodeinterface.h @@ -0,0 +1,19 @@ +#pragma once + +#include "backend/basenode.h" + +namespace rendergraph { + +template +class NodeInterface : public T_Node { + public: + void appendChildNode(std::unique_ptr&& pNode) { + T_Node::appendChildNode(pNode.release()); + } + std::unique_ptr detachChildNode(BaseNode* pNode) { + T_Node::removeChildNode(pNode); + return std::unique_ptr(pNode); + } +}; + +} // namespace rendergraph diff --git a/src/rendergraph/common/rendergraph/opacitynode.h b/src/rendergraph/common/rendergraph/opacitynode.h index dd537d6b4589..d69f0b1c42a6 100644 --- a/src/rendergraph/common/rendergraph/opacitynode.h +++ b/src/rendergraph/common/rendergraph/opacitynode.h @@ -1,19 +1,11 @@ #pragma once #include "backend/baseopacitynode.h" -#include "rendergraph/treenode.h" +#include "rendergraph/nodeinterface.h" namespace rendergraph { class OpacityNode; } // namespace rendergraph -class rendergraph::OpacityNode : public rendergraph::BaseOpacityNode, - public rendergraph::TreeNode { - public: - using rendergraph::TreeNode::appendChildNode; - using rendergraph::TreeNode::firstChild; - using rendergraph::TreeNode::lastChild; - using rendergraph::TreeNode::nextSibling; - using rendergraph::TreeNode::removeChildNode; - OpacityNode(); +class rendergraph::OpacityNode : public rendergraph::NodeInterface { }; diff --git a/src/rendergraph/common/rendergraph/treenode.h b/src/rendergraph/common/rendergraph/treenode.h deleted file mode 100644 index 46c32b6a2c53..000000000000 --- a/src/rendergraph/common/rendergraph/treenode.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include - -#include "backend/basenode.h" - -namespace rendergraph { -class Engine; // fwd decl to avoid circular dependency -class TreeNode; -} // namespace rendergraph - -class rendergraph::TreeNode { - public: - TreeNode(rendergraph::BaseNode* pBackendNode); - virtual ~TreeNode(); - - void appendChildNode(std::unique_ptr&& pChild); - - // remove all child nodes. returns the list of child nodes - // by returning the node in the list. the caller can keep - // the pointer, thus transferring ownership. otherwise the - // nodes will be destroyed - std::unique_ptr removeAllChildNodes(); - - // remove a single child node for the list of child nodes. - // the caller can keep the pointer, thus transferring ownership. - // otherwise the node will be destroyed - std::unique_ptr removeChildNode(TreeNode* pChild); - - TreeNode* parent() const { - return m_pParent; - } - TreeNode* firstChild() const { - return m_pFirstChild.get(); - } - TreeNode* lastChild() const { - return m_pLastChild; - } - TreeNode* nextSibling() const { - return m_pNextSibling.get(); - } - TreeNode* previousSibling() const { - return m_pPreviousSibling; - } - - void setUsePreprocess(bool value); - - rendergraph::BaseNode* backendNode() { - return m_pBackendNode; - } - - private: - void onAppendChildNode(TreeNode* pChild); - void onRemoveAllChildNodes(); - void onRemoveChildNode(TreeNode* pChild); - - rendergraph::BaseNode* m_pBackendNode; - TreeNode* m_pParent{}; - std::unique_ptr m_pFirstChild; - TreeNode* m_pLastChild{}; - std::unique_ptr m_pNextSibling; - TreeNode* m_pPreviousSibling{}; -}; diff --git a/src/rendergraph/common/treenode.cpp b/src/rendergraph/common/treenode.cpp deleted file mode 100644 index 63fe5667ffc7..000000000000 --- a/src/rendergraph/common/treenode.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "rendergraph/treenode.h" - -#include "backend/basenode.h" - -using namespace rendergraph; - -void TreeNode::appendChildNode(std::unique_ptr&& pChild) { - auto pChildRawPtr = pChild.get(); - if (m_pLastChild) { - pChild->m_pPreviousSibling = m_pLastChild; - m_pLastChild->m_pNextSibling = std::move(pChild); - } else { - m_pFirstChild = std::move(pChild); - } - m_pLastChild = pChildRawPtr; - m_pLastChild->m_pParent = this; - - onAppendChildNode(pChildRawPtr); -} - -std::unique_ptr TreeNode::removeAllChildNodes() { - onRemoveAllChildNodes(); - - m_pLastChild = nullptr; - TreeNode* pChild = m_pFirstChild.get(); - while (pChild) { - pChild->m_pParent = nullptr; - pChild = pChild->m_pNextSibling.get(); - } - return std::move(m_pFirstChild); -} - -std::unique_ptr TreeNode::removeChildNode(TreeNode* pChild) { - onRemoveChildNode(pChild); - - std::unique_ptr pRemoved; - if (pChild == m_pFirstChild.get()) { - pRemoved = std::move(m_pFirstChild); - m_pFirstChild = std::move(pChild->m_pNextSibling); - } else { - pRemoved = std::move(pChild->m_pPreviousSibling->m_pNextSibling); - pChild->m_pPreviousSibling->m_pNextSibling = std::move(pChild->m_pNextSibling); - pChild->m_pPreviousSibling = nullptr; - } - if (pChild == m_pLastChild) { - m_pLastChild = nullptr; - } - pChild->m_pParent = nullptr; - return pRemoved; -} diff --git a/src/rendergraph/examples/common/examplenode.cpp b/src/rendergraph/examples/common/examplenode.cpp index 62500521aaf3..452d4613b71a 100644 --- a/src/rendergraph/examples/common/examplenode.cpp +++ b/src/rendergraph/examples/common/examplenode.cpp @@ -16,8 +16,7 @@ using namespace rendergraph; ExampleNode::ExampleNode(rendergraph::Context* pContext) { { - TreeNode::appendChildNode(std::make_unique()); - auto pNode = static_cast(TreeNode::lastChild()); + auto pNode = std::make_unique(); pNode->initForRectangles(1); auto& material = dynamic_cast(pNode->material()); material.setTexture(std::make_unique( @@ -25,10 +24,10 @@ ExampleNode::ExampleNode(rendergraph::Context* pContext) { TexturedVertexUpdater vertexUpdater{ pNode->geometry().vertexDataAs()}; vertexUpdater.addRectangle({0, 0}, {100, 100}, {0.f, 0.f}, {1.f, 1.f}); + appendChildNode(std::move(pNode)); } { - TreeNode::appendChildNode(std::make_unique()); - auto pNode = static_cast(TreeNode::lastChild()); + auto pNode = std::make_unique(); pNode->initForRectangles(2); pNode->material().setUniform(1, QColor(255, 127, 0)); pNode->geometry().setDrawingMode(Geometry::DrawingMode::Triangles); @@ -37,10 +36,10 @@ ExampleNode::ExampleNode(rendergraph::Context* pContext) { .vertexDataAs()}; vertexUpdater.addRectangle({100, 100}, {160, 160}); vertexUpdater.addRectangle({200, 160}, {240, 190}); + appendChildNode(std::move(pNode)); } { - TreeNode::appendChildNode(std::make_unique()); - auto pNode = static_cast(TreeNode::lastChild()); + auto pNode = std::make_unique(); pNode->initForRectangles(2); pNode->geometry().setDrawingMode(Geometry::DrawingMode::Triangles); rendergraph::RGBVertexUpdater vertexUpdater{ @@ -48,5 +47,6 @@ ExampleNode::ExampleNode(rendergraph::Context* pContext) { vertexUpdater.addRectangle({300, 100}, {340, 140}, {1.f, 0.f, 0.5f}); vertexUpdater.addRectangleHGradient( {340, 100}, {440, 130}, {0.f, 1.f, 0.5f}, {0.5f, 0.f, 1.f}); + appendChildNode(std::move(pNode)); } } diff --git a/src/rendergraph/examples/gl_example/window.cpp b/src/rendergraph/examples/gl_example/window.cpp index 0eb1570c8f9c..de643ee8ba76 100644 --- a/src/rendergraph/examples/gl_example/window.cpp +++ b/src/rendergraph/examples/gl_example/window.cpp @@ -17,8 +17,8 @@ void Window::closeEvent(QCloseEvent*) { void Window::initializeGL() { rendergraph::Context context; - auto node = std::make_unique(&context); - m_pEngine = std::make_unique(std::move(node)); + auto pExampleNode = std::make_unique(&context); + m_pEngine = std::make_unique(std::move(pExampleNode)); } void Window::resizeGL(int w, int h) { diff --git a/src/rendergraph/examples/sg_example/CMakeLists.txt b/src/rendergraph/examples/sg_example/CMakeLists.txt index 0f17e2b76416..303987868d9e 100644 --- a/src/rendergraph/examples/sg_example/CMakeLists.txt +++ b/src/rendergraph/examples/sg_example/CMakeLists.txt @@ -12,7 +12,7 @@ target_include_directories(sg_example PRIVATE ../common) target_compile_definitions(sg_example PRIVATE rendergraph=rendergraph_sg) if(QT_VERSION VERSION_LESS "6.3.0") - set_target_properties(sg_example PROPERTIES AUTOMOC ON) + set_target_properties(sg_example PROPERTIES AUTOMOC ON) endif() qt_add_qml_module(sg_example diff --git a/src/rendergraph/examples/sg_example/customitem.cpp b/src/rendergraph/examples/sg_example/customitem.cpp index b1ddaa0efb56..720e67232787 100644 --- a/src/rendergraph/examples/sg_example/customitem.cpp +++ b/src/rendergraph/examples/sg_example/customitem.cpp @@ -44,9 +44,9 @@ QSGNode* CustomItem::updatePaintNode(QSGNode* node, UpdatePaintNodeData*) { material->setColor(QColor(255, 0, 0)); rendergraph::Context context(window()); - m_pExampleNode = std::make_unique(&context); + auto pExampleNode = std::make_unique(&context); - bgNode->appendChildNode(m_pExampleNode->backendNode()); + bgNode->appendChildNode(pExampleNode.release()); node = bgNode; } else { diff --git a/src/rendergraph/examples/sg_example/customitem.h b/src/rendergraph/examples/sg_example/customitem.h index de574d2a6269..86f8e19f813d 100644 --- a/src/rendergraph/examples/sg_example/customitem.h +++ b/src/rendergraph/examples/sg_example/customitem.h @@ -4,9 +4,7 @@ #include #include -namespace rendergraph { -class Node; -} +#include "rendergraph/node.h" class CustomItem : public QQuickItem { Q_OBJECT @@ -21,9 +19,6 @@ class CustomItem : public QQuickItem { void geometryChange(const QRectF& newGeometry, const QRectF& oldGeometry) override; bool m_geometryChanged{}; - - private: - std::unique_ptr m_pExampleNode; }; #endif // CUSTOMITEM_H diff --git a/src/rendergraph/opengl/CMakeLists.txt b/src/rendergraph/opengl/CMakeLists.txt index ad5bc67a660d..9501c2b2b153 100644 --- a/src/rendergraph/opengl/CMakeLists.txt +++ b/src/rendergraph/opengl/CMakeLists.txt @@ -1,6 +1,4 @@ add_library(rendergraph_gl -../common/node.cpp -../common/opacitynode.cpp ../common/rendergraph/attributeinit.h ../common/rendergraph/attributeset.h ../common/rendergraph/geometry.h @@ -23,14 +21,12 @@ add_library(rendergraph_gl ../common/rendergraph/node.h ../common/rendergraph/opacitynode.h ../common/rendergraph/texture.h -../common/rendergraph/treenode.h ../common/rendergraph/types.h ../common/rendergraph/uniform.h ../common/rendergraph/uniformscache.cpp ../common/rendergraph/uniformscache.h ../common/rendergraph/uniformset.cpp ../common/rendergraph/uniformset.h -../common/treenode.cpp ../common/types.cpp attributeset.cpp backend/baseattributeset.cpp @@ -44,6 +40,7 @@ backend/basematerial.h backend/basematerialshader.cpp backend/basematerialtype.h backend/basenode.h +backend/basenode.cpp backend/baseopacitynode.h backend/baseopenglnode.cpp backend/baseopenglnode.h @@ -54,12 +51,10 @@ geometry.cpp geometrynode.cpp material.cpp materialshader.cpp -openglnode.cpp rendergraph/context.h rendergraph/engine.h rendergraph/openglnode.h texture.cpp -treenode.cpp ) target_link_libraries(rendergraph_gl PUBLIC diff --git a/src/rendergraph/opengl/backend/basegeometrynode.h b/src/rendergraph/opengl/backend/basegeometrynode.h index 2f44f95d8e4f..a795a67b134e 100644 --- a/src/rendergraph/opengl/backend/basegeometrynode.h +++ b/src/rendergraph/opengl/backend/basegeometrynode.h @@ -10,8 +10,9 @@ class BaseGeometryNode; class rendergraph::BaseGeometryNode : public rendergraph::BaseNode, public QOpenGLFunctions { - protected: + public: BaseGeometryNode() = default; + virtual ~BaseGeometryNode() = default; public: void initialize() override; diff --git a/src/rendergraph/opengl/backend/basenode.cpp b/src/rendergraph/opengl/backend/basenode.cpp new file mode 100644 index 000000000000..5a902f5cc927 --- /dev/null +++ b/src/rendergraph/opengl/backend/basenode.cpp @@ -0,0 +1,59 @@ +#include "backend/basenode.h" + +#include "rendergraph/assert.h" +#include "rendergraph/engine.h" + +using namespace rendergraph; + +BaseNode::~BaseNode() { + DEBUG_ASSERT(m_pParent == nullptr); + DEBUG_ASSERT(m_pEngine == nullptr); + + while (m_pFirstChild) { + std::unique_ptr pChild(m_pFirstChild); + removeChildNode(pChild.get()); + } +} + +void BaseNode::appendChildNode(BaseNode* pChild) { + if (m_pLastChild) { + pChild->m_pPreviousSibling = m_pLastChild; + m_pLastChild->m_pNextSibling = pChild; + } else { + m_pFirstChild = pChild; + } + m_pLastChild = pChild; + m_pLastChild->m_pParent = this; + + DEBUG_ASSERT(m_pLastChild->m_pNextSibling == nullptr); + + if (m_pEngine) { + m_pEngine->add(pChild); + } +} + +void BaseNode::removeAllChildNodes() { + while (m_pFirstChild) { + removeChildNode(m_pFirstChild); + } +} + +void BaseNode::removeChildNode(BaseNode* pChild) { + if (pChild == m_pFirstChild) { + m_pFirstChild = pChild->m_pNextSibling; + } else { + pChild->m_pPreviousSibling->m_pNextSibling = pChild->m_pNextSibling; + } + + if (pChild == m_pLastChild) { + m_pLastChild = nullptr; + } + + if (pChild->m_pEngine) { + pChild->m_pEngine->remove(pChild); + } + + pChild->m_pNextSibling = nullptr; + pChild->m_pPreviousSibling = nullptr; + pChild->m_pParent = nullptr; +} diff --git a/src/rendergraph/opengl/backend/basenode.h b/src/rendergraph/opengl/backend/basenode.h index 03c06dc3bb8c..5ca86197a877 100644 --- a/src/rendergraph/opengl/backend/basenode.h +++ b/src/rendergraph/opengl/backend/basenode.h @@ -8,11 +8,11 @@ class Engine; } class rendergraph::BaseNode { - protected: + public: BaseNode() = default; + virtual ~BaseNode(); - public: - void setUsePreprocessFlag(bool value) { + void setUsePreprocess(bool value) { m_usePreprocess = value; } bool usePreprocess() const { @@ -36,7 +36,33 @@ class rendergraph::BaseNode { return m_pEngine; } + void appendChildNode(BaseNode* pChild); + void removeAllChildNodes(); + void removeChildNode(BaseNode* pChild); + + BaseNode* parent() const { + return m_pParent; + } + BaseNode* firstChild() const { + return m_pFirstChild; + } + BaseNode* lastChild() const { + return m_pLastChild; + } + BaseNode* nextSibling() const { + return m_pNextSibling; + } + BaseNode* previousSibling() const { + return m_pPreviousSibling; + } + private: Engine* m_pEngine{}; bool m_usePreprocess{}; + + BaseNode* m_pParent{}; + BaseNode* m_pFirstChild{}; + BaseNode* m_pLastChild{}; + BaseNode* m_pNextSibling{}; + BaseNode* m_pPreviousSibling{}; }; diff --git a/src/rendergraph/opengl/backend/baseopacitynode.h b/src/rendergraph/opengl/backend/baseopacitynode.h index e07f7d141fbe..8917dfb10da8 100644 --- a/src/rendergraph/opengl/backend/baseopacitynode.h +++ b/src/rendergraph/opengl/backend/baseopacitynode.h @@ -7,10 +7,10 @@ class BaseOpacityNode; } class rendergraph::BaseOpacityNode : public rendergraph::BaseNode { - protected: + public: BaseOpacityNode() = default; + virtual ~BaseOpacityNode() = default; - public: void setOpacity(float opacity) { m_opacity = opacity; } diff --git a/src/rendergraph/opengl/backend/baseopenglnode.cpp b/src/rendergraph/opengl/backend/baseopenglnode.cpp index 1d591e02a02a..165275448cb2 100644 --- a/src/rendergraph/opengl/backend/baseopenglnode.cpp +++ b/src/rendergraph/opengl/backend/baseopenglnode.cpp @@ -6,16 +6,15 @@ using namespace rendergraph; void BaseOpenGLNode::initialize() { initializeOpenGLFunctions(); - OpenGLNode* pThis = static_cast(this); - pThis->initializeGL(); + initializeGL(); } void BaseOpenGLNode::render() { OpenGLNode* pThis = static_cast(this); - pThis->paintGL(); + paintGL(); } void BaseOpenGLNode::resize(int w, int h) { OpenGLNode* pThis = static_cast(this); - pThis->resizeGL(w, h); + resizeGL(w, h); } diff --git a/src/rendergraph/opengl/backend/baseopenglnode.h b/src/rendergraph/opengl/backend/baseopenglnode.h index 73bff2e81d9d..641d286b65ec 100644 --- a/src/rendergraph/opengl/backend/baseopenglnode.h +++ b/src/rendergraph/opengl/backend/baseopenglnode.h @@ -10,11 +10,18 @@ class BaseOpenGLNode; class rendergraph::BaseOpenGLNode : public rendergraph::BaseNode, public QOpenGLFunctions { - protected: + public: BaseOpenGLNode() = default; + virtual ~BaseOpenGLNode() = default; - public: void initialize() override; void render() override; void resize(int w, int h) override; + + virtual void initializeGL() { + } + virtual void paintGL() { + } + virtual void resizeGL(int, int) { + } }; diff --git a/src/rendergraph/opengl/engine.cpp b/src/rendergraph/opengl/engine.cpp index 132bfa231d7a..c5202918155d 100644 --- a/src/rendergraph/opengl/engine.cpp +++ b/src/rendergraph/opengl/engine.cpp @@ -5,17 +5,20 @@ using namespace rendergraph; -Engine::Engine(std::unique_ptr pNode) - : m_pTopNode(std::move(pNode)) { - add(m_pTopNode.get()); +Engine::Engine(std::unique_ptr pRootNode) + : m_pRootNode(std::move(pRootNode)) { + add(m_pRootNode.get()); } -void Engine::add(TreeNode* pNode) { - assert(pNode->backendNode()->engine() == nullptr || pNode->backendNode()->engine() == this); - if (pNode->backendNode()->engine() == nullptr) { - pNode->backendNode()->setEngine(this); +Engine::~Engine() { +} + +void Engine::add(BaseNode* pNode) { + assert(pNode->engine() == nullptr || pNode->engine() == this); + if (pNode->engine() == nullptr) { + pNode->setEngine(this); m_pInitializeNodes.push_back(pNode); - if (pNode->backendNode()->usePreprocess()) { + if (pNode->usePreprocess()) { m_pPreprocessNodes.push_back(pNode); } pNode = pNode->firstChild(); @@ -26,23 +29,45 @@ void Engine::add(TreeNode* pNode) { } } +void Engine::remove(BaseNode* pNode) { + assert(pNode->engine() == this); + pNode->setEngine(nullptr); + + { + auto it = std::find(m_pInitializeNodes.begin(), m_pInitializeNodes.end(), pNode); + if (it != m_pInitializeNodes.end()) { + m_pInitializeNodes.erase(it); + } + } + { + auto it = std::find(m_pPreprocessNodes.begin(), m_pPreprocessNodes.end(), pNode); + if (it != m_pPreprocessNodes.end()) { + m_pPreprocessNodes.erase(it); + } + } + + if (m_pRootNode.get() == pNode) { + m_pRootNode.reset(); + } +} + void Engine::render() { if (!m_pInitializeNodes.empty()) { for (auto pNode : m_pInitializeNodes) { - pNode->backendNode()->initialize(); + pNode->initialize(); } m_pInitializeNodes.clear(); } - if (!m_pTopNode->backendNode()->isSubtreeBlocked()) { - render(m_pTopNode.get()); + if (m_pRootNode && !m_pRootNode->isSubtreeBlocked()) { + render(m_pRootNode.get()); } } -void Engine::render(TreeNode* pNode) { - pNode->backendNode()->render(); +void Engine::render(BaseNode* pNode) { + pNode->render(); pNode = pNode->firstChild(); while (pNode) { - if (!pNode->backendNode()->isSubtreeBlocked()) { + if (!pNode->isSubtreeBlocked()) { render(pNode); } pNode = pNode->nextSibling(); @@ -51,8 +76,8 @@ void Engine::render(TreeNode* pNode) { void Engine::preprocess() { for (auto pNode : m_pPreprocessNodes) { - if (!pNode->backendNode()->isSubtreeBlocked()) { - pNode->backendNode()->preprocess(); + if (!pNode->isSubtreeBlocked()) { + pNode->preprocess(); } } } @@ -66,11 +91,13 @@ void Engine::resize(int w, int h) { // matrix.translate(0.f, -waveformRenderer->getWidth() * ratio, 0.f); //} - resize(m_pTopNode.get(), w, h); + if (m_pRootNode) { + resize(m_pRootNode.get(), w, h); + } } -void Engine::resize(TreeNode* pNode, int w, int h) { - pNode->backendNode()->resize(w, h); +void Engine::resize(BaseNode* pNode, int w, int h) { + pNode->resize(w, h); pNode = pNode->firstChild(); while (pNode) { resize(pNode, w, h); diff --git a/src/rendergraph/opengl/geometrynode.cpp b/src/rendergraph/opengl/geometrynode.cpp index 1af643cb8e2d..7c5020974bc2 100644 --- a/src/rendergraph/opengl/geometrynode.cpp +++ b/src/rendergraph/opengl/geometrynode.cpp @@ -2,8 +2,10 @@ using namespace rendergraph; -GeometryNode::GeometryNode() - : TreeNode(this) { +GeometryNode::GeometryNode() = default; + +void GeometryNode::setUsePreprocess(bool value) { + BaseNode::setUsePreprocess(value); } void GeometryNode::setGeometry(std::unique_ptr pGeometry) { diff --git a/src/rendergraph/opengl/openglnode.cpp b/src/rendergraph/opengl/openglnode.cpp deleted file mode 100644 index c9e3e17ff879..000000000000 --- a/src/rendergraph/opengl/openglnode.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "rendergraph/openglnode.h" - -using namespace rendergraph; - -OpenGLNode::OpenGLNode() - : TreeNode(this) { -} diff --git a/src/rendergraph/opengl/rendergraph/context.h b/src/rendergraph/opengl/rendergraph/context.h index 20b49acb7bf9..d5d0611408ff 100644 --- a/src/rendergraph/opengl/rendergraph/context.h +++ b/src/rendergraph/opengl/rendergraph/context.h @@ -1,14 +1,8 @@ #pragma once -class QQuickWindow; - namespace rendergraph { class Context; } class rendergraph::Context { - public: - QQuickWindow* window() const { - return nullptr; - } }; diff --git a/src/rendergraph/opengl/rendergraph/engine.h b/src/rendergraph/opengl/rendergraph/engine.h index b86ab2411f01..83e480727e00 100644 --- a/src/rendergraph/opengl/rendergraph/engine.h +++ b/src/rendergraph/opengl/rendergraph/engine.h @@ -12,21 +12,24 @@ class Engine; class rendergraph::Engine { public: - Engine(std::unique_ptr pNode); + Engine(std::unique_ptr pRootNode); + ~Engine(); + void render(); void resize(int w, int h); void preprocess(); - void add(TreeNode* pNode); + void add(BaseNode* pNode); + void remove(BaseNode* pNode); const QMatrix4x4& matrix() const { return m_matrix; } private: - void render(TreeNode* pNode); - void resize(TreeNode* pNode, int, int); + void render(BaseNode* pNode); + void resize(BaseNode* pNode, int, int); QMatrix4x4 m_matrix; - const std::unique_ptr m_pTopNode; - std::vector m_pPreprocessNodes; - std::vector m_pInitializeNodes; + std::unique_ptr m_pRootNode; + std::vector m_pPreprocessNodes; + std::vector m_pInitializeNodes; }; diff --git a/src/rendergraph/opengl/rendergraph/openglnode.h b/src/rendergraph/opengl/rendergraph/openglnode.h index 5cb3497edb3a..7499312cb082 100644 --- a/src/rendergraph/opengl/rendergraph/openglnode.h +++ b/src/rendergraph/opengl/rendergraph/openglnode.h @@ -1,21 +1,7 @@ #pragma once #include "backend/baseopenglnode.h" -#include "rendergraph/treenode.h" namespace rendergraph { -class OpenGLNode; +using OpenGLNode = BaseOpenGLNode; } // namespace rendergraph - -class rendergraph::OpenGLNode : public rendergraph::BaseOpenGLNode, - public rendergraph::TreeNode { - public: - OpenGLNode(); - - virtual void initializeGL() { - } - virtual void paintGL() { - } - virtual void resizeGL(int, int) { - } -}; diff --git a/src/rendergraph/opengl/treenode.cpp b/src/rendergraph/opengl/treenode.cpp deleted file mode 100644 index 9da325852525..000000000000 --- a/src/rendergraph/opengl/treenode.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "rendergraph/treenode.h" -#include "rendergraph/engine.h" - -using namespace rendergraph; - -TreeNode::TreeNode(rendergraph::BaseNode* pBackendNode) - : m_pBackendNode(pBackendNode) { -} - -TreeNode::~TreeNode() { -} - -void TreeNode::setUsePreprocess(bool value) { - backendNode()->setUsePreprocessFlag(value); -} - -void TreeNode::onAppendChildNode(TreeNode* pChild) { - if (backendNode()->engine()) { - backendNode()->engine()->add(pChild); - } -} - -void TreeNode::onRemoveChildNode(TreeNode*) { -} - -void TreeNode::onRemoveAllChildNodes() { -} diff --git a/src/rendergraph/scenegraph/CMakeLists.txt b/src/rendergraph/scenegraph/CMakeLists.txt index 0539eff855fa..45c22885c13d 100644 --- a/src/rendergraph/scenegraph/CMakeLists.txt +++ b/src/rendergraph/scenegraph/CMakeLists.txt @@ -1,6 +1,4 @@ add_library(rendergraph_sg -../common/node.cpp -../common/opacitynode.cpp ../common/rendergraph/attributeinit.h ../common/rendergraph/attributeset.h ../common/rendergraph/geometry.h @@ -23,14 +21,12 @@ add_library(rendergraph_sg ../common/rendergraph/node.h ../common/rendergraph/opacitynode.h ../common/rendergraph/texture.h -../common/rendergraph/treenode.h ../common/rendergraph/types.h ../common/rendergraph/uniform.h ../common/rendergraph/uniformscache.cpp ../common/rendergraph/uniformscache.h ../common/rendergraph/uniformset.cpp ../common/rendergraph/uniformset.h -../common/treenode.cpp ../common/types.cpp attributeset.cpp backend/baseattributeset.cpp @@ -51,7 +47,6 @@ material.cpp materialshader.cpp rendergraph/context.h texture.cpp -treenode.cpp ) target_link_libraries(rendergraph_sg PUBLIC diff --git a/src/rendergraph/scenegraph/backend/basematerialshader.cpp b/src/rendergraph/scenegraph/backend/basematerialshader.cpp index 4d01acaa928e..7a49a3d5afd5 100644 --- a/src/rendergraph/scenegraph/backend/basematerialshader.cpp +++ b/src/rendergraph/scenegraph/backend/basematerialshader.cpp @@ -28,7 +28,7 @@ void BaseMaterialShader::updateSampledImage(RenderState& state, QSGTexture** texture, QSGMaterial* newMaterial, QSGMaterial* oldMaterial) { - if (!newMaterial || !static_cast(newMaterial)->texture(binding)){ + if (!newMaterial || !static_cast(newMaterial)->texture(binding)) { *texture = nullptr; return; } diff --git a/src/rendergraph/scenegraph/geometrynode.cpp b/src/rendergraph/scenegraph/geometrynode.cpp index 59455ed9e8f8..21196f2b8a38 100644 --- a/src/rendergraph/scenegraph/geometrynode.cpp +++ b/src/rendergraph/scenegraph/geometrynode.cpp @@ -2,8 +2,10 @@ using namespace rendergraph; -GeometryNode::GeometryNode() - : TreeNode(this) { +GeometryNode::GeometryNode() = default; + +void GeometryNode::setUsePreprocess(bool value) { + setFlag(QSGNode::UsePreprocess, value); } void GeometryNode::setGeometry(std::unique_ptr pGeometry) { diff --git a/src/rendergraph/scenegraph/rendergraph/context.h b/src/rendergraph/scenegraph/rendergraph/context.h index e0f2539d4cc2..e26e6eb78599 100644 --- a/src/rendergraph/scenegraph/rendergraph/context.h +++ b/src/rendergraph/scenegraph/rendergraph/context.h @@ -8,7 +8,7 @@ class Context; class rendergraph::Context { public: - Context(QQuickWindow* pWindow = nullptr); + Context(QQuickWindow* pWindow); QQuickWindow* window() const; private: diff --git a/src/rendergraph/scenegraph/texture.cpp b/src/rendergraph/scenegraph/texture.cpp index c795949798fb..130d10df8211 100644 --- a/src/rendergraph/scenegraph/texture.cpp +++ b/src/rendergraph/scenegraph/texture.cpp @@ -1,13 +1,12 @@ #include "rendergraph/texture.h" + #include "rendergraph/assert.h" #include "rendergraph/context.h" using namespace rendergraph; Texture::Texture(Context* pContext, const QImage& image) - : m_pTexture{std::unique_ptr(pContext->window() - ? pContext->window()->createTextureFromImage(image) - : nullptr)} { + : m_pTexture(pContext->window()->createTextureFromImage(image)) { VERIFY_OR_DEBUG_ASSERT(pContext->window() != nullptr) { return; } diff --git a/src/rendergraph/scenegraph/treenode.cpp b/src/rendergraph/scenegraph/treenode.cpp deleted file mode 100644 index fbaf5474951e..000000000000 --- a/src/rendergraph/scenegraph/treenode.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "rendergraph/treenode.h" - -using namespace rendergraph; - -TreeNode::TreeNode(rendergraph::BaseNode* pBackendNode) - : m_pBackendNode(pBackendNode) { - m_pBackendNode->setFlag(QSGNode::OwnedByParent, false); -} - -TreeNode::~TreeNode() { - m_pFirstChild.release(); - m_pNextSibling.release(); -} - -void TreeNode::setUsePreprocess(bool value) { - backendNode()->setFlag(QSGNode::UsePreprocess, value); -} - -void TreeNode::onAppendChildNode(TreeNode* pChild) { - auto pThisBackendNode = backendNode(); - auto pChildBackendNode = pChild->backendNode(); - - pThisBackendNode->appendChildNode(pChildBackendNode); - - // backendNode()->appendChildNode(pChild->backendNode()); -} - -void TreeNode::onRemoveChildNode(TreeNode* pChild) { - backendNode()->removeChildNode(pChild->backendNode()); -} - -void TreeNode::onRemoveAllChildNodes() { - backendNode()->removeAllChildNodes(); -} diff --git a/src/waveform/renderers/allshader/waveformrendermark.cpp b/src/waveform/renderers/allshader/waveformrendermark.cpp index a6c1d1e81284..c1cf43a5e7ae 100644 --- a/src/waveform/renderers/allshader/waveformrendermark.cpp +++ b/src/waveform/renderers/allshader/waveformrendermark.cpp @@ -18,12 +18,12 @@ using namespace rendergraph; - allshader::WaveformMarkNode::WaveformMarkNode(WaveformMark* pOwner, rendergraph::Context* pContext, const QImage& image) : m_pOwner(pOwner) { initForRectangles(1); updateTexture(pContext, image); } + void allshader::WaveformMarkNode::updateTexture(rendergraph::Context* pContext, const QImage& image) { dynamic_cast(material()) .setTexture(std::make_unique(pContext, image)); diff --git a/src/waveform/renderers/allshader/waveformrendermark.h b/src/waveform/renderers/allshader/waveformrendermark.h index 02e57834af9a..bf2aee489be8 100644 --- a/src/waveform/renderers/allshader/waveformrendermark.h +++ b/src/waveform/renderers/allshader/waveformrendermark.h @@ -2,6 +2,7 @@ #include +#include "rendergraph/geometrynode.h" #include "rendergraph/node.h" #include "waveform/renderers/waveformrendermarkbase.h" @@ -138,10 +139,10 @@ class allshader::WaveformMarkNodeGraphics : public WaveformMark::Graphics { float textureHeight() const { return waveformMarkNode()->textureHeight(); } - void setNode(std::unique_ptr&& pNode) { + void setNode(std::unique_ptr&& pNode) { m_pNode = std::move(pNode); } - void moveNodeToChildrenOf(rendergraph::TreeNode* pParent) { + void moveNodeToChildrenOf(rendergraph::Node* pParent) { pParent->appendChildNode(std::move(m_pNode)); } @@ -150,5 +151,5 @@ class allshader::WaveformMarkNodeGraphics : public WaveformMark::Graphics { return static_cast(m_pNode.get()); } - std::unique_ptr m_pNode; + std::unique_ptr m_pNode; }; diff --git a/src/waveform/widgets/allshader/waveformwidget.cpp b/src/waveform/widgets/allshader/waveformwidget.cpp index 5f4ffdb180bb..192392a57eda 100644 --- a/src/waveform/widgets/allshader/waveformwidget.cpp +++ b/src/waveform/widgets/allshader/waveformwidget.cpp @@ -20,18 +20,17 @@ #include "waveform/renderers/allshader/waveformrendermarkrange.h" #include "waveform/widgets/allshader/moc_waveformwidget.cpp" -namespace { -void appendChildTo(std::unique_ptr& pNode, rendergraph::TreeNode* pChild) { - pNode->appendChildNode(std::unique_ptr(pChild)); -} -void appendChildTo(std::unique_ptr& pNode, - rendergraph::TreeNode* pChild) { - pNode->appendChildNode(std::unique_ptr(pChild)); -} -} // namespace - namespace allshader { +template +std::unique_ptr castUniqueNodePtr(std::unique_ptr&& p) { + if (dynamic_cast(p.get())) { + return std::unique_ptr( + dynamic_cast(p.release())); + } + return std::unique_ptr(); +} + WaveformWidget::WaveformWidget(QWidget* parent, WaveformWidgetType::Type type, const QString& group, @@ -40,48 +39,55 @@ WaveformWidget::WaveformWidget(QWidget* parent, auto pTopNode = std::make_unique(); auto pOpacityNode = std::make_unique(); - appendChildTo(pTopNode, addRenderer()); - appendChildTo(pOpacityNode, addRenderer()); - appendChildTo(pOpacityNode, addRenderer()); - m_pWaveformRenderMarkRange = addRenderer(); - appendChildTo(pOpacityNode, m_pWaveformRenderMarkRange); + pTopNode->appendChildNode(addRendererNode()); + pOpacityNode->appendChildNode(addRendererNode()); + pOpacityNode->appendChildNode(addRendererNode()); + auto pWaveformRenderMarkRange = addRendererNode(); + m_pWaveformRenderMarkRange = pWaveformRenderMarkRange.get(); + pOpacityNode->appendChildNode(std::move(pWaveformRenderMarkRange)); #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. - appendChildTo(pOpacityNode, addRenderer()); + pOpacityNode->appendChildNode(addRendererNode()); #endif - allshader::WaveformRendererSignalBase* waveformSignalRenderer = - addWaveformSignalRenderer( - type, options, ::WaveformRendererAbstract::Play); - appendChildTo(pOpacityNode, dynamic_cast(waveformSignalRenderer)); - - appendChildTo(pOpacityNode, addRenderer()); - m_pWaveformRenderMark = addRenderer(); - appendChildTo(pOpacityNode, m_pWaveformRenderMark); + auto pWaveformSignalRenderer = addWaveformSignalRenderer( + type, options, ::WaveformRendererAbstract::Play); + const bool supportsSlip = pWaveformSignalRenderer && pWaveformSignalRenderer->supportsSlip(); + auto pNode = castUniqueNodePtr(std::move(pWaveformSignalRenderer)); + if (pNode) { + pOpacityNode->appendChildNode(std::move(pNode)); + } + pOpacityNode->appendChildNode(addRendererNode()); + auto pWaveformRenderMark = addRendererNode(); + m_pWaveformRenderMark = pWaveformRenderMark.get(); + pOpacityNode->appendChildNode(std::move(pWaveformRenderMark)); // if the signal renderer supports slip, we add it again, now for slip, together with the // other slip renderers - if (waveformSignalRenderer && waveformSignalRenderer->supportsSlip()) { + if (supportsSlip) { // The following renderer will add an overlay waveform if a slip is in progress - appendChildTo(pOpacityNode, addRenderer()); - appendChildTo(pOpacityNode, - addRenderer( + pOpacityNode->appendChildNode(addRendererNode()); + pOpacityNode->appendChildNode( + addRendererNode( ::WaveformRendererAbstract::Slip)); #ifdef __STEM__ - appendChildTo(pOpacityNode, - addRenderer( + pOpacityNode->appendChildNode( + addRendererNode( ::WaveformRendererAbstract::Slip)); #endif - appendChildTo(pOpacityNode, - dynamic_cast(addWaveformSignalRenderer( - type, options, ::WaveformRendererAbstract::Slip))); - appendChildTo(pOpacityNode, - addRenderer( + auto pWaveformSignalRenderer = addWaveformSignalRenderer( + type, options, ::WaveformRendererAbstract::Slip); + auto pNode = castUniqueNodePtr(std::move(pWaveformSignalRenderer)); + if (pNode) { + pOpacityNode->appendChildNode(std::move(pNode)); + } + pOpacityNode->appendChildNode( + addRendererNode( ::WaveformRendererAbstract::Slip)); - appendChildTo(pOpacityNode, - addRenderer( + pOpacityNode->appendChildNode( + addRendererNode( ::WaveformRendererAbstract::Slip)); } @@ -100,10 +106,18 @@ WaveformWidget::~WaveformWidget() { doneCurrent(); } -allshader::WaveformRendererSignalBase* +std::unique_ptr WaveformWidget::addWaveformSignalRenderer(WaveformWidgetType::Type type, WaveformRendererSignalBase::Options options, ::WaveformRendererAbstract::PositionSource positionSource) { + return std::unique_ptr( + addWaveformSignalRendererInner(type, options, positionSource)); +} + +allshader::WaveformRendererSignalBase* +WaveformWidget::addWaveformSignalRendererInner(WaveformWidgetType::Type type, + WaveformRendererSignalBase::Options options, + ::WaveformRendererAbstract::PositionSource positionSource) { #ifndef QT_OPENGL_ES_2 if (options & allshader::WaveformRendererSignalBase::Option::HighDetail) { switch (type) { diff --git a/src/waveform/widgets/allshader/waveformwidget.h b/src/waveform/widgets/allshader/waveformwidget.h index 347a347aabd0..41c195118f3f 100644 --- a/src/waveform/widgets/allshader/waveformwidget.h +++ b/src/waveform/widgets/allshader/waveformwidget.h @@ -42,13 +42,23 @@ class allshader::WaveformWidget final : public ::WGLWidget, static WaveformWidgetVars vars(); static WaveformRendererSignalBase::Options supportedOptions(WaveformWidgetType::Type type); + template + inline std::unique_ptr addRendererNode(Args&&... args) { + return std::unique_ptr(addRenderer(std::forward(args)...)); + } + private: void castToQWidget() override; void paintEvent(QPaintEvent* event) override; void wheelEvent(QWheelEvent* event) override; void leaveEvent(QEvent* event) override; - allshader::WaveformRendererSignalBase* addWaveformSignalRenderer( + std::unique_ptr addWaveformSignalRenderer( + WaveformWidgetType::Type type, + WaveformRendererSignalBase::Options options, + ::WaveformRendererAbstract::PositionSource positionSource); + + allshader::WaveformRendererSignalBase* addWaveformSignalRendererInner( WaveformWidgetType::Type type, WaveformRendererSignalBase::Options options, ::WaveformRendererAbstract::PositionSource positionSource);