Commit 3f7e32c9 authored by Dmitry Kazakov's avatar Dmitry Kazakov

Fix race condition in start/stop isolated mode

We should not use QtCuncurrent anywhere in Krita
parent dea45823
......@@ -104,6 +104,11 @@
#include "kis_time_range.h"
#include "KisRunnableBasedStrokeStrategy.h"
#include "KisRunnableStrokeJobData.h"
#include "KisRunnableStrokeJobUtils.h"
#include "KisRunnableStrokeJobsInterface.h"
// #define SANITY_CHECKS
#ifdef SANITY_CHECKS
......@@ -238,7 +243,7 @@ public:
bool tryCancelCurrentStrokeAsync();
void notifyProjectionUpdatedInPatches(const QRect &rc);
void notifyProjectionUpdatedInPatches(const QRect &rc, QVector<KisRunnableStrokeJobData *> &jobs);
};
KisImage::KisImage(KisUndoStore *undoStore, qint32 width, qint32 height, const KoColorSpace * colorSpace, const QString& name)
......@@ -1520,7 +1525,7 @@ KisStrokeId KisImage::startStroke(KisStrokeStrategy *strokeStrategy)
return m_d->scheduler.startStroke(strokeStrategy);
}
void KisImage::KisImagePrivate::notifyProjectionUpdatedInPatches(const QRect &rc)
void KisImage::KisImagePrivate::notifyProjectionUpdatedInPatches(const QRect &rc, QVector<KisRunnableStrokeJobData*> &jobs)
{
KisImageConfig imageConfig(true);
int patchWidth = imageConfig.updatePatchWidth();
......@@ -1531,20 +1536,21 @@ void KisImage::KisImagePrivate::notifyProjectionUpdatedInPatches(const QRect &rc
QRect patchRect(x, y, patchWidth, patchHeight);
patchRect &= rc;
QtConcurrent::run(std::bind(&KisImage::notifyProjectionUpdated, q, patchRect));
KritaUtils::addJobConcurrent(jobs, std::bind(&KisImage::notifyProjectionUpdated, q, patchRect));
}
}
}
bool KisImage::startIsolatedMode(KisNodeSP node)
{
struct StartIsolatedModeStroke : public KisSimpleStrokeStrategy {
struct StartIsolatedModeStroke : public KisRunnableBasedStrokeStrategy {
StartIsolatedModeStroke(KisNodeSP node, KisImageSP image)
: KisSimpleStrokeStrategy("start-isolated-mode", kundo2_noi18n("start-isolated-mode")),
: KisRunnableBasedStrokeStrategy("start-isolated-mode", kundo2_noi18n("start-isolated-mode")),
m_node(node),
m_image(image)
{
this->enableJob(JOB_INIT, true, KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::EXCLUSIVE);
this->enableJob(JOB_DOSTROKE, true);
setClearsRedoOnStart(false);
}
......@@ -1558,7 +1564,10 @@ bool KisImage::startIsolatedMode(KisNodeSP node)
// the GUI uses our thread to do the color space conversion so we
// need to emit this signal in multiple threads
m_image->m_d->notifyProjectionUpdatedInPatches(m_image->bounds());
QVector<KisRunnableStrokeJobData*> jobs;
m_image->m_d->notifyProjectionUpdatedInPatches(m_image->bounds(), jobs);
this->runnableJobsInterface()->addRunnableJobs(jobs);
m_image->invalidateAllFrames();
}
......@@ -1578,12 +1587,13 @@ void KisImage::stopIsolatedMode()
{
if (!m_d->isolatedRootNode) return;
struct StopIsolatedModeStroke : public KisSimpleStrokeStrategy {
struct StopIsolatedModeStroke : public KisRunnableBasedStrokeStrategy {
StopIsolatedModeStroke(KisImageSP image)
: KisSimpleStrokeStrategy("stop-isolated-mode", kundo2_noi18n("stop-isolated-mode")),
: KisRunnableBasedStrokeStrategy("stop-isolated-mode", kundo2_noi18n("stop-isolated-mode")),
m_image(image)
{
this->enableJob(JOB_INIT);
this->enableJob(JOB_DOSTROKE, true);
setClearsRedoOnStart(false);
}
......@@ -1595,10 +1605,13 @@ void KisImage::stopIsolatedMode()
emit m_image->sigIsolatedModeChanged();
m_image->invalidateAllFrames();
// the GUI uses our thread to do the color space conversion so we
// need to emit this signal in multiple threads
m_image->m_d->notifyProjectionUpdatedInPatches(m_image->bounds());
m_image->invalidateAllFrames();
QVector<KisRunnableStrokeJobData*> jobs;
m_image->m_d->notifyProjectionUpdatedInPatches(m_image->bounds(), jobs);
this->runnableJobsInterface()->addRunnableJobs(jobs);
// TODO: Substitute notifyProjectionUpdated() with this code
// when update optimization is implemented
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment