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