qint64 KisTileDataSwapper::pass(qint64 needToFreeMetric) { qint64 freedMetric = 0; QList<KisTileData*> additionalCandidates; typename strategy::iterator *iter = strategy::beginIteration(m_d->store); KisTileData *item; while(iter->hasNext()) { item = iter->next(); if(freedMetric >= needToFreeMetric) break; if(!strategy::isInteresting(item)) continue; if(strategy::swapOutFirst(item)) { if(iter->trySwapOut(item)) { freedMetric += item->pixelSize(); } } else { item->markOld(); additionalCandidates.append(item); } } foreach(item, additionalCandidates) { if(freedMetric >= needToFreeMetric) break; if(iter->trySwapOut(item)) { freedMetric += item->pixelSize(); } } strategy::endIteration(m_d->store, iter); return freedMetric; }
void KisTileCompressorsTest::doLowLevelRoundTrip(KisAbstractTileCompressor *compressor) { const qint32 pixelSize = 1; quint8 oddPixel1 = 128; quint8 oddPixel2 = 129; /** * A small hack to acquire a standalone tile data. * globalTileDataStore is not exported out of kritaimage.so, * so we get it from the data manager */ KisTiledDataManager dm(pixelSize, &oddPixel1); KisTileSP tile = dm.getTile(0, 0, true); tile->lockForWrite(); KisTileData *td = tile->tileData(); QVERIFY(memoryIsFilled(oddPixel1, td->data(), TILESIZE)); qint32 bufferSize = compressor->tileDataBufferSize(td); quint8 *buffer = new quint8[bufferSize]; qint32 bytesWritten; compressor->compressTileData(td, buffer, bufferSize, bytesWritten); dbgKrita << ppVar(bytesWritten); memset(td->data(), oddPixel2, TILESIZE); QVERIFY(memoryIsFilled(oddPixel2, td->data(), TILESIZE)); compressor->decompressTileData(buffer, bytesWritten, td); QVERIFY(memoryIsFilled(oddPixel1, td->data(), TILESIZE)); delete[] buffer; tile->unlock(); }
void KisSwappedDataStoreTest::testRoundTrip() { const qint32 pixelSize = 1; const quint8 defaultPixel = 128; const qint32 NUM_TILES = 10000; KisImageConfig config; config.setMaxSwapSize(4); config.setSwapSlabSize(1); config.setSwapWindowSize(1); KisSwappedDataStore store; QList<KisTileData*> tileDataList; for(qint32 i = 0; i < NUM_TILES; i++) tileDataList.append(new KisTileData(pixelSize, &defaultPixel, KisTileDataStore::instance())); for(qint32 i = 0; i < NUM_TILES; i++) { KisTileData *td = tileDataList[i]; QVERIFY(memoryIsFilled(defaultPixel, td->data(), TILESIZE)); memset(td->data(), COLUMN2COLOR(i), TILESIZE); QVERIFY(memoryIsFilled(COLUMN2COLOR(i), td->data(), TILESIZE)); // FIXME: take a lock of the tile data store.swapOutTileData(td); } store.debugStatistics(); for(qint32 i = 0; i < NUM_TILES; i++) { KisTileData *td = tileDataList[i]; QVERIFY(!td->data()); // TODO: check num clones // FIXME: take a lock of the tile data store.swapInTileData(td); QVERIFY(memoryIsFilled(COLUMN2COLOR(i), td->data(), TILESIZE)); } store.debugStatistics(); for(qint32 i = 0; i < NUM_TILES; i++) delete tileDataList[i]; }
void KisTileCompressorsTest::doLowLevelRoundTripIncompressible(KisAbstractTileCompressor *compressor) { const qint32 pixelSize = 1; quint8 oddPixel1 = 128; quint8 oddPixel2 = 129; QFile file(QString(FILES_DATA_DIR) + QDir::separator() + "tile.png"); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return; QByteArray incompressibleArray = file.readAll(); /** * A small hack to acquire a standalone tile data. * globalTileDataStore is not exported out of kritaimage.so, * so we get it from the data manager */ KisTiledDataManager dm(pixelSize, &oddPixel1); KisTileSP tile = dm.getTile(0, 0, true); tile->lockForWrite(); KisTileData *td = tile->tileData(); QVERIFY(memoryIsFilled(oddPixel1, td->data(), TILESIZE)); memcpy(td->data(), incompressibleArray.data(), TILESIZE); QVERIFY(!memcmp(td->data(), incompressibleArray.data(), TILESIZE)); qint32 bufferSize = compressor->tileDataBufferSize(td); quint8 *buffer = new quint8[bufferSize]; qint32 bytesWritten; compressor->compressTileData(td, buffer, bufferSize, bytesWritten); dbgKrita << ppVar(bytesWritten); memset(td->data(), oddPixel2, TILESIZE); QVERIFY(memoryIsFilled(oddPixel2, td->data(), TILESIZE)); compressor->decompressTileData(buffer, bytesWritten, td); QVERIFY(!memcmp(td->data(), incompressibleArray.data(), TILESIZE)); delete[] buffer; tile->unlock(); }
void KisLowMemoryTests::hangingTilesTest() { quint8 defaultPixel = 0; KisTiledDataManager srcDM(1, &defaultPixel); KisTileSP srcTile = srcDM.getTile(0, 0, true); srcTile->lockForWrite(); srcTile->lockForRead(); KisTiledDataManager dstDM(1, &defaultPixel); dstDM.bitBlt(&srcDM, QRect(0,0,64,64)); KisTileSP dstTile = dstDM.getTile(0, 0, true); dstTile->lockForRead(); KisTileData *weirdTileData = dstTile->tileData(); quint8 *weirdData = dstTile->data(); QCOMPARE(weirdTileData, srcTile->tileData()); QCOMPARE(weirdData, srcTile->data()); KisTileDataStore::instance()->debugSwapAll(); QCOMPARE(srcTile->tileData(), weirdTileData); QCOMPARE(dstTile->tileData(), weirdTileData); QCOMPARE(srcTile->data(), weirdData); QCOMPARE(dstTile->data(), weirdData); dstTile->lockForWrite(); KisTileData *cowedTileData = dstTile->tileData(); quint8 *cowedData = dstTile->data(); QVERIFY(cowedTileData != weirdTileData); KisTileDataStore::instance()->debugSwapAll(); QCOMPARE(srcTile->tileData(), weirdTileData); QCOMPARE(dstTile->tileData(), cowedTileData); QCOMPARE(srcTile->data(), weirdData); QCOMPARE(dstTile->data(), cowedData); QCOMPARE((int)weirdTileData->m_usersCount, 2); srcTile->unlock(); srcTile->unlock(); srcTile = 0; srcDM.clear(); KisTileDataStore::instance()->debugSwapAll(); QCOMPARE(dstTile->tileData(), cowedTileData); QCOMPARE(dstTile->data(), cowedData); // two crash tests QCOMPARE(weirdTileData->data(), weirdData); quint8 testPixel = *weirdData; QCOMPARE(testPixel, defaultPixel); QCOMPARE((int)weirdTileData->m_usersCount, 1); dstTile->unlock(); dstTile->unlock(); dstTile = 0; }