hash function for QskGraphic added

This commit is contained in:
Uwe Rathmann 2021-02-05 13:21:35 +01:00
parent 1ec464a139
commit 40b257a36f
3 changed files with 50 additions and 32 deletions

View File

@ -15,6 +15,7 @@
#include <qpainter.h> #include <qpainter.h>
#include <qpainterpath.h> #include <qpainterpath.h>
#include <qpixmap.h> #include <qpixmap.h>
#include <qhashfunctions.h>
QSK_QT_PRIVATE_BEGIN QSK_QT_PRIVATE_BEGIN
#include <private/qpainter_p.h> #include <private/qpainter_p.h>
@ -328,9 +329,7 @@ class QskGraphic::PrivateData : public QSharedData
{ {
public: public:
PrivateData() PrivateData()
: boundingRect( 0.0, 0.0, -1.0, -1.0 ) : commandTypes( 0 )
, pointRect( 0.0, 0.0, -1.0, -1.0 )
, commandTypes( 0 )
, renderHints( 0 ) , renderHints( 0 )
{ {
} }
@ -342,27 +341,35 @@ class QskGraphic::PrivateData : public QSharedData
, pathInfos( other.pathInfos ) , pathInfos( other.pathInfos )
, boundingRect( other.boundingRect ) , boundingRect( other.boundingRect )
, pointRect( other.pointRect ) , pointRect( other.pointRect )
, modificationId( other.modificationId )
, commandTypes( other.commandTypes ) , commandTypes( other.commandTypes )
, renderHints( other.renderHints ) , renderHints( other.renderHints )
{ {
} }
~PrivateData()
{
}
inline bool operator==( const PrivateData& other ) const inline bool operator==( const PrivateData& other ) const
{ {
return ( renderHints == other.renderHints ) && return ( modificationId == other.modificationId ) &&
( commands == other.commands ); ( renderHints == other.renderHints ) &&
( defaultSize == other.defaultSize );
}
inline void addCommand( const QskPainterCommand& command )
{
commands += command;
static QAtomicInteger< quint64 > nextId( 1 );
modificationId = nextId.fetchAndAddRelaxed( 1 );
} }
QSizeF defaultSize; QSizeF defaultSize;
QVector< QskPainterCommand > commands; QVector< QskPainterCommand > commands;
QVector< QskGraphicPrivate::PathInfo > pathInfos; QVector< QskGraphicPrivate::PathInfo > pathInfos;
QRectF boundingRect; QRectF boundingRect = { 0.0, 0.0, -1.0, -1.0 };
QRectF pointRect; QRectF pointRect = { 0.0, 0.0, -1.0, -1.0 };
quint64 modificationId = 0;
uint commandTypes : 4; uint commandTypes : 4;
uint renderHints : 4; uint renderHints : 4;
@ -482,6 +489,8 @@ void QskGraphic::reset()
m_data->pointRect = QRectF( 0.0, 0.0, -1.0, -1.0 ); m_data->pointRect = QRectF( 0.0, 0.0, -1.0, -1.0 );
m_data->defaultSize = QSizeF(); m_data->defaultSize = QSizeF();
m_data->modificationId = 0;
delete m_paintEngine; delete m_paintEngine;
m_paintEngine = nullptr; m_paintEngine = nullptr;
} }
@ -605,9 +614,9 @@ void QskGraphic::render( QPainter* painter,
return; return;
const int numCommands = m_data->commands.size(); const int numCommands = m_data->commands.size();
const QskPainterCommand* commands = m_data->commands.constData(); const auto commands = m_data->commands.constData();
const QTransform transform = painter->transform(); const auto transform = painter->transform();
const QskGraphic::RenderHints renderHints( m_data->renderHints ); const QskGraphic::RenderHints renderHints( m_data->renderHints );
painter->save(); painter->save();
@ -836,16 +845,16 @@ QImage QskGraphic::toImage( qreal devicePixelRatio ) const
void QskGraphic::drawPath( const QPainterPath& path ) void QskGraphic::drawPath( const QPainterPath& path )
{ {
const QPainter* painter = paintEngine()->painter(); const auto painter = paintEngine()->painter();
if ( painter == nullptr ) if ( painter == nullptr )
return; return;
m_data->commands += QskPainterCommand( path ); m_data->addCommand( QskPainterCommand( path ) );
m_data->commandTypes |= QskGraphic::VectorData; m_data->commandTypes |= QskGraphic::VectorData;
if ( !path.isEmpty() ) if ( !path.isEmpty() )
{ {
const QPainterPath scaledPath = painter->transform().map( path ); const auto scaledPath = painter->transform().map( path );
QRectF pointRect = scaledPath.boundingRect(); QRectF pointRect = scaledPath.boundingRect();
QRectF boundingRect = pointRect; QRectF boundingRect = pointRect;
@ -871,7 +880,7 @@ void QskGraphic::drawPixmap( const QRectF& rect,
if ( painter == nullptr ) if ( painter == nullptr )
return; return;
m_data->commands += QskPainterCommand( rect, pixmap, subRect ); m_data->addCommand( QskPainterCommand( rect, pixmap, subRect ) );
m_data->commandTypes |= QskGraphic::RasterData; m_data->commandTypes |= QskGraphic::RasterData;
const QRectF r = painter->transform().mapRect( rect ); const QRectF r = painter->transform().mapRect( rect );
@ -886,7 +895,7 @@ void QskGraphic::drawImage( const QRectF& rect, const QImage& image,
if ( painter == nullptr ) if ( painter == nullptr )
return; return;
m_data->commands += QskPainterCommand( rect, image, subRect, flags ); m_data->addCommand( QskPainterCommand( rect, image, subRect, flags ) );
m_data->commandTypes |= QskGraphic::RasterData; m_data->commandTypes |= QskGraphic::RasterData;
const QRectF r = painter->transform().mapRect( rect ); const QRectF r = painter->transform().mapRect( rect );
@ -897,7 +906,7 @@ void QskGraphic::drawImage( const QRectF& rect, const QImage& image,
void QskGraphic::updateState( const QPaintEngineState& state ) void QskGraphic::updateState( const QPaintEngineState& state )
{ {
m_data->commands += QskPainterCommand( state ); m_data->addCommand( QskPainterCommand( state ) );
if ( state.state() & QPaintEngine::DirtyTransform ) if ( state.state() & QPaintEngine::DirtyTransform )
{ {
@ -959,12 +968,13 @@ void QskGraphic::setCommands( const QVector< QskPainterCommand >& commands )
// to calculate a proper bounding rectangle we don't simply copy // to calculate a proper bounding rectangle we don't simply copy
// the commands. // the commands.
const QskPainterCommand* cmds = commands.constData(); const auto cmds = commands.constData();
const QskColorFilter noFilter; const QskColorFilter noFilter;
const QTransform noTransform; const QTransform noTransform;
QPainter painter( this ); QPainter painter( this );
for ( int i = 0; i < numCommands; i++ ) for ( int i = 0; i < numCommands; i++ )
{ {
qskExecCommand( &painter, cmds[ i ], qskExecCommand( &painter, cmds[ i ],
@ -974,6 +984,21 @@ void QskGraphic::setCommands( const QVector< QskPainterCommand >& commands )
painter.end(); painter.end();
} }
quint64 QskGraphic::modificationId() const
{
return m_data->modificationId;
}
uint QskGraphic::hash( uint seed ) const
{
auto hash = qHash( m_data->renderHints, seed );
hash = qHash( m_data->defaultSize.width(), hash );
hash = qHash( m_data->defaultSize.height(), hash );
return qHash( m_data->modificationId, hash );
}
QskGraphic QskGraphic::fromImage( const QImage& image ) QskGraphic QskGraphic::fromImage( const QImage& image )
{ {
QskGraphic graphic; QskGraphic graphic;

View File

@ -115,6 +115,9 @@ class QSK_EXPORT QskGraphic : public QPaintDevice
static QskGraphic fromImage( const QImage& ); static QskGraphic fromImage( const QImage& );
static QskGraphic fromPixmap( const QPixmap& ); static QskGraphic fromPixmap( const QPixmap& );
quint64 modificationId() const;
uint hash( uint seed ) const;
protected: protected:
friend class QskGraphicPaintEngine; friend class QskGraphicPaintEngine;

View File

@ -12,7 +12,7 @@ static inline uint qskHash(
const QskGraphic& graphic, const QskColorFilter& colorFilter, const QskGraphic& graphic, const QskColorFilter& colorFilter,
QskTextureRenderer::RenderMode renderMode ) QskTextureRenderer::RenderMode renderMode )
{ {
uint hash = 0; uint hash = 12000;
const auto& substitutions = colorFilter.substitutions(); const auto& substitutions = colorFilter.substitutions();
if ( substitutions.size() > 0 ) if ( substitutions.size() > 0 )
@ -21,17 +21,7 @@ static inline uint qskHash(
substitutions.size() * sizeof( substitutions[ 0 ] ), hash ); substitutions.size() * sizeof( substitutions[ 0 ] ), hash );
} }
const auto& commands = graphic.commands(); hash = graphic.hash( hash );
if ( commands.size() > 0 )
{
hash = qHash( commands.constData(), hash );
}
hash = qHash( graphic.renderHints(), hash );
const QSizeF sz = graphic.defaultSize();
hash = qHashBits( &sz, sizeof( sz ), hash );
hash = qHash( renderMode, hash ); hash = qHash( renderMode, hash );
return hash; return hash;