From kde-kimageshop Tue Oct 27 11:27:11 2020 From: Dmitry Kazakov Date: Tue, 27 Oct 2020 11:27:11 +0000 To: kde-kimageshop Subject: [graphics/krita/krita/4.4.0] libs: Workaround a deadlock when painting on a vector selection with In Message-Id: <20201027112711.73C411240F82 () leptone ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-kimageshop&m=160379804704416 Git commit 90a75b4ba8d57a8cdae6035d1b82619c2f4e30d5 by Dmitry Kazakov. Committed on 27/10/2020 at 11:26. Pushed by dkazakov into branch 'krita/4.4.0'. Workaround a deadlock when painting on a vector selection with Instant Prev= iew Instant Preview is based on running two consequent with different level of detail, but our vector selection don't support that. More than that, when starting a paint operation on a vector selection, it should be flattened into a pixel selection. Which means that in LoD mode the flattening will happen twice. Ideally, we should somehow make KisSelection survive flattening in two separate LoD strokes, but I'm not sure it is really worth the effort. The downsides of the patch are: 1) The first painting stroke on a selection based layer or mask with vector selection will always be executed without instant preview. It affects all mask, generator layers and filter layers. 2) The first applicaiton of a filter on such a layer will also be slow. BUG:428260 CC:kimageshop@kde.org M +5 -0 libs/image/kis_base_node.cpp M +6 -0 libs/image/kis_base_node.h M +5 -0 libs/image/kis_mask.cc M +2 -0 libs/image/kis_mask.h M +5 -0 libs/image/kis_selection_based_layer.cpp M +2 -0 libs/image/kis_selection_based_layer.h M +1 -0 libs/ui/tool/strokes/freehand_stroke.cpp M +1 -0 libs/ui/tool/strokes/kis_filter_stroke_strategy.cpp https://invent.kde.org/graphics/krita/commit/90a75b4ba8d57a8cdae6035d1b8261= 9c2f4e30d5 diff --git a/libs/image/kis_base_node.cpp b/libs/image/kis_base_node.cpp index 7d0b5b6c00..1452392e00 100644 --- a/libs/image/kis_base_node.cpp +++ b/libs/image/kis_base_node.cpp @@ -393,6 +393,11 @@ bool KisBaseNode::supportsLodMoves() const return m_d->supportsLodMoves; } = +bool KisBaseNode::supportsLodPainting() const +{ + return true; +} + void KisBaseNode::setImage(KisImageWSP image) { m_d->image =3D image; diff --git a/libs/image/kis_base_node.h b/libs/image/kis_base_node.h index f6301afe57..74d5021688 100644 --- a/libs/image/kis_base_node.h +++ b/libs/image/kis_base_node.h @@ -490,6 +490,12 @@ public: */ bool supportsLodMoves() const; = + /** + * Returns true if the node can be painted via KisPaintDevice. Notable + * exceptions are selection-based layers and masks. + */ + virtual bool supportsLodPainting() const; + /** * Return the keyframe channels associated with this node * @return list of keyframe channels diff --git a/libs/image/kis_mask.cc b/libs/image/kis_mask.cc index 9450a4e105..97dc1ae62a 100644 --- a/libs/image/kis_mask.cc +++ b/libs/image/kis_mask.cc @@ -485,6 +485,11 @@ void KisMask::testingInitSelection(const QRect &rect, = KisLayerSP parentLayer) m_d->selection->setParentNode(this); } = +bool KisMask::supportsLodPainting() const +{ + return !m_d->selection || !m_d->selection->hasShapeSelection(); +} + KisKeyframeChannel *KisMask::requestKeyframeChannel(const QString &id) { if (id =3D=3D KisKeyframeChannel::Content.id()) { diff --git a/libs/image/kis_mask.h b/libs/image/kis_mask.h index 648cd5fe9c..2f72ffc897 100644 --- a/libs/image/kis_mask.h +++ b/libs/image/kis_mask.h @@ -191,6 +191,8 @@ public: = void testingInitSelection(const QRect &rect, KisLayerSP parentLayer); = + bool supportsLodPainting() const override; + protected: /** * Apply the effect the projection using the mask as a selection. diff --git a/libs/image/kis_selection_based_layer.cpp b/libs/image/kis_sele= ction_based_layer.cpp index c75b9acc0b..be6287bb8f 100644 --- a/libs/image/kis_selection_based_layer.cpp +++ b/libs/image/kis_selection_based_layer.cpp @@ -281,6 +281,11 @@ void KisSelectionBasedLayer::setY(qint32 y) } } = +bool KisSelectionBasedLayer::supportsLodPainting() const +{ + return !m_d->selection || !m_d->selection->hasShapeSelection(); +} + KisKeyframeChannel *KisSelectionBasedLayer::requestKeyframeChannel(const Q= String &id) { if (id =3D=3D KisKeyframeChannel::Content.id()) { diff --git a/libs/image/kis_selection_based_layer.h b/libs/image/kis_select= ion_based_layer.h index 3acefceef1..a8d17f5f5e 100644 --- a/libs/image/kis_selection_based_layer.h +++ b/libs/image/kis_selection_based_layer.h @@ -140,6 +140,8 @@ public: */ void setY(qint32 y) override; = + bool supportsLodPainting() const override; + public: = /** diff --git a/libs/ui/tool/strokes/freehand_stroke.cpp b/libs/ui/tool/stroke= s/freehand_stroke.cpp index 2d6ac5926c..f136b73430 100644 --- a/libs/ui/tool/strokes/freehand_stroke.cpp +++ b/libs/ui/tool/strokes/freehand_stroke.cpp @@ -334,6 +334,7 @@ void FreehandStrokeStrategy::issueSetDirtySignals() KisStrokeStrategy* FreehandStrokeStrategy::createLodClone(int levelOfDetai= l) { if (!m_d->resources->presetAllowsLod()) return 0; + if (!m_d->resources->currentNode()->supportsLodPainting()) return 0; = FreehandStrokeStrategy *clone =3D new FreehandStrokeStrategy(*this, le= velOfDetail); return clone; diff --git a/libs/ui/tool/strokes/kis_filter_stroke_strategy.cpp b/libs/ui/= tool/strokes/kis_filter_stroke_strategy.cpp index 9d054138e2..4961080209 100644 --- a/libs/ui/tool/strokes/kis_filter_stroke_strategy.cpp +++ b/libs/ui/tool/strokes/kis_filter_stroke_strategy.cpp @@ -191,6 +191,7 @@ void KisFilterStrokeStrategy::finishStrokeCallback() KisStrokeStrategy* KisFilterStrokeStrategy::createLodClone(int levelOfDeta= il) { if (!m_d->filter->supportsLevelOfDetail(m_d->filterConfig.data(), leve= lOfDetail)) return 0; + if (!m_d->node->supportsLodPainting()) return 0; = KisFilterStrokeStrategy *clone =3D new KisFilterStrokeStrategy(*this, = levelOfDetail); return clone;