being more careful with setting the dirty bits of a QskBoxShadowNode

This commit is contained in:
Uwe Rathmann 2022-06-15 10:59:39 +02:00
parent 49bc726376
commit 824325eccf
6 changed files with 80 additions and 131 deletions

View File

@ -135,27 +135,21 @@ QSGNode* LightDisplaySkinlet::updateSubNode(
{ {
return updateBoxNode( skinnable, node, LightDisplay::Panel ); return updateBoxNode( skinnable, node, LightDisplay::Panel );
} }
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
case GrooveRole: case GrooveRole:
{ {
const QRectF grooveRect = display->subControlRect( LightDisplay::Groove ); const QRectF grooveRect = display->subControlRect( LightDisplay::Groove );
if ( grooveRect.isEmpty() ) if ( grooveRect.isEmpty() )
return nullptr; return nullptr;
auto shadowNode = QskSGNode::ensureNode< QskBoxShadowNode >( node );
const auto& shadowMetrics = display->shadow(); const auto& shadowMetrics = display->shadow();
const auto shadowRect = shadowMetrics.shadowRect( grooveRect );
shadowNode->setRect( shadowMetrics.shadowRect( grooveRect ) ); auto shadowNode = QskSGNode::ensureNode< QskBoxShadowNode >( node );
shadowNode->setShape( grooveRect.width() / 2 ); shadowNode->setShadowData( shadowRect, grooveRect.width() / 2,
shadowNode->setBlurRadius( shadowMetrics.blurRadius() ); shadowMetrics.blurRadius(), display->shadowColor() );
shadowNode->setColor( display->shadowColor() );
shadowNode->updateGeometry();
return shadowNode; return shadowNode;
} }
#endif
case ColdAndWarmArcRole: case ColdAndWarmArcRole:
{ {
return updateArcNode( skinnable, node, LightDisplay::ColdAndWarmArc ); return updateArcNode( skinnable, node, LightDisplay::ColdAndWarmArc );

View File

@ -55,12 +55,8 @@ namespace
auto shadowNode = QskSGNode::ensureNode< QskBoxShadowNode >( node ); auto shadowNode = QskSGNode::ensureNode< QskBoxShadowNode >( node );
shadowNode->setRect( shadowMetrics.shadowRect( r ) ); shadowNode->setShadowData( shadowMetrics.shadowRect( r ),
shadowNode->setShape( box->shape() ); box->shape(), shadowMetrics.blurRadius(), box->shadowColor() );
shadowNode->setBlurRadius( shadowMetrics.blurRadius() );
shadowNode->setColor( box->shadowColor() );
shadowNode->updateGeometry();
return shadowNode; return shadowNode;
} }

View File

@ -268,15 +268,21 @@ QskBoxShadowNode::~QskBoxShadowNode()
{ {
} }
void QskBoxShadowNode::setRect( const QRectF& rect ) void QskBoxShadowNode::setShadowData(
const QRectF& rect, const QskBoxShapeMetrics& shape,
qreal blurRadius, const QColor& color )
{ {
Q_D( QskBoxShadowNode ); Q_D( QskBoxShadowNode );
if ( rect == d->rect ) if ( rect != d->rect )
return; {
d->rect = rect; d->rect = rect;
QSGGeometry::updateTexturedRectGeometry(
&d->geometry, d->rect, QRectF( -0.5, -0.5, 1.0, 1.0 ) );
markDirty( QSGNode::DirtyGeometry );
QVector2D aspect( 1.0, 1.0 ); QVector2D aspect( 1.0, 1.0 );
if ( rect.width() >= rect.height() ) if ( rect.width() >= rect.height() )
@ -289,12 +295,9 @@ void QskBoxShadowNode::setRect( const QRectF& rect )
d->material.m_aspect = aspect; d->material.m_aspect = aspect;
markDirty( QSGNode::DirtyMaterial ); markDirty( QSGNode::DirtyMaterial );
} }
} }
void QskBoxShadowNode::setShape( const QskBoxShapeMetrics& shape )
{
Q_D( QskBoxShadowNode );
{
const float t = std::min( d->rect.width(), d->rect.height() ); const float t = std::min( d->rect.width(), d->rect.height() );
const float r1 = shape.radius( Qt::BottomRightCorner ).width(); const float r1 = shape.radius( Qt::BottomRightCorner ).width();
@ -309,30 +312,11 @@ void QskBoxShadowNode::setShape( const QskBoxShapeMetrics& shape )
if ( d->material.m_radius != uniformRadius ) if ( d->material.m_radius != uniformRadius )
{ {
d->material.m_radius = uniformRadius; d->material.m_radius = uniformRadius;
markDirty( QSGNode::DirtyMaterial ); markDirty( QSGNode::DirtyMaterial );
} }
} }
void QskBoxShadowNode::setColor( const QColor& color )
{
Q_D( QskBoxShadowNode );
const auto a = color.alphaF();
const QVector4D c( color.redF() * a, color.greenF() * a, color.blueF() * a, a );
if ( d->material.m_color != c )
{ {
d->material.m_color = c;
markDirty( QSGNode::DirtyMaterial );
}
}
void QskBoxShadowNode::setBlurRadius( qreal blurRadius )
{
Q_D( QskBoxShadowNode );
if ( blurRadius <= 0.0 ) if ( blurRadius <= 0.0 )
blurRadius = 0.0; blurRadius = 0.0;
@ -344,22 +328,17 @@ void QskBoxShadowNode::setBlurRadius( qreal blurRadius )
d->material.m_blurExtent = uniformExtent; d->material.m_blurExtent = uniformExtent;
markDirty( QSGNode::DirtyMaterial ); markDirty( QSGNode::DirtyMaterial );
} }
} }
void QskBoxShadowNode::setClipShape( const QskBoxShapeMetrics& ) {
{ const auto a = color.alphaF();
/*
Usually only the parts, that are not covered by the related box const QVector4D c( color.redF() * a, color.greenF() * a, color.blueF() * a, a );
should be painted. TODO ...
*/ if ( d->material.m_color != c )
} {
d->material.m_color = c;
void QskBoxShadowNode::updateGeometry() markDirty( QSGNode::DirtyMaterial );
{ }
Q_D( QskBoxShadowNode ); }
QSGGeometry::updateTexturedRectGeometry(
&d->geometry, d->rect, QRectF( -0.5, -0.5, 1.0, 1.0 ) );
markDirty( QSGNode::DirtyGeometry );
} }

View File

@ -20,14 +20,8 @@ class QSK_EXPORT QskBoxShadowNode : public QSGGeometryNode
QskBoxShadowNode(); QskBoxShadowNode();
~QskBoxShadowNode() override; ~QskBoxShadowNode() override;
void setRect( const QRectF& ); void setShadowData( const QRectF&, const QskBoxShapeMetrics&,
void setShape( const QskBoxShapeMetrics& ); qreal blurRadius, const QColor& );
void setColor( const QColor& );
void setBlurRadius( qreal );
void setClipShape( const QskBoxShapeMetrics& );
void updateGeometry();
private: private:
Q_DECLARE_PRIVATE( QskBoxShadowNode ) Q_DECLARE_PRIVATE( QskBoxShadowNode )

View File

@ -24,14 +24,9 @@ void QskShadedBoxNode::setBoxData( const QRectF& rect,
const QskShadowMetrics& shadowMetrics, const QColor& shadowColor ) const QskShadowMetrics& shadowMetrics, const QColor& shadowColor )
{ {
m_boxNode.setBoxData( rect, shape, borderMetrics, borderColors, gradient ); m_boxNode.setBoxData( rect, shape, borderMetrics, borderColors, gradient );
setShadowData( rect, shape, shadowMetrics, shadowColor );
}
void QskShadedBoxNode::setShadowData( if ( shadowMetrics.isNull()
const QRectF& rect, const QskBoxShapeMetrics& shape, || !shadowColor.isValid() || shadowColor.alpha() == 0 )
const QskShadowMetrics& metrics, const QColor& color )
{
if ( metrics.isNull() || !color.isValid() || color.alpha() == 0 )
{ {
if ( m_shadowNode ) if ( m_shadowNode )
{ {
@ -48,13 +43,7 @@ void QskShadedBoxNode::setShadowData(
insertChildNodeBefore( m_shadowNode, &m_boxNode ); insertChildNodeBefore( m_shadowNode, &m_boxNode );
} }
m_shadowNode->setColor( color ); m_shadowNode->setShadowData( shadowMetrics.shadowRect( rect ),
shape, shadowMetrics.blurRadius(), shadowColor );
m_shadowNode->setRect( metrics.shadowRect( rect ) );
m_shadowNode->setShape( shape );
m_shadowNode->setBlurRadius( metrics.blurRadius() );
m_shadowNode->setClipShape( shape );
m_shadowNode->updateGeometry();
} }
} }

View File

@ -24,9 +24,6 @@ class QSK_EXPORT QskShadedBoxNode : public QSGNode
const QskShadowMetrics&, const QColor& shadowColor ); const QskShadowMetrics&, const QColor& shadowColor );
private: private:
void setShadowData( const QRectF&, const QskBoxShapeMetrics&,
const QskShadowMetrics&, const QColor& );
QskBoxNode m_boxNode; QskBoxNode m_boxNode;
QskBoxShadowNode* m_shadowNode = nullptr; QskBoxShadowNode* m_shadowNode = nullptr;
}; };