blocking updates for nodes that are not part of the QskSceneTexture

This commit is contained in:
Uwe Rathmann 2023-12-28 16:57:58 +01:00
parent 56b1ecf707
commit bba0a680bf
3 changed files with 41 additions and 27 deletions

View File

@ -152,7 +152,6 @@ namespace
const bool useRhi = qskRenderingHardwareInterface( window );
textureNode = new FilterNode( useRhi, texture );
texture->setTextureNode( textureNode );
}
auto texture = qobject_cast< QskSceneTexture* >( textureNode->texture() );

View File

@ -29,6 +29,26 @@ QSK_QT_PRIVATE_END
#include <qopenglframebufferobject.h>
#endif
static int qskRenderOrderCompare( const QSGNode* rootNode,
const QSGNode* node1, const QSGNode* node2 )
{
if ( rootNode == node1 )
return 1;
if ( rootNode == node2 )
return -1;
for ( auto node = rootNode->firstChild();
node != nullptr; node = node->nextSibling() )
{
const auto ret = qskRenderOrderCompare( node, node1, node2 );
if ( ret )
return ret;
}
return 0;
}
namespace
{
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
@ -84,6 +104,7 @@ namespace
private:
void createTarget( const QSize& );
void clearTarget();
void markDirty();
QSGTransformNode* m_finalNode = nullptr;
QskSceneTexture* m_texture = nullptr;
@ -114,6 +135,9 @@ namespace
, m_texture( texture )
{
setClearColor( Qt::transparent );
connect( this, &QSGRenderer::sceneGraphChanged,
this, &Renderer::markDirty );
}
Renderer::~Renderer()
@ -126,6 +150,7 @@ namespace
if ( node != m_finalNode )
{
m_finalNode = node;
markDirty();
}
}
@ -205,16 +230,25 @@ namespace
void Renderer::nodeChanged( QSGNode* node, QSGNode::DirtyState state )
{
Inherited::nodeChanged( node, state );
/*
We want to limit updates to nodes, that are actually rendered. TODO ...
No need to update the texture for changes of nodes behind
the final node.
In any case we need to block update requests, when the textureNode reports
that it has been updated by us to the renderer of the window.
Unfortunately QQuickWindow does not update the scene graph in
rendering order and we might be called for relevant nodes after
the texture has already been updated. In these situations we
update the texture twice. Not so good ...
*/
if ( ( state != QSGNode::DirtyMaterial )
|| ( node != m_texture->textureNode() ) )
if ( qskRenderOrderCompare( rootNode(), node, m_finalNode ) > 0 )
{
// triggering QSGRenderer::sceneGraphChanged signals
Inherited::nodeChanged( node, state );
}
}
void Renderer::markDirty()
{
if ( !m_dirty )
{
m_dirty = true;
Q_EMIT m_texture->updateRequested();
@ -352,8 +386,6 @@ class QskSceneTexturePrivate final : public QSGTexturePrivate
Renderer* renderer = nullptr;
QSGDefaultRenderContext* context = nullptr;
const QSGGeometryNode* textureNode = nullptr;
};
QskSceneTexture::QskSceneTexture( const QQuickWindow* window )
@ -367,16 +399,6 @@ QskSceneTexture::~QskSceneTexture()
delete d_func()->renderer;
}
void QskSceneTexture::setTextureNode( const QSGGeometryNode* node )
{
d_func()->textureNode = node;
}
const QSGGeometryNode* QskSceneTexture::textureNode() const
{
return d_func()->textureNode;
}
QSize QskSceneTexture::textureSize() const
{
Q_D( const QskSceneTexture );

View File

@ -13,7 +13,6 @@ class QskSceneTexturePrivate;
class QSGRootNode;
class QSGTransformNode;
class QSGGeometryNode;
class QQuickWindow;
class QSK_EXPORT QskSceneTexture : public QSGTexture
@ -26,12 +25,6 @@ class QSK_EXPORT QskSceneTexture : public QSGTexture
QskSceneTexture( const QQuickWindow* );
~QskSceneTexture();
#if 1
// to avoid recursive update - need to find a better solution TODO
void setTextureNode( const QSGGeometryNode* );
const QSGGeometryNode* textureNode() const;
#endif
void render( const QSGRootNode*, const QSGTransformNode*, const QRectF& );
QSize textureSize() const override;