Krita Source Code Documentation
Loading...
Searching...
No Matches
KisTileData Class Reference

#include <kis_tile_data_interface.h>

Public Types

enum  EnumTileDataState { NORMAL = 0 , COMPRESSED , SWAPPED }
 

Public Member Functions

bool acquire ()
 
int age () const
 
void allocateMemory ()
 
void blockSwapping ()
 
KisTileDataclone ()
 
quint8 * data () const
 
bool deref ()
 
bool historical () const
 
 KisTileData (qint32 pixelSize, const quint8 *defPixel, KisTileDataStore *store, bool checkFreeMemory=true)
 
void markOld ()
 
bool mementoed () const
 
qint32 numUsers () const
 
quint32 pixelSize () const
 
bool ref () const
 
bool release ()
 
void releaseMemory ()
 
void resetAge ()
 
void setData (const quint8 *data)
 
void setMementoed (bool value)
 
void setSwapChunk (KisChunk chunk)
 
KisChunk swapChunk () const
 
void unblockSwapping ()
 
 ~KisTileData ()
 

Static Public Member Functions

static void releaseInternalPools ()
 

Static Public Attributes

static const qint32 HEIGHT = __TILE_DATA_HEIGHT
 
static const qint32 WIDTH = __TILE_DATA_WIDTH
 

Private Member Functions

void fillWithPixel (const quint8 *defPixel)
 
 KisTileData (const KisTileData &rhs, bool checkFreeMemory=true)
 

Static Private Member Functions

static quint8 * allocateData (const qint32 pixelSize)
 
static void freeData (quint8 *ptr, const qint32 pixelSize)
 

Private Attributes

int m_age
 
KisTileDataCache m_clonesStack
 
quint8 * m_data
 
qint32 m_mementoFlag
 
qint32 m_pixelSize
 
QAtomicInt m_refCount
 
EnumTileDataState m_state
 
KisTileDataStorem_store
 
KisChunk m_swapChunk
 
QReadWriteLock m_swapLock
 
int m_tileNumber = -1
 
QAtomicInt m_usersCount
 

Static Private Attributes

static SimpleCache m_cache
 

Friends

class KisLowMemoryTests
 
class KisTile
 
class KisTileDataPooler
 
class KisTileDataPoolerTest
 
class KisTileDataStore
 
class KisTileDataStoreClockIterator
 
class KisTileDataStoreIterator
 
class KisTileDataStoreReverseIterator
 

Detailed Description

Stores actual tile's data

Definition at line 88 of file kis_tile_data_interface.h.

Member Enumeration Documentation

◆ EnumTileDataState

Enumerator
NORMAL 
COMPRESSED 
SWAPPED 

Definition at line 99 of file kis_tile_data_interface.h.

Constructor & Destructor Documentation

◆ KisTileData() [1/2]

KisTileData::KisTileData ( qint32 pixelSize,
const quint8 * defPixel,
KisTileDataStore * store,
bool checkFreeMemory = true )

Definition at line 53 of file kis_tile_data.cc.

54 : m_state(NORMAL),
56 m_age(0),
57 m_usersCount(0),
58 m_refCount(0),
60 m_store(store)
61{
62 if (checkFreeMemory) {
64 }
66
67 fillWithPixel(defPixel);
68}
quint32 pixelSize() const
EnumTileDataState m_state
void fillWithPixel(const quint8 *defPixel)
KisTileDataStore * m_store
static quint8 * allocateData(const qint32 pixelSize)

References allocateData(), KisTileDataStore::checkFreeMemory(), fillWithPixel(), m_data, m_pixelSize, and m_store.

◆ KisTileData() [2/2]

KisTileData::KisTileData ( const KisTileData & rhs,
bool checkFreeMemory = true )
private

Duplicating tiledata

  • new object loaded in memory
  • it's unlocked and has refCount==0

NOTE: the memory allocated by the pooler for clones is not counted by the store in memoryHardLimit. The pooler has it's own slice of memory and keeps track of the its size itself. So we should be able to disable the memory check with checkFreeMemory, otherwise, there is a deadlock.

Definition at line 82 of file kis_tile_data.cc.

83 : m_state(NORMAL),
85 m_age(0),
86 m_usersCount(0),
87 m_refCount(0),
89 m_store(rhs.m_store)
90{
91 if (checkFreeMemory) {
93 }
95
96 memcpy(m_data, rhs.data(), m_pixelSize * WIDTH * HEIGHT);
97}
quint8 * data() const
static const qint32 HEIGHT
static const qint32 WIDTH

References allocateData(), KisTileDataStore::checkFreeMemory(), data(), HEIGHT, m_data, m_pixelSize, m_store, and WIDTH.

◆ ~KisTileData()

KisTileData::~KisTileData ( )

Definition at line 100 of file kis_tile_data.cc.

101{
103}
void releaseMemory()

References releaseMemory().

Member Function Documentation

◆ acquire()

bool KisTileData::acquire ( )
inline

Increments usersCount of a TD and refs shared pointer counter Used by KisTile for COW

We need to ensure the clones in the stack are consistent with the data. When we have a single user, the most probably, the clone has already started stinking. So just clean it up.

Definition at line 35 of file kis_tile_data.h.

35 {
43 if(m_usersCount == 1) {
44 KisTileData *clone = 0;
45 while(m_clonesStack.pop(clone)) {
46 delete clone;
47 }
48 }
49
50 bool _ref = ref();
51 m_usersCount.ref();
52 return _ref;
53}
bool ref() const
KisTileData * clone()
KisTileDataCache m_clonesStack

References clone(), m_clonesStack, m_usersCount, KisLocklessStack< T >::pop(), and ref().

◆ age()

int KisTileData::age ( ) const
inline

Controlling methods for setting 'age' marks

Definition at line 110 of file kis_tile_data.h.

110 {
111 return m_age;
112}

References m_age.

◆ allocateData()

quint8 * KisTileData::allocateData ( const qint32 pixelSize)
staticprivate

Definition at line 135 of file kis_tile_data.cc.

136{
137 quint8 *ptr = 0;
138
139 if (!m_cache.pop(pixelSize, ptr)) {
140 switch (pixelSize) {
141 case 4:
142 ptr = (quint8*)BoostPool4BPP::malloc();
143 break;
144 case 8:
145 ptr = (quint8*)BoostPool8BPP::malloc();
146 break;
147 default:
148 ptr = (quint8*) malloc(pixelSize * WIDTH * HEIGHT);
149 break;
150 }
151 }
152
153 return ptr;
154}
static SimpleCache m_cache
bool pop(int pixelSize, quint8 *&ptr)

References HEIGHT, m_cache, pixelSize(), SimpleCache::pop(), and WIDTH.

◆ allocateMemory()

void KisTileData::allocateMemory ( )

Used for swapping purposes only. Allocates memory for the tile data after it has been freed in releaseMemory(). NOTE: the new data can be not-initialized and you must fill it yourself!

See also
releaseMemory()

Definition at line 129 of file kis_tile_data.cc.

130{
131 Q_ASSERT(!m_data);
133}

References allocateData(), m_data, and m_pixelSize.

◆ blockSwapping()

void KisTileData::blockSwapping ( )
inline

Control the access of swapper to the tile data

Definition at line 79 of file kis_tile_data.h.

79 {
80 m_swapLock.lockForRead();
81 if(!m_data) {
82 m_swapLock.unlock();
84 }
85 resetAge();
86}
void ensureTileDataLoaded(KisTileData *td)
QReadWriteLock m_swapLock

References KisTileDataStore::ensureTileDataLoaded(), m_data, m_store, m_swapLock, and resetAge().

◆ clone()

KisTileData * KisTileData::clone ( )
inline

Creates a clone of the tile data safely. It will try to use the cached clones.

Definition at line 75 of file kis_tile_data.h.

75 {
76 return m_store->duplicateTileData(this);
77}
KisTileData * duplicateTileData(KisTileData *rhs)

References KisTileDataStore::duplicateTileData(), and m_store.

◆ data()

quint8 * KisTileData::data ( ) const
inline

Information about data stored

Some methods of KisTileData have a cyclic dependency to the KisTileDataStore, so we've moved the class declaration to a separate file, that will be included by the store.

Definition at line 21 of file kis_tile_data.h.

21 {
22 // WARN: be careful - it can be null when swapped out!
23 return m_data;
24 }

References m_data.

◆ deref()

bool KisTileData::deref ( )
inline

Only refs shared pointer counter. Used only by KisMementoManager without consideration of COW.

Definition at line 65 of file kis_tile_data.h.

65 {
66 bool _ref;
67
68 if (!(_ref = m_refCount.deref())) {
69 m_store->freeTileData(this);
70 return 0;
71 }
72 return _ref;
73}
void freeTileData(KisTileData *td)

References KisTileDataStore::freeTileData(), m_refCount, and m_store.

◆ fillWithPixel()

void KisTileData::fillWithPixel ( const quint8 * defPixel)
private

Definition at line 105 of file kis_tile_data.cc.

106{
107 quint8 *it = m_data;
108
109 for (int i = 0; i < WIDTH * HEIGHT; i++, it += m_pixelSize) {
110 memcpy(it, defPixel, m_pixelSize);
111 }
112}

References HEIGHT, m_data, m_pixelSize, and WIDTH.

◆ freeData()

void KisTileData::freeData ( quint8 * ptr,
const qint32 pixelSize )
staticprivate

Definition at line 156 of file kis_tile_data.cc.

157{
158 if (!m_cache.push(pixelSize, ptr)) {
159 switch (pixelSize) {
160 case 4:
161 BoostPool4BPP::free(ptr);
162 break;
163 case 8:
164 BoostPool8BPP::free(ptr);
165 break;
166 default:
167 free(ptr);
168 break;
169 }
170 }
171}
bool push(int pixelSize, quint8 *&ptr)

References m_cache, pixelSize(), and SimpleCache::push().

◆ historical()

bool KisTileData::historical ( ) const
inline

Convenience method. Returns true iff the tile data is linked to information only and therefore can be swapped out easily.

Effectively equivalent to: (mementoed() && numUsers() <= 1)

Definition at line 106 of file kis_tile_data.h.

106 {
107 return mementoed() && numUsers() <= 1;
108}
qint32 numUsers() const
bool mementoed() const

References mementoed(), and numUsers().

◆ markOld()

void KisTileData::markOld ( )
inline

Definition at line 116 of file kis_tile_data.h.

116 {
117 m_age++;
118}

References m_age.

◆ mementoed()

bool KisTileData::mementoed ( ) const
inline

Show whether a tile data is a part of history

Definition at line 99 of file kis_tile_data.h.

99 {
100 return m_mementoFlag;
101}

References m_mementoFlag.

◆ numUsers()

qint32 KisTileData::numUsers ( ) const
inline

Returns number of tiles (or memento items), referencing the tile data.

Definition at line 120 of file kis_tile_data.h.

120 {
121 return m_usersCount;
122}

References m_usersCount.

◆ pixelSize()

quint32 KisTileData::pixelSize ( ) const
inline

Definition at line 31 of file kis_tile_data.h.

31 {
32 return m_pixelSize;
33}

References m_pixelSize.

◆ ref()

bool KisTileData::ref ( ) const
inline

Only refs shared pointer counter. Used only by KisMementoManager without consideration of COW.

Definition at line 61 of file kis_tile_data.h.

61 {
62 return m_refCount.ref();
63}

References m_refCount.

◆ release()

bool KisTileData::release ( )
inline

Decrements usersCount of a TD and derefs shared pointer counter Used by KisTile for COW

Definition at line 55 of file kis_tile_data.h.

55 {
56 m_usersCount.deref();
57 bool _ref = deref();
58 return _ref;
59}

References deref(), and m_usersCount.

◆ releaseInternalPools()

void KisTileData::releaseInternalPools ( )
static

Releases internal pools, which keep blobs where the tiles are stored. The point is that we don't allocate the tiles from glibc directly, but use pools (implemented via boost) to allocate bigger chunks. This method should be called when one knows that we have just free'd quite a lot of memory and we won't need it anymore. E.g. when a document has been closed.

Definition at line 179 of file kis_tile_data.cc.

180{
181 const int maxMigratedTiles = 100;
182
183 if (KisTileDataStore::instance()->numTilesInMemory() < maxMigratedTiles) {
184
185 QVector<KisTileData*> dataObjects;
186 QVector<QByteArray> memoryChunks;
187 bool failedToLock = false;
188
190
191 while (iter->hasNext()) {
192 KisTileData *item = iter->next();
193
194 // first release all the clones
195 KisTileData *clone = 0;
196 while (item->m_clonesStack.pop(clone)) {
197 delete clone;
198 }
199
200 // check if the tile data has actually been pooled
201 if (item->m_pixelSize != 4 &&
202 item->m_pixelSize != 8 &&
203 item->m_pixelSize != 16) {
204
205 continue;
206 }
207
208 // check if the tile has been swapped out
209 if (item->m_data) {
210 const bool locked = item->m_swapLock.tryLockForWrite();
211 if (!locked) {
212 failedToLock = true;
213 break;
214 }
215
216 const int chunkSize = item->m_pixelSize * WIDTH * HEIGHT;
217 dataObjects << item;
218 memoryChunks << QByteArray((const char*)item->m_data, chunkSize);
219 }
220
221 }
222
223 if (!failedToLock) {
224 // purge the pools memory
225 m_cache.clear();
226 BoostPool4BPP::purge_memory();
227 BoostPool8BPP::purge_memory();
228
229 auto it = dataObjects.begin();
230 auto chunkIt = memoryChunks.constBegin();
231
232 for (; it != dataObjects.end(); ++it, ++chunkIt) {
233 KisTileData *item = *it;
234 const int chunkSize = item->m_pixelSize * WIDTH * HEIGHT;
235
236 item->m_data = allocateData(item->m_pixelSize);
237 memcpy(item->m_data, chunkIt->data(), chunkSize);
238
239 item->m_swapLock.unlock();
240 }
241 } else {
242 Q_FOREACH (KisTileData *item, dataObjects) {
243 item->m_swapLock.unlock();
244 }
245
246 warnKrita << "WARNING: Failed to lock the tiles while trying to release the pooled memory";
247 }
248
250
251#ifdef DEBUG_POOL_RELEASE
252 dbgKrita << "After purging unused memory:";
253
254 char command[256];
255 sprintf(command, "cat /proc/%d/status | grep -i vm", (int)getpid());
256 printf("--- %s ---\n", command);
257 (void)system(command);
258#endif /* DEBUG_POOL_RELEASE */
259
260 } else {
261 dbgKrita << "DEBUG: releasing of the pooled memory has been cancelled:"
262 << "there are still"
264 << "tiles in memory";
265 }
266}
qint32 numTilesInMemory() const
void endIteration(KisTileDataStoreIterator *iterator)
KisTileDataStoreIterator * beginIteration()
static KisTileDataStore * instance()
#define dbgKrita
Definition kis_debug.h:45
#define warnKrita
Definition kis_debug.h:87
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)

References allocateData(), KisTileDataStore::beginIteration(), SimpleCache::clear(), clone(), dbgKrita, KisTileDataStore::endIteration(), KisTileDataStoreIterator::hasNext(), HEIGHT, KisTileDataStore::instance(), m_cache, m_clonesStack, m_data, m_pixelSize, m_swapLock, KisTileDataStoreIterator::next(), KisTileDataStore::numTilesInMemory(), KisLocklessStack< T >::pop(), void(), warnKrita, and WIDTH.

◆ releaseMemory()

void KisTileData::releaseMemory ( )

Used for swapping purposes only. Frees the memory occupied by the tile data. (the caller must save the data beforehand)

Definition at line 114 of file kis_tile_data.cc.

115{
116 if (m_data) {
118 m_data = 0;
119 }
120
121 KisTileData *clone = 0;
122 while (m_clonesStack.pop(clone)) {
123 delete clone;
124 }
125
126 Q_ASSERT(m_clonesStack.isEmpty());
127}
static void freeData(quint8 *ptr, const qint32 pixelSize)

References clone(), freeData(), KisLocklessStack< T >::isEmpty(), m_clonesStack, m_data, m_pixelSize, and KisLocklessStack< T >::pop().

◆ resetAge()

void KisTileData::resetAge ( )
inline

Definition at line 113 of file kis_tile_data.h.

113 {
114 m_age = 0;
115}

References m_age.

◆ setData()

void KisTileData::setData ( const quint8 * data)
inline

Definition at line 26 of file kis_tile_data.h.

26 {
27 Q_ASSERT(m_data);
29}

References data(), HEIGHT, m_data, m_pixelSize, and WIDTH.

◆ setMementoed()

void KisTileData::setMementoed ( bool value)
inline

Definition at line 102 of file kis_tile_data.h.

102 {
103 m_mementoFlag += value ? 1 : -1;
104}
float value(const T *src, size_t ch)

References m_mementoFlag, and value().

◆ setSwapChunk()

void KisTileData::setSwapChunk ( KisChunk chunk)
inline

Definition at line 95 of file kis_tile_data.h.

95 {
96 m_swapChunk = chunk;
97}

References m_swapChunk.

◆ swapChunk()

KisChunk KisTileData::swapChunk ( ) const
inline

The position of the tile data in a swap file

Definition at line 92 of file kis_tile_data.h.

92 {
93 return m_swapChunk;
94}

References m_swapChunk.

◆ unblockSwapping()

void KisTileData::unblockSwapping ( )
inline

Definition at line 88 of file kis_tile_data.h.

88 {
89 m_swapLock.unlock();
90}

References m_swapLock.

Friends And Related Symbol Documentation

◆ KisLowMemoryTests

friend class KisLowMemoryTests
friend

Definition at line 284 of file kis_tile_data_interface.h.

◆ KisTile

friend class KisTile
friend

Definition at line 227 of file kis_tile_data_interface.h.

◆ KisTileDataPooler

friend class KisTileDataPooler
friend

Definition at line 217 of file kis_tile_data_interface.h.

◆ KisTileDataPoolerTest

friend class KisTileDataPoolerTest
friend

Definition at line 218 of file kis_tile_data_interface.h.

◆ KisTileDataStore

friend class KisTileDataStore
friend

Definition at line 228 of file kis_tile_data_interface.h.

◆ KisTileDataStoreClockIterator

friend class KisTileDataStoreClockIterator
friend

Definition at line 232 of file kis_tile_data_interface.h.

◆ KisTileDataStoreIterator

friend class KisTileDataStoreIterator
friend

Definition at line 230 of file kis_tile_data_interface.h.

◆ KisTileDataStoreReverseIterator

friend class KisTileDataStoreReverseIterator
friend

Definition at line 231 of file kis_tile_data_interface.h.

Member Data Documentation

◆ HEIGHT

const qint32 KisTileData::HEIGHT = __TILE_DATA_HEIGHT
static

Definition at line 312 of file kis_tile_data_interface.h.

◆ m_age

int KisTileData::m_age
private

Counts up time after last access to the tile data. 0 - recently accessed 1+ - not recently accessed

Definition at line 271 of file kis_tile_data_interface.h.

◆ m_cache

SimpleCache KisTileData::m_cache
staticprivate

Definition at line 308 of file kis_tile_data_interface.h.

◆ m_clonesStack

KisTileDataCache KisTileData::m_clonesStack
private

A list of pre-duplicated tiledatas. To make a COW faster, KisTileDataPooler thread duplicates a tile beforehand and stores clones here, in this stack

Definition at line 224 of file kis_tile_data_interface.h.

◆ m_data

quint8* KisTileData::m_data
mutableprivate

FIXME: We should be able to work in const environment even when actual data is swapped out to disk

Definition at line 290 of file kis_tile_data_interface.h.

◆ m_mementoFlag

qint32 KisTileData::m_mementoFlag
private

The flag is set by KisMementoItem to show this tile data is going down in history.

(m_mementoFlag && m_usersCount == 1) means that the only user of tile data is a memento manager.

Definition at line 263 of file kis_tile_data_interface.h.

◆ m_pixelSize

qint32 KisTileData::m_pixelSize
private

Definition at line 304 of file kis_tile_data_interface.h.

◆ m_refCount

QAtomicInt KisTileData::m_refCount
mutableprivate

Shared pointer counter

Definition at line 301 of file kis_tile_data_interface.h.

◆ m_state

EnumTileDataState KisTileData::m_state
mutableprivate

The state of the tile. Filled in by tileDataStore and checked in KisTile::acquireFor* see also: comment for @m_data

Definition at line 240 of file kis_tile_data_interface.h.

◆ m_store

KisTileDataStore* KisTileData::m_store
private

Definition at line 307 of file kis_tile_data_interface.h.

◆ m_swapChunk

KisChunk KisTileData::m_swapChunk
private

The chunk of the swap file, that corresponds to this tile data. Used by KisSwappedDataStore.

Definition at line 253 of file kis_tile_data_interface.h.

◆ m_swapLock

QReadWriteLock KisTileData::m_swapLock
private

The primitive for controlling swapping of the tile. lockForRead() - used by regular threads to ensure swapper won't touch this tile data. tryLockForWrite() - used by swapper to check no-one reads this tile data

Definition at line 281 of file kis_tile_data_interface.h.

◆ m_tileNumber

int KisTileData::m_tileNumber = -1
private

Iterator that points to a position in the list where the tile data is stored

Definition at line 246 of file kis_tile_data_interface.h.

◆ m_usersCount

QAtomicInt KisTileData::m_usersCount
mutableprivate

How many tiles/mementoes use this tiledata through COW?

Definition at line 296 of file kis_tile_data_interface.h.

◆ WIDTH

const qint32 KisTileData::WIDTH = __TILE_DATA_WIDTH
static

Definition at line 311 of file kis_tile_data_interface.h.


The documentation for this class was generated from the following files: