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,31 +67,34 @@ void QskBoxNode::updateNode( const QRectF& rect,
QskBoxRectangleNode* rectNode = nullptr;
QskBoxRectangleNode* fillNode = nullptr;
if ( !shadowMetrics.isNull()
&& shadowColor.isValid() && shadowColor.alpha() != 0 )
if ( !rect.isEmpty() )
{
shadowNode = qskNode< QskBoxShadowNode >( this, ShadowRole );
shadowNode->setShadowData( shadowMetrics.shadowRect( rect ),
shape, shadowMetrics.blurRadius(), shadowColor );
}
if ( QskBoxRectangleNode::isCombinedGeometrySupported( gradient ) )
{
rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole );
rectNode->updateBox( rect, shape, borderMetrics, borderColors, gradient );
}
else
{
if ( !borderMetrics.isNull() && borderColors.isVisible() )
if ( !shadowMetrics.isNull()
&& shadowColor.isValid() && shadowColor.alpha() != 0 )
{
rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole );
rectNode->updateBorder( rect, shape, borderMetrics, borderColors );
shadowNode = qskNode< QskBoxShadowNode >( this, ShadowRole );
shadowNode->setShadowData( shadowMetrics.shadowRect( rect ),
shape, shadowMetrics.blurRadius(), shadowColor );
}
if ( gradient.isVisible() )
if ( QskBoxRectangleNode::isCombinedGeometrySupported( gradient ) )
{
fillNode = qskNode< QskBoxRectangleNode >( this, FillRole );
fillNode->updateFilling( rect, shape, borderMetrics, gradient );
rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole );
rectNode->updateBox( rect, shape, borderMetrics, borderColors, gradient );
}
else
{
if ( !borderMetrics.isNull() && borderColors.isVisible() )
{
rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole );
rectNode->updateBorder( rect, shape, borderMetrics, borderColors );
}
if ( gradient.isVisible() )
{
fillNode = qskNode< QskBoxRectangleNode >( this, FillRole );
fillNode->updateFilling( rect, shape, borderMetrics, gradient );
}
}
}

View File

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