File indexing completed on 2024-12-22 04:10:03

0001 /*
0002  *  SPDX-FileCopyrightText: 2019 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "KisHoldUIUpdatesCommand.h"
0008 
0009 #include <algorithm>
0010 #include "kis_image_interfaces.h"
0011 #include "krita_utils.h"
0012 #include "kis_paintop_utils.h"
0013 #include "kis_image_signal_router.h"
0014 #include "KisRunnableStrokeJobData.h"
0015 #include "KisRunnableStrokeJobUtils.h"
0016 #include "KisRunnableStrokeJobsInterface.h"
0017 
0018 
0019 KisHoldUIUpdatesCommand::KisHoldUIUpdatesCommand(KisUpdatesFacade *updatesFacade, State state)
0020     : KisCommandUtils::FlipFlopCommand(state),
0021       m_updatesFacade(updatesFacade),
0022       m_batchUpdateStarted(new bool(false))
0023 {
0024 }
0025 
0026 void KisHoldUIUpdatesCommand::partA()
0027 {
0028     if (*m_batchUpdateStarted) {
0029         m_updatesFacade->notifyBatchUpdateEnded();
0030         *m_batchUpdateStarted = false;
0031     }
0032 
0033     m_updatesFacade->disableUIUpdates();
0034 }
0035 
0036 void KisHoldUIUpdatesCommand::partB()
0037 {
0038     QVector<QRect> totalDirtyRects = m_updatesFacade->enableUIUpdates();
0039 
0040     const QRect totalRect =
0041         m_updatesFacade->bounds() &
0042         std::accumulate(totalDirtyRects.begin(), totalDirtyRects.end(), QRect(), std::bit_or<QRect>());
0043 
0044     totalDirtyRects =
0045         KisPaintOpUtils::splitAndFilterDabRect(totalRect,
0046                                                totalDirtyRects,
0047                                                KritaUtils::optimalPatchSize().width());
0048 
0049     *m_batchUpdateStarted = true;
0050     m_updatesFacade->notifyBatchUpdateStarted();
0051 
0052     KisUpdatesFacade *updatesFacade = m_updatesFacade;
0053     QSharedPointer<bool> batchUpdateStarted = m_batchUpdateStarted;
0054 
0055     QVector<KisRunnableStrokeJobDataBase*> jobsData;
0056     Q_FOREACH (const QRect &rc, totalDirtyRects) {
0057         KritaUtils::addJobConcurrent(jobsData, [updatesFacade, rc] () {
0058             updatesFacade->notifyUIUpdateCompleted(rc);
0059         });
0060     }
0061 
0062     KritaUtils::addJobBarrier(jobsData, [updatesFacade, batchUpdateStarted] () {
0063         updatesFacade->notifyBatchUpdateEnded();
0064         *batchUpdateStarted = false;
0065     });
0066 
0067     runnableJobsInterface()->addRunnableJobs(jobsData);
0068 }