author | simon <simon> | 2002-12-14 17:54:47 (UTC) |
---|---|---|
committer | simon <simon> | 2002-12-14 17:54:47 (UTC) |
commit | 03c4518324c328c530eb795705b6a4281d65055a (patch) (side-by-side diff) | |
tree | 903d32d360050d5eb1a65f104618d215e6f804ae | |
parent | a3b9d0a1e6ee4f1e74ac3335cb2ba67f6da30476 (diff) | |
download | opie-03c4518324c328c530eb795705b6a4281d65055a.zip opie-03c4518324c328c530eb795705b6a4281d65055a.tar.gz opie-03c4518324c328c530eb795705b6a4281d65055a.tar.bz2 |
- save a bit of memory by caching a pixmap instead
-rw-r--r-- | noncore/multimedia/opieplayer2/skin.cpp | 46 | ||||
-rw-r--r-- | noncore/multimedia/opieplayer2/skin.h | 4 |
2 files changed, 25 insertions, 25 deletions
diff --git a/noncore/multimedia/opieplayer2/skin.cpp b/noncore/multimedia/opieplayer2/skin.cpp index e9fb5a6..d6f4080 100644 --- a/noncore/multimedia/opieplayer2/skin.cpp +++ b/noncore/multimedia/opieplayer2/skin.cpp @@ -1,324 +1,324 @@ /* Copyright (C) 2002 Simon Hausmann <simon@lst.de> (C) 2002 Max Reiss <harlekin@handhelds.org> (C) 2002 L. Potter <ljp@llornkcor.com> (C) 2002 Holger Freyther <zecke@handhelds.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "skin.h" #include "singleton.h" #include <qcache.h> #include <qmap.h> #include <qtimer.h> #include <qpe/resource.h> #include <qpe/config.h> #include <assert.h> struct SkinData { typedef QMap<QString, QImage> ButtonMaskImageMap; - QImage backgroundImage; + QPixmap backgroundPixmap; QImage buttonUpImage; QImage buttonDownImage; QImage buttonMask; ButtonMaskImageMap buttonMasks; }; class SkinCache : public Singleton<SkinCache> { public: SkinCache(); SkinData *lookupAndTake( const QString &skinPath, const QString &fileNameInfix ); void store( const QString &skinPath, const QString &fileNameInfix, SkinData *data ); private: typedef QCache<SkinData> DataCache; - typedef QCache<QImage> BackgroundImageCache; + typedef QCache<QPixmap> BackgroundPixmapCache; template <class CacheType> void store( const QCache<CacheType> &cache, const QString &key, CacheType *data ); DataCache m_cache; - BackgroundImageCache m_backgroundImageCache; + BackgroundPixmapCache m_backgroundPixmapCache; }; Skin::Skin( const QString &name, const QString &fileNameInfix ) : m_fileNameInfix( fileNameInfix ) { init( name ); } Skin::Skin( const QString &fileNameInfix ) : m_fileNameInfix( fileNameInfix ) { init( defaultSkinName() ); } Skin::~Skin() { SkinCache::self().store( m_skinPath, m_fileNameInfix, d ); } void Skin::init( const QString &name ) { m_skinPath = "opieplayer2/skins/" + name; d = SkinCache::self().lookupAndTake( m_skinPath, m_fileNameInfix ); } void Skin::preload( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) { - backgroundImage(); + backgroundPixmap(); buttonUpImage(); buttonDownImage(); ( void )buttonMask( skinButtonInfo, buttonCount ); } -QImage Skin::backgroundImage() const +QPixmap Skin::backgroundPixmap() const { - if ( d->backgroundImage.isNull() ) - d->backgroundImage = loadImage( QString( "%1/background" ).arg( m_skinPath ) ); - return d->backgroundImage; + if ( d->backgroundPixmap.isNull() ) + d->backgroundPixmap = loadImage( QString( "%1/background" ).arg( m_skinPath ) ); + return d->backgroundPixmap; } QImage Skin::buttonUpImage() const { if ( d->buttonUpImage.isNull() ) d->buttonUpImage = loadImage( QString( "%1/skin%2_up" ).arg( m_skinPath ).arg( m_fileNameInfix ) ); return d->buttonUpImage; } QImage Skin::buttonDownImage() const { if ( d->buttonDownImage.isNull() ) d->buttonDownImage = loadImage( QString( "%1/skin%2_down" ).arg( m_skinPath ).arg( m_fileNameInfix ) ); return d->buttonDownImage; } QImage Skin::buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const { if ( !d->buttonMask.isNull() ) return d->buttonMask; QSize buttonAreaSize = buttonUpImage().size(); d->buttonMask = QImage( buttonAreaSize, 8, 255 ); d->buttonMask.fill( 0 ); for ( uint i = 0; i < buttonCount; ++i ) addButtonToMask( skinButtonInfo[ i ].command + 1, buttonMaskImage( skinButtonInfo[ i ].fileName ) ); return d->buttonMask; } void Skin::addButtonToMask( int tag, const QImage &maskImage ) const { if ( maskImage.isNull() ) return; uchar **dest = d->buttonMask.jumpTable(); for ( int y = 0; y < d->buttonMask.height(); y++ ) { uchar *line = dest[y]; for ( int x = 0; x < d->buttonMask.width(); x++ ) if ( !qRed( maskImage.pixel( x, y ) ) ) line[x] = tag; } } QImage Skin::buttonMaskImage( const QString &fileName ) const { SkinData::ButtonMaskImageMap::Iterator it = d->buttonMasks.find( fileName ); if ( it == d->buttonMasks.end() ) { QString prefix = m_skinPath + QString::fromLatin1( "/skin%1_mask_" ).arg( m_fileNameInfix ); QString path = prefix + fileName + ".png"; it = d->buttonMasks.insert( fileName, loadImage( path ) ); } return *it; } QString Skin::defaultSkinName() { Config cfg( "OpiePlayer" ); cfg.setGroup( "Options" ); return cfg.readEntry( "Skin", "default" ); } QImage Skin::loadImage( const QString &fileName ) { return QImage( Resource::findPixmap( fileName ) ); } SkinCache::SkinCache() { // let's say we cache two skins (audio+video) at maximum m_cache.setMaxCost( 2 ); // ... and one background pixmap - m_backgroundImageCache.setMaxCost( 1 ); + m_backgroundPixmapCache.setMaxCost( 1 ); } SkinData *SkinCache::lookupAndTake( const QString &skinPath, const QString &fileNameInfix ) { QString key = skinPath + fileNameInfix; SkinData *data = m_cache.take( key ); if ( !data ) data = new SkinData; else qDebug( "SkinCache: hit" ); - QImage *bgImage = m_backgroundImageCache.find( skinPath ); - if ( bgImage ) { - qDebug( "SkinCache: hit on bgimage" ); - data->backgroundImage = *bgImage; + QPixmap *bgPixmap = m_backgroundPixmapCache.find( skinPath ); + if ( bgPixmap ) { + qDebug( "SkinCache: hit on bgpixmap" ); + data->backgroundPixmap = *bgPixmap; } else - data->backgroundImage = QImage(); + data->backgroundPixmap = QPixmap(); return data; } void SkinCache::store( const QString &skinPath, const QString &fileNameInfix, SkinData *data ) { - QImage *backgroundImage = new QImage( data->backgroundImage ); + QPixmap *backgroundPixmap = new QPixmap( data->backgroundPixmap ); - data->backgroundImage = QImage(); + data->backgroundPixmap = QPixmap(); QString key = skinPath + fileNameInfix; if ( m_cache.find( key, false /*ref*/ ) != 0 || !m_cache.insert( key, data ) ) delete data; - if ( m_backgroundImageCache.find( skinPath, false /*ref*/ ) != 0 || - !m_backgroundImageCache.insert( skinPath, backgroundImage ) ) - delete backgroundImage; + if ( m_backgroundPixmapCache.find( skinPath, false /*ref*/ ) != 0 || + !m_backgroundPixmapCache.insert( skinPath, backgroundPixmap ) ) + delete backgroundPixmap; } SkinLoader::IncrementalLoader::IncrementalLoader( const Info &info ) : m_skin( info.skinName, info.fileNameInfix ), m_info( info ) { - m_currentState = LoadBackgroundImage; + m_currentState = LoadBackgroundPixmap; } SkinLoader::IncrementalLoader::LoaderResult SkinLoader::IncrementalLoader::loadStep() { switch ( m_currentState ) { - case LoadBackgroundImage: - qDebug( "load bgimage" ); - m_skin.backgroundImage(); + case LoadBackgroundPixmap: + qDebug( "load bgpixmap" ); + m_skin.backgroundPixmap(); m_currentState = LoadButtonUpImage; break; case LoadButtonUpImage: qDebug( "load upimage" ); m_skin.buttonUpImage(); m_currentState = LoadButtonDownImage; break; case LoadButtonDownImage: qDebug( "load downimage" ); m_skin.buttonDownImage(); m_currentState = LoadButtonMasks; m_currentButton = 0; break; case LoadButtonMasks: qDebug( "load button masks %i", m_currentButton ); m_skin.buttonMaskImage( m_info.buttonInfo[ m_currentButton ].fileName ); m_currentButton++; if ( m_currentButton >= m_info.buttonCount ) m_currentState = LoadButtonMask; break; case LoadButtonMask: qDebug( "load whole mask" ); m_skin.buttonMask( m_info.buttonInfo, m_info.buttonCount ); return LoadingCompleted; } return MoreToCome; } SkinLoader::SkinLoader() : m_currentLoader( 0 ), m_timerId( -1 ) { } SkinLoader::~SkinLoader() { qDebug( "SkinLoader::~SkinLoader()" ); killTimers(); delete m_currentLoader; } void SkinLoader::schedule( const MediaWidget::GUIInfo &guiInfo ) { schedule( Skin::defaultSkinName(), guiInfo ); } void SkinLoader::schedule( const QString &skinName, const MediaWidget::GUIInfo &guiInfo ) { pendingSkins << Info( skinName, guiInfo ); } void SkinLoader::start() { assert( m_timerId == -1 ); m_timerId = startTimer( 100 /* ms */ ); qDebug( "SkinLoader::start() %d jobs", pendingSkins.count() ); } void SkinLoader::timerEvent( QTimerEvent *ev ) { if ( ev->timerId() != m_timerId ) { QObject::timerEvent( ev ); return; } if ( !m_currentLoader ) { if ( pendingSkins.isEmpty() ) { qDebug( "all jobs done" ); killTimer( m_timerId ); m_timerId = -1; // ### qt3: use deleteLater(); QTimer::singleShot( 0, this, SLOT( deleteMe() ) ); return; } Info nfo = *pendingSkins.begin(); pendingSkins.remove( pendingSkins.begin() ); m_currentLoader = new IncrementalLoader( nfo ); qDebug( "new loader %i jobs left", pendingSkins.count() ); } if ( m_currentLoader->loadStep() == IncrementalLoader::LoadingCompleted ) { delete m_currentLoader; m_currentLoader = 0; } qDebug( "finished step" ); } void SkinLoader::deleteMe() { delete this; diff --git a/noncore/multimedia/opieplayer2/skin.h b/noncore/multimedia/opieplayer2/skin.h index a43a1d0..90062c2 100644 --- a/noncore/multimedia/opieplayer2/skin.h +++ b/noncore/multimedia/opieplayer2/skin.h @@ -1,124 +1,124 @@ /* Copyright (C) 2002 Simon Hausmann <simon@lst.de> (C) 2002 Max Reiss <harlekin@handhelds.org> (C) 2002 L. Potter <ljp@llornkcor.com> (C) 2002 Holger Freyther <zecke@handhelds.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef SKIN_H #define SKIN_H #include <qstring.h> #include <qimage.h> #include <qobject.h> #include "mediawidget.h" struct SkinData; class Skin { public: Skin( const QString &name, const QString &fileNameInfix ); Skin( const QString &fileNameInfix ); ~Skin(); void preload( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ); - QImage backgroundImage() const; + QPixmap backgroundPixmap() const; QImage buttonUpImage() const; QImage buttonDownImage() const; QImage buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const; QImage buttonMaskImage( const QString &fileName ) const; static QString defaultSkinName(); private: void init( const QString &name ); void addButtonToMask( int tag, const QImage &maskImage ) const; static QImage loadImage( const QString &fileName ); QString m_fileNameInfix; QString m_skinPath; SkinData *d; Skin( const Skin & ); Skin &operator=( const Skin & ); }; class SkinLoader : public QObject { Q_OBJECT public: SkinLoader(); virtual ~SkinLoader(); void schedule( const MediaWidget::GUIInfo &guiInfo ); void schedule( const QString &skinName, const MediaWidget::GUIInfo &guiInfo ); void start(); protected: virtual void timerEvent( QTimerEvent *ev ); private slots: void deleteMe(); private: struct Info : public MediaWidget::GUIInfo { Info() {} Info( const QString &_skinName, const MediaWidget::GUIInfo &guiInfo ) : MediaWidget::GUIInfo( guiInfo ), skinName( _skinName ) {} QString skinName; }; typedef QValueList<Info> InfoList; class IncrementalLoader { public: enum LoaderResult { LoadingCompleted, MoreToCome }; IncrementalLoader( const Info &info ); LoaderResult loadStep(); private: - enum State { LoadBackgroundImage, LoadButtonUpImage, LoadButtonDownImage, LoadButtonMasks, LoadButtonMask }; + enum State { LoadBackgroundPixmap, LoadButtonUpImage, LoadButtonDownImage, LoadButtonMasks, LoadButtonMask }; Skin m_skin; Info m_info; State m_currentState; uint m_currentButton; }; InfoList pendingSkins; IncrementalLoader *m_currentLoader; int m_timerId; }; #endif // SKIN_H /* vim: et sw=4 ts=4 */ |