void run() { switch(m_type) { case PRODUCER: for (int j = 0; j < m_numCycles; j++) { for (int i = 0; i < m_numTiles; i++) { KisTileSP voidTile = m_srcDM.getTile(i, 0, true); voidTile->lockForWrite(); QTest::qSleep(1); voidTile->unlock(); } QRect cloneRect(0, 0, m_numTiles * 64, 64); m_dstDM.bitBltRough(&m_srcDM, cloneRect); if(j % 50 == 0) dbgKrita << "Producer:" << j << "of" << m_numCycles; KisTileDataStore::instance()->debugSwapAll(); } break; case CONSUMER_SRC: for (int j = 0; j < m_numCycles; j++) { for (int i = 0; i < m_numTiles; i++) { KisTileSP voidTile = m_srcDM.getTile(i, 0, false); voidTile->lockForRead(); char temp = *voidTile->data(); Q_UNUSED(temp); QTest::qSleep(1); voidTile->unlock(); } if(j % 50 == 0) dbgKrita << "Consumer_src:" << j << "of" << m_numCycles; KisTileDataStore::instance()->debugSwapAll(); } break; case CONSUMER_DST: for (int j = 0; j < m_numCycles; j++) { for (int i = 0; i < m_numTiles; i++) { KisTileSP voidTile = m_dstDM.getTile(i, 0, false); voidTile->lockForRead(); char temp = *voidTile->data(); Q_UNUSED(temp); QTest::qSleep(1); voidTile->unlock(); } if(j % 50 == 0) dbgKrita << "Consumer_dst:" << j << "of" << m_numCycles; KisTileDataStore::instance()->debugSwapAll(); } } }
void run() { qsrand(QTime::currentTime().msec()); for(qint32 i = 0; i < NUM_CYCLES; i++) { qint32 type = qrand() % NUM_TYPES; qint32 t; switch(type) { case 0: run_concurrent(lock,t) { quint8 *buf; buf = new quint8[dm.pixelSize()]; memcpy(buf, dm.defaultPixel(), dm.pixelSize()); dm.setDefaultPixel(buf); delete[] buf; } break; case 1: case 2: run_concurrent(lock,t) { KisTileSP tile; tile = dm.getTile(m_accessRect.x() / TILE_DIMENSION, m_accessRect.y() / TILE_DIMENSION, false); tile->lockForRead(); tile->unlock(); tile = dm.getTile(m_accessRect.x() / TILE_DIMENSION, m_accessRect.y() / TILE_DIMENSION, true); tile->lockForWrite(); tile->unlock(); tile = dm.getOldTile(m_accessRect.x() / TILE_DIMENSION, m_accessRect.y() / TILE_DIMENSION); tile->lockForRead(); tile->unlock(); } break; case 3: run_concurrent(lock,t) { QRect newRect = dm.extent(); Q_UNUSED(newRect); }
void KisTiledDataManagerTest::benchmarkCOWImpl() { const int pixelSize = 8; quint8 defaultPixel[pixelSize]; memset(defaultPixel, 1, pixelSize); KisTiledDataManager dm(pixelSize, defaultPixel); KisMementoSP memento1 = dm.getMemento(); /** * Imagine a regular image of 4096x2048 pixels * (64x32 tiles) */ for (int i = 0; i < 32; i++) { for (int j = 0; j < 64; j++) { KisTileSP tile = dm.getTile(j, i, true); tile->lockForWrite(); tile->unlock(); } } dm.commit(); QTest::qSleep(500); KisMementoSP memento2 = dm.getMemento(); QTest::qSleep(500); QBENCHMARK { for (int i = 0; i < 32; i++) { for (int j = 0; j < 64; j++) { KisTileSP tile = dm.getTile(j, i, true); tile->lockForWrite(); tile->unlock(); } } } dm.commit(); }
void KisLegacyTileCompressor::writeTile(KisTileSP tile, KisPaintDeviceWriter &store) { const qint32 tileDataSize = TILE_DATA_SIZE(tile->pixelSize()); const qint32 bufferSize = maxHeaderLength() + 1; quint8 *headerBuffer = new quint8[bufferSize]; writeHeader(tile, headerBuffer); store.write((char *)headerBuffer, strlen((char *)headerBuffer)); tile->lockForRead(); store.write((char *)tile->data(), tileDataSize); tile->unlock(); delete[] headerBuffer; }
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(); }
bool KisLegacyTileCompressor::writeTile(KisTileSP tile, KisPaintDeviceWriter &store) { const qint32 tileDataSize = TILE_DATA_SIZE(tile->pixelSize()); const qint32 bufferSize = maxHeaderLength() + 1; QScopedArrayPointer<quint8> headerBuffer(new quint8[bufferSize]); bool retval = writeHeader(tile, headerBuffer.data()); Q_ASSERT(retval); // currently the code returns true unconditionally if (!retval) { return false; } store.write((char *)headerBuffer.data(), strlen((char *)headerBuffer.data())); tile->lockForRead(); retval = store.write((char *)tile->data(), tileDataSize); tile->unlock(); return retval; }
void KisLegacyTileCompressor::readTile(QIODevice *stream, KisTiledDataManager *dm) { const qint32 tileDataSize = TILE_DATA_SIZE(pixelSize(dm)); const qint32 bufferSize = maxHeaderLength() + 1; quint8 *headerBuffer = new quint8[bufferSize]; qint32 x, y; qint32 width, height; stream->readLine((char *)headerBuffer, bufferSize); sscanf((char *) headerBuffer, "%d,%d,%d,%d", &x, &y, &width, &height); qint32 row = yToRow(dm, y); qint32 col = xToCol(dm, x); KisTileSP tile = dm->getTile(col, row, true); tile->lockForWrite(); stream->read((char *)tile->data(), tileDataSize); tile->unlock(); }
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 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; }