Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_tiled_data_manager.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2004 Boudewijn Rempt <boud@valdyas.org>
3 * SPDX-FileCopyrightText: 2009 Dmitry Kazakov <dimula73@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7#ifndef KIS_TILEDDATAMANAGER_H_
8#define KIS_TILEDDATAMANAGER_H_
9
10#include <QtGlobal>
11#include <QVector>
12#include <KisRegion.h>
13
14#include <kis_shared.h>
15#include <kis_shared_ptr.h>
16#include "config-hash-table-implementation.h"
17
18//#include "kis_debug.h"
19#include "kritaimage_export.h"
20
21#ifdef USE_LOCK_FREE_HASH_TABLE
23#else
24#include "kis_tile_hash_table.h"
25#endif // USE_LOCK_FREE_HASH_TABLE
26
27#include "kis_memento_manager.h"
28#include "kis_memento.h"
30
33
34class KisTiledIterator;
35class KisTiledRandomAccessor;
37class QIODevice;
38
55class KRITAIMAGE_EXPORT KisTiledDataManager : public KisShared
56{
57private:
58 static const qint32 LEGACY_VERSION = 1;
59 static const qint32 CURRENT_VERSION = 2;
60
61protected:
62 /*FIXME:*/
63public:
64 KisTiledDataManager(quint32 pixelSize, const quint8 *defPixel);
65 virtual ~KisTiledDataManager();
68
69
70protected:
71 // Allow the baseclass of iterators access to the interior
72 // derived iterator classes must go through KisTiledIterator
73 friend class KisTiledIterator;
74 friend class KisBaseIterator;
75 friend class KisTiledRandomAccessor;
76 friend class KisRandomAccessor2;
77 friend class KisStressJob;
78
79public:
80 void setDefaultPixel(const quint8 *defPixel);
81 const quint8 *defaultPixel() const {
82 return m_defaultPixel;
83 }
84
94 inline void getTilesPair(qint32 col, qint32 row, bool writable, KisTileSP *tile, KisTileSP *oldTile) {
95 *tile = getTile(col, row, writable);
96
97 bool unused;
98 *oldTile = m_mementoManager->getCommittedTile(col, row, unused);
99
100 if (!*oldTile) {
101 *oldTile = *tile;
102 }
103 }
104
105 inline KisTileSP getTile(qint32 col, qint32 row, bool writable) {
106 if (writable) {
107 bool newTile;
108 KisTileSP tile = m_hashTable->getTileLazy(col, row, newTile);
109 if (newTile) {
110 m_extentManager.notifyTileAdded(col, row);
111 }
112 return tile;
113
114 } else {
115 bool unused;
116 return m_hashTable->getReadOnlyTileLazy(col, row, unused);
117 }
118 }
119
120 inline KisTileSP getReadOnlyTileLazy(qint32 col, qint32 row, bool &existingTile) {
121 return m_hashTable->getReadOnlyTileLazy(col, row, existingTile);
122 }
123
124 inline KisTileSP getOldTile(qint32 col, qint32 row, bool &existingTile) {
125 KisTileSP tile = m_mementoManager->getCommittedTile(col, row, existingTile);
126 return tile ? tile : getReadOnlyTileLazy(col, row, existingTile);
127 }
128
129 inline KisTileSP getOldTile(qint32 col, qint32 row) {
130 bool unused;
131 return getOldTile(col, row, unused);
132 }
133
135 QWriteLocker locker(&m_lock);
136 KisMementoSP memento = m_mementoManager->getMemento();
137 memento->saveOldDefaultPixel(m_defaultPixel, m_pixelSize);
138 return memento;
139 }
140
144 void commit() {
145 QWriteLocker locker(&m_lock);
146
147 KisMementoSP memento = m_mementoManager->currentMemento();
148 if(memento) {
149 memento->saveNewDefaultPixel(m_defaultPixel, m_pixelSize);
150 }
151
152 m_mementoManager->commit();
153 }
154
155 void rollback(KisMementoSP memento) {
156 commit();
157
158 QWriteLocker locker(&m_lock);
159 m_mementoManager->rollback(m_hashTable, memento);
160 const quint8 *defaultPixel = memento->oldDefaultPixel();
161 if(memcmp(m_defaultPixel, defaultPixel, m_pixelSize)) {
162 setDefaultPixelImpl(defaultPixel);
163 }
164 recalculateExtent();
165 }
166 void rollforward(KisMementoSP memento) {
167 commit();
168
169 QWriteLocker locker(&m_lock);
170 m_mementoManager->rollforward(m_hashTable, memento);
171 const quint8 *defaultPixel = memento->newDefaultPixel();
172 if(memcmp(m_defaultPixel, defaultPixel, m_pixelSize)) {
173 setDefaultPixelImpl(defaultPixel);
174 }
175 recalculateExtent();
176 }
177 bool hasCurrentMemento() const {
178 return m_mementoManager->hasCurrentMemento();
179 //return true;
180 }
181
188 void purgeHistory(KisMementoSP oldestMemento) {
189 QWriteLocker locker(&m_lock);
190 m_mementoManager->purgeHistory(oldestMemento);
191 }
192
193 static void releaseInternalPools();
194
195protected:
199 bool write(KisPaintDeviceWriter &store);
200 bool read(QIODevice *stream);
201
202 void purge(const QRect& area);
203
204 inline quint32 pixelSize() const {
205 return m_pixelSize;
206 }
207
208 /* FIXME:*/
209public:
210
211
212 void extent(qint32 &x, qint32 &y, qint32 &w, qint32 &h) const;
213 void setExtent(qint32 x, qint32 y, qint32 w, qint32 h);
214 QRect extent() const;
215 void setExtent(QRect newRect);
216
217 KisRegion region() const;
218
219 void clear(QRect clearRect, quint8 clearValue);
220 void clear(QRect clearRect, const quint8 *clearPixel);
221 void clear(qint32 x, qint32 y, qint32 w, qint32 h, quint8 clearValue);
222 void clear(qint32 x, qint32 y, qint32 w, qint32 h, const quint8 *clearPixel);
223 void clear();
224
231 void bitBlt(KisTiledDataManager *srcDM, const QRect &rect);
232
236 void bitBltOldData(KisTiledDataManager *srcDM, const QRect &rect);
237
245 void bitBltRough(KisTiledDataManager *srcDM, const QRect &rect);
246
250 void bitBltRoughOldData(KisTiledDataManager *srcDM, const QRect &rect);
251
255 void setPixel(qint32 x, qint32 y, const quint8 * data);
256
257
271 void readBytes(quint8 * bytes,
272 qint32 x, qint32 y,
273 qint32 w, qint32 h,
274 qint32 dataRowStride = -1) const;
290 void writeBytes(const quint8 * bytes,
291 qint32 x, qint32 y,
292 qint32 w, qint32 h,
293 qint32 dataRowStride = -1);
294
301 QVector<quint8*> readPlanarBytes(QVector<qint32> channelsizes, qint32 x, qint32 y, qint32 w, qint32 h) const;
302
314 void writePlanarBytes(QVector<quint8*> planes, QVector<qint32> channelsizes, qint32 x, qint32 y, qint32 w, qint32 h);
315
320 qint32 numContiguousColumns(qint32 x, qint32 minY, qint32 maxY) const;
321
326 qint32 numContiguousRows(qint32 y, qint32 minX, qint32 maxX) const;
327
332 qint32 rowStride(qint32 x, qint32 y) const;
333
334private:
340
341 mutable QReadWriteLock m_lock;
342
343private:
344 // Allow compression routines to calculate (col,row) coordinates
345 // and pixel size
347 friend class KisTileDataWrapper;
348 inline qint32 xToCol(qint32 x) const
349 {
350 return divideRoundDown(x, KisTileData::WIDTH);
351 }
352 inline qint32 yToRow(qint32 y) const
353 {
354 return divideRoundDown(y, KisTileData::HEIGHT);
355 }
356
357private:
358 void setDefaultPixelImpl(const quint8 *defPixel);
359
360 bool writeTilesHeader(KisPaintDeviceWriter &store, quint32 numTiles);
361 bool processTilesHeader(QIODevice *stream, quint32 &numTiles);
362
363 inline qint32 divideRoundDown(qint32 x, const qint32 y) const
364 {
370 return x >= 0 ? x / y : -(((-x - 1) / y) + 1);
371 }
372
373 void recalculateExtent();
374
375 quint8* duplicatePixel(qint32 num, const quint8 *pixel);
376
377 template<bool useOldSrcData>
378 void bitBltImpl(KisTiledDataManager *srcDM, const QRect &rect);
379 template<bool useOldSrcData>
380 void bitBltRoughImpl(KisTiledDataManager *srcDM, const QRect &rect);
381
382 void writeBytesBody(const quint8 *data,
383 qint32 x, qint32 y,
384 qint32 width, qint32 height,
385 qint32 dataRowStride = -1);
386 void readBytesBody(quint8 *data,
387 qint32 x, qint32 y,
388 qint32 width, qint32 height,
389 qint32 dataRowStride = -1) const;
390
391 template <bool allChannelsPresent>
392 void writePlanarBytesBody(QVector<quint8*> planes,
393 QVector<qint32> channelsizes,
394 qint32 x, qint32 y, qint32 w, qint32 h);
395 QVector<quint8*> readPlanarBytesBody(QVector<qint32> channelsizes,
396 qint32 x, qint32 y,
397 qint32 w, qint32 h) const;
398public:
400 m_mementoManager->debugPrintInfo();
401 }
402
403};
404
405// during development the following line helps to check the interface is correct
406// it should be safe to keep it here even during normal compilation
407//#include "kis_datamanager.h"
408
409#endif // KIS_TILEDDATAMANAGER_H_
410
const quint8 * newDefaultPixel() const
Definition kis_memento.h:81
const quint8 * oldDefaultPixel() const
Definition kis_memento.h:77
void saveNewDefaultPixel(const quint8 *pixel, quint32 pixelSize)
Definition kis_memento.h:72
void saveOldDefaultPixel(const quint8 *pixel, quint32 pixelSize)
Definition kis_memento.h:67
static const qint32 HEIGHT
static const qint32 WIDTH
KisTiledDataManager & operator=(const KisTiledDataManager &dm)
KisMementoManager * m_mementoManager
KisTiledExtentManager m_extentManager
qint32 yToRow(qint32 y) const
void purgeHistory(KisMementoSP oldestMemento)
const quint8 * defaultPixel() const
void rollforward(KisMementoSP memento)
qint32 xToCol(qint32 x) const
KisTileSP getOldTile(qint32 col, qint32 row, bool &existingTile)
qint32 divideRoundDown(qint32 x, const qint32 y) const
KisTileHashTable * m_hashTable
void getTilesPair(qint32 col, qint32 row, bool writable, KisTileSP *tile, KisTileSP *oldTile)
KisTileSP getTile(qint32 col, qint32 row, bool writable)
void rollback(KisMementoSP memento)
KisTileSP getOldTile(qint32 col, qint32 row)
KisTileSP getReadOnlyTileLazy(qint32 col, qint32 row, bool &existingTile)
KisSharedPtr< KisTiledDataManager > KisTiledDataManagerSP
struct Tile * newTile(struct rect r)
Definition pixels.c:231