From e1682b84bb09ce3b45237b964c820eb4b92857a2 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 26 May 2016 14:34:00 +0200 Subject: Refactor the rendernode example By removing the Renderer abstraction it becomes easier to follow and understand. Change-Id: Iddacb461d51a75864983850660c5480985b3524f Reviewed-by: Andy Nichols --- .../scenegraph/rendernode/customrenderitem.cpp | 64 ++++++---------------- .../quick/scenegraph/rendernode/customrenderitem.h | 23 -------- .../quick/scenegraph/rendernode/d3d12renderer.cpp | 45 ++++++++++----- .../quick/scenegraph/rendernode/d3d12renderer.h | 23 ++++---- .../quick/scenegraph/rendernode/openglrenderer.cpp | 35 ++++++++---- .../quick/scenegraph/rendernode/openglrenderer.h | 16 +++--- 6 files changed, 94 insertions(+), 112 deletions(-) (limited to 'examples') diff --git a/examples/quick/scenegraph/rendernode/customrenderitem.cpp b/examples/quick/scenegraph/rendernode/customrenderitem.cpp index dbb9ee79e8..4070a86395 100644 --- a/examples/quick/scenegraph/rendernode/customrenderitem.cpp +++ b/examples/quick/scenegraph/rendernode/customrenderitem.cpp @@ -45,63 +45,35 @@ #include "openglrenderer.h" #include "d3d12renderer.h" -CustomRenderNode::~CustomRenderNode() +CustomRenderItem::CustomRenderItem(QQuickItem *parent) + : QQuickItem(parent) { - releaseResources(); + // Our item shows something so set the flag. + setFlag(ItemHasContents); } -void CustomRenderNode::render(const RenderState *state) +QSGNode *CustomRenderItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *) { - QSGRendererInterface *ri = m_item->window()->rendererInterface(); - if (!ri) - return; - - if (!m_renderer) { + QSGRenderNode *n = static_cast(node); + if (!n) { + QSGRendererInterface *ri = window()->rendererInterface(); + if (!ri) + return nullptr; switch (ri->graphicsAPI()) { - case QSGRendererInterface::OpenGL: + case QSGRendererInterface::OpenGL: #ifndef QT_NO_OPENGL - m_renderer = new OpenGLRenderer(m_item, this); + n = new OpenGLRenderNode(this); + break; #endif - break; - case QSGRendererInterface::Direct3D12: + case QSGRendererInterface::Direct3D12: #ifdef HAS_D3D12 - m_renderer = new D3D12Renderer(m_item, this); + n = new D3D12RenderNode(this); + break; #endif - break; - default: - break; + default: + return nullptr; } - Q_ASSERT(m_renderer); - m_renderer->init(); } - m_renderer->render(state); -} - -// No need to reimplement changedStates() since our rendering is so simple, -// without involving any state changes. - -void CustomRenderNode::releaseResources() -{ - if (!m_renderer) - return; - - delete m_renderer; - m_renderer = nullptr; -} - -CustomRenderItem::CustomRenderItem(QQuickItem *parent) - : QQuickItem(parent) -{ - // Our item shows something so set the flag. - setFlag(ItemHasContents); -} - -QSGNode *CustomRenderItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *) -{ - CustomRenderNode *n = static_cast(node); - if (!node) - n = new CustomRenderNode(this); - return n; } diff --git a/examples/quick/scenegraph/rendernode/customrenderitem.h b/examples/quick/scenegraph/rendernode/customrenderitem.h index b9828adaeb..43b0b00ed5 100644 --- a/examples/quick/scenegraph/rendernode/customrenderitem.h +++ b/examples/quick/scenegraph/rendernode/customrenderitem.h @@ -42,29 +42,6 @@ #define CUSTOMRENDERITEM_H #include -#include - -class CustomRenderer -{ -public: - virtual ~CustomRenderer() { } - virtual void init() = 0; - virtual void render(const QSGRenderNode::RenderState *state) = 0; -}; - -class CustomRenderNode : public QSGRenderNode -{ -public: - CustomRenderNode(QQuickItem *item) : m_item(item) { } - ~CustomRenderNode(); - - void render(const RenderState *state) override; - void releaseResources() override; - -private: - QQuickItem *m_item; - CustomRenderer *m_renderer = nullptr; -}; class CustomRenderItem : public QQuickItem { diff --git a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp index a48719e5dd..3694c6ae75 100644 --- a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp +++ b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp @@ -39,6 +39,7 @@ ****************************************************************************/ #include "d3d12renderer.h" +#include #include #include @@ -47,15 +48,34 @@ #include "vs_shader.hlslh" #include "ps_shader.hlslh" -D3D12Renderer::D3D12Renderer(QQuickItem *item, QSGRenderNode *node) - : m_item(item), - m_node(node), - vbPtr(nullptr), - cbPtr(nullptr) +D3D12RenderNode::D3D12RenderNode(QQuickItem *item) + : m_item(item) { } -void D3D12Renderer::init() +D3D12RenderNode::~D3D12RenderNode() +{ + releaseResources(); +} + +void D3D12RenderNode::releaseResources() +{ + if (vbPtr) { + vertexBuffer->Unmap(0, nullptr); + vbPtr = nullptr; + } + if (cbPtr) { + constantBuffer->Unmap(0, nullptr); + cbPtr = nullptr; + } + constantBuffer = nullptr; + vertexBuffer = nullptr; + rootSignature = nullptr; + pipelineState = nullptr; + m_device = nullptr; +} + +void D3D12RenderNode::init() { QSGRendererInterface *rif = m_item->window()->rendererInterface(); m_device = static_cast(rif->getResource(QSGRendererInterface::Device)); @@ -180,22 +200,17 @@ void D3D12Renderer::init() } } -D3D12Renderer::~D3D12Renderer() +void D3D12RenderNode::render(const RenderState *state) { - if (vbPtr) - vertexBuffer->Unmap(0, nullptr); - if (cbPtr) - constantBuffer->Unmap(0, nullptr); -} + if (!m_device) + init(); -void D3D12Renderer::render(const QSGRenderNode::RenderState *state) -{ QSGRendererInterface *rif = m_item->window()->rendererInterface(); ID3D12GraphicsCommandList *commandList = static_cast(rif->getResource(QSGRendererInterface::CommandList)); Q_ASSERT(commandList); const int msize = 16 * sizeof(float); - memcpy(cbPtr, m_node->matrix()->constData(), msize); + memcpy(cbPtr, matrix()->constData(), msize); memcpy(cbPtr + msize, state->projectionMatrix()->constData(), msize); const QPointF p0(m_item->width() - 1, m_item->height() - 1); diff --git a/examples/quick/scenegraph/rendernode/d3d12renderer.h b/examples/quick/scenegraph/rendernode/d3d12renderer.h index 365b483422..a81db0f398 100644 --- a/examples/quick/scenegraph/rendernode/d3d12renderer.h +++ b/examples/quick/scenegraph/rendernode/d3d12renderer.h @@ -41,35 +41,38 @@ #ifndef D3D12RENDERER_H #define D3D12RENDERER_H -#include "customrenderitem.h" #include #ifdef HAS_D3D12 +class QQuickItem; + #include #include using namespace Microsoft::WRL; -class D3D12Renderer : public CustomRenderer +class D3D12RenderNode : public QSGRenderNode { public: - D3D12Renderer(QQuickItem *item, QSGRenderNode *node); - ~D3D12Renderer(); - void init() override; - void render(const QSGRenderNode::RenderState *state) override; + D3D12RenderNode(QQuickItem *item); + ~D3D12RenderNode(); + + void render(const RenderState *state) override; + void releaseResources() override; private: + void init(); + QQuickItem *m_item; - QSGRenderNode *m_node; - ID3D12Device *m_device; + ID3D12Device *m_device = nullptr; ComPtr pipelineState; ComPtr rootSignature; ComPtr vertexBuffer; ComPtr constantBuffer; D3D12_VERTEX_BUFFER_VIEW vertexBufferView; - quint8 *vbPtr; - quint8 *cbPtr; + quint8 *vbPtr = nullptr; + quint8 *cbPtr = nullptr; }; #endif // HAS_D3D12 diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.cpp b/examples/quick/scenegraph/rendernode/openglrenderer.cpp index e9c1be071c..27712e13b2 100644 --- a/examples/quick/scenegraph/rendernode/openglrenderer.cpp +++ b/examples/quick/scenegraph/rendernode/openglrenderer.cpp @@ -39,6 +39,7 @@ ****************************************************************************/ #include "openglrenderer.h" +#include #ifndef QT_NO_OPENGL @@ -46,13 +47,28 @@ #include #include -OpenGLRenderer::OpenGLRenderer(QQuickItem *item, QSGRenderNode *node) - : m_item(item), - m_node(node) +OpenGLRenderNode::OpenGLRenderNode(QQuickItem *item) + : m_item(item) { } -void OpenGLRenderer::init() +OpenGLRenderNode::~OpenGLRenderNode() +{ + releaseResources(); +} + +// No need to reimplement changedStates() since our rendering is so simple, +// without involving any state changes. + +void OpenGLRenderNode::releaseResources() +{ + delete m_program; + m_program = nullptr; + delete m_vbo; + m_vbo = nullptr; +} + +void OpenGLRenderNode::init() { m_program = new QOpenGLShaderProgram; @@ -98,18 +114,15 @@ void OpenGLRenderer::init() m_vbo->release(); } -OpenGLRenderer::~OpenGLRenderer() +void OpenGLRenderNode::render(const RenderState *state) { - delete m_program; - delete m_vbo; -} + if (!m_program) + init(); -void OpenGLRenderer::render(const QSGRenderNode::RenderState *state) -{ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); m_program->bind(); - m_program->setUniformValue(m_matrixUniform, *state->projectionMatrix() * *m_node->matrix()); + m_program->setUniformValue(m_matrixUniform, *state->projectionMatrix() * *matrix()); m_vbo->bind(); diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.h b/examples/quick/scenegraph/rendernode/openglrenderer.h index d445b35c1e..3f38faf458 100644 --- a/examples/quick/scenegraph/rendernode/openglrenderer.h +++ b/examples/quick/scenegraph/rendernode/openglrenderer.h @@ -41,25 +41,27 @@ #ifndef OPENGLRENDERER_H #define OPENGLRENDERER_H -#include "customrenderitem.h" #include #ifndef QT_NO_OPENGL +class QQuickItem; class QOpenGLShaderProgram; class QOpenGLBuffer; -class OpenGLRenderer : public CustomRenderer +class OpenGLRenderNode : public QSGRenderNode { public: - OpenGLRenderer(QQuickItem *item, QSGRenderNode *node); - ~OpenGLRenderer(); - void init() override; - void render(const QSGRenderNode::RenderState *state) override; + OpenGLRenderNode(QQuickItem *item); + ~OpenGLRenderNode(); + + void render(const RenderState *state) override; + void releaseResources() override; private: + void init(); + QQuickItem *m_item; - QSGRenderNode *m_node; QOpenGLShaderProgram *m_program = nullptr; int m_matrixUniform; QOpenGLBuffer *m_vbo = nullptr; -- cgit v1.2.3