File indexing completed on 2025-02-16 04:05:06
0001 /* 0002 * SPDX-FileCopyrightText: 2009 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_filter_selections_benchmark.h" 0008 0009 #include "kis_painter.h" 0010 0011 #include <simpletest.h> 0012 #include <testutil.h> 0013 #include "kis_transaction.h" 0014 #include <KoCompositeOpRegistry.h> 0015 #include "kis_datamanager.h" 0016 #include <KisGlobalResourcesInterface.h> 0017 0018 #define NUM_CYCLES 50 0019 #define WARMUP_CYCLES 2 0020 #define SHOW_WARMUPS 0 0021 0022 /** 0023 * Our filters don't know anything about applyAlphaU8Mask 0024 * That's why they treat semy-selected pixels badly 0025 * 0026 * If you have a hack in KisFilter - processSpecial(..) method 0027 * that takes into account this alpha mask then activate 0028 * the following define 0029 */ 0030 #define USE_GOOD_SELECTIONS 0 0031 0032 #define USE_UTIME 0 0033 0034 0035 #if(USE_UTIME==1) 0036 #include <sys/times.h> 0037 class KisTimeCounter 0038 { 0039 public: 0040 KisTimeCounter() { 0041 m_factor = double(sysconf(_SC_CLK_TCK)) / 1000.0; 0042 restart(); 0043 } 0044 0045 void restart() { 0046 times(&m_startTime); 0047 } 0048 0049 double elapsed() { 0050 struct tms endTime; 0051 times(&endTime); 0052 return double(endTime.tms_utime - m_startTime.tms_utime) / m_factor; 0053 } 0054 0055 private: 0056 struct tms m_startTime; 0057 double m_factor; 0058 }; 0059 #else /* if(USE_UTIME==0) */ 0060 typedef QElapsedTimer KisTimeCounter; 0061 #endif 0062 0063 void KisFilterSelectionsBenchmark::initSelection() 0064 { 0065 m_selection = new KisSelection(); 0066 KisPixelSelectionSP pixelSelection = m_selection->pixelSelection(); 0067 0068 0069 //67.2% deselected 0070 dbgKrita << "Deselected: 67.2%"; 0071 pixelSelection->dataManager()->clear(75, 75, 500, 320, 255); 0072 pixelSelection->dataManager()->clear(100, 100, 50, 50, quint8(0)); 0073 pixelSelection->dataManager()->clear(150, 150, 50, 50, quint8(0)); 0074 pixelSelection->dataManager()->clear(200, 200, 50, 50, quint8(0)); 0075 0076 pixelSelection->dataManager()->clear(375, 195, 200, 200, quint8(0)); 0077 pixelSelection->dataManager()->clear(75, 195, 200, 200, quint8(0)); 0078 0079 pixelSelection->dataManager()->clear(375, 75, 150, 150, quint8(0)); 0080 0081 pixelSelection->dataManager()->clear(205, 105, 50, 50, quint8(128)); 0082 0083 // 94.9% deselected 0084 // dbgKrita << "Deselected: 94.9%"; 0085 // pixelSelection->dataManager()->clear(75,75,500,320,255); 0086 // pixelSelection->dataManager()->clear(80,80,490,310,quint8(0)); 0087 0088 0089 0090 pixelSelection->convertToQImage(0).save("TEST_FILTER_SELECTION.png"); 0091 } 0092 0093 void KisFilterSelectionsBenchmark::initFilter(const QString &name) 0094 { 0095 m_filter = KisFilterRegistry::instance()->value(name); 0096 Q_ASSERT(m_filter); 0097 m_configuration = m_filter->defaultConfiguration(KisGlobalResourcesInterface::instance()); 0098 0099 dbgKrita << "Filter initialized:" << name; 0100 } 0101 0102 void KisFilterSelectionsBenchmark::testFilter(const QString &name) 0103 { 0104 blockSignals(true); 0105 0106 initFilter(name); 0107 0108 testUsualSelections(WARMUP_CYCLES); 0109 testUsualSelections(NUM_CYCLES); 0110 0111 testGoodSelections(WARMUP_CYCLES); 0112 testGoodSelections(NUM_CYCLES); 0113 0114 testNoSelections(WARMUP_CYCLES); 0115 testNoSelections(NUM_CYCLES); 0116 0117 testBitBltWOSelections(WARMUP_CYCLES); 0118 testBitBltWOSelections(NUM_CYCLES); 0119 0120 testBitBltSelections(WARMUP_CYCLES); 0121 testBitBltSelections(NUM_CYCLES); 0122 0123 blockSignals(false); 0124 } 0125 0126 0127 void KisFilterSelectionsBenchmark::testAll() 0128 { 0129 initSelection(); 0130 0131 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8(); 0132 QImage image(QString(FILES_DATA_DIR) + '/' + "hakonepa.png"); 0133 m_device = new KisPaintDevice(cs); 0134 m_device->convertFromQImage(image, 0, 0, 0); 0135 0136 testFilter("brightnesscontrast"); 0137 testFilter("invert"); 0138 // testFilter("levels"); 0139 0140 } 0141 0142 void KisFilterSelectionsBenchmark::testUsualSelections(int num) 0143 { 0144 KisPaintDeviceSP projection = 0145 new KisPaintDevice(m_device->colorSpace()); 0146 0147 double avTime; 0148 KisTimeCounter timer; 0149 0150 QRect filterRect = m_selection->selectedExactRect(); 0151 0152 timer.restart(); 0153 for (int i = 0; i < num; i++) { 0154 KisTransaction transac(projection, 0); 0155 m_filter->process(m_device, projection, m_selection, filterRect, m_configuration, 0); 0156 } 0157 avTime = double(timer.elapsed()) / num; 0158 0159 projection->convertToQImage(0).save("TFS__USUAL_SELECTIONS.png"); 0160 0161 if (num > WARMUP_CYCLES || SHOW_WARMUPS) 0162 dbgKrita << "Selections inside filter:\t\t" << avTime; 0163 } 0164 0165 void KisFilterSelectionsBenchmark::testNoSelections(int num) 0166 { 0167 KisPaintDeviceSP projection = 0168 new KisPaintDevice(m_device->colorSpace()); 0169 0170 double avTime; 0171 KisTimeCounter timer; 0172 0173 QRect filterRect = m_selection->selectedExactRect(); 0174 0175 timer.restart(); 0176 for (int i = 0; i < num; i++) { 0177 KisTransaction transac(projection, 0); 0178 m_filter->process(m_device, projection, 0, filterRect, m_configuration, 0); 0179 } 0180 avTime = double(timer.elapsed()) / num; 0181 0182 projection->convertToQImage(0).save("TFS__NO_SELECTIONS.png"); 0183 0184 if (num > WARMUP_CYCLES || SHOW_WARMUPS) 0185 dbgKrita << "No Selections:\t\t\t\t" << avTime; 0186 } 0187 0188 void KisFilterSelectionsBenchmark::testGoodSelections(int num) 0189 { 0190 #if(USE_GOOD_SELECTIONS==1) 0191 KisPaintDeviceSP projection = 0192 new KisPaintDevice(m_device->colorSpace()); 0193 0194 double avTime; 0195 KisTimeCounter timer; 0196 0197 QRect filterRect = m_selection->selectedExactRect(); 0198 KisConstProcessingInformation src(m_device, filterRect.topLeft(), m_selection); 0199 KisProcessingInformation dst(projection, filterRect.topLeft(), 0); 0200 0201 timer.restart(); 0202 for (int i = 0; i < num; i++) { 0203 KisTransaction transac(0, projection, 0); 0204 m_filter->processSpecial(src, dst, filterRect.size(), m_configuration, 0); 0205 } 0206 avTime = double(timer.elapsed()) / num; 0207 0208 projection->convertToQImage(0).save("TFS__GOOD_SELECTIONS.png"); 0209 0210 if (num > WARMUP_CYCLES || SHOW_WARMUPS) 0211 dbgKrita << "Selections with alpha (filter):\t" << avTime; 0212 #else /* if (USE_GOOD_SELECTIONS!=1) */ 0213 if (num > WARMUP_CYCLES || SHOW_WARMUPS) 0214 dbgKrita << "Selections with alpha (filter):\t [Disabled]"; 0215 #endif 0216 } 0217 0218 void KisFilterSelectionsBenchmark::testBitBltWOSelections(int num) 0219 { 0220 KisPaintDeviceSP projection = 0221 new KisPaintDevice(m_device->colorSpace()); 0222 0223 double avTime; 0224 KisTimeCounter timer; 0225 0226 QRect filterRect = m_selection->selectedExactRect(); 0227 0228 timer.restart(); 0229 for (int i = 0; i < num; i++) { 0230 KisPaintDeviceSP cacheDevice = new KisPaintDevice(projection->colorSpace()); 0231 0232 KisTransaction transac(cacheDevice, 0); 0233 m_filter->process(m_device, projection, 0, filterRect, m_configuration, 0); 0234 0235 KisPainter painter(projection); 0236 painter.beginTransaction(); 0237 painter.setCompositeOpId(COMPOSITE_ALPHA_DARKEN); 0238 painter.bitBlt(filterRect.topLeft(), cacheDevice, filterRect); 0239 painter.deleteTransaction(); 0240 } 0241 avTime = double(timer.elapsed()) / num; 0242 0243 projection->convertToQImage(0).save("TFS__BITBLT_WO_SELECTIONS.png"); 0244 0245 if (num > WARMUP_CYCLES || SHOW_WARMUPS) 0246 dbgKrita << "bitBlt w/o sel:\t\t\t" << avTime; 0247 } 0248 0249 void KisFilterSelectionsBenchmark::testBitBltSelections(int num) 0250 { 0251 KisPaintDeviceSP projection = 0252 new KisPaintDevice(m_device->colorSpace()); 0253 0254 double avTime; 0255 KisTimeCounter timer; 0256 0257 QRect filterRect = m_selection->selectedExactRect(); 0258 0259 timer.restart(); 0260 for (int i = 0; i < num; i++) { 0261 KisPaintDeviceSP cacheDevice = new KisPaintDevice(projection->colorSpace()); 0262 0263 KisTransaction transac(cacheDevice, 0); 0264 m_filter->process(m_device, cacheDevice, 0, filterRect, m_configuration, 0); 0265 0266 KisPainter gc(projection); 0267 gc.beginTransaction(); 0268 gc.setCompositeOpId(COMPOSITE_ALPHA_DARKEN); 0269 gc.setSelection(m_selection); 0270 gc.bitBlt(filterRect.topLeft(), cacheDevice, filterRect); 0271 gc.deleteTransaction(); 0272 } 0273 avTime = double(timer.elapsed()) / num; 0274 0275 projection->convertToQImage(0).save("TFS__BITBLT_WITH_SELECTIONS.png"); 0276 0277 if (num > WARMUP_CYCLES || SHOW_WARMUPS) 0278 dbgKrita << "bitBlt with sel:\t\t\t" << avTime; 0279 } 0280 0281 SIMPLE_TEST_MAIN(KisFilterSelectionsBenchmark)