bool KisTiledDataManagerTest::checkTilesShared(KisTiledDataManager *srcDM,
        KisTiledDataManager *dstDM,
        bool takeOldSrc,
        bool takeOldDst,
        QRect tilesRect)
{
    for(qint32 row = tilesRect.y(); row <= tilesRect.bottom(); row++) {
        for(qint32 col = tilesRect.x(); col <= tilesRect.right(); col++) {
            KisTileSP srcTile = takeOldSrc ? srcDM->getOldTile(col, row)
                                : srcDM->getTile(col, row, false);
            KisTileSP dstTile = takeOldDst ? dstDM->getOldTile(col, row)
                                : dstDM->getTile(col, row, false);

            if(srcTile->tileData() != dstTile->tileData()) {
                dbgKrita << "Expected tile data (" << col << row << ")"
                         << srcTile->extent()
                         << srcTile->tileData()
                         << "but found" << dstTile->tileData();
                dbgKrita << "Expected" << srcTile->data()[0] << "but found" << dstTile->data()[0];
                return false;
            }
        }
    }
    return true;
}
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;
}
Exemplo n.º 3
0
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();
}
inline void KisLegacyTileCompressor::writeHeader(KisTileSP tile,
                                                 quint8 *buffer)
{
    qint32 x, y;
    qint32 width, height;

    tile->extent().getRect(&x, &y, &width, &height);
    sprintf((char *)buffer, "%d,%d,%d,%d\n", x, y, width, height);
}
Exemplo n.º 5
0
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();
}
Exemplo n.º 7
0
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 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();
}
Exemplo n.º 10
0
    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();
            }

        }
    }
Exemplo n.º 11
0
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;
}