Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit e0d24657 authored by Michael Pyne's avatar Michael Pyne

Use a cache of pixmaps for the covers instead of keeping them all loaded in

memory.  The default size is large enough to hold two full 1024x768 screenfuls
of pixmaps.

svn path=/trunk/KDE/kdemultimedia/juk/; revision=414825
parent 35b789f6
......@@ -21,6 +21,7 @@
#include <qdir.h>
#include <qdatastream.h>
#include <qdict.h>
#include <qcache.h>
#include <kdebug.h>
#include <kstaticdeleter.h>
......@@ -38,6 +39,10 @@ typedef QDict<coverKey> TrackLookupMap;
// gets properly destructed on shutdown.
static KStaticDeleter<CoverManagerPrivate> sd;
// Caches the QPixmaps for the covers so that the covers are not all kept in
// memory for no reason.
typedef QCache<QPixmap> CoverPixmapCache;
CoverManagerPrivate *CoverManager::m_data = 0;
// Used to save and load CoverData from a QDataStream
......@@ -50,26 +55,12 @@ QDataStream &operator>>(QDataStream &in, CoverData &data);
QPixmap CoverData::pixmap() const
{
if(m_pixmap.isNull())
m_pixmap = QPixmap(path);
return m_pixmap;
return CoverManager::coverFromData(*this, CoverManager::FullSize);
}
QPixmap CoverData::thumbnail() const
{
if(!m_thumbnail.isNull())
return m_thumbnail;
QPixmap base = pixmap();
if(base.isNull())
return QPixmap();
// Convert to image for smoothScale()
QImage image = base.convertToImage();
m_thumbnail.convertFromImage(image.smoothScale(80, 80));
return m_thumbnail;
return CoverManager::coverFromData(*this, CoverManager::Thumbnail);
}
/**
......@@ -90,9 +81,15 @@ public:
/// Maps file names to coverKey id's.
TrackLookupMap tracks;
CoverManagerPrivate() : tracks(1301)
/// A cache of the cover representations. The key format is:
/// 'f' followed by the pathname for FullSize covers, and
/// 't' followed by the pathname for Thumbnail covers.
CoverPixmapCache pixmapCache;
CoverManagerPrivate() : tracks(1301), pixmapCache(2 * 1024 * 768)
{
loadCovers();
pixmapCache.setAutoDelete(true);
}
~CoverManagerPrivate()
......@@ -269,6 +266,43 @@ QPixmap CoverManager::coverFromId(coverKey id, Size size)
return info->pixmap();
}
QPixmap CoverManager::coverFromData(const CoverData &coverData, Size size)
{
QString path = coverData.path;
// Prepend a tag to the path to separate in the cache between full size
// and thumbnail pixmaps. If we add a different kind of pixmap in the
// future we also need to add a tag letter for it.
if(size == FullSize)
path.prepend('f');
else
path.prepend('t');
// Check in cache for the pixmap.
QPixmap *pix = data()->pixmapCache[path];
if(pix) {
kdDebug(65432) << "Found pixmap in cover cache.\n";
return *pix;
}
// Not in cache, load it and add it.
pix = new QPixmap(coverData.path);
if(pix->isNull())
return QPixmap();
if(size == Thumbnail) {
// Convert to image for smoothScale()
QImage image = pix->convertToImage();
pix->convertFromImage(image.smoothScale(80, 80));
}
QPixmap returnValue = *pix; // Save it early.
if(!data()->pixmapCache.insert(path, pix, pix->height() * pix->width()))
delete pix;
return returnValue;
}
coverKey CoverManager::addCover(const QPixmap &large, const QString &artist, const QString &album)
{
kdDebug() << k_funcinfo << endl;
......@@ -294,7 +328,6 @@ coverKey CoverManager::addCover(const QPixmap &large, const QString &artist, con
return NoMatch;
}
coverData->setPixmap(large);
coverData->artist = artist.lower();
coverData->album = album.lower();
......@@ -336,7 +369,10 @@ bool CoverManager::replaceCover(coverKey id, const QPixmap &large)
return false;
CoverDataPtr coverData = coverInfo(id);
coverData->setPixmap(large);
// Empty old pixmaps from cache.
data()->pixmapCache.remove(QString("%1%2").arg("t", coverData->path));
data()->pixmapCache.remove(QString("%1%2").arg("f", coverData->path));
large.save(coverData->path, "PNG");
return true;
......
......@@ -38,19 +38,9 @@ public:
QPixmap pixmap() const;
QPixmap thumbnail() const;
void setPixmap(const QPixmap &pixmap)
{
m_pixmap = pixmap;
m_thumbnail = QPixmap();
}
QString artist;
QString album;
QString path;
private:
mutable QPixmap m_pixmap;
mutable QPixmap m_thumbnail;
};
typedef KSharedPtr<CoverData> CoverDataPtr;
......@@ -99,6 +89,17 @@ public:
*/
static QPixmap coverFromId(coverKey id, Size size = Thumbnail);
/**
* Returns the cover art for @p ptr. This function is intended for use
* by CoverData.
*
* @param ptr The CoverData to get the cover of. Note that it is a
* CoverData, not CoverDataPtr.
* @param size The size to return it as.
* @see CoverData
*/
static QPixmap coverFromData(const CoverData &coverData, Size size = Thumbnail);
/**
* Returns the full suite of information known about the cover given by
* @p id.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment