[graphics/krita/krita/4.3] libs: Workaround a deadlock when painting on a vector selection with Instant Preview

Dmitry Kazakov null at kde.org
Tue Oct 27 11:26:00 GMT 2020


Git commit 62f487a6807f60d0a075deba4a052ebe0a565802 by Dmitry Kazakov.
Committed on 27/10/2020 at 11:18.
Pushed by dkazakov into branch 'krita/4.3'.

Workaround a deadlock when painting on a vector selection with Instant Preview

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 at 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/62f487a6807f60d0a075deba4a052ebe0a565802

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 = 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 == 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_selection_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 QString &id)
 {
     if (id == KisKeyframeChannel::Content.id()) {
diff --git a/libs/image/kis_selection_based_layer.h b/libs/image/kis_selection_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/strokes/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 levelOfDetail)
 {
     if (!m_d->resources->presetAllowsLod()) return 0;
+    if (!m_d->resources->currentNode()->supportsLodPainting()) return 0;
 
     FreehandStrokeStrategy *clone = new FreehandStrokeStrategy(*this, levelOfDetail);
     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 levelOfDetail)
 {
     if (!m_d->filter->supportsLevelOfDetail(m_d->filterConfig.data(), levelOfDetail)) return 0;
+    if (!m_d->node->supportsLodPainting()) return 0;
 
     KisFilterStrokeStrategy *clone = new KisFilterStrokeStrategy(*this, levelOfDetail);
     return clone;


More information about the kimageshop mailing list