6#include "QskColorRamp.h"
7#include "QskRgbValue.h"
10#include <private/qrhi_p.h>
11#include <private/qsgplaintexture_p.h>
14#include <qcoreapplication.h>
18 class Texture :
public QSGPlainTexture
21 Texture(
const QskGradientStops& stops, QskGradient::SpreadMode spreadMode )
29 const int size = qBound( 256, 2 * stops.count(), 1024 );
30 setImage( QskRgb::colorTable( size, stops ) );
32 const auto wrapMode = this->wrapMode( spreadMode );
34 setHorizontalWrapMode( wrapMode );
35 setVerticalWrapMode( wrapMode );
37 setFiltering( QSGTexture::Linear );
41 static inline QSGTexture::WrapMode wrapMode( QskGradient::SpreadMode spreadMode )
45 case QskGradient::RepeatSpread:
46 return QSGTexture::Repeat;
48 case QskGradient::ReflectSpread:
49 return QSGTexture::MirroredRepeat;
52 return QSGTexture::ClampToEdge;
60 inline bool operator==(
const HashKey& other )
const
62 return rhi == other.rhi && spreadMode == other.spreadMode && stops == other.stops;
66 const QskGradientStops stops;
67 const QskGradient::SpreadMode spreadMode;
70 inline size_t qHash(
const HashKey& key,
size_t seed = 0 )
72 size_t values = seed + key.spreadMode;
74 for (
const auto& stop : key.stops )
83 ~Cache() { qDeleteAll( m_hashTable ); }
85 void cleanupRhi(
const QRhi* );
87 Texture* texture(
const void* rhi,
88 const QskGradientStops&, QskGradient::SpreadMode );
91 QHash< HashKey, Texture* > m_hashTable;
92 QVector< const QRhi* > m_rhiTable;
95 static Cache* s_cache;
98static void qskCleanupCache()
104static void qskCleanupRhi(
const QRhi* rhi )
107 s_cache->cleanupRhi( rhi );
110Texture* Cache::texture(
const void* rhi,
111 const QskGradientStops& stops, QskGradient::SpreadMode spreadMode )
113 const HashKey key { rhi, stops, spreadMode };
115 auto texture = m_hashTable[key];
116 if ( texture ==
nullptr )
118 texture =
new Texture( stops, spreadMode );
119 m_hashTable[ key ] = texture;
121 if ( rhi !=
nullptr )
123 auto myrhi = ( QRhi* )rhi;
125 if ( !m_rhiTable.contains( myrhi ) )
127 myrhi->addCleanupCallback( qskCleanupRhi );
136void Cache::cleanupRhi(
const QRhi* rhi )
138 for (
auto it = m_hashTable.begin(); it != m_hashTable.end(); )
140 if ( it.key().rhi == rhi )
143 it = m_hashTable.erase( it );
151 m_rhiTable.removeAll( rhi );
154QSGTexture* QskColorRamp::texture(
const void* rhi,
155 const QskGradientStops& stops, QskGradient::SpreadMode spreadMode )
157 if ( s_cache ==
nullptr )
159 s_cache =
new Cache();
167 qAddPostRoutine( qskCleanupCache );
170 return s_cache->texture( rhi, stops, spreadMode );