[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: koffice/krita/core/tiles
From: Bart Coppens <kde () bartcoppens ! be>
Date: 2005-08-09 18:25:14
Message-ID: 1123611914.337571.15290.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 444323 by coppens:
Some changes to the tile manager:
* Now each pixelsize has its own freelist
* Some changes to the way swappable tiles are handled
A quick performance test indicates that the filling on RGBA8 is about 3 times faster \
than before (not really noticeable since it was already quite fast, but still a nice \
improvement)
M +58 -36 kis_tilemanager.cc
M +15 -4 kis_tilemanager.h
--- trunk/koffice/krita/core/tiles/kis_tilemanager.cc #444322:444323
@@ -52,24 +52,35 @@
m_maxInMem = config.maxTilesInMem();
m_swappiness = config.swappiness();
+ m_tileSize = KisTile::WIDTH * KisTile::HEIGHT;
+ m_freeLists.reserve(8);
+
counter = 0;
}
KisTileManager::~KisTileManager() {
kdDebug(DBG_AREA_TILES) << "Destructing TileManager: unmapping everything" << endl;
- if (!m_freeList.empty()) { // Let's see if there is an item in the freelist that \
fits
- FreeList::iterator it = m_freeList.begin();
- FreeList::iterator end = m_freeList.end();
+ if (!m_freeLists.empty()) { // See if there are any nonempty freelists
+ FreeListList::iterator listsIt = m_freeLists.begin();
+ FreeListList::iterator listsEnd = m_freeLists.end();
+
+ while(listsIt != listsEnd) {
+ if ( ! (*listsIt).empty() ) {
+ FreeList::iterator it = (*listsIt).begin();
+ FreeList::iterator end = (*listsIt).end();
- while (it != end) {
- // munmap it
- munmap((*it) -> pointer, (*it) -> size);
- delete *it;
- ++it;
+ while (it != end) {
+ // munmap it
+ munmap((*it) -> pointer, (*it) -> size);
+ delete *it;
+ ++it;
+ }
+ (*listsIt).clear();
+ }
+ ++listsIt;
}
-
- m_freeList.clear();
+ m_freeLists.clear();
}
kdDebug(DBG_AREA_TILES) << "Destructing TileManager: deleting file" << endl;
@@ -92,9 +103,11 @@
info -> filePos = -1;
info -> size = tile -> WIDTH * tile -> HEIGHT * tile -> m_pixelSize;
info -> fsize = 0; // the size in the file
+ info -> validNode = true;
m_tileMap[tile] = info;
m_swappableList.push_back(info);
+ info -> node = -- m_swappableList.end();
m_currentInMem++;
m_bytesTotal += info -> size;
@@ -117,7 +130,10 @@
freeInfo -> pointer = tile -> m_data;
freeInfo -> filePos = info -> filePos;
freeInfo -> size = info -> fsize;
- m_freeList.push_back(freeInfo);
+ int pixelSize = (info -> size / m_tileSize);
+ if (m_freeLists.capacity() <= pixelSize)
+ m_freeLists.resize(pixelSize);
+ m_freeLists[pixelSize].push_back(freeInfo);
madvise(info -> tile -> m_data, info -> fsize, MADV_DONTNEED);
@@ -129,7 +145,10 @@
m_currentInMem--;
}
- m_swappableList.remove(info);
+ if (info -> validNode) {
+ m_swappableList.erase(info -> node);
+ info -> validNode = false;
+ }
m_bytesTotal -= info -> size;
@@ -142,7 +161,10 @@
void KisTileManager::ensureTileLoaded(KisTile* tile) {
TileInfo* info = m_tileMap[tile];
- m_swappableList.remove(info);
+ if (info -> validNode) {
+ m_swappableList.erase(info -> node);
+ info -> validNode = false;
+ }
if (!info -> inMem) {
fromSwap(info);
@@ -150,7 +172,11 @@
}
void KisTileManager::maySwapTile(KisTile* tile) {
- m_swappableList.push_back(m_tileMap[tile]);
+ TileInfo* info = m_tileMap[tile];
+ m_swappableList.push_back(info);
+ info -> validNode = true;
+ info -> node = -- m_swappableList.end();
+
doSwapping();
}
@@ -175,28 +201,17 @@
// ### check return values of mmap functions!
KisTile *tile = info -> tile;
Q_UINT8* data = 0;
+ int pixelSize = (info -> size / m_tileSize);
+ if (m_freeLists.capacity() > pixelSize) {
+ if (!m_freeLists[pixelSize].empty()) {
+ // found one
+ FreeList::iterator it = m_freeLists[pixelSize].begin();
+ data = (*it) -> pointer;
+ info -> filePos = (*it) -> filePos;
+ info -> fsize = (*it) -> size;
- if (!m_freeList.empty()) { // Let's see if there is an item in the freelist that \
fits
- FreeList::iterator it = m_freeList.begin();
- FreeList::iterator end = m_freeList.end();
-
- while (it != end) {
- if ( (*it) -> size >= info -> size ) {
- // found one
- data = (*it) -> pointer;
- info -> filePos = (*it) -> filePos;
- info -> fsize = (*it) -> size;
-
- delete *it;
- m_freeList.erase(it);
-
- kdDebug(DBG_AREA_TILES) << "found in freelist\n";
-
- break;
- } else {
- kdDebug(DBG_AREA_TILES) << (*it) -> size << " < " << info -> size << endl;
- }
- ++it;
+ delete *it;
+ m_freeLists[pixelSize].erase(it);
}
}
@@ -245,6 +260,7 @@
for (Q_INT32 i = 0; i < count; i++) {
toSwap(m_swappableList.front());
+ m_swappableList.front() -> validNode = false;
m_swappableList.pop_front();
}
#endif
@@ -254,7 +270,13 @@
kdDebug(DBG_AREA_TILES) << m_bytesInMem << " out of " << m_bytesTotal << " bytes in \
memory\n"; kdDebug(DBG_AREA_TILES) << m_currentInMem << " out of " << \
m_tileMap.size() << " tiles in memory\n"; kdDebug(DBG_AREA_TILES) << \
m_swappableList.size() << " elements in the swapable list\n";
- kdDebug(DBG_AREA_TILES) << m_freeList.size() << " elements in the freelist\n";
+ kdDebug(DBG_AREA_TILES) << "Freelists information\n";
+ for (int i = 0; i < m_freeLists.capacity(); i++) {
+ if ( ! m_freeLists[i].empty() ) {
+ kdDebug(DBG_AREA_TILES) << m_freeLists[i].size()
+ << " elements in the freelist for pixelsize " << i << "\n";
+ }
+ }
kdDebug(DBG_AREA_TILES) << endl;
}
--- trunk/koffice/krita/core/tiles/kis_tilemanager.h #444322:444323
@@ -27,7 +27,15 @@
class KisTiledDataManager;
/**
- * Provides a way to store tiles on disk to a swap file, to reduce memory usage.
+ * This class keeps has the intention to make certain tile-related operations faster \
or more + * efficient. It does this by keeping lots of info on KisTiles, and manages \
the way they are + * created, used, etc.
+ * It mainly does the following more visible things
+ * * provide a way to store tiles on disk to a swap file, to reduce memory usage
+ * * keep a list of previously swapped (but now unused) tiles, to reuse these when \
we want + * to swap new tiles.
+ * * tries to preallocate and recycle some tiles to make future allocations faster
+ * (not done yet)
*/
class KisTileManager {
public:
@@ -40,7 +48,7 @@
void ensureTileLoaded(KisTile* tile);
void maySwapTile(KisTile* tile);
-public slots:
+public:
void configChanged();
private:
@@ -53,18 +61,21 @@
KTempFile m_tempFile;
int m_fileSize;
- typedef struct { KisTile *tile; bool inMem; int filePos; int size; int fsize; } \
TileInfo; + struct TileInfo { KisTile *tile; bool inMem; int filePos; int size; int \
fsize; + bool validNode; QValueList<TileInfo*>::iterator node; };
typedef struct { Q_UINT8 *pointer; int filePos; int size; } FreeInfo;
typedef QMap<KisTile*, TileInfo*> TileMap;
typedef QValueList<TileInfo*> TileList;
typedef QValueList<FreeInfo*> FreeList;
+ typedef QValueVector<FreeList> FreeListList;
TileMap m_tileMap;
TileList m_swappableList;
- FreeList m_freeList;
+ FreeListList m_freeLists;
Q_INT32 m_maxInMem;
Q_INT32 m_currentInMem;
Q_INT32 m_swappiness;
+ Q_INT32 m_tileSize; // size of a tile if it used 1 byte per pixel
unsigned long m_bytesInMem;
unsigned long m_bytesTotal;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic