File indexing completed on 2024-12-22 04:12:50

0001 /*
0002  *  SPDX-FileCopyrightText: 2017 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "FreehandStrokeBenchmark.h"
0008 
0009 #include "KisAsynchronousStrokeUpdateHelper.h"
0010 #include "kis_image.h"
0011 #include "kis_resources_snapshot.h"
0012 #include "stroke_testing_utils.h"
0013 #include "strokes/KisFreehandStrokeInfo.h"
0014 #include "strokes/freehand_stroke.h"
0015 #include <KoColor.h>
0016 #include <KoCompositeOpRegistry.h>
0017 #include <brushengine/kis_paint_information.h>
0018 #include <simpletest.h>
0019 #include <testui.h>
0020 
0021 
0022 #include "testutil.h"
0023 #include "KisResourceModel.h"
0024 #include "KisGlobalResourcesInterface.h"
0025 
0026 
0027 class FreehandStrokeBenchmarkTester : public utils::StrokeTester
0028 {
0029 public:
0030     FreehandStrokeBenchmarkTester(const QString &presetFilename)
0031         : StrokeTester("freehand_benchmark", QSize(5000, 5000), presetFilename)
0032     {
0033         setBaseFuzziness(3);
0034     }
0035 
0036     void setCpuCoresLimit(int value) {
0037         m_cpuCoresLimit = value;
0038     }
0039 
0040 protected:
0041     using utils::StrokeTester::initImage;
0042     void initImage(KisImageWSP image, KisNodeSP activeNode) override {
0043         Q_UNUSED(activeNode);
0044 
0045         if (m_cpuCoresLimit > 0) {
0046             image->setWorkingThreadsLimit(m_cpuCoresLimit);
0047         }
0048     }
0049 
0050     KisStrokeStrategy* createStroke(KisResourcesSnapshotSP resources,
0051                                     KisImageWSP image) override {
0052         Q_UNUSED(image);
0053 
0054         KisFreehandStrokeInfo *strokeInfo = new KisFreehandStrokeInfo();
0055 
0056         QScopedPointer<FreehandStrokeStrategy> stroke(
0057             new FreehandStrokeStrategy(resources, strokeInfo, kundo2_noi18n("Freehand Stroke")));
0058 
0059         return stroke.take();
0060     }
0061 
0062     void addPaintingJobs(KisImageWSP image,
0063                                  KisResourcesSnapshotSP resources) override
0064     {
0065         addPaintingJobs(image, resources, 0);
0066     }
0067 
0068     void addPaintingJobs(KisImageWSP image, KisResourcesSnapshotSP resources, int iteration) override {
0069         Q_UNUSED(iteration);
0070         Q_UNUSED(resources);
0071 
0072         for (int y = 100; y < 4900; y += 300) {
0073             KisPaintInformation pi1;
0074             KisPaintInformation pi2;
0075 
0076             pi1 = KisPaintInformation(QPointF(100, y), 0.5);
0077             pi2 = KisPaintInformation(QPointF(4900, y + 100), 1.0);
0078 
0079             QScopedPointer<KisStrokeJobData> data(
0080                 new FreehandStrokeStrategy::Data(0, pi1, pi2));
0081 
0082             image->addJob(strokeId(), data.take());
0083         }
0084 
0085         image->addJob(strokeId(), new KisAsynchronousStrokeUpdateHelper::UpdateData(true));
0086     }
0087 
0088 private:
0089     int m_cpuCoresLimit = -1;
0090 };
0091 
0092 void benchmarkBrush(const QString &presetName)
0093 {
0094     FreehandStrokeBenchmarkTester tester(presetName);
0095 
0096     for (int i = 1; i <= QThread::idealThreadCount(); i++) {
0097         tester.setCpuCoresLimit(i);
0098         tester.benchmark();
0099 
0100         qDebug() << qPrintable(QString("Cores: %1 Time: %2 (ms)").arg(i).arg(tester.lastStrokeTime()));
0101     }
0102 }
0103 
0104 void benchmarkBrushUnthreaded(const QString &presetName)
0105 {
0106     FreehandStrokeBenchmarkTester tester(presetName);
0107 
0108 
0109     Q_FOREACH(int i, QVector<int>({1, QThread::idealThreadCount()})) {
0110         tester.setCpuCoresLimit(i);
0111         tester.benchmark();
0112 
0113         qDebug() << qPrintable(QString("Cores: %1 Time: %2 (ms)").arg(i).arg(tester.lastStrokeTime()));
0114     }
0115 }
0116 
0117 #include <KoResourcePaths.h>
0118 #include <KisSupportedArchitectures.h>
0119 
0120 void FreehandStrokeBenchmark::initTestCase()
0121 {
0122     {
0123         QString fullFileName = TestUtil::fetchDataFileLazy("3_texture.png");
0124         KIS_ASSERT(!fullFileName.isEmpty());
0125         KIS_ASSERT(QFileInfo(fullFileName).exists());
0126 
0127         KisResourceModel model(ResourceType::Brushes);
0128         model.importResourceFile(fullFileName, true);
0129     }
0130 
0131     {
0132         QString fullFileName = TestUtil::fetchDataFileLazy("DA_RGBA bluegreen_small1.png");
0133         KIS_ASSERT(!fullFileName.isEmpty());
0134         KIS_ASSERT(QFileInfo(fullFileName).exists());
0135 
0136         KisResourceModel model(ResourceType::Brushes);
0137         model.importResourceFile(fullFileName, true);
0138     }
0139 
0140     // warm-up memory pools
0141     {
0142         FreehandStrokeBenchmarkTester tester("testing_1000px_auto_default.kpp");
0143         tester.setCpuCoresLimit(QThread::idealThreadCount());
0144         tester.benchmark();
0145         QTest::qSleep(500);
0146     }
0147 
0148     qDebug() << "Base instruction set:" << KisSupportedArchitectures::baseArchName();
0149     qDebug() << "Optimized code uses set:" << KisSupportedArchitectures::bestArchName();
0150     qDebug() << "Supported instruction sets:" << KisSupportedArchitectures::supportedInstructionSets();
0151 }
0152 
0153 void FreehandStrokeBenchmark::testDefaultTip()
0154 {
0155     benchmarkBrush("testing_1000px_auto_default.kpp");
0156 }
0157 
0158 void FreehandStrokeBenchmark::testSoftTip()
0159 {
0160     benchmarkBrushUnthreaded("testing_1000px_auto_soft.kpp");
0161 }
0162 
0163 void FreehandStrokeBenchmark::testGaussianTip()
0164 {
0165     benchmarkBrushUnthreaded("testing_1000px_auto_gaussian.kpp");
0166 }
0167 
0168 void FreehandStrokeBenchmark::testRectangularTip()
0169 {
0170     benchmarkBrushUnthreaded("testing_1000px_auto_rectangular.kpp");
0171 }
0172 
0173 void FreehandStrokeBenchmark::testRectGaussianTip()
0174 {
0175     benchmarkBrushUnthreaded("testing_1000px_auto_gaussian_rect.kpp");
0176 }
0177 
0178 void FreehandStrokeBenchmark::testRectSoftTip()
0179 {
0180     benchmarkBrushUnthreaded("testing_1000px_auto_soft_rect.kpp");
0181 }
0182 
0183 void FreehandStrokeBenchmark::testStampTip()
0184 {
0185     benchmarkBrushUnthreaded("testing_1000px_stamp_450_rotated.kpp");
0186 }
0187 
0188 void FreehandStrokeBenchmark::testColorsmudgeDefaultTip_dull_old_sa()
0189 {
0190     benchmarkBrushUnthreaded("testing_200px_colorsmudge_default_dulling_old_sa.kpp");
0191 }
0192 
0193 void FreehandStrokeBenchmark::testColorsmudgeDefaultTip_dull_old_nsa()
0194 {
0195     benchmarkBrushUnthreaded("testing_200px_colorsmudge_default_dulling_old_nsa.kpp");
0196 }
0197 
0198 void FreehandStrokeBenchmark::testColorsmudgeDefaultTip_dull_new_sa()
0199 {
0200     benchmarkBrushUnthreaded("testing_200px_colorsmudge_default_dulling_new_sa.kpp");
0201 }
0202 
0203 #ifndef LIMIT_LONG_TESTS
0204 
0205 void FreehandStrokeBenchmark::testColorsmudgeDefaultTip_dull_new_sa_800px()
0206 {
0207     benchmarkBrushUnthreaded("testing_800px_colorsmudge_default_dulling_new_sa.kpp");
0208 }
0209 
0210 #endif
0211 
0212 void FreehandStrokeBenchmark::testColorsmudgeDefaultTip_dull_new_nsa()
0213 {
0214     benchmarkBrushUnthreaded("testing_200px_colorsmudge_default_dulling_new_nsa.kpp");
0215 }
0216 
0217 void FreehandStrokeBenchmark::testColorsmudgeDefaultTip_smear_old_sa()
0218 {
0219     benchmarkBrushUnthreaded("testing_200px_colorsmudge_default_smearing_old_sa.kpp");
0220 }
0221 
0222 void FreehandStrokeBenchmark::testColorsmudgeDefaultTip_smear_old_nsa()
0223 {
0224     benchmarkBrushUnthreaded("testing_200px_colorsmudge_default_smearing_old_nsa.kpp");
0225 }
0226 
0227 void FreehandStrokeBenchmark::testColorsmudgeDefaultTip_smear_new_sa()
0228 {
0229     benchmarkBrushUnthreaded("testing_200px_colorsmudge_default_smearing_new_sa.kpp");
0230 }
0231 
0232 void FreehandStrokeBenchmark::testColorsmudgeDefaultTip_smear_new_nsa()
0233 {
0234     benchmarkBrushUnthreaded("testing_200px_colorsmudge_default_smearing_new_nsa.kpp");
0235 }
0236 
0237 void FreehandStrokeBenchmark::testColorsmudgeLightness_smear_new_nsa_maskmode()
0238 {
0239     benchmarkBrushUnthreaded("testing_200px_colorsmudge_lightness_smearing_new_nsa_maskmode.kpp");
0240 }
0241 
0242 void FreehandStrokeBenchmark::testColorsmudgeLightness_smear_new_nsa_nopt()
0243 {
0244     benchmarkBrushUnthreaded("testing_200px_colorsmudge_lightness_smearing_new_nsa_nopt.kpp");
0245 }
0246 
0247 void FreehandStrokeBenchmark::testColorsmudgeLightness_smear_new_nsa_ptoverlay()
0248 {
0249     benchmarkBrushUnthreaded("testing_200px_colorsmudge_lightness_smearing_new_nsa_ptoverlay.kpp");
0250 }
0251 
0252 void FreehandStrokeBenchmark::testColorsmudgeLightness_smear_new_nsa_ptoverwrite()
0253 {
0254     benchmarkBrushUnthreaded("testing_200px_colorsmudge_lightness_smearing_new_nsa_ptoverwrite.kpp");
0255 }
0256 
0257 KISTEST_MAIN(FreehandStrokeBenchmark)