File indexing completed on 2024-06-23 04:22:03
0001 /* 0002 * SPDX-FileCopyrightText: 2004 C. Boemann <cbo@boemann.dk> 0003 * (c) 2009 Dmitry Kazakov <dimula73@gmail.com> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 #ifndef KIS_TILE_H_ 0008 #define KIS_TILE_H_ 0009 0010 #include <QReadWriteLock> 0011 0012 #include <QMutex> 0013 #include <QAtomicPointer> 0014 0015 #include <QRect> 0016 #include <QStack> 0017 0018 #include <kis_shared.h> 0019 #include <kis_shared_ptr.h> 0020 0021 #include "kis_tile_data.h" 0022 #include "kis_tile_data_store.h" 0023 0024 //#define DEAD_TILES_SANITY_CHECK 0025 0026 class KisTile; 0027 typedef KisSharedPtr<KisTile> KisTileSP; 0028 0029 class KisMementoManager; 0030 0031 0032 /** 0033 * Provides abstraction to a tile. 0034 * + A tile contains a part of a PaintDevice, 0035 * but only the individual pixels are accessible 0036 * and that only via iterators. 0037 * + Actual tile data is stored in KisTileData that can be 0038 * shared between many tiles 0039 */ 0040 class KRITAIMAGE_EXPORT KisTile : public KisShared 0041 { 0042 public: 0043 KisTile(qint32 col, qint32 row, 0044 KisTileData *defaultTileData, KisMementoManager* mm); 0045 KisTile(const KisTile& rhs, qint32 col, qint32 row, KisMementoManager* mm); 0046 KisTile(const KisTile& rhs, KisMementoManager* mm); 0047 KisTile(const KisTile& rhs); 0048 ~KisTile(); 0049 0050 /** 0051 * This method is called by the hash table when the tile is 0052 * disconnected from it. It means that from now on the tile is not 0053 * associated with any particular datamanager. All the users of 0054 * the tile (via shared pointers) may silently finish they work on 0055 * this tile and leave it. No result will be saved. Used for 0056 * threading purposes 0057 */ 0058 void notifyDetachedFromDataManager(); 0059 0060 /** 0061 * Sometimes the tile gets replaced with another tile. In this case 0062 * we shouldn't notify memento manager that the tile has died. Just 0063 * forget the link to the manager and bury it in peace. 0064 */ 0065 void notifyDeadWithoutDetaching(); 0066 0067 /** 0068 * Called by the hash table to notify that the tile has been attached 0069 * to the data manager. 0070 */ 0071 void notifyAttachedToDataManager(KisMementoManager *mm); 0072 0073 public: 0074 0075 void debugPrintInfo(); 0076 void debugDumpTile(); 0077 0078 void lockForRead() const; 0079 void lockForWrite(); 0080 void unlockForWrite(); 0081 void unlockForRead() const; 0082 0083 0084 /* this allows us work directly on tile's data */ 0085 inline quint8 *data() const { 0086 return m_tileData->data(); 0087 } 0088 inline void setData(const quint8 *data) { 0089 m_tileData->setData(data); 0090 } 0091 0092 inline qint32 row() const { 0093 return m_row; 0094 } 0095 inline qint32 col() const { 0096 return m_col; 0097 } 0098 0099 inline QRect extent() const { 0100 return m_extent; 0101 //QRect(m_col * KisTileData::WIDTH, m_row * KisTileData::HEIGHT, 0102 // KisTileData::WIDTH, KisTileData::HEIGHT); 0103 } 0104 0105 inline KisTileSP next() const { 0106 return m_nextTile; 0107 } 0108 0109 void setNext(KisTileSP next) { 0110 m_nextTile = next; 0111 } 0112 0113 inline qint32 pixelSize() const { 0114 /* don't lock here as pixelSize is constant */ 0115 return m_tileData->pixelSize(); 0116 } 0117 0118 inline KisTileData* tileData() const { 0119 return m_tileData; 0120 } 0121 0122 private: 0123 void init(qint32 col, qint32 row, 0124 KisTileData *defaultTileData, KisMementoManager* mm); 0125 0126 inline void blockSwapping() const; 0127 inline void unblockSwapping() const; 0128 0129 inline void safeReleaseOldTileData(KisTileData *td); 0130 0131 private: 0132 KisTileData *m_tileData; 0133 mutable QStack<KisTileData*> m_oldTileData; 0134 mutable volatile int m_lockCounter; 0135 0136 qint32 m_col; 0137 qint32 m_row; 0138 0139 /** 0140 * Added for faster retrieving by processors 0141 */ 0142 QRect m_extent; 0143 0144 /** 0145 * For KisTiledDataManager's hash table 0146 */ 0147 KisTileSP m_nextTile; 0148 0149 QAtomicPointer<KisMementoManager> m_mementoManager; 0150 0151 /** 0152 * This is a special mutex for guarding copy-on-write 0153 * operations. We do not use lockless way here as it'll 0154 * create too much overhead for the most common operations 0155 * like "read the pointer of m_tileData". 0156 */ 0157 QMutex m_COWMutex; 0158 0159 /** 0160 * This lock is used to ensure no one will read the tile data 0161 * before it has been loaded from to the memory. 0162 */ 0163 mutable QMutex m_swapBarrierLock; 0164 0165 0166 #ifdef DEAD_TILES_SANITY_CHECK 0167 QAtomicInt m_sanityHasBeenDetached; 0168 QAtomicInt m_sanityIsDead; 0169 QAtomicInt m_sanityMMHasBeenInitializedManually; 0170 QAtomicInt m_sanityNumCOWHappened; 0171 QAtomicInt m_sanityLockedForWrite; 0172 mutable QAtomicInt m_sanityLockedForRead; 0173 0174 void sanityCheckIsNotDestroyedYet(); 0175 void sanityCheckIsNotLockedForWrite(); 0176 #endif 0177 0178 }; 0179 0180 #endif // KIS_TILE_H_ 0181