classes moved from parrot to src/nodes
This commit is contained in:
parent
3e32a14264
commit
e0acd82619
|
@ -6,7 +6,6 @@
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
Overlay.h Overlay.cpp
|
Overlay.h Overlay.cpp
|
||||||
BlurringNode.h BlurringNode.cpp
|
BlurringNode.h BlurringNode.cpp
|
||||||
SceneTexture.h SceneTexture.cpp
|
|
||||||
main.cpp)
|
main.cpp)
|
||||||
|
|
||||||
qt_add_resources(SOURCES images.qrc shaders.qrc)
|
qt_add_resources(SOURCES images.qrc shaders.qrc)
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
|
|
||||||
#include "Overlay.h"
|
#include "Overlay.h"
|
||||||
#include "BlurringNode.h"
|
#include "BlurringNode.h"
|
||||||
#include "SceneTexture.h"
|
|
||||||
|
|
||||||
|
#include <QskSceneTexture.h>
|
||||||
#include <QskTreeNode.h>
|
#include <QskTreeNode.h>
|
||||||
|
|
||||||
#include <private/qquickitem_p.h>
|
#include <private/qquickitem_p.h>
|
||||||
|
@ -112,9 +112,6 @@ QSGNode* Overlay::updatePaintNode( QSGNode* oldNode, UpdatePaintNodeData* )
|
||||||
|
|
||||||
auto grabbedNode = d->grabbedNode();
|
auto grabbedNode = d->grabbedNode();
|
||||||
|
|
||||||
if ( grabbedNode == nullptr )
|
|
||||||
QMetaObject::invokeMethod( this, &QQuickItem::update );
|
|
||||||
|
|
||||||
if ( grabbedNode == nullptr || size().isEmpty() )
|
if ( grabbedNode == nullptr || size().isEmpty() )
|
||||||
{
|
{
|
||||||
delete oldNode;
|
delete oldNode;
|
||||||
|
@ -127,26 +124,30 @@ QSGNode* Overlay::updatePaintNode( QSGNode* oldNode, UpdatePaintNodeData* )
|
||||||
{
|
{
|
||||||
node = new BlurringNode();
|
node = new BlurringNode();
|
||||||
|
|
||||||
auto texture = new SceneTexture( d->sceneGraphRenderContext() );
|
auto texture = new QskSceneTexture( d->sceneGraphRenderContext() );
|
||||||
texture->setDevicePixelRatio( window()->effectiveDevicePixelRatio() );
|
texture->setDevicePixelRatio( window()->effectiveDevicePixelRatio() );
|
||||||
|
|
||||||
|
connect( texture, &QskSceneTexture::updateRequested,
|
||||||
|
this, &QQuickItem::update );
|
||||||
|
|
||||||
node->setTexture( texture );
|
node->setTexture( texture );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto texture = static_cast< SceneTexture* >( node->texture() );
|
auto texture = qobject_cast< QskSceneTexture* >( node->texture() );
|
||||||
|
Q_ASSERT( texture );
|
||||||
|
|
||||||
if ( !texture->isRendering() )
|
texture->setFiltering( smooth() ? QSGTexture::Linear : QSGTexture::Nearest );
|
||||||
{
|
|
||||||
texture->setFiltering( smooth() ? QSGTexture::Linear : QSGTexture::Nearest );
|
|
||||||
|
|
||||||
texture->render( grabbedNode, d->itemNode(),
|
texture->render( grabbedNode, d->itemNode(),
|
||||||
QRectF( x(), y(), width(), height() ) );
|
QRectF( x(), y(), width(), height() ) );
|
||||||
|
|
||||||
QMetaObject::invokeMethod( this, &QQuickItem::update );
|
|
||||||
}
|
|
||||||
|
|
||||||
node->setRect( QRectF( 0, 0, width(), height() ) );
|
node->setRect( QRectF( 0, 0, width(), height() ) );
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// always updating ...
|
||||||
|
QMetaObject::invokeMethod( this, &QQuickItem::update );
|
||||||
|
#endif
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,263 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include "SceneTexture.h"
|
|
||||||
|
|
||||||
#include <QskTreeNode.h>
|
|
||||||
#include <private/qsgbatchrenderer_p.h>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
class Renderer : public QSGBatchRenderer::Renderer
|
|
||||||
{
|
|
||||||
using Inherited = QSGBatchRenderer::Renderer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Renderer( QSGDefaultRenderContext* context )
|
|
||||||
: Inherited( context, renderMode( context ) )
|
|
||||||
{
|
|
||||||
setClearColor( Qt::transparent );
|
|
||||||
}
|
|
||||||
|
|
||||||
~Renderer() override
|
|
||||||
{
|
|
||||||
clearTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFinalNode( QSGTransformNode* node )
|
|
||||||
{
|
|
||||||
if ( node != m_finalNode )
|
|
||||||
{
|
|
||||||
m_finalNode = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QRhiTexture* texture() const { return m_rhiTexture; }
|
|
||||||
|
|
||||||
void setProjection( const QRectF& rect )
|
|
||||||
{
|
|
||||||
const auto rhi = context()->rhi();
|
|
||||||
|
|
||||||
auto r = rect;
|
|
||||||
|
|
||||||
if ( rhi->isYUpInFramebuffer() )
|
|
||||||
{
|
|
||||||
r.moveTop( r.bottom() );
|
|
||||||
r.setHeight( -r.height() );
|
|
||||||
}
|
|
||||||
|
|
||||||
MatrixTransformFlags matrixFlags;
|
|
||||||
|
|
||||||
if ( !rhi->isYUpInNDC() )
|
|
||||||
matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
|
|
||||||
|
|
||||||
setProjectionMatrixToRect( r, matrixFlags );
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTextureSize( const QSize& size )
|
|
||||||
{
|
|
||||||
if ( m_rt.rt && m_rt.rt->pixelSize() != size )
|
|
||||||
clearTarget();
|
|
||||||
|
|
||||||
if ( m_rt.rt == nullptr )
|
|
||||||
createTarget( size );
|
|
||||||
|
|
||||||
const QRect r( 0, 0, size.width(), size.height() );
|
|
||||||
|
|
||||||
setDeviceRect( r );
|
|
||||||
setViewportRect( r );
|
|
||||||
}
|
|
||||||
|
|
||||||
void render() override
|
|
||||||
{
|
|
||||||
setNodesBlocked( m_finalNode, true );
|
|
||||||
#if 0
|
|
||||||
qDebug() << "===================";
|
|
||||||
QSGNodeDumper::dump( rootNode() );
|
|
||||||
#endif
|
|
||||||
Inherited::render();
|
|
||||||
setNodesBlocked( m_finalNode, false );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setNodesBlocked( QSGNode* node, bool on )
|
|
||||||
{
|
|
||||||
setSubtreeBlocked( node, on );
|
|
||||||
|
|
||||||
for ( auto sibling = node->nextSibling();
|
|
||||||
sibling != nullptr; sibling = sibling->nextSibling() )
|
|
||||||
{
|
|
||||||
setSubtreeBlocked( sibling, on );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( node != rootNode() )
|
|
||||||
{
|
|
||||||
if ( auto upperNode = node->parent() )
|
|
||||||
{
|
|
||||||
upperNode = upperNode->nextSibling();
|
|
||||||
if ( upperNode )
|
|
||||||
setNodesBlocked( upperNode, on );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSubtreeBlocked( QSGNode* node, bool on )
|
|
||||||
{
|
|
||||||
if ( qskTrySubtreeBlocked( node, on, false ) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
for ( auto child = node->firstChild();
|
|
||||||
child != nullptr; child = child->nextSibling() )
|
|
||||||
{
|
|
||||||
setSubtreeBlocked( child, on );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void createTarget( const QSize& size )
|
|
||||||
{
|
|
||||||
const auto rhi = context()->rhi();
|
|
||||||
|
|
||||||
auto flags = QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource;
|
|
||||||
|
|
||||||
m_rhiTexture = rhi->newTexture( QRhiTexture::RGBA8, size, 1, flags );
|
|
||||||
m_rhiTexture->create();
|
|
||||||
|
|
||||||
QRhiColorAttachment color0( m_rhiTexture );
|
|
||||||
auto target = rhi->newTextureRenderTarget( { color0 } );
|
|
||||||
|
|
||||||
target->setRenderPassDescriptor(
|
|
||||||
target->newCompatibleRenderPassDescriptor() );
|
|
||||||
|
|
||||||
target->create();
|
|
||||||
|
|
||||||
m_rt.rt = target;
|
|
||||||
m_rt.rpDesc = target->renderPassDescriptor();
|
|
||||||
|
|
||||||
auto defaultContext = qobject_cast< QSGDefaultRenderContext* >( context() );
|
|
||||||
m_rt.cb = defaultContext->currentFrameCommandBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearTarget()
|
|
||||||
{
|
|
||||||
delete m_rt.rt;
|
|
||||||
m_rt.rt = nullptr;
|
|
||||||
|
|
||||||
delete m_rt.rpDesc;
|
|
||||||
m_rt.rpDesc = nullptr;
|
|
||||||
|
|
||||||
delete m_rhiTexture;
|
|
||||||
m_rhiTexture = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline QSGRendererInterface::RenderMode renderMode(
|
|
||||||
QSGDefaultRenderContext* context ) const
|
|
||||||
{
|
|
||||||
return context->useDepthBufferFor2D()
|
|
||||||
? QSGRendererInterface::RenderMode2D
|
|
||||||
: QSGRendererInterface::RenderMode2DNoDepthBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
QRhiTexture* m_rhiTexture = nullptr;
|
|
||||||
QSGTransformNode* m_finalNode = nullptr;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class SceneTexturePrivate final : public QSGTexturePrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SceneTexturePrivate( SceneTexture* texture )
|
|
||||||
: QSGTexturePrivate( texture )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF rect;
|
|
||||||
qreal devicePixelRatio = 1.0;
|
|
||||||
|
|
||||||
Renderer* renderer = nullptr;
|
|
||||||
QSGDefaultRenderContext* context = nullptr;
|
|
||||||
|
|
||||||
bool isRendering = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
SceneTexture::SceneTexture( QSGRenderContext* context )
|
|
||||||
: Inherited(*( new SceneTexturePrivate(this) ) )
|
|
||||||
{
|
|
||||||
d_func()->context = static_cast< QSGDefaultRenderContext* >( context );
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneTexture::~SceneTexture()
|
|
||||||
{
|
|
||||||
delete d_func()->renderer;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize SceneTexture::textureSize() const
|
|
||||||
{
|
|
||||||
Q_D( const SceneTexture );
|
|
||||||
|
|
||||||
QSize size( qCeil( d->rect.width() ), qCeil( d->rect.height() ) );
|
|
||||||
size *= d->devicePixelRatio;
|
|
||||||
|
|
||||||
const QSize minSize = d->context->sceneGraphContext()->minimumFBOSize();
|
|
||||||
|
|
||||||
while ( size.width() < minSize.width() )
|
|
||||||
size.rwidth() *= 2;
|
|
||||||
|
|
||||||
while ( size.height() < minSize.height() )
|
|
||||||
size.rheight() *= 2;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 SceneTexture::comparisonKey() const
|
|
||||||
{
|
|
||||||
return qint64( rhiTexture() );
|
|
||||||
}
|
|
||||||
|
|
||||||
QRhiTexture* SceneTexture::rhiTexture() const
|
|
||||||
{
|
|
||||||
Q_D( const SceneTexture );
|
|
||||||
return d->renderer ? d->renderer->texture() : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneTexture::render( QSGRootNode* rootNode,
|
|
||||||
QSGTransformNode* finalNode, const QRectF& rect )
|
|
||||||
{
|
|
||||||
Q_D( SceneTexture );
|
|
||||||
|
|
||||||
d->rect = rect;
|
|
||||||
|
|
||||||
const auto pixelSize = textureSize();
|
|
||||||
|
|
||||||
if ( d->renderer == nullptr )
|
|
||||||
{
|
|
||||||
d->renderer = new Renderer( d->context );
|
|
||||||
d->renderer->setDevicePixelRatio( d->devicePixelRatio );
|
|
||||||
}
|
|
||||||
|
|
||||||
d->renderer->setRootNode( rootNode );
|
|
||||||
d->renderer->setFinalNode( finalNode );
|
|
||||||
d->renderer->setProjection( d->rect );
|
|
||||||
d->renderer->setTextureSize( pixelSize );
|
|
||||||
|
|
||||||
d->isRendering = true;
|
|
||||||
d->renderer->renderScene();
|
|
||||||
d->isRendering = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SceneTexture::isRendering() const
|
|
||||||
{
|
|
||||||
return d_func()->isRendering;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneTexture::setDevicePixelRatio( qreal ratio )
|
|
||||||
{
|
|
||||||
d_func()->devicePixelRatio = ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF SceneTexture::normalizedTextureSubRect() const
|
|
||||||
{
|
|
||||||
return QRectF( 0, 1, 1, -1 );
|
|
||||||
}
|
|
|
@ -120,6 +120,7 @@ list(APPEND HEADERS
|
||||||
nodes/QskPaintedNode.h
|
nodes/QskPaintedNode.h
|
||||||
nodes/QskPlainTextRenderer.h
|
nodes/QskPlainTextRenderer.h
|
||||||
nodes/QskRichTextRenderer.h
|
nodes/QskRichTextRenderer.h
|
||||||
|
nodes/QskSceneTexture.h
|
||||||
nodes/QskSGNode.h
|
nodes/QskSGNode.h
|
||||||
nodes/QskStrokeNode.h
|
nodes/QskStrokeNode.h
|
||||||
nodes/QskStippledLineRenderer.h
|
nodes/QskStippledLineRenderer.h
|
||||||
|
@ -158,6 +159,7 @@ list(APPEND SOURCES
|
||||||
nodes/QskPlainTextRenderer.cpp
|
nodes/QskPlainTextRenderer.cpp
|
||||||
nodes/QskRectangleNode.cpp
|
nodes/QskRectangleNode.cpp
|
||||||
nodes/QskRichTextRenderer.cpp
|
nodes/QskRichTextRenderer.cpp
|
||||||
|
nodes/QskSceneTexture.cpp
|
||||||
nodes/QskSGNode.cpp
|
nodes/QskSGNode.cpp
|
||||||
nodes/QskStrokeNode.cpp
|
nodes/QskStrokeNode.cpp
|
||||||
nodes/QskStippledLineRenderer.cpp
|
nodes/QskStippledLineRenderer.cpp
|
||||||
|
|
|
@ -0,0 +1,268 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "QskSceneTexture.h"
|
||||||
|
#include "QskTreeNode.h"
|
||||||
|
|
||||||
|
QSK_QT_PRIVATE_BEGIN
|
||||||
|
#include <private/qsgbatchrenderer_p.h>
|
||||||
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
inline QSGRendererInterface::RenderMode contextRenderMode(
|
||||||
|
QSGDefaultRenderContext* context )
|
||||||
|
{
|
||||||
|
return context->useDepthBufferFor2D()
|
||||||
|
? QSGRendererInterface::RenderMode2D
|
||||||
|
: QSGRendererInterface::RenderMode2DNoDepthBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Renderer final : public QSGBatchRenderer::Renderer
|
||||||
|
{
|
||||||
|
using Inherited = QSGBatchRenderer::Renderer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Renderer( QskSceneTexture*, QSGDefaultRenderContext* );
|
||||||
|
~Renderer() override;
|
||||||
|
|
||||||
|
void setFinalNode( QSGTransformNode* );
|
||||||
|
QRhiTexture* texture() const { return m_rhiTexture; }
|
||||||
|
|
||||||
|
void setProjection( const QRectF& );
|
||||||
|
void setTextureSize( const QSize& );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void nodeChanged( QSGNode*, QSGNode::DirtyState ) override;
|
||||||
|
void render() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void createTarget( const QSize& );
|
||||||
|
void clearTarget();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QRhiTexture* m_rhiTexture = nullptr;
|
||||||
|
QSGTransformNode* m_finalNode = nullptr;
|
||||||
|
|
||||||
|
QskSceneTexture* m_texture = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
Renderer::Renderer( QskSceneTexture* texture, QSGDefaultRenderContext* context )
|
||||||
|
: Inherited( context, contextRenderMode( context ) )
|
||||||
|
, m_texture( texture )
|
||||||
|
{
|
||||||
|
setClearColor( Qt::transparent );
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer::~Renderer()
|
||||||
|
{
|
||||||
|
clearTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::setFinalNode( QSGTransformNode* node )
|
||||||
|
{
|
||||||
|
if ( node != m_finalNode )
|
||||||
|
{
|
||||||
|
m_finalNode = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::setProjection( const QRectF& rect )
|
||||||
|
{
|
||||||
|
const auto rhi = context()->rhi();
|
||||||
|
|
||||||
|
auto r = rect;
|
||||||
|
|
||||||
|
if ( rhi->isYUpInFramebuffer() )
|
||||||
|
{
|
||||||
|
r.moveTop( r.bottom() );
|
||||||
|
r.setHeight( -r.height() );
|
||||||
|
}
|
||||||
|
|
||||||
|
MatrixTransformFlags matrixFlags;
|
||||||
|
|
||||||
|
if ( !rhi->isYUpInNDC() )
|
||||||
|
matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
|
||||||
|
|
||||||
|
setProjectionMatrixToRect( r, matrixFlags );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::setTextureSize( const QSize& size )
|
||||||
|
{
|
||||||
|
if ( m_rt.rt && m_rt.rt->pixelSize() != size )
|
||||||
|
clearTarget();
|
||||||
|
|
||||||
|
if ( m_rt.rt == nullptr )
|
||||||
|
createTarget( size );
|
||||||
|
|
||||||
|
const QRect r( 0, 0, size.width(), size.height() );
|
||||||
|
|
||||||
|
setDeviceRect( r );
|
||||||
|
setViewportRect( r );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::render()
|
||||||
|
{
|
||||||
|
qskTryBlockTrailingNodes( m_finalNode, rootNode(), true, false );
|
||||||
|
#if 0
|
||||||
|
QSGNodeDumper::dump( rootNode() );
|
||||||
|
#endif
|
||||||
|
Inherited::render();
|
||||||
|
qskTryBlockTrailingNodes( m_finalNode, rootNode(), false, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::nodeChanged( QSGNode* node, QSGNode::DirtyState state )
|
||||||
|
{
|
||||||
|
// do not forward nodes that are blocked while rendering
|
||||||
|
|
||||||
|
const bool isTrailingNode = false; // TODO ...
|
||||||
|
|
||||||
|
if ( !isTrailingNode )
|
||||||
|
{
|
||||||
|
Inherited::nodeChanged( node, state );
|
||||||
|
Q_EMIT m_texture->updateRequested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::createTarget( const QSize& size )
|
||||||
|
{
|
||||||
|
const auto rhi = context()->rhi();
|
||||||
|
|
||||||
|
auto flags = QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource;
|
||||||
|
|
||||||
|
m_rhiTexture = rhi->newTexture( QRhiTexture::RGBA8, size, 1, flags );
|
||||||
|
m_rhiTexture->create();
|
||||||
|
|
||||||
|
QRhiColorAttachment color0( m_rhiTexture );
|
||||||
|
auto target = rhi->newTextureRenderTarget( { color0 } );
|
||||||
|
|
||||||
|
target->setRenderPassDescriptor(
|
||||||
|
target->newCompatibleRenderPassDescriptor() );
|
||||||
|
|
||||||
|
target->create();
|
||||||
|
|
||||||
|
m_rt.rt = target;
|
||||||
|
m_rt.rpDesc = target->renderPassDescriptor();
|
||||||
|
|
||||||
|
auto defaultContext = qobject_cast< QSGDefaultRenderContext* >( context() );
|
||||||
|
m_rt.cb = defaultContext->currentFrameCommandBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::clearTarget()
|
||||||
|
{
|
||||||
|
delete m_rt.rt;
|
||||||
|
m_rt.rt = nullptr;
|
||||||
|
|
||||||
|
delete m_rt.rpDesc;
|
||||||
|
m_rt.rpDesc = nullptr;
|
||||||
|
|
||||||
|
delete m_rhiTexture;
|
||||||
|
m_rhiTexture = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class QskSceneTexturePrivate final : public QSGTexturePrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QskSceneTexturePrivate( QskSceneTexture* texture )
|
||||||
|
: QSGTexturePrivate( texture )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF rect;
|
||||||
|
qreal devicePixelRatio = 1.0;
|
||||||
|
|
||||||
|
Renderer* renderer = nullptr;
|
||||||
|
QSGDefaultRenderContext* context = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
QskSceneTexture::QskSceneTexture( QSGRenderContext* context )
|
||||||
|
: Inherited(*( new QskSceneTexturePrivate(this) ) )
|
||||||
|
{
|
||||||
|
d_func()->context = static_cast< QSGDefaultRenderContext* >( context );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskSceneTexture::~QskSceneTexture()
|
||||||
|
{
|
||||||
|
delete d_func()->renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize QskSceneTexture::textureSize() const
|
||||||
|
{
|
||||||
|
Q_D( const QskSceneTexture );
|
||||||
|
|
||||||
|
QSize size( qCeil( d->rect.width() ), qCeil( d->rect.height() ) );
|
||||||
|
size *= d->devicePixelRatio;
|
||||||
|
|
||||||
|
const QSize minSize = d->context->sceneGraphContext()->minimumFBOSize();
|
||||||
|
|
||||||
|
while ( size.width() < minSize.width() )
|
||||||
|
size.rwidth() *= 2;
|
||||||
|
|
||||||
|
while ( size.height() < minSize.height() )
|
||||||
|
size.rheight() *= 2;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QskSceneTexture::comparisonKey() const
|
||||||
|
{
|
||||||
|
return qint64( rhiTexture() );
|
||||||
|
}
|
||||||
|
|
||||||
|
QRhiTexture* QskSceneTexture::rhiTexture() const
|
||||||
|
{
|
||||||
|
Q_D( const QskSceneTexture );
|
||||||
|
return d->renderer ? d->renderer->texture() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskSceneTexture::render( QSGRootNode* rootNode,
|
||||||
|
QSGTransformNode* finalNode, const QRectF& rect )
|
||||||
|
{
|
||||||
|
Q_D( QskSceneTexture );
|
||||||
|
|
||||||
|
d->rect = rect;
|
||||||
|
|
||||||
|
const auto pixelSize = textureSize();
|
||||||
|
|
||||||
|
if ( d->renderer == nullptr )
|
||||||
|
{
|
||||||
|
d->renderer = new Renderer( this, d->context );
|
||||||
|
d->renderer->setDevicePixelRatio( d->devicePixelRatio );
|
||||||
|
}
|
||||||
|
|
||||||
|
d->renderer->setRootNode( rootNode );
|
||||||
|
d->renderer->setFinalNode( finalNode );
|
||||||
|
d->renderer->setProjection( d->rect );
|
||||||
|
d->renderer->setTextureSize( pixelSize );
|
||||||
|
d->renderer->renderScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskSceneTexture::setDevicePixelRatio( qreal ratio )
|
||||||
|
{
|
||||||
|
d_func()->devicePixelRatio = ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF QskSceneTexture::normalizedTextureSubRect() const
|
||||||
|
{
|
||||||
|
return QRectF( 0, 1, 1, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskSceneTexture::hasAlphaChannel() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskSceneTexture::hasMipmaps() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskSceneTexture::commitTextureOperations( QRhi*, QRhiResourceUpdateBatch* )
|
||||||
|
{
|
||||||
|
// what to do here ?
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_QskSceneTexture.cpp"
|
|
@ -3,23 +3,27 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#ifndef QSK_SCENE_TEXTURE_H
|
||||||
|
#define QSK_SCENE_TEXTURE_H
|
||||||
|
|
||||||
|
#include "QskGlobal.h"
|
||||||
#include <qsgtexture.h>
|
#include <qsgtexture.h>
|
||||||
|
|
||||||
class SceneTexturePrivate;
|
class QskSceneTexturePrivate;
|
||||||
class QSGRenderContext;
|
class QSGRenderContext;
|
||||||
|
|
||||||
class QSGRootNode;
|
class QSGRootNode;
|
||||||
class QSGTransformNode;
|
class QSGTransformNode;
|
||||||
|
|
||||||
class SceneTexture : public QSGTexture
|
class QSK_EXPORT QskSceneTexture : public QSGTexture // QSGDynamicTexture: TODO ...
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
using Inherited = QSGTexture;
|
using Inherited = QSGTexture;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SceneTexture( QSGRenderContext* );
|
QskSceneTexture( QSGRenderContext* );
|
||||||
~SceneTexture();
|
~QskSceneTexture();
|
||||||
|
|
||||||
void setDevicePixelRatio( qreal );
|
void setDevicePixelRatio( qreal );
|
||||||
void render( QSGRootNode*, QSGTransformNode*, const QRectF& );
|
void render( QSGRootNode*, QSGTransformNode*, const QRectF& );
|
||||||
|
@ -31,13 +35,16 @@ class SceneTexture : public QSGTexture
|
||||||
|
|
||||||
QRectF normalizedTextureSubRect() const override;
|
QRectF normalizedTextureSubRect() const override;
|
||||||
|
|
||||||
bool isRendering() const;
|
// satisfy the QSGTexture API
|
||||||
|
bool hasAlphaChannel() const override;
|
||||||
|
bool hasMipmaps() const override;
|
||||||
|
void commitTextureOperations( QRhi*, QRhiResourceUpdateBatch* ) override;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void updateRequested();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// satisfy the QSGTexture API
|
Q_DECLARE_PRIVATE( QskSceneTexture )
|
||||||
bool hasAlphaChannel() const override { return false; }
|
|
||||||
bool hasMipmaps() const override { return false; }
|
|
||||||
void commitTextureOperations( QRhi*, QRhiResourceUpdateBatch* ) override {}
|
|
||||||
|
|
||||||
Q_DECLARE_PRIVATE( SceneTexture )
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -97,7 +97,7 @@ const QskItemNode* qskItemNodeCast( const QSGNode* node )
|
||||||
qskCheckedNode( node, QSGNode::TransformNodeType ) );
|
qskCheckedNode( node, QSGNode::TransformNodeType ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool qskIsNodeBlockable( const QSGNode* node )
|
bool qskIsBlockableNode( const QSGNode* node )
|
||||||
{
|
{
|
||||||
switch( node->type() )
|
switch( node->type() )
|
||||||
{
|
{
|
||||||
|
@ -110,7 +110,7 @@ bool qskIsNodeBlockable( const QSGNode* node )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool qskTrySubtreeBlocked( QSGNode* node, bool on, bool notify )
|
bool qskTryBlockNode( QSGNode* node, bool on, bool notify )
|
||||||
{
|
{
|
||||||
if ( node && ( node->flags() & extraFlag ) )
|
if ( node && ( node->flags() & extraFlag ) )
|
||||||
{
|
{
|
||||||
|
@ -129,3 +129,37 @@ bool qskTrySubtreeBlocked( QSGNode* node, bool on, bool notify )
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qskTryBlockTree( QSGNode* node, bool on, bool notify )
|
||||||
|
{
|
||||||
|
if ( qskTryBlockNode( node, on, notify ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
for ( auto child = node->firstChild();
|
||||||
|
child != nullptr; child = child->nextSibling() )
|
||||||
|
{
|
||||||
|
qskTryBlockTree( child, on, notify );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void qskTryBlockTrailingNodes(
|
||||||
|
QSGNode* node, const QSGNode* ancestorNode, bool on, bool notify )
|
||||||
|
{
|
||||||
|
qskTryBlockTree( node, on, notify );
|
||||||
|
|
||||||
|
for ( auto sibling = node->nextSibling();
|
||||||
|
sibling != nullptr; sibling = sibling->nextSibling() )
|
||||||
|
{
|
||||||
|
qskTryBlockTree( sibling, on, notify );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( node != ancestorNode )
|
||||||
|
{
|
||||||
|
if ( auto upperNode = node->parent() )
|
||||||
|
{
|
||||||
|
upperNode = upperNode->nextSibling();
|
||||||
|
if ( upperNode )
|
||||||
|
qskTryBlockTrailingNodes( upperNode, ancestorNode, on, notify );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -51,7 +51,13 @@ class QSK_EXPORT QskItemNode final : public QSGTransformNode
|
||||||
QSK_EXPORT QskItemNode* qskItemNodeCast( QSGNode* );
|
QSK_EXPORT QskItemNode* qskItemNodeCast( QSGNode* );
|
||||||
QSK_EXPORT const QskItemNode* qskItemNodeCast( const QSGNode* );
|
QSK_EXPORT const QskItemNode* qskItemNodeCast( const QSGNode* );
|
||||||
|
|
||||||
QSK_EXPORT bool qskIsNodeBlockable( const QSGNode* );
|
QSK_EXPORT bool qskIsBlockableNode( const QSGNode* );
|
||||||
QSK_EXPORT bool qskTrySubtreeBlocked( QSGNode*, bool on, bool notify = true );
|
QSK_EXPORT bool qskTryBlockNode( QSGNode*, bool on, bool notify = true );
|
||||||
|
|
||||||
|
QSK_EXPORT void qskTryBlockTree( QSGNode*, bool on, bool notify = true );
|
||||||
|
|
||||||
|
// un/block a node and all its successors in the rendering pipeline
|
||||||
|
QSK_EXPORT void qskTryBlockTrailingNodes(
|
||||||
|
QSGNode*, const QSGNode* ancestorNode, bool on, bool notify = true );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue