Commit b7c5e029 authored by Dmitry Kazakov's avatar Dmitry Kazakov

Remove KisRectIteratorNG and KisRectConstIteratorNG class

From now on, Krita uses KisSequentialIterator, which is almost twice
faster (due to inlining) and is much easier to maintain for
Wraparound Mode.
parent e7f5b985
......@@ -38,6 +38,7 @@
#include "kis_selection.h"
#include <kis_iterator_ng.h>
void KisBContrastBenchmark::initTestCase()
{
m_colorSpace = KoColorSpaceRegistry::instance()->rgb8();
......@@ -47,16 +48,16 @@ void KisBContrastBenchmark::initTestCase()
srand(31524744);
int r,g,b;
KisRectIteratorSP it = m_device->createRectIteratorNG(QRect(0, 0, GMP_IMAGE_WIDTH, GMP_IMAGE_HEIGHT));
KisSequentialIterator it(m_device, QRect(0, 0, GMP_IMAGE_WIDTH, GMP_IMAGE_HEIGHT));
do {
r = rand() % 255;
g = rand() % 255;
b = rand() % 255;
m_color.fromQColor(QColor(r,g,b));
memcpy(it->rawData(), m_color.data(), m_colorSpace->pixelSize());
} while (it->nextPixel());
memcpy(it.rawData(), m_color.data(), m_colorSpace->pixelSize());
} while (it.nextPixel());
}
......
......@@ -49,15 +49,15 @@ void KisBlurBenchmark::initTestCase()
int r,g,b;
KisRectIteratorSP it = m_device->createRectIteratorNG(QRect(0,0,GMP_IMAGE_WIDTH, GMP_IMAGE_HEIGHT));
KisSequentialIterator it(m_device, QRect(0,0,GMP_IMAGE_WIDTH, GMP_IMAGE_HEIGHT));
do {
r = rand() % 255;
g = rand() % 255;
b = rand() % 255;
m_color.fromQColor(QColor(r,g,b));
memcpy(it->rawData(), m_color.data(), m_colorSpace->pixelSize());
} while (it->nextPixel());
memcpy(it.rawData(), m_color.data(), m_colorSpace->pixelSize());
} while (it.nextPixel());
}
void KisBlurBenchmark::cleanupTestCase()
......
......@@ -21,7 +21,6 @@ set(libkritatile_SRCS
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_memento_manager.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_hline_iterator.cpp
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_vline_iterator.cpp
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_rect_iterator.cpp
${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_random_accessor.cc
${CMAKE_SOURCE_DIR}/krita/image/tiles3/swap/kis_abstract_compression.cpp
${CMAKE_SOURCE_DIR}/krita/image/tiles3/swap/kis_lzf_compression.cpp
......
......@@ -32,7 +32,6 @@
#endif
#include <kis_iterator_ng.h>
KisColorTransformationFilter::KisColorTransformationFilter(const KoID& id, const KoID & category, const QString & entry) : KisFilter(id, category, entry)
{
}
......@@ -57,18 +56,17 @@ void KisColorTransformationFilter::processImpl(KisPaintDeviceSP device,
KoColorTransformation* colorTransformation = createTransformation(cs, config);
if (!colorTransformation) return;
KisRectIteratorSP it = device->createRectIteratorNG(applyRect);
KisSequentialIterator it(device, applyRect);
int p = 0;
int conseq;
do {
conseq = it->nConseqPixels();
conseq = it.nConseqPixels();
colorTransformation->transform(it->oldRawData(), it->rawData(), conseq);
colorTransformation->transform(it.oldRawData(), it.rawData(), conseq);
if (progressUpdater) progressUpdater->setValue(p += conseq);
} while(it->nextPixels(conseq));
} while(it.nextPixels(conseq));
delete colorTransformation;
}
......@@ -82,7 +82,7 @@ void KisHistogram::updateHistogram()
return;
}
KisRectConstIteratorSP srcIt = m_paintDevice->createRectConstIteratorNG(m_bounds);
KisSequentialConstIterator srcIt(m_paintDevice, m_bounds);
const KoColorSpace* cs = m_paintDevice->colorSpace();
// Let the producer do it's work
......@@ -95,9 +95,9 @@ void KisHistogram::updateHistogram()
// paint devices didn't know about their selections anymore.
// updateHistogram should get a selection parameter.
do {
i = srcIt->nConseqPixels();
m_producer->addRegionToBin(srcIt->oldRawData(), 0, i, cs);
} while (srcIt->nextPixels(i));
i = srcIt.nConseqPixels();
m_producer->addRegionToBin(srcIt.oldRawData(), 0, i, cs);
} while (srcIt.nextPixels(i));
computeHistogram();
}
......
......@@ -41,11 +41,3 @@ KisVLineConstIteratorNG::~KisVLineConstIteratorNG()
KisVLineIteratorNG::~KisVLineIteratorNG()
{
}
KisRectConstIteratorNG::~KisRectConstIteratorNG()
{
}
KisRectIteratorNG::~KisRectIteratorNG()
{
}
......@@ -108,28 +108,6 @@ public:
virtual ~KisVLineIteratorNG();
};
/**
* Create an iterator over a rectangle section of a paint device, the path followed by
* the iterator is not guaranteed, it is optimized for speed, which means that you shouldn't
* use this type of iterator if you are combining two differents layers.
*/
class KRITAIMAGE_EXPORT KisRectConstIteratorNG : public virtual KisBaseConstIteratorNG
{
Q_DISABLE_COPY(KisRectConstIteratorNG)
public:
KisRectConstIteratorNG() {}
virtual ~KisRectConstIteratorNG();
};
/**
* Also support writing.
*/
class KRITAIMAGE_EXPORT KisRectIteratorNG : public KisRectConstIteratorNG, public KisBaseIteratorNG
{
Q_DISABLE_COPY(KisRectIteratorNG)
public:
KisRectIteratorNG() {}
virtual ~KisRectIteratorNG();
};
#include "kis_sequential_iterator.h"
#endif
......@@ -51,7 +51,6 @@
#include "tiles3/kis_hline_iterator.h"
#include "tiles3/kis_vline_iterator.h"
#include "tiles3/kis_rect_iterator.h"
#include "tiles3/kis_random_accessor.h"
#include "kis_default_bounds.h"
......@@ -829,17 +828,6 @@ KisVLineConstIteratorSP KisPaintDevice::createVLineConstIteratorNG(qint32 x, qin
return m_d->currentStrategy()->createVLineConstIteratorNG(x, y, w);
}
KisRectIteratorSP KisPaintDevice::createRectIteratorNG(const QRect &rc)
{
m_d->cache.invalidate();
return m_d->currentStrategy()->createRectIteratorNG(rc);
}
KisRectConstIteratorSP KisPaintDevice::createRectConstIteratorNG(const QRect &rc) const
{
return m_d->currentStrategy()->createRectConstIteratorNG(rc);
}
KisRepeatHLineConstIteratorSP KisPaintDevice::createRepeatHLineConstIterator(qint32 x, qint32 y, qint32 w, const QRect& _dataWidth) const
{
KisDataManager* dm = const_cast< KisDataManager*>(m_d->dataManager.data());
......
......@@ -669,9 +669,6 @@ public:
KisVLineIteratorSP createVLineIteratorNG(qint32 x, qint32 y, qint32 h);
KisVLineConstIteratorSP createVLineConstIteratorNG(qint32 x, qint32 y, qint32 h) const;
KisRectIteratorSP createRectIteratorNG(const QRect &rc);
KisRectConstIteratorSP createRectConstIteratorNG(const QRect &rc) const;
KisRandomAccessorSP createRandomAccessorNG(qint32 x, qint32 y);
KisRandomConstAccessorSP createRandomConstAccessorNG(qint32 x, qint32 y) const;
......
......@@ -22,7 +22,6 @@
#include "kis_wrapped_rect.h"
#include "kis_wrapped_hline_iterator.h"
#include "kis_wrapped_vline_iterator.h"
#include "kis_wrapped_rect_iterator.h"
#include "kis_wrapped_random_accessor.h"
......@@ -107,17 +106,6 @@ public:
return new KisVLineIterator2(m_d->dataManager.data(), x, y, w, m_d->x, m_d->y, false);
}
virtual KisRectIteratorSP createRectIteratorNG(const QRect &rc) {
m_d->cache.invalidate();
return new KisRectIterator2(m_d->dataManager.data(), rc.x(), rc.y(), rc.width(), rc.height(), m_d->x, m_d->y, true);
}
virtual KisRectConstIteratorSP createRectConstIteratorNG(const QRect &rc) const{
return new KisRectIterator2(m_d->dataManager.data(), rc.x(), rc.y(), rc.width(), rc.height(), m_d->x, m_d->y, false);
}
virtual KisRandomAccessorSP createRandomAccessorNG(qint32 x, qint32 y) {
m_d->cache.invalidate();
return new KisRandomAccessor2(m_d->dataManager.data(), x, y, m_d->x, m_d->y, true);
......@@ -318,24 +306,6 @@ public:
return new KisWrappedVLineIterator(m_d->dataManager.data(), splitRect, m_d->x, m_d->y, false);
}
virtual KisRectIteratorSP createRectIteratorNG(const QRect &rc) {
m_d->cache.invalidate();
KisWrappedRect splitRect(rc, m_wrapRect);
if (!splitRect.isSplit()) {
return KisPaintDeviceStrategy::createRectIteratorNG(rc);
}
return new KisWrappedRectIterator(m_d->dataManager.data(), splitRect, m_d->x, m_d->y, true);
}
virtual KisRectConstIteratorSP createRectConstIteratorNG(const QRect &rc) const {
KisWrappedRect splitRect(rc, m_wrapRect);
if (!splitRect.isSplit()) {
return KisPaintDeviceStrategy::createRectConstIteratorNG(rc);
}
return new KisWrappedRectIterator(m_d->dataManager.data(), splitRect, m_d->x, m_d->y, false);
}
virtual KisRandomAccessorSP createRandomAccessorNG(qint32 x, qint32 y) {
m_d->cache.invalidate();
return new KisWrappedRandomAccessor(m_d->dataManager.data(), x, y, m_d->x, m_d->y, true, m_wrapRect);
......
......@@ -41,6 +41,7 @@
#include "kis_outline_generator.h"
#include <kis_iterator_ng.h>
struct KisPixelSelection::Private {
KisSelectionWSP parentSelection;
......@@ -244,10 +245,10 @@ void KisPixelSelection::invert()
QRect rc = region().boundingRect();
if (!rc.isEmpty()) {
KisRectIteratorSP it = createRectIteratorNG(rc);
KisSequentialIterator it(this, rc);
do {
*(it->rawData()) = MAX_SELECTED - *(it->rawData());
} while (it->nextPixel());
*(it.rawData()) = MAX_SELECTED - *(it.rawData());
} while (it.nextPixel());
}
quint8 defPixel = MAX_SELECTED - *defaultPixel();
setDefaultPixel(&defPixel);
......
......@@ -98,6 +98,20 @@ public:
m_policy.updatePointersCache();
}
inline int nConseqPixels() const {
return m_columnsLeft;
}
inline bool nextPixels(int numPixels) {
// leave one step for the nextPixel() call
numPixels--;
m_columnsLeft -= numPixels;
m_columnOffset += numPixels * m_pixelSize;
return nextPixel();
}
inline bool nextPixel() {
m_columnsLeft--;
......@@ -122,6 +136,15 @@ public:
return m_columnsLeft > 0;
}
ALWAYS_INLINE int x() const {
return m_policy.m_iter->x() + m_numConseqPixels - m_columnsLeft;
}
ALWAYS_INLINE int y() const {
return m_policy.m_iter->y();
}
// SFINAE: This method becomes undefined for const version of the
// iterator automatically
ALWAYS_INLINE quint8* rawData() {
......
......@@ -162,12 +162,6 @@ typedef KisSharedPtr<KisVLineIteratorNG> KisVLineIteratorSP;
class KisVLineConstIteratorNG;
typedef KisSharedPtr<KisVLineConstIteratorNG> KisVLineConstIteratorSP;
class KisRectIteratorNG;
typedef KisSharedPtr<KisRectIteratorNG> KisRectIteratorSP;
class KisRectConstIteratorNG;
typedef KisSharedPtr<KisRectConstIteratorNG> KisRectConstIteratorSP;
class KisRandomConstAccessorNG;
typedef KisSharedPtr<KisRandomConstAccessorNG> KisRandomConstAccessorSP;
......
/*
* Copyright (c) 2013 Dmitry Kazakov <dimula73@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __KIS_WRAPPED_RECT_ITERATOR_H
#define __KIS_WRAPPED_RECT_ITERATOR_H
#include "kis_iterator_ng.h"
#include "kis_wrapped_rect.h"
class WrappedRectIteratorStrategy
{
public:
typedef KisRectIteratorSP IteratorTypeSP;
WrappedRectIteratorStrategy()
: m_iteratorRowStart(KisWrappedRect::TOPLEFT)
{
}
inline QSize originalRectToColumnsRows(const QRect &rect) {
return QSize(rect.width() * rect.height(), 1);
}
inline QPoint columnRowToXY(const QPoint &pt) const {
int col = pt.x();
int width = m_splitRect->originalRect().width();
return QPoint(col % width, col / width);
}
inline IteratorTypeSP createIterator(KisDataManager *dataManager,
const QRect &rc,
qint32 offsetX, qint32 offsetY,
bool writable) {
return new KisRectIterator2(dataManager,
rc.x(), rc.y(),
rc.width(),
rc.height(),
offsetX, offsetY,
writable);
}
inline void completeInitialization(QVector<IteratorTypeSP> *iterators,
KisWrappedRect *splitRect) {
m_splitRect = splitRect;
m_iterators = iterators;
int iterationWidth = m_splitRect->topLeft().width() + m_splitRect->topRight().width();
int iterationHeight = m_splitRect->topLeft().height() + m_splitRect->topRight().height();
if (m_splitRect->wrapRect().width() < m_splitRect->originalRect().width() ||
m_splitRect->wrapRect().width() < m_splitRect->originalRect().height()) {
qCritical() << "CRITICAL: KisWrappedRectIterator does *not* support";
qCritical() << " iteration over area larger than the wrapRect";
qCritical() << " (not implemented).";
qCritical() << " The result is UNDEFINED!";
KIS_ASSERT_RECOVER_NOOP(false);
}
}
inline IteratorTypeSP leftColumnIterator() const {
return m_iterators->at(m_iteratorRowStart + KisWrappedRect::TOPLEFT);
}
inline IteratorTypeSP rightColumnIterator() const {
return m_iterators->at(m_iteratorRowStart + KisWrappedRect::TOPRIGHT);
}
inline bool trySwitchColumnForced() {
bool result =
m_iteratorRowStart != KisWrappedRect::BOTTOMLEFT &&
m_iterators->at(KisWrappedRect::BOTTOMLEFT);
if (result) {
m_iteratorRowStart = KisWrappedRect::BOTTOMLEFT;
}
return result;
}
inline bool trySwitchIteratorStripe() {
qFatal("Not accessible for rect iterator!");
return false;
}
inline void iteratorsToNextRow() {
qFatal("Not accessible for rect iterator!");
}
private:
KisWrappedRect *m_splitRect;
QVector<IteratorTypeSP> *m_iterators;
int m_iteratorRowStart; // may be either KisWrappedRect::TOPLEFT or KisWrappedRect::BOTTOMLEFT
};
#include "kis_wrapped_line_iterator_base.h"
typedef KisWrappedLineIteratorBase<WrappedRectIteratorStrategy, KisRectIteratorNG> KisWrappedRectIterator;
#endif /* __KIS_WRAPPED_RECT_ITERATOR_H */
......@@ -29,48 +29,12 @@
#include "kis_random_sub_accessor.h"
#include <kis_iterator_ng.h>
#include <kis_repeat_iterators_pixel.h>
#include <kis_sequential_iterator.h>
#include "kis_paint_device.h"
#define TEST_WIDTH 3000
#define TEST_HEIGHT 3000
void KisIteratorBenchmark::rectIter(const KoColorSpace * colorSpace)
{
KisPaintDevice dev(colorSpace);
quint8 * bytes = new quint8[colorSpace->pixelSize() * 64*64];
memset(bytes, 128, 64 * 64 * colorSpace->pixelSize());
QTime t;
t.start();
for (int i = 0; i < 3; i++) {
KisRectIteratorSP it = dev.createRectIteratorNG(QRect(0, 0, TEST_WIDTH, TEST_HEIGHT));
do {
memcpy(it->rawData(), bytes, colorSpace->pixelSize());
} while (it->nextPixel());
qDebug() << "RectIterator run " << i << "took" << t.elapsed();
t.restart();
}
for (int i = 0; i < 3; i++) {
KisRectIteratorSP it = dev.createRectIteratorNG(QRect(0, 0, TEST_WIDTH, TEST_HEIGHT));
int nConseqPixels;
do {
nConseqPixels = it->nConseqPixels();
memcpy(it->rawData(), bytes, nConseqPixels * colorSpace->pixelSize());
} while (it->nextPixels(nConseqPixels));
qDebug() << "RectIterator run (with nConseqPixels)" << i << "took" << t.elapsed();
t.restart();
}
delete[] bytes;
}
void KisIteratorBenchmark::sequentialIter(const KoColorSpace * colorSpace)
{
......@@ -264,7 +228,6 @@ void KisIteratorBenchmark::runBenchmark()
hLineIterNG(cs);
vLineIterNG(cs);
rectIter(cs);
sequentialIter(cs);
randomAccessor(cs);
}
......
......@@ -32,7 +32,6 @@ private:
void vLineIterNG(const KoColorSpace * cs);
void sequentialIter(const KoColorSpace * colorSpace);
void rectIter(const KoColorSpace * cs);
void hLineIterNG(const KoColorSpace * cs);
void randomAccessor(const KoColorSpace * cs);
......
......@@ -130,63 +130,6 @@ void KisIteratorTest::fill(const KoColorSpace * colorSpace)
delete[] bytes;
}
void KisIteratorTest::rectIter(const KoColorSpace * colorSpace)
{
KisPaintDevice dev(colorSpace);
quint8 * bytes = allocatePixels(colorSpace, 1);
QCOMPARE(dev.extent(), QRect(qint32_MAX, qint32_MAX, 0, 0));
{
// Const does not extend the extent
KisRectConstIteratorSP cit = dev.createRectConstIteratorNG(QRect(0, 0, 128, 128));
do {} while (cit->nextPixel());
QCOMPARE(dev.extent(), QRect(qint32_MAX, qint32_MAX, 0, 0));
QCOMPARE(dev.exactBounds(), QRect(qint32_MAX, qint32_MAX, 0, 0));
// Non-const does
KisRectIteratorSP it = dev.createRectIteratorNG(QRect(0, 0, 128, 128));
do {
memcpy(it->rawData(), bytes, colorSpace->pixelSize());
} while (it->nextPixel());
QCOMPARE(dev.extent(), QRect(0, 0, 128, 128));
QCOMPARE(dev.exactBounds(), QRect(0, 0, 128, 128));
}
dev.clear();
{
KisRectIteratorSP it = dev.createRectIteratorNG(QRect(10, 10, 128, 128));
do {
memcpy(it->rawData(), bytes, colorSpace->pixelSize());
} while (it->nextPixel());
QCOMPARE(dev.extent(), QRect(0, 0, 3 * 64, 3 * 64));
QCOMPARE(dev.exactBounds(), QRect(10, 10, 128, 128));
}
dev.clear();
dev.setX(10);
dev.setY(-15);
{
KisRectIteratorSP it = dev.createRectIteratorNG(QRect(10, 10, 128, 128));
do {
memcpy(it->rawData(), bytes, colorSpace->pixelSize());
} while (it->nextPixel());
QCOMPARE(dev.extent(), QRect(10, -15, 128, 192));
QCOMPARE(dev.exactBounds(), QRect(10, 10, 128, 128));
}
delete[] bytes;
}
void KisIteratorTest::hLineIter(const KoColorSpace * colorSpace)
{
KisPaintDevice dev(colorSpace);
......@@ -392,11 +335,6 @@ void KisIteratorTest::fill()
allCsApplicator(&KisIteratorTest::fill);
}
void KisIteratorTest::rectIter()
{
allCsApplicator(&KisIteratorTest::rectIter);
}
void KisIteratorTest::hLineIter()
{
allCsApplicator(&KisIteratorTest::hLineIter);
......
......@@ -36,7 +36,6 @@ private:
void vLineIter(const KoColorSpace * cs);
void writeBytes(const KoColorSpace * cs);
void fill(const KoColorSpace * cs);
void rectIter(const KoColorSpace * cs);
void hLineIter(const KoColorSpace * cs);
void randomAccessor(const KoColorSpace * cs);
void repeatHLineIter(const KoColorSpace * cs);
......@@ -47,7 +46,6 @@ private slots:
void vLineIter();
void writeBytes();
void fill();
void rectIter();
void hLineIter();
void randomAccessor();
void repeatHLineIter();
......
......@@ -31,7 +31,6 @@
#include "kis_paint_device.h"
#include <kis_iterator_ng.h>
#include "kis_sequential_iterator.h"
void KisIteratorTest::allCsApplicator(void (KisIteratorTest::* funcPtr)(const KoColorSpace*cs))
......@@ -129,58 +128,6 @@ void KisIteratorTest::fill(const KoColorSpace * colorSpace)
delete[] bytes;
}
void KisIteratorTest::rectIter(const KoColorSpace * colorSpace)
{
KisPaintDevice dev(colorSpace);
quint8 * bytes = allocatePixels(colorSpace, 1);
QCOMPARE(dev.extent(), QRect(qint32_MAX, qint32_MAX, 0, 0));
// Const does not extend the extent
KisRectConstIteratorSP cit = dev.createRectConstIteratorNG(QRect(0, 0, 128, 128));
while (cit->nextPixel());
QCOMPARE(dev.extent(), QRect(qint32_MAX, qint32_MAX, 0, 0));
QCOMPARE(dev.exactBounds(), QRect(qint32_MAX, qint32_MAX, 0, 0));
// Non-const does
KisRectIteratorSP it = dev.createRectIteratorNG(QRect(0, 0, 128, 128));
do {
memcpy(it->rawData(), bytes, colorSpace->pixelSize());
} while (it->nextPixel());
QCOMPARE(dev.extent(), QRect(0, 0, 128, 128));
QCOMPARE(dev.exactBounds(), QRect(0, 0, 128, 128));
dev.clear();
it = dev.createRectIteratorNG(QRect(10, 10, 128, 128));
do {
memcpy(it->rawData(), bytes, colorSpace->pixelSize());
} while (it->nextPixel());
QCOMPARE(dev.extent(), QRect(0, 0, 3 * 64, 3 * 64));
QCOMPARE(dev.exactBounds(), QRect(10, 10, 128, 128));
dev.clear();
dev.setX(10);
dev.setY(-15);
it = dev.createRectIteratorNG(QRect(10, 10, 128, 128));
do {
memcpy(it->rawData(), bytes, colorSpace->pixelSize());
} while (it->nextPixel());
QCOMPARE(dev.extent(), QRect(10, -15, 128, 192));
QCOMPARE(dev.exactBounds(), QRect(10, 10, 128, 128));
it = dev.createRectIteratorNG(QRect(10, 10, 128, 128));
QCOMPARE(it->rawData(), it->oldRawData());
delete[] bytes;
}