kis_filter_selections_benchmark.cpp 8.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 *  Copyright (c) 2009 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.
 */

#include "kis_filter_selections_benchmark.h"

#include "kis_painter.h"

23
#include <QTest>
24 25
#include "testutil.h"
#include "kis_transaction.h"
26
#include <KoCompositeOpRegistry.h>
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
#include "kis_datamanager.h"


#define NUM_CYCLES 50
#define WARMUP_CYCLES 2
#define SHOW_WARMUPS  0

/**
 * Our filters don't know anything about applyAlphaU8Mask
 * That's why they treat semy-selected pixels badly
 *
 * If you have a hack in KisFilter - processSpecial(..) method
 * that takes into account this alpha mask then activate
 * the following define
 */
#define USE_GOOD_SELECTIONS 0

#define USE_UTIME 0


#if(USE_UTIME==1)
#include <sys/times.h>
class KisTimeCounter
{
public:
Boudewijn Rempt's avatar
Boudewijn Rempt committed
52 53
    KisTimeCounter() {
        m_factor = double(sysconf(_SC_CLK_TCK)) / 1000.0;
54 55 56 57 58 59 60
        restart();
    }

    void restart() {
        times(&m_startTime);
    }

Boudewijn Rempt's avatar
Boudewijn Rempt committed
61
    double elapsed() {
62 63
        struct tms endTime;
        times(&endTime);
Boudewijn Rempt's avatar
Boudewijn Rempt committed
64
        return double(endTime.tms_utime - m_startTime.tms_utime) / m_factor;
65 66 67 68 69 70 71 72 73 74 75 76 77
    }

private:
    struct tms m_startTime;
    double m_factor;
};
#else /* if(USE_UTIME==0) */
typedef QTime KisTimeCounter;
#endif

void KisFilterSelectionsBenchmark::initSelection()
{
    m_selection = new KisSelection();
78
    KisPixelSelectionSP pixelSelection = m_selection->pixelSelection();
79

80 81

//67.2% deselected
82
    dbgKrita << "Deselected: 67.2%";
83 84 85 86
    pixelSelection->dataManager()->clear(75, 75, 500, 320, 255);
    pixelSelection->dataManager()->clear(100, 100, 50, 50, quint8(0));
    pixelSelection->dataManager()->clear(150, 150, 50, 50, quint8(0));
    pixelSelection->dataManager()->clear(200, 200, 50, 50, quint8(0));
87

88 89
    pixelSelection->dataManager()->clear(375, 195, 200, 200, quint8(0));
    pixelSelection->dataManager()->clear(75, 195, 200, 200, quint8(0));
90

91
    pixelSelection->dataManager()->clear(375, 75, 150, 150, quint8(0));
92

93
    pixelSelection->dataManager()->clear(205, 105, 50, 50, quint8(128));
94 95

// 94.9% deselected
96
//    dbgKrita << "Deselected: 94.9%";
97 98
//    pixelSelection->dataManager()->clear(75,75,500,320,255);
//    pixelSelection->dataManager()->clear(80,80,490,310,quint8(0));
99 100 101



102
    pixelSelection->convertToQImage(0).save("TEST_FILTER_SELECTION.png");
103 104 105 106 107 108
}

void KisFilterSelectionsBenchmark::initFilter(const QString &name)
{
    m_filter = KisFilterRegistry::instance()->value(name);
    Q_ASSERT(m_filter);
109
    m_configuration = m_filter->defaultConfiguration();
110

111
    dbgKrita << "Filter initialized:" << name;
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
}

void KisFilterSelectionsBenchmark::testFilter(const QString &name)
{
    blockSignals(true);

    initFilter(name);

    testUsualSelections(WARMUP_CYCLES);
    testUsualSelections(NUM_CYCLES);

    testGoodSelections(WARMUP_CYCLES);
    testGoodSelections(NUM_CYCLES);

    testNoSelections(WARMUP_CYCLES);
    testNoSelections(NUM_CYCLES);

    testBitBltWOSelections(WARMUP_CYCLES);
    testBitBltWOSelections(NUM_CYCLES);

    testBitBltSelections(WARMUP_CYCLES);
    testBitBltSelections(NUM_CYCLES);

    blockSignals(false);
}


void KisFilterSelectionsBenchmark::testAll()
{
    initSelection();

    const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8();
    QImage image(QString(FILES_DATA_DIR) + QDir::separator() + "hakonepa.png");
    m_device = new KisPaintDevice(cs);
146
    m_device->convertFromQImage(image, 0, 0, 0);
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164

    testFilter("brightnesscontrast");
    testFilter("invert");
//    testFilter("levels");

}

void KisFilterSelectionsBenchmark::testUsualSelections(int num)
{
    KisPaintDeviceSP projection =
        new KisPaintDevice(m_device->colorSpace());

    double avTime;
    KisTimeCounter timer;

    QRect filterRect = m_selection->selectedExactRect();

    timer.restart();
Boudewijn Rempt's avatar
Boudewijn Rempt committed
165
    for (int i = 0; i < num; i++) {
166
        KisTransaction transac(projection, 0);
167
        m_filter->process(m_device, projection, m_selection, filterRect, m_configuration, 0);
168
    }
Boudewijn Rempt's avatar
Boudewijn Rempt committed
169
    avTime = double(timer.elapsed()) / num;
170 171 172

    projection->convertToQImage(0).save("TFS__USUAL_SELECTIONS.png");

Boudewijn Rempt's avatar
Boudewijn Rempt committed
173
    if (num > WARMUP_CYCLES || SHOW_WARMUPS)
174
        dbgKrita << "Selections inside filter:\t\t" << avTime;
175 176 177 178 179 180 181 182 183 184 185 186 187
}

void KisFilterSelectionsBenchmark::testNoSelections(int num)
{
    KisPaintDeviceSP projection =
        new KisPaintDevice(m_device->colorSpace());

    double avTime;
    KisTimeCounter timer;

    QRect filterRect = m_selection->selectedExactRect();

    timer.restart();
Boudewijn Rempt's avatar
Boudewijn Rempt committed
188
    for (int i = 0; i < num; i++) {
189
        KisTransaction transac(projection, 0);
190
        m_filter->process(m_device, projection, 0, filterRect, m_configuration, 0);
191
    }
Boudewijn Rempt's avatar
Boudewijn Rempt committed
192
    avTime = double(timer.elapsed()) / num;
193 194 195

    projection->convertToQImage(0).save("TFS__NO_SELECTIONS.png");

Boudewijn Rempt's avatar
Boudewijn Rempt committed
196
    if (num > WARMUP_CYCLES || SHOW_WARMUPS)
197
        dbgKrita << "No Selections:\t\t\t\t" << avTime;
198 199 200 201 202 203 204 205 206 207 208 209
}

void KisFilterSelectionsBenchmark::testGoodSelections(int num)
{
#if(USE_GOOD_SELECTIONS==1)
    KisPaintDeviceSP projection =
        new KisPaintDevice(m_device->colorSpace());

    double avTime;
    KisTimeCounter timer;

    QRect filterRect = m_selection->selectedExactRect();
Boudewijn Rempt's avatar
Boudewijn Rempt committed
210
    KisConstProcessingInformation src(m_device,  filterRect.topLeft(), m_selection);
211 212 213
    KisProcessingInformation dst(projection, filterRect.topLeft(), 0);

    timer.restart();
Boudewijn Rempt's avatar
Boudewijn Rempt committed
214
    for (int i = 0; i < num; i++) {
215
        KisTransaction transac(0, projection, 0);
216 217
        m_filter->processSpecial(src, dst, filterRect.size(), m_configuration, 0);
    }
Boudewijn Rempt's avatar
Boudewijn Rempt committed
218
    avTime = double(timer.elapsed()) / num;
219 220 221

    projection->convertToQImage(0).save("TFS__GOOD_SELECTIONS.png");

Boudewijn Rempt's avatar
Boudewijn Rempt committed
222
    if (num > WARMUP_CYCLES || SHOW_WARMUPS)
223
        dbgKrita << "Selections with alpha (filter):\t" << avTime;
224
#else /* if (USE_GOOD_SELECTIONS!=1) */
Boudewijn Rempt's avatar
Boudewijn Rempt committed
225
    if (num > WARMUP_CYCLES || SHOW_WARMUPS)
226
        dbgKrita << "Selections with alpha (filter):\t [Disabled]";
227 228 229 230 231 232 233 234 235 236 237 238 239 240
#endif
}

void KisFilterSelectionsBenchmark::testBitBltWOSelections(int num)
{
    KisPaintDeviceSP projection =
        new KisPaintDevice(m_device->colorSpace());

    double avTime;
    KisTimeCounter timer;

    QRect filterRect = m_selection->selectedExactRect();

    timer.restart();
Boudewijn Rempt's avatar
Boudewijn Rempt committed
241
    for (int i = 0; i < num; i++) {
242 243
        KisPaintDeviceSP cacheDevice = new KisPaintDevice(projection->colorSpace());

244
        KisTransaction transac(cacheDevice, 0);
245
        m_filter->process(m_device, projection, 0, filterRect, m_configuration, 0);
246

247
        KisPainter painter(projection);
248
        painter.beginTransaction();
249 250
        painter.setCompositeOp(projection->colorSpace()->compositeOp(COMPOSITE_ALPHA_DARKEN));
        painter.bitBlt(filterRect.topLeft(), cacheDevice, filterRect);
251
        painter.deleteTransaction();
252
    }
Boudewijn Rempt's avatar
Boudewijn Rempt committed
253
    avTime = double(timer.elapsed()) / num;
254 255 256

    projection->convertToQImage(0).save("TFS__BITBLT_WO_SELECTIONS.png");

Boudewijn Rempt's avatar
Boudewijn Rempt committed
257
    if (num > WARMUP_CYCLES || SHOW_WARMUPS)
258
        dbgKrita << "bitBlt w/o sel:\t\t\t" << avTime;
259 260 261 262 263 264 265 266 267 268 269 270 271
}

void KisFilterSelectionsBenchmark::testBitBltSelections(int num)
{
    KisPaintDeviceSP projection =
        new KisPaintDevice(m_device->colorSpace());

    double avTime;
    KisTimeCounter timer;

    QRect filterRect = m_selection->selectedExactRect();

    timer.restart();
Boudewijn Rempt's avatar
Boudewijn Rempt committed
272
    for (int i = 0; i < num; i++) {
273 274
        KisPaintDeviceSP cacheDevice = new KisPaintDevice(projection->colorSpace());

275
        KisTransaction transac(cacheDevice, 0);
276
        m_filter->process(m_device, cacheDevice, 0, filterRect, m_configuration, 0);
277 278

        KisPainter gc(projection);
279
        gc.beginTransaction();
280 281 282
        gc.setCompositeOp(projection->colorSpace()->compositeOp(COMPOSITE_ALPHA_DARKEN));
        gc.setSelection(m_selection);
        gc.bitBlt(filterRect.topLeft(), cacheDevice, filterRect);
283
        gc.deleteTransaction();
284
    }
Boudewijn Rempt's avatar
Boudewijn Rempt committed
285
    avTime = double(timer.elapsed()) / num;
286 287 288

    projection->convertToQImage(0).save("TFS__BITBLT_WITH_SELECTIONS.png");

Boudewijn Rempt's avatar
Boudewijn Rempt committed
289
    if (num > WARMUP_CYCLES || SHOW_WARMUPS)
290
        dbgKrita << "bitBlt with sel:\t\t\t" << avTime;
291 292
}

293
QTEST_MAIN(KisFilterSelectionsBenchmark)