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

#include <kis_tile.h>

+ Inheritance diagram for KisTile:

Public Member Functions

qint32 col () const
 
quint8 * data () const
 
void debugDumpTile ()
 
void debugPrintInfo ()
 
QRect extent () const
 
 KisTile (const KisTile &rhs)
 
 KisTile (const KisTile &rhs, KisMementoManager *mm)
 
 KisTile (const KisTile &rhs, qint32 col, qint32 row, KisMementoManager *mm)
 
 KisTile (qint32 col, qint32 row, KisTileData *defaultTileData, KisMementoManager *mm)
 
void lockForRead () const
 
void lockForWrite ()
 
KisTileSP next () const
 
void notifyAttachedToDataManager (KisMementoManager *mm)
 
void notifyDeadWithoutDetaching ()
 
void notifyDetachedFromDataManager ()
 
qint32 pixelSize () const
 
qint32 row () const
 
void setData (const quint8 *data)
 
void setNext (KisTileSP next)
 
KisTileDatatileData () const
 
void unlockForRead () const
 
void unlockForWrite ()
 
 ~KisTile ()
 
- Public Member Functions inherited from KisShared
bool deref ()
 
bool ref ()
 
int refCount ()
 
QAtomicInt * sharedWeakReference ()
 

Private Member Functions

void blockSwapping () const
 
void init (qint32 col, qint32 row, KisTileData *defaultTileData, KisMementoManager *mm)
 
void safeReleaseOldTileData (KisTileData *td)
 
void unblockSwapping () const
 

Private Attributes

qint32 m_col
 
QMutex m_COWMutex
 
QRect m_extent
 
volatile int m_lockCounter
 
QAtomicPointer< KisMementoManagerm_mementoManager
 
KisTileSP m_nextTile
 
QStack< KisTileData * > m_oldTileData
 
qint32 m_row
 
QMutex m_swapBarrierLock
 
KisTileDatam_tileData
 

Additional Inherited Members

- Protected Member Functions inherited from KisShared
 KisShared ()
 
 ~KisShared ()
 

Detailed Description

Provides abstraction to a tile.

  • A tile contains a part of a PaintDevice, but only the individual pixels are accessible and that only via iterators.
  • Actual tile data is stored in KisTileData that can be shared between many tiles

Definition at line 40 of file kis_tile.h.

Constructor & Destructor Documentation

◆ KisTile() [1/4]

KisTile::KisTile ( qint32 col,
qint32 row,
KisTileData * defaultTileData,
KisMementoManager * mm )

Definition at line 36 of file kis_tile.cc.

38{
39 init(col, row, defaultTileData, mm);
40}
qint32 row() const
Definition kis_tile.h:92
qint32 col() const
Definition kis_tile.h:95
void init(qint32 col, qint32 row, KisTileData *defaultTileData, KisMementoManager *mm)
Definition kis_tile.cc:17

References col(), init(), and row().

◆ KisTile() [2/4]

KisTile::KisTile ( const KisTile & rhs,
qint32 col,
qint32 row,
KisMementoManager * mm )

Definition at line 42 of file kis_tile.cc.

43 : KisShared()
44{
45 init(col, row, rhs.tileData(), mm);
46}
KisTileData * tileData() const
Definition kis_tile.h:118

References col(), init(), row(), and tileData().

◆ KisTile() [3/4]

KisTile::KisTile ( const KisTile & rhs,
KisMementoManager * mm )

Definition at line 48 of file kis_tile.cc.

49 : KisShared()
50{
51 init(rhs.col(), rhs.row(), rhs.tileData(), mm);
52}

References col(), init(), row(), and tileData().

◆ KisTile() [4/4]

KisTile::KisTile ( const KisTile & rhs)

Definition at line 54 of file kis_tile.cc.

55 : KisShared()
56{
57 init(rhs.col(), rhs.row(), rhs.tileData(), rhs.m_mementoManager);
58}
QAtomicPointer< KisMementoManager > m_mementoManager
Definition kis_tile.h:149

References col(), init(), m_mementoManager, row(), and tileData().

◆ ~KisTile()

KisTile::~KisTile ( )

Definition at line 60 of file kis_tile.cc.

61{
62#ifdef DEAD_TILES_SANITY_CHECK
64
71 if (m_mementoManager) {
72 qDebug() << this << ppVar(m_sanityNumCOWHappened);
73 qDebug() << this << ppVar(m_sanityHasBeenDetached);
74 qDebug() << this << ppVar(m_sanityMMHasBeenInitializedManually);
75 qDebug() << this << ppVar(m_sanityIsDead);
76 KIS_ASSERT(0 && "m_mementoManager is still initialized during destruction");
77 }
78#endif
79
81}
KisTileData * m_tileData
Definition kis_tile.h:132
volatile int m_lockCounter
Definition kis_tile.h:134
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
#define ppVar(var)
Definition kis_debug.h:155

References KIS_ASSERT, m_lockCounter, m_mementoManager, m_tileData, ppVar, and KisTileData::release().

Member Function Documentation

◆ blockSwapping()

void KisTile::blockSwapping ( ) const
inlineprivate

We need to hold a special barrier lock here to ensure m_tileData->blockSwapping() has finished executing before anyone started reading the tile data. That is why we can not use atomic operations here.

Definition at line 158 of file kis_tile.cc.

159{
167 QMutexLocker locker(&m_swapBarrierLock);
168 Q_ASSERT(m_lockCounter >= 0);
169
170 if(!m_lockCounter++)
172
173 Q_ASSERT(data());
174}
void blockSwapping()
QMutex m_swapBarrierLock
Definition kis_tile.h:163
quint8 * data() const
Definition kis_tile.h:85

References KisTileData::blockSwapping(), data(), m_lockCounter, m_swapBarrierLock, and m_tileData.

◆ col()

qint32 KisTile::col ( ) const
inline

Definition at line 95 of file kis_tile.h.

95 {
96 return m_col;
97 }
qint32 m_col
Definition kis_tile.h:136

◆ data()

quint8 * KisTile::data ( ) const
inline

Definition at line 85 of file kis_tile.h.

85 {
86 return m_tileData->data();
87 }
quint8 * data() const

◆ debugDumpTile()

void KisTile::debugDumpTile ( )

Definition at line 297 of file kis_tile.cc.

298{
299 lockForRead();
300 quint8 *data = this->data();
301
302 for (int i = 0; i < KisTileData::HEIGHT; i++) {
303 for (int j = 0; j < KisTileData::WIDTH; j++) {
305 }
306 }
308}
static const qint32 HEIGHT
static const qint32 WIDTH
void lockForRead() const
Definition kis_tile.cc:208
void unlockForRead() const
Definition kis_tile.cc:275
qint32 pixelSize() const
Definition kis_tile.h:113
#define dbgTiles
Definition kis_debug.h:49

References data(), dbgTiles, KisTileData::HEIGHT, lockForRead(), pixelSize(), unlockForRead(), and KisTileData::WIDTH.

◆ debugPrintInfo()

void KisTile::debugPrintInfo ( )

Definition at line 288 of file kis_tile.cc.

289{
290 dbgTiles << "------\n"
291 "Tile:\t\t\t" << this
292 << "\n data:\t" << m_tileData
293 << "\n next:\t" << m_nextTile.data();
294
295}
KisTileSP m_nextTile
Definition kis_tile.h:147

References KisSharedPtr< T >::data(), dbgTiles, m_nextTile, and m_tileData.

◆ extent()

QRect KisTile::extent ( ) const
inline

Definition at line 99 of file kis_tile.h.

99 {
100 return m_extent;
101//QRect(m_col * KisTileData::WIDTH, m_row * KisTileData::HEIGHT,
102// KisTileData::WIDTH, KisTileData::HEIGHT);
103 }
QRect m_extent
Definition kis_tile.h:142

◆ init()

void KisTile::init ( qint32 col,
qint32 row,
KisTileData * defaultTileData,
KisMementoManager * mm )
private

Definition at line 17 of file kis_tile.cc.

19{
20 m_col = col;
21 m_row = row;
22 m_lockCounter = 0;
23
26
27 m_tileData = defaultTileData;
29
30 if (mm) {
31 mm->registerTileChange(this);
32 }
33 m_mementoManager.storeRelease(mm);
34}
void registerTileChange(KisTile *tile)
qint32 m_row
Definition kis_tile.h:137

References KisTileData::acquire(), col(), KisTileData::HEIGHT, m_col, m_extent, m_lockCounter, m_mementoManager, m_row, m_tileData, KisMementoManager::registerTileChange(), row(), and KisTileData::WIDTH.

◆ lockForRead()

void KisTile::lockForRead ( ) const

Definition at line 208 of file kis_tile.cc.

209{
210#ifdef DEAD_TILES_SANITY_CHECK
211 m_sanityLockedForRead.ref();
212#endif
213
214 DEBUG_LOG_ACTION("lock [R]");
216}
void blockSwapping() const
Definition kis_tile.cc:158
#define DEBUG_LOG_ACTION(action)
Definition kis_tile.cc:148

References blockSwapping(), and DEBUG_LOG_ACTION.

◆ lockForWrite()

void KisTile::lockForWrite ( )

Everything could have happened before we took the mutex, so let's check again...

Definition at line 221 of file kis_tile.cc.

222{
223#ifdef DEAD_TILES_SANITY_CHECK
224 m_sanityLockedForWrite.ref();
225#endif
226
228
229 /* We are doing COW here */
230 if (lazyCopying()) {
231 m_COWMutex.lock();
232
238 if (lazyCopying()) {
239
241 tileData->acquire();
243 KisTileData *oldTileData = m_tileData;
245 safeReleaseOldTileData(oldTileData);
246
248
249 KisMementoManager *mm = m_mementoManager.loadRelaxed();
250 if (mm) {
251 mm->registerTileChange(this);
252 }
253 }
254 m_COWMutex.unlock();
255
256#ifdef DEAD_TILES_SANITY_CHECK
257 m_sanityNumCOWHappened.ref();
258#endif
259 }
260
261 DEBUG_LOG_ACTION("lock [W]");
262}
KisTileData * clone()
void safeReleaseOldTileData(KisTileData *td)
Definition kis_tile.cc:194
QMutex m_COWMutex
Definition kis_tile.h:157
#define lazyCopying()
Definition kis_tile.cc:219
#define DEBUG_COWING(newTD)
Definition kis_tile.cc:155

References KisTileData::acquire(), KisTileData::blockSwapping(), blockSwapping(), KisTileData::clone(), DEBUG_COWING, DEBUG_LOG_ACTION, lazyCopying, m_COWMutex, m_mementoManager, m_tileData, KisMementoManager::registerTileChange(), safeReleaseOldTileData(), and tileData().

◆ next()

KisTileSP KisTile::next ( ) const
inline

Definition at line 105 of file kis_tile.h.

105 {
106 return m_nextTile;
107 }

◆ notifyAttachedToDataManager()

void KisTile::notifyAttachedToDataManager ( KisMementoManager * mm)

Called by the hash table to notify that the tile has been attached to the data manager.

Definition at line 113 of file kis_tile.cc.

114{
115#ifdef DEAD_TILES_SANITY_CHECK
116 sanityCheckIsNotDestroyedYet();
117#endif
118
119 // TODO: check if we really need locking here
120 if (!m_mementoManager.loadAcquire()) {
121 QMutexLocker locker(&m_COWMutex);
122
123 if (!m_mementoManager.loadAcquire()) {
124
125 if (mm) {
126 mm->registerTileChange(this);
127 }
128 m_mementoManager.storeRelease(mm);
129
130#ifdef DEAD_TILES_SANITY_CHECK
131 m_sanityMMHasBeenInitializedManually.ref();
132#endif
133 }
134 }
135
136#ifdef DEAD_TILES_SANITY_CHECK
137 sanityCheckIsNotDestroyedYet();
138#endif
139}

References m_COWMutex, m_mementoManager, and KisMementoManager::registerTileChange().

◆ notifyDeadWithoutDetaching()

void KisTile::notifyDeadWithoutDetaching ( )

Sometimes the tile gets replaced with another tile. In this case we shouldn't notify memento manager that the tile has died. Just forget the link to the manager and bury it in peace.

Definition at line 100 of file kis_tile.cc.

101{
102#ifdef DEAD_TILES_SANITY_CHECK
103 sanityCheckIsNotLockedForWrite();
104#endif
105
106 m_mementoManager.storeRelease(0);
107
108#ifdef DEAD_TILES_SANITY_CHECK
109 m_sanityIsDead.ref();
110#endif
111}

References m_mementoManager.

◆ notifyDetachedFromDataManager()

void KisTile::notifyDetachedFromDataManager ( )

This method is called by the hash table when the tile is disconnected from it. It means that from now on the tile is not associated with any particular datamanager. All the users of the tile (via shared pointers) may silently finish they work on this tile and leave it. No result will be saved. Used for threading purposes

Definition at line 83 of file kis_tile.cc.

84{
85#ifdef DEAD_TILES_SANITY_CHECK
86 sanityCheckIsNotLockedForWrite();
87#endif
88
89 if (m_mementoManager.loadAcquire()) {
91 m_mementoManager.storeRelease(0);
92 manager->registerTileDeleted(this);
93 }
94
95#ifdef DEAD_TILES_SANITY_CHECK
96 m_sanityHasBeenDetached.ref();
97#endif
98}
void registerTileDeleted(KisTile *tile)

References m_mementoManager, and KisMementoManager::registerTileDeleted().

◆ pixelSize()

qint32 KisTile::pixelSize ( ) const
inline

Definition at line 113 of file kis_tile.h.

113 {
114 /* don't lock here as pixelSize is constant */
115 return m_tileData->pixelSize();
116 }
quint32 pixelSize() const

◆ row()

qint32 KisTile::row ( ) const
inline

Definition at line 92 of file kis_tile.h.

92 {
93 return m_row;
94 }

◆ safeReleaseOldTileData()

void KisTile::safeReleaseOldTileData ( KisTileData * td)
inlineprivate

Definition at line 194 of file kis_tile.cc.

195{
196 QMutexLocker locker(&m_swapBarrierLock);
197 Q_ASSERT(m_lockCounter >= 0);
198
199 if(m_lockCounter > 0) {
200 m_oldTileData.push(td);
201 }
202 else {
203 td->unblockSwapping();
204 td->release();
205 }
206}
void unblockSwapping()
QStack< KisTileData * > m_oldTileData
Definition kis_tile.h:133

References m_lockCounter, m_oldTileData, m_swapBarrierLock, KisTileData::release(), and KisTileData::unblockSwapping().

◆ setData()

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

Definition at line 88 of file kis_tile.h.

88 {
90 }
void setData(const quint8 *data)

◆ setNext()

void KisTile::setNext ( KisTileSP next)
inline

Definition at line 109 of file kis_tile.h.

109 {
111 }
KisTileSP next() const
Definition kis_tile.h:105

◆ tileData()

KisTileData * KisTile::tileData ( ) const
inline

Definition at line 118 of file kis_tile.h.

118 {
119 return m_tileData;
120 }

◆ unblockSwapping()

void KisTile::unblockSwapping ( ) const
inlineprivate

Definition at line 176 of file kis_tile.cc.

177{
178 QMutexLocker locker(&m_swapBarrierLock);
179 Q_ASSERT(m_lockCounter > 0);
180
181 if(--m_lockCounter == 0) {
183
184 if(!m_oldTileData.isEmpty()) {
185 Q_FOREACH (KisTileData *td, m_oldTileData) {
186 td->unblockSwapping();
187 td->release();
188 }
189 m_oldTileData.clear();
190 }
191 }
192}

References m_lockCounter, m_oldTileData, m_swapBarrierLock, m_tileData, KisTileData::release(), and KisTileData::unblockSwapping().

◆ unlockForRead()

void KisTile::unlockForRead ( ) const

Definition at line 275 of file kis_tile.cc.

276{
278 DEBUG_LOG_ACTION("unlock [R]");
279
280#ifdef DEAD_TILES_SANITY_CHECK
281 m_sanityLockedForRead.deref();
282 KIS_ASSERT(m_sanityLockedForRead.loadAcquire() >= 0);
283#endif
284}
void unblockSwapping() const
Definition kis_tile.cc:176

References DEBUG_LOG_ACTION, KIS_ASSERT, and unblockSwapping().

◆ unlockForWrite()

void KisTile::unlockForWrite ( )

Definition at line 264 of file kis_tile.cc.

265{
267 DEBUG_LOG_ACTION("unlock [W]");
268
269#ifdef DEAD_TILES_SANITY_CHECK
270 m_sanityLockedForWrite.deref();
271 KIS_ASSERT(m_sanityLockedForWrite.loadAcquire() >= 0);
272#endif
273}

References DEBUG_LOG_ACTION, KIS_ASSERT, and unblockSwapping().

Member Data Documentation

◆ m_col

qint32 KisTile::m_col
private

Definition at line 136 of file kis_tile.h.

◆ m_COWMutex

QMutex KisTile::m_COWMutex
private

This is a special mutex for guarding copy-on-write operations. We do not use lockless way here as it'll create too much overhead for the most common operations like "read the pointer of m_tileData".

Definition at line 157 of file kis_tile.h.

◆ m_extent

QRect KisTile::m_extent
private

Added for faster retrieving by processors

Definition at line 142 of file kis_tile.h.

◆ m_lockCounter

volatile int KisTile::m_lockCounter
mutableprivate

Definition at line 134 of file kis_tile.h.

◆ m_mementoManager

QAtomicPointer<KisMementoManager> KisTile::m_mementoManager
private

Definition at line 149 of file kis_tile.h.

◆ m_nextTile

KisTileSP KisTile::m_nextTile
private

For KisTiledDataManager's hash table

Definition at line 147 of file kis_tile.h.

◆ m_oldTileData

QStack<KisTileData*> KisTile::m_oldTileData
mutableprivate

Definition at line 133 of file kis_tile.h.

◆ m_row

qint32 KisTile::m_row
private

Definition at line 137 of file kis_tile.h.

◆ m_swapBarrierLock

QMutex KisTile::m_swapBarrierLock
mutableprivate

This lock is used to ensure no one will read the tile data before it has been loaded from to the memory.

Definition at line 163 of file kis_tile.h.

◆ m_tileData

KisTileData* KisTile::m_tileData
private

Definition at line 132 of file kis_tile.h.


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