better detection of the dirty flags

This commit is contained in:
Uwe Rathmann 2024-09-23 15:55:00 +02:00
parent 591fc55479
commit c9f7bf59ee
2 changed files with 73 additions and 46 deletions

View File

@ -67,6 +67,8 @@ void QskBoxNode::updateNode( const QRectF& rect,
QskBoxRectangleNode* rectNode = nullptr; QskBoxRectangleNode* rectNode = nullptr;
QskBoxRectangleNode* fillNode = nullptr; QskBoxRectangleNode* fillNode = nullptr;
if ( !rect.isEmpty() )
{
if ( !shadowMetrics.isNull() if ( !shadowMetrics.isNull()
&& shadowColor.isValid() && shadowColor.alpha() != 0 ) && shadowColor.isValid() && shadowColor.alpha() != 0 )
{ {
@ -94,6 +96,7 @@ void QskBoxNode::updateNode( const QRectF& rect,
fillNode->updateFilling( rect, shape, borderMetrics, gradient ); fillNode->updateFilling( rect, shape, borderMetrics, gradient );
} }
} }
}
qskUpdateChildren( this, ShadowRole, shadowNode ); qskUpdateChildren( this, ShadowRole, shadowNode );
qskUpdateChildren( this, BoxRole, rectNode ); qskUpdateChildren( this, BoxRole, rectNode );

View File

@ -12,6 +12,12 @@
#include "QskGradientDirection.h" #include "QskGradientDirection.h"
#include "QskFillNodePrivate.h" #include "QskFillNodePrivate.h"
static inline bool qskHasBorder(
const QskBoxBorderMetrics& metrics, const QskBoxBorderColors& colors )
{
return !metrics.isNull() && colors.isVisible();
}
class QskBoxRectangleNodePrivate final : public QskFillNodePrivate class QskBoxRectangleNodePrivate final : public QskFillNodePrivate
{ {
public: public:
@ -21,7 +27,7 @@ class QskBoxRectangleNodePrivate final : public QskFillNodePrivate
node->resetGeometry(); node->resetGeometry();
} }
bool updateMetrics( const QRectF& rect, inline bool updateMetrics( const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics ) const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics )
{ {
QskHashValue hash = 13000; QskHashValue hash = 13000;
@ -30,10 +36,11 @@ class QskBoxRectangleNodePrivate final : public QskFillNodePrivate
hash = shape.hash( hash ); hash = shape.hash( hash );
hash = borderMetrics.hash( hash ); hash = borderMetrics.hash( hash );
return updateValue( m_metricsHash, hash ); return updateHash( m_metricsHash, hash );
} }
bool updateColors( const QskBoxBorderColors& borderColors, const QskGradient& gradient ) inline bool updateColors(
const QskBoxBorderColors& borderColors, const QskGradient& gradient )
{ {
QskHashValue hash = 13000; QskHashValue hash = 13000;
@ -43,11 +50,11 @@ class QskBoxRectangleNodePrivate final : public QskFillNodePrivate
if ( gradient.isVisible() ) if ( gradient.isVisible() )
hash = gradient.hash( hash ); hash = gradient.hash( hash );
return updateValue( m_colorsHash, hash ); return updateHash( m_colorsHash, hash );
} }
private: private:
inline bool updateValue( QskHashValue& value, const QskHashValue newValue ) const inline bool updateHash( QskHashValue& value, const QskHashValue newValue ) const
{ {
if ( newValue != value ) if ( newValue != value )
{ {
@ -102,11 +109,13 @@ void QskBoxRectangleNode::updateFilling( const QRectF& rect,
const bool coloredGeometry = hasHint( PreferColoredGeometry ) const bool coloredGeometry = hasHint( PreferColoredGeometry )
&& QskBoxRenderer::isGradientSupported( fillGradient ); && QskBoxRenderer::isGradientSupported( fillGradient );
const bool dirtyMetrics = d->updateMetrics( rect, shape, borderMetrics ); bool dirtyGeometry = d->updateMetrics( rect, shape, borderMetrics );
const bool dirtyColors = d->updateColors( QskBoxBorderColors(), fillGradient ) bool dirtyMaterial = d->updateColors( QskBoxBorderColors(), fillGradient );
&& ( coloredGeometry == isGeometryColored() );
if ( dirtyMetrics || dirtyColors ) if ( coloredGeometry != isGeometryColored() )
dirtyGeometry = dirtyMaterial = true;
if ( dirtyGeometry || dirtyMaterial )
{ {
if ( coloredGeometry ) if ( coloredGeometry )
{ {
@ -121,16 +130,15 @@ void QskBoxRectangleNode::updateFilling( const QRectF& rect,
{ {
if ( fillGradient.isMonochrome() ) if ( fillGradient.isMonochrome() )
{ {
if ( dirtyColors ) if ( dirtyMaterial )
setColoring( fillGradient.rgbStart() ); setColoring( fillGradient.rgbStart() );
} }
else else
{ {
// dirtyMetrics: the shader also depends on rect !
setColoring( rect, fillGradient ); setColoring( rect, fillGradient );
} }
if ( dirtyMetrics ) if ( dirtyGeometry )
{ {
QskBoxRenderer::setFillLines( QskBoxRenderer::setFillLines(
rect, shape, borderMetrics, *geometry() ); rect, shape, borderMetrics, *geometry() );
@ -147,29 +155,45 @@ void QskBoxRectangleNode::updateBorder( const QRectF& rect,
{ {
Q_D( QskBoxRectangleNode ); Q_D( QskBoxRectangleNode );
if ( rect.isEmpty() || borderMetrics.isNull() || !borderColors.isVisible() ) if ( rect.isEmpty() || !qskHasBorder( borderMetrics, borderColors ) )
{ {
d->resetNode( this ); d->resetNode( this );
return; return;
} }
const bool dirtyMetrics = d->updateMetrics( rect, shape, borderMetrics ); const bool coloredGeometry = hasHint( PreferColoredGeometry )
const bool dirtyColors = d->updateColors( borderColors, QskGradient() ); || !borderColors.isMonochrome();
if ( dirtyMetrics || dirtyColors ) bool dirtyGeometry = d->updateMetrics( rect, shape, borderMetrics );
bool dirtyMaterial = d->updateColors( borderColors, QskGradient() );
if ( coloredGeometry != isGeometryColored() )
dirtyGeometry = dirtyMaterial = true;
if ( dirtyGeometry || dirtyMaterial )
{ {
const auto coloring = QskFillNode::Polychrome; if ( coloredGeometry )
{
setColoring( QskFillNode::Polychrome );
if ( coloring == QskFillNode::Polychrome ) QskBoxRenderer::setColoredBorderLines( rect, shape,
setColoring( coloring ); borderMetrics, borderColors, *geometry() );
else
setColoring( borderColors.left().rgbStart() );
QskBoxRenderer::setColoredBorderLines( rect, shape, borderMetrics,
borderColors, *this->geometry() );
markDirty( QSGNode::DirtyGeometry ); markDirty( QSGNode::DirtyGeometry );
} }
else
{
setColoring( borderColors.left().rgbStart() );
if ( dirtyGeometry )
{
QskBoxRenderer::setBorderLines( rect, shape,
borderMetrics, *geometry() );
markDirty( QSGNode::DirtyGeometry );
}
}
}
} }
void QskBoxRectangleNode::updateBox( const QRectF& rect, void QskBoxRectangleNode::updateBox( const QRectF& rect,
@ -185,14 +209,14 @@ void QskBoxRectangleNode::updateBox( const QRectF& rect,
} }
const bool hasFill = gradient.isVisible(); const bool hasFill = gradient.isVisible();
const bool hasBorder = !borderMetrics.isNull() && borderColors.isVisible(); const bool hasBorder = qskHasBorder( borderMetrics, borderColors );
if ( hasFill && hasBorder ) if ( hasFill && hasBorder )
{ {
const bool dirtyMetrics = d->updateMetrics( rect, shape, borderMetrics ); const bool isDirty = d->updateMetrics( rect, shape, borderMetrics )
const bool dirtyColors = d->updateColors( borderColors, gradient ); || d->updateColors( borderColors, gradient ) || !isGeometryColored();
if ( dirtyMetrics || dirtyColors ) if ( isDirty )
{ {
/* /*
For monochrome border/fiiling with the same color we might be For monochrome border/fiiling with the same color we might be