diff options
9 files changed, 114 insertions, 81 deletions
diff --git a/examples/quick/scenegraph/rendernode/customrenderitem.cpp b/examples/quick/scenegraph/rendernode/customrenderitem.cpp index 67a9cccfc6..8aaa56c359 100644 --- a/examples/quick/scenegraph/rendernode/customrenderitem.cpp +++ b/examples/quick/scenegraph/rendernode/customrenderitem.cpp @@ -70,48 +70,56 @@ CustomRenderItem::CustomRenderItem(QQuickItem *parent) QSGNode *CustomRenderItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *) { QSGRenderNode *n = static_cast<QSGRenderNode *>(node); - if (!n) { - QSGRendererInterface *ri = window()->rendererInterface(); - if (!ri) - return nullptr; - switch (ri->graphicsApi()) { - case QSGRendererInterface::OpenGL: - Q_FALLTHROUGH(); - case QSGRendererInterface::OpenGLRhi: + + QSGRendererInterface *ri = window()->rendererInterface(); + if (!ri) + return nullptr; + + switch (ri->graphicsApi()) { + case QSGRendererInterface::OpenGL: + Q_FALLTHROUGH(); + case QSGRendererInterface::OpenGLRhi: #if QT_CONFIG(opengl) - n = new OpenGLRenderNode(this); + if (!n) + n = new OpenGLRenderNode; + static_cast<OpenGLRenderNode *>(n)->sync(this); #endif - break; + break; - case QSGRendererInterface::MetalRhi: + case QSGRendererInterface::MetalRhi: #ifdef Q_OS_DARWIN - { - MetalRenderNode *metalNode = new MetalRenderNode(this); + if (!n) { + MetalRenderNode *metalNode = new MetalRenderNode; n = metalNode; metalNode->resourceBuilder()->setWindow(window()); QObject::connect(window(), &QQuickWindow::beforeRendering, metalNode->resourceBuilder(), &MetalRenderNodeResourceBuilder::build); } + static_cast<MetalRenderNode *>(n)->sync(this); #endif - break; + break; - case QSGRendererInterface::Direct3D12: // ### Qt 6: remove + case QSGRendererInterface::Direct3D12: // ### Qt 6: remove #if QT_CONFIG(d3d12) - n = new D3D12RenderNode(this); + if (!n) + n = new D3D12RenderNode; + static_cast<D3D12RenderNode *>(n)->sync(this); #endif - break; + break; - case QSGRendererInterface::Software: - n = new SoftwareRenderNode(this); - break; - - default: - break; - } + case QSGRendererInterface::Software: if (!n) - qWarning("QSGRendererInterface reports unknown graphics API %d", ri->graphicsApi()); + n = new SoftwareRenderNode; + static_cast<SoftwareRenderNode *>(n)->sync(this); + break; + + default: + break; } + if (!n) + qWarning("QSGRendererInterface reports unknown graphics API %d", ri->graphicsApi()); + return n; } //! [2] diff --git a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp index 878b022950..e85811c089 100644 --- a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp +++ b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp @@ -58,11 +58,6 @@ #if QT_CONFIG(d3d12) -D3D12RenderNode::D3D12RenderNode(QQuickItem *item) - : m_item(item) -{ -} - D3D12RenderNode::~D3D12RenderNode() { releaseResources(); @@ -87,8 +82,8 @@ void D3D12RenderNode::releaseResources() void D3D12RenderNode::init() { - QSGRendererInterface *rif = m_item->window()->rendererInterface(); - m_device = static_cast<ID3D12Device *>(rif->getResource(m_item->window(), QSGRendererInterface::DeviceResource)); + QSGRendererInterface *rif = m_window->rendererInterface(); + m_device = static_cast<ID3D12Device *>(rif->getResource(m_window, QSGRendererInterface::DeviceResource)); Q_ASSERT(m_device); D3D12_ROOT_PARAMETER rootParameter; @@ -178,7 +173,7 @@ void D3D12RenderNode::init() psoDesc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; // not in use due to !DepthEnable, but this would be the correct format otherwise // We are rendering on the default render target so if the QuickWindow/View // has requested samples > 0 then we have to follow suit. - const uint samples = qMax(1, m_item->window()->format().samples()); + const uint samples = qMax(1, m_window->format().samples()); psoDesc.SampleDesc.Count = samples; if (samples > 1) { D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msaaInfo = {}; @@ -257,9 +252,9 @@ void D3D12RenderNode::render(const RenderState *state) if (!m_device) init(); - QSGRendererInterface *rif = m_item->window()->rendererInterface(); + QSGRendererInterface *rif = m_window->rendererInterface(); ID3D12GraphicsCommandList *commandList = static_cast<ID3D12GraphicsCommandList *>( - rif->getResource(m_item->window(), QSGRendererInterface::CommandListResource)); + rif->getResource(m_window, QSGRendererInterface::CommandListResource)); Q_ASSERT(commandList); const int msize = 16 * sizeof(float); @@ -268,9 +263,9 @@ void D3D12RenderNode::render(const RenderState *state) const float opacity = inheritedOpacity(); memcpy(cbPtr + 2 * msize, &opacity, sizeof(float)); - const QPointF p0(m_item->width() - 1, m_item->height() - 1); + const QPointF p0(m_width - 1, m_height - 1); const QPointF p1(0, 0); - const QPointF p2(0, m_item->height() - 1); + const QPointF p2(0, m_height - 1); float *vp = reinterpret_cast<float *>(vbPtr); *vp++ = p0.x(); @@ -301,7 +296,14 @@ QSGRenderNode::RenderingFlags D3D12RenderNode::flags() const QRectF D3D12RenderNode::rect() const { - return QRect(0, 0, m_item->width(), m_item->height()); + return QRect(0, 0, m_width, m_height); +} + +void D3D12RenderNode::sync(QQuickItem *item) +{ + m_window = item->window(); + m_width = item->width(); + m_height = item->height(); } #endif // d3d12 diff --git a/examples/quick/scenegraph/rendernode/d3d12renderer.h b/examples/quick/scenegraph/rendernode/d3d12renderer.h index ec4b5f85e8..7186b72c04 100644 --- a/examples/quick/scenegraph/rendernode/d3d12renderer.h +++ b/examples/quick/scenegraph/rendernode/d3d12renderer.h @@ -52,11 +52,10 @@ #define D3D12RENDERER_H #include <qsgrendernode.h> +#include <QQuickItem> #if QT_CONFIG(d3d12) -QT_FORWARD_DECLARE_CLASS(QQuickItem) - #include <d3d12.h> #include <wrl/client.h> @@ -65,7 +64,6 @@ using namespace Microsoft::WRL; class D3D12RenderNode : public QSGRenderNode { public: - D3D12RenderNode(QQuickItem *item); ~D3D12RenderNode(); void render(const RenderState *state) override; @@ -73,10 +71,15 @@ public: RenderingFlags flags() const override; QRectF rect() const override; + void sync(QQuickItem *item); + private: void init(); - QQuickItem *m_item; + QQuickWindow *m_window = nullptr; + int m_width = 0; + int m_height = 0; + ID3D12Device *m_device = nullptr; ComPtr<ID3D12PipelineState> pipelineState; ComPtr<ID3D12RootSignature> rootSignature; diff --git a/examples/quick/scenegraph/rendernode/metalrenderer.h b/examples/quick/scenegraph/rendernode/metalrenderer.h index 77c9892313..31387a0e24 100644 --- a/examples/quick/scenegraph/rendernode/metalrenderer.h +++ b/examples/quick/scenegraph/rendernode/metalrenderer.h @@ -52,14 +52,12 @@ #define METALRENDERER_H #include <qsgrendernode.h> +#include <QQuickItem> #ifdef Q_OS_DARWIN QT_BEGIN_NAMESPACE -class QQuickItem; -class QQuickWindow; - QT_END_NAMESPACE class MetalRenderNodeResourceBuilder : public QObject @@ -79,7 +77,7 @@ private: class MetalRenderNode : public QSGRenderNode { public: - MetalRenderNode(QQuickItem *item); + MetalRenderNode(); ~MetalRenderNode(); void render(const RenderState *state) override; @@ -90,9 +88,14 @@ public: MetalRenderNodeResourceBuilder *resourceBuilder() { return &m_resourceBuilder; } + void sync(QQuickItem *item); + private: - QQuickItem *m_item; MetalRenderNodeResourceBuilder m_resourceBuilder; + QQuickWindow *m_window = nullptr; + int m_width = 0; + int m_height = 0; + int m_outputHeight = 0; }; #endif // Q_OS_DARWIN diff --git a/examples/quick/scenegraph/rendernode/metalrenderer.mm b/examples/quick/scenegraph/rendernode/metalrenderer.mm index 4cb973abee..11db276f37 100644 --- a/examples/quick/scenegraph/rendernode/metalrenderer.mm +++ b/examples/quick/scenegraph/rendernode/metalrenderer.mm @@ -214,8 +214,7 @@ void MetalRenderNodeResourceBuilder::build() } } -MetalRenderNode::MetalRenderNode(QQuickItem *item) - : m_item(item) +MetalRenderNode::MetalRenderNode() { g.vs.first = g.fs.first = nil; g.vs.second = g.fs.second = nil; @@ -258,14 +257,14 @@ void MetalRenderNode::releaseResources() void MetalRenderNode::render(const RenderState *state) { - QQuickWindow *window = m_item->window(); - const QQuickWindow::GraphicsStateInfo *stateInfo = window->graphicsStateInfo(); + Q_ASSERT(m_window); + const QQuickWindow::GraphicsStateInfo *stateInfo = m_window->graphicsStateInfo(); id<MTLBuffer> vbuf = g.vbuf[stateInfo->currentFrameSlot]; id<MTLBuffer> ubuf = g.ubuf[stateInfo->currentFrameSlot]; - QPointF p0(m_item->width() - 1, m_item->height() - 1); + QPointF p0(m_width - 1, m_height - 1); QPointF p1(0, 0); - QPointF p2(0, m_item->height() - 1); + QPointF p2(0, m_height - 1); float vertices[6] = { float(p0.x()), float(p0.y()), float(p1.x()), float(p1.y()), @@ -280,9 +279,9 @@ void MetalRenderNode::render(const RenderState *state) memcpy(p, mvp.constData(), 64); memcpy(p + 64, &opacity, 4); - QSGRendererInterface *rif = window->rendererInterface(); + QSGRendererInterface *rif = m_window->rendererInterface(); id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>) rif->getResource( - window, QSGRendererInterface::CommandEncoderResource); + m_window, QSGRendererInterface::CommandEncoderResource); Q_ASSERT(encoder); [encoder setVertexBuffer: vbuf offset: 0 atIndex: 1]; @@ -296,7 +295,7 @@ void MetalRenderNode::render(const RenderState *state) const QRect r = state->scissorRect(); // bottom-up MTLScissorRect s; s.x = r.x(); - s.y = (window->height() * window->effectiveDevicePixelRatio()) - (r.y() + r.height()); + s.y = m_outputHeight - (r.y() + r.height()); s.width = r.width(); s.height = r.height(); [encoder setScissorRect: s]; @@ -322,5 +321,13 @@ QSGRenderNode::RenderingFlags MetalRenderNode::flags() const QRectF MetalRenderNode::rect() const { - return QRect(0, 0, m_item->width(), m_item->height()); + return QRect(0, 0, m_width, m_height); +} + +void MetalRenderNode::sync(QQuickItem *item) +{ + m_window = item->window(); + m_width = item->width(); + m_height = item->height(); + m_outputHeight = m_window->height() * m_window->effectiveDevicePixelRatio(); } diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.cpp b/examples/quick/scenegraph/rendernode/openglrenderer.cpp index 0633731617..a4e619bea9 100644 --- a/examples/quick/scenegraph/rendernode/openglrenderer.cpp +++ b/examples/quick/scenegraph/rendernode/openglrenderer.cpp @@ -58,11 +58,6 @@ #include <QOpenGLFunctions> //! [1] -OpenGLRenderNode::OpenGLRenderNode(QQuickItem *item) - : m_item(item) -{ -} - OpenGLRenderNode::~OpenGLRenderNode() { releaseResources(); @@ -138,9 +133,9 @@ void OpenGLRenderNode::render(const RenderState *state) m_vbo->bind(); //! [5] - QPointF p0(m_item->width() - 1, m_item->height() - 1); + QPointF p0(m_width - 1, m_height - 1); QPointF p1(0, 0); - QPointF p2(0, m_item->height() - 1); + QPointF p2(0, m_height - 1); GLfloat vertices[6] = { GLfloat(p0.x()), GLfloat(p0.y()), GLfloat(p1.x()), GLfloat(p1.y()), @@ -192,8 +187,14 @@ QSGRenderNode::RenderingFlags OpenGLRenderNode::flags() const QRectF OpenGLRenderNode::rect() const { - return QRect(0, 0, m_item->width(), m_item->height()); + return QRect(0, 0, m_width, m_height); } //! [4] +void OpenGLRenderNode::sync(QQuickItem *item) +{ + m_width = item->width(); + m_height = item->height(); +} + #endif // opengl diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.h b/examples/quick/scenegraph/rendernode/openglrenderer.h index 8d2d3caad1..1e7977481a 100644 --- a/examples/quick/scenegraph/rendernode/openglrenderer.h +++ b/examples/quick/scenegraph/rendernode/openglrenderer.h @@ -52,12 +52,12 @@ #define OPENGLRENDERER_H #include <qsgrendernode.h> +#include <QQuickItem> #if QT_CONFIG(opengl) QT_BEGIN_NAMESPACE -class QQuickItem; class QOpenGLShaderProgram; class QOpenGLBuffer; @@ -67,7 +67,6 @@ QT_END_NAMESPACE class OpenGLRenderNode : public QSGRenderNode { public: - OpenGLRenderNode(QQuickItem *item); ~OpenGLRenderNode(); void render(const RenderState *state) override; @@ -77,10 +76,13 @@ public: QRectF rect() const override; //! [1] + void sync(QQuickItem *item); + private: void init(); - QQuickItem *m_item; + int m_width = 0; + int m_height = 0; QOpenGLShaderProgram *m_program = nullptr; int m_matrixUniform; int m_opacityUniform; diff --git a/examples/quick/scenegraph/rendernode/softwarerenderer.cpp b/examples/quick/scenegraph/rendernode/softwarerenderer.cpp index 0a0ec4b485..bba364ac97 100644 --- a/examples/quick/scenegraph/rendernode/softwarerenderer.cpp +++ b/examples/quick/scenegraph/rendernode/softwarerenderer.cpp @@ -54,11 +54,6 @@ #include <QSGRendererInterface> #include <QPainter> -SoftwareRenderNode::SoftwareRenderNode(QQuickItem *item) - : m_item(item) -{ -} - SoftwareRenderNode::~SoftwareRenderNode() { releaseResources(); @@ -70,8 +65,10 @@ void SoftwareRenderNode::releaseResources() void SoftwareRenderNode::render(const RenderState *renderState) { - QSGRendererInterface *rif = m_item->window()->rendererInterface(); - QPainter *p = static_cast<QPainter *>(rif->getResource(m_item->window(), QSGRendererInterface::PainterResource)); + Q_ASSERT(m_window); + + QSGRendererInterface *rif = m_window->rendererInterface(); + QPainter *p = static_cast<QPainter *>(rif->getResource(m_window, QSGRendererInterface::PainterResource)); Q_ASSERT(p); const QRegion *clipRegion = renderState->clipRegion(); @@ -81,15 +78,15 @@ void SoftwareRenderNode::render(const RenderState *renderState) p->setTransform(matrix()->toTransform()); p->setOpacity(inheritedOpacity()); - const QPointF p0(m_item->width() - 1, m_item->height() - 1); + const QPointF p0(m_width - 1, m_height - 1); const QPointF p1(0, 0); - const QPointF p2(0, m_item->height() - 1); + const QPointF p2(0, m_height - 1); QPainterPath path(p0); path.lineTo(p1); path.lineTo(p2); path.closeSubpath(); - QLinearGradient gradient(QPointF(0, 0), QPointF(m_item->width(), m_item->height())); + QLinearGradient gradient(QPointF(0, 0), QPointF(m_width, m_height)); gradient.setColorAt(0, Qt::green); gradient.setColorAt(1, Qt::red); @@ -108,5 +105,12 @@ QSGRenderNode::RenderingFlags SoftwareRenderNode::flags() const QRectF SoftwareRenderNode::rect() const { - return QRect(0, 0, m_item->width(), m_item->height()); + return QRect(0, 0, m_width, m_height); +} + +void SoftwareRenderNode::sync(QQuickItem *item) +{ + m_window = item->window(); + m_width = item->width(); + m_height = item->height(); } diff --git a/examples/quick/scenegraph/rendernode/softwarerenderer.h b/examples/quick/scenegraph/rendernode/softwarerenderer.h index cc2aaf7ed3..6091a13ca3 100644 --- a/examples/quick/scenegraph/rendernode/softwarerenderer.h +++ b/examples/quick/scenegraph/rendernode/softwarerenderer.h @@ -57,7 +57,6 @@ class SoftwareRenderNode : public QSGRenderNode { public: - SoftwareRenderNode(QQuickItem *item); ~SoftwareRenderNode(); void render(const RenderState *state) override; @@ -66,8 +65,12 @@ public: RenderingFlags flags() const override; QRectF rect() const override; + void sync(QQuickItem *item); + private: - QQuickItem *m_item; + QQuickWindow *m_window = nullptr; + int m_width = 0; + int m_height = 0; }; #endif |