[graphics/krita] libs/image: Mask generation refactor

L. E. Segovia null at kde.org
Sun Mar 27 16:47:19 BST 2022


Git commit 3aeeae38ee1f51cc9a294d5f4dab94529db09d58 by L. E. Segovia.
Committed on 27/03/2022 at 14:46.
Pushed by lsegovia into branch 'master'.

Mask generation refactor

This commit is a preparation for the xsimd port. It refactors the
following:

- FastRowProcessor is now a templated class that takes the individual
  generators + a friend class statement. This allows to hide the
  implementation inside a Vc-aware processor factory.
- MaskApplicatorFactory is now Vc-aware, needing only the generator
  class as a parameter.
- MaskApplicatorFactory is now instantiated separately for the Scalar
  mode, implementing properly the #define hack used for the Vc-free mode
  by splitting the cpp in two source files.
- Scalar and vector applicators are now compiled separately, allowing to
  use the latter only when Vc is available, and thus enabling the above
  change.

CCMAIL: kimageshop at kde.org

M  +8    -3    libs/image/CMakeLists.txt
M  +2    -1    libs/image/kis_base_mask_generator.cpp
M  +28   -588  libs/image/kis_brush_mask_applicator_factories.cpp
M  +5    -20   libs/image/kis_brush_mask_applicator_factories.h
A  +73   -0    libs/image/kis_brush_mask_applicator_factories_Scalar.cpp     [License: GPL(v2.0+)]
D  +0    -201  libs/image/kis_brush_mask_applicators.h
C  +115  -205  libs/image/kis_brush_mask_processor_factories.cpp [from: libs/image/kis_brush_mask_applicator_factories.cpp - 058% similarity]
A  +92   -0    libs/image/kis_brush_mask_scalar_applicator.h     [License: GPL(v2.0+)]
A  +143  -0    libs/image/kis_brush_mask_vector_applicator.h     [License: GPL(v2.0+)]
M  +3    -22   libs/image/kis_circle_mask_generator.cpp
M  +6    -3    libs/image/kis_circle_mask_generator.h
M  +3    -26   libs/image/kis_curve_circle_mask_generator.cpp
M  +6    -3    libs/image/kis_curve_circle_mask_generator.h
M  +4    -24   libs/image/kis_curve_rect_mask_generator.cpp
M  +7    -3    libs/image/kis_curve_rect_mask_generator.h
M  +3    -23   libs/image/kis_gauss_circle_mask_generator.cpp
M  +7    -4    libs/image/kis_gauss_circle_mask_generator.h
M  +4    -22   libs/image/kis_gauss_rect_mask_generator.cpp
M  +7    -3    libs/image/kis_gauss_rect_mask_generator.h
M  +4    -23   libs/image/kis_rect_mask_generator.cpp
M  +9    -4    libs/image/kis_rect_mask_generator.h

https://invent.kde.org/graphics/krita/commit/3aeeae38ee1f51cc9a294d5f4dab94529db09d58

diff --git a/libs/image/CMakeLists.txt b/libs/image/CMakeLists.txt
index bbcdf3b895..95b3996a84 100644
--- a/libs/image/CMakeLists.txt
+++ b/libs/image/CMakeLists.txt
@@ -27,9 +27,12 @@ endif()
 
 if(HAVE_VC)
   include_directories(SYSTEM ${Vc_INCLUDE_DIR} ${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS})
-  ko_compile_for_all_implementations(__per_arch_circle_mask_generator_objs kis_brush_mask_applicator_factories.cpp)
-else()
-  set(__per_arch_circle_mask_generator_objs kis_brush_mask_applicator_factories.cpp)
+  ko_compile_for_all_implementations_no_scalar(__per_arch_circle_mask_generator_objs kis_brush_mask_applicator_factories.cpp)
+  ko_compile_for_all_implementations_no_scalar(_per_arch_processor_objs kis_brush_mask_processor_factories.cpp)
+
+  message("Following objects are generated from the per-arch lib")
+  message("${__per_arch_circle_mask_generator_objs}")
+  message("${_per_arch_processor_objs}")
 endif()
 
 set(kritaimage_LIB_SRCS
@@ -245,6 +248,8 @@ set(kritaimage_LIB_SRCS
    kis_gauss_circle_mask_generator.cpp
    kis_gauss_rect_mask_generator.cpp
    ${__per_arch_circle_mask_generator_objs}
+   ${_per_arch_processor_objs}
+   kis_brush_mask_applicator_factories_Scalar.cpp
    kis_curve_circle_mask_generator.cpp
    kis_curve_rect_mask_generator.cpp
    kis_math_toolbox.cpp
diff --git a/libs/image/kis_base_mask_generator.cpp b/libs/image/kis_base_mask_generator.cpp
index 3f04e8c422..94a3f755a2 100644
--- a/libs/image/kis_base_mask_generator.cpp
+++ b/libs/image/kis_base_mask_generator.cpp
@@ -2,6 +2,7 @@
  *  SPDX-FileCopyrightText: 2004, 2007-2009 Cyrille Berger <cberger at cberger.net>
  *  SPDX-FileCopyrightText: 2010 Lukáš Tvrdý <lukast.dev at gmail.com>
  *  SPDX-FileCopyrightText: 2011 Sven Langkamp <sven.langkamp at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -134,7 +135,7 @@ KisBrushMaskApplicatorBase* KisMaskGenerator::applicator()
 {
     if (!d->defaultMaskProcessor) {
         d->defaultMaskProcessor.reset(
-            createOptimizedClass<MaskApplicatorFactory<KisMaskGenerator, KisBrushMaskScalarApplicator> >(this));
+            createOptimizedClass<MaskApplicatorFactory<KisMaskGenerator>>(this));
     }
 
     return d->defaultMaskProcessor.data();
diff --git a/libs/image/kis_brush_mask_applicator_factories.cpp b/libs/image/kis_brush_mask_applicator_factories.cpp
index 11f5688c5f..105d8577da 100644
--- a/libs/image/kis_brush_mask_applicator_factories.cpp
+++ b/libs/image/kis_brush_mask_applicator_factories.cpp
@@ -1,634 +1,74 @@
 /*
  *  SPDX-FileCopyrightText: 2012 Dmitry Kazakov <dimula73 at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 #include "kis_brush_mask_applicator_factories.h"
-#include "vc_extra_math.h"
 
 #include "kis_circle_mask_generator.h"
-#include "kis_circle_mask_generator_p.h"
-#include "kis_gauss_circle_mask_generator_p.h"
-#include "kis_curve_circle_mask_generator_p.h"
-#include "kis_gauss_rect_mask_generator_p.h"
-#include "kis_curve_rect_mask_generator_p.h"
-#include "kis_rect_mask_generator_p.h"
+#include "kis_gauss_circle_mask_generator.h"
+#include "kis_curve_circle_mask_generator.h"
+#include "kis_gauss_rect_mask_generator.h"
+#include "kis_curve_rect_mask_generator.h"
+#include "kis_rect_mask_generator.h"
 
-#include "kis_brush_mask_applicators.h"
 #include "kis_brush_mask_applicator_base.h"
-
-#define a(_s) #_s
-#define b(_s) a(_s)
+#include "kis_brush_mask_vector_applicator.h"
 
 template<>
 template<>
-MaskApplicatorFactory<KisMaskGenerator, KisBrushMaskScalarApplicator>::ReturnType
-MaskApplicatorFactory<KisMaskGenerator, KisBrushMaskScalarApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
+MaskApplicatorFactory<KisMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisMaskGenerator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
 {
-    return new KisBrushMaskScalarApplicator<KisMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
+    return new KisBrushMaskScalarApplicator<KisMaskGenerator, Vc::CurrentImplementation::current()>(maskGenerator);
 }
 
 template<>
 template<>
-MaskApplicatorFactory<KisCircleMaskGenerator, KisBrushMaskVectorApplicator>::ReturnType
-MaskApplicatorFactory<KisCircleMaskGenerator, KisBrushMaskVectorApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
+MaskApplicatorFactory<KisCircleMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisCircleMaskGenerator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
 {
-    return new KisBrushMaskVectorApplicator<KisCircleMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
+    return new KisBrushMaskVectorApplicator<KisCircleMaskGenerator, Vc::CurrentImplementation::current()>(maskGenerator);
 }
 
 template<>
 template<>
-MaskApplicatorFactory<KisGaussCircleMaskGenerator, KisBrushMaskVectorApplicator>::ReturnType
-MaskApplicatorFactory<KisGaussCircleMaskGenerator, KisBrushMaskVectorApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
+MaskApplicatorFactory<KisGaussCircleMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisGaussCircleMaskGenerator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
 {
-    return new KisBrushMaskVectorApplicator<KisGaussCircleMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
+    return new KisBrushMaskVectorApplicator<KisGaussCircleMaskGenerator, Vc::CurrentImplementation::current()>(maskGenerator);
 }
 
 template<>
 template<>
-MaskApplicatorFactory<KisCurveCircleMaskGenerator, KisBrushMaskVectorApplicator>::ReturnType
-MaskApplicatorFactory<KisCurveCircleMaskGenerator, KisBrushMaskVectorApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
+MaskApplicatorFactory<KisCurveCircleMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisCurveCircleMaskGenerator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
 {
-    return new KisBrushMaskVectorApplicator<KisCurveCircleMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
+    return new KisBrushMaskVectorApplicator<KisCurveCircleMaskGenerator, Vc::CurrentImplementation::current()>(maskGenerator);
 }
 
 template<>
 template<>
-MaskApplicatorFactory<KisRectangleMaskGenerator, KisBrushMaskVectorApplicator>::ReturnType
-MaskApplicatorFactory<KisRectangleMaskGenerator, KisBrushMaskVectorApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
+MaskApplicatorFactory<KisRectangleMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisRectangleMaskGenerator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
 {
-    return new KisBrushMaskVectorApplicator<KisRectangleMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
+    return new KisBrushMaskVectorApplicator<KisRectangleMaskGenerator, Vc::CurrentImplementation::current()>(maskGenerator);
 }
 
 template<>
 template<>
-MaskApplicatorFactory<KisGaussRectangleMaskGenerator, KisBrushMaskVectorApplicator>::ReturnType
-MaskApplicatorFactory<KisGaussRectangleMaskGenerator, KisBrushMaskVectorApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
+MaskApplicatorFactory<KisGaussRectangleMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisGaussRectangleMaskGenerator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
 {
-    return new KisBrushMaskVectorApplicator<KisGaussRectangleMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
+    return new KisBrushMaskVectorApplicator<KisGaussRectangleMaskGenerator, Vc::CurrentImplementation::current()>(maskGenerator);
 }
 
 template<>
 template<>
-MaskApplicatorFactory<KisCurveRectangleMaskGenerator, KisBrushMaskVectorApplicator>::ReturnType
-MaskApplicatorFactory<KisCurveRectangleMaskGenerator, KisBrushMaskVectorApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
-{
-    return new KisBrushMaskVectorApplicator<KisCurveRectangleMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
-}
-
-
-#if defined HAVE_VC
-
-struct KisCircleMaskGenerator::FastRowProcessor
-{
-    FastRowProcessor(KisCircleMaskGenerator *maskGenerator)
-        : d(maskGenerator->d.data()) {}
-
-    template<Vc::Implementation _impl>
-    void process(float* buffer, int width, float y, float cosa, float sina,
-                 float centerX, float centerY);
-
-    KisCircleMaskGenerator::Private *d;
-};
-
-template<> void KisCircleMaskGenerator::
-FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, int width, float y, float cosa, float sina,
-                                   float centerX, float centerY)
-{
-    const bool useSmoothing = d->copyOfAntialiasEdges;
-
-    float y_ = y - centerY;
-    float sinay_ = sina * y_;
-    float cosay_ = cosa * y_;
-
-    float* bufferPointer = buffer;
-
-    Vc::float_v currentIndices = Vc::float_v::IndexesFromZero();
-
-    Vc::float_v increment((float)Vc::float_v::size());
-    Vc::float_v vCenterX(centerX);
-
-    Vc::float_v vCosa(cosa);
-    Vc::float_v vSina(sina);
-    Vc::float_v vCosaY_(cosay_);
-    Vc::float_v vSinaY_(sinay_);
-
-    Vc::float_v vXCoeff(static_cast<float>(d->xcoef));
-    Vc::float_v vYCoeff(static_cast<float>(d->ycoef));
-
-    Vc::float_v vTransformedFadeX(static_cast<float>(d->transformedFadeX));
-    Vc::float_v vTransformedFadeY(static_cast<float>(d->transformedFadeY));
-
-    Vc::float_v vOne(Vc::One);
-
-    for (size_t i=0; i < static_cast<size_t>(width); i+= Vc::float_v::size()){
-
-        Vc::float_v x_ = currentIndices - vCenterX;
-
-        Vc::float_v xr = x_ * vCosa - vSinaY_;
-        Vc::float_v yr = x_ * vSina + vCosaY_;
-
-        Vc::float_v n = pow2(xr * vXCoeff) + pow2(yr * vYCoeff);
-        Vc::float_m outsideMask = n > vOne;
-
-        if (!outsideMask.isFull()) {
-            if (useSmoothing) {
-                xr = Vc::abs(xr) + vOne;
-                yr = Vc::abs(yr) + vOne;
-            }
-            Vc::float_v vNormFade = pow2(xr * vTransformedFadeX) + pow2(yr * vTransformedFadeY);
-            Vc::float_m vNormLowMask = vNormFade < vOne;
-            vNormFade.setZero(vNormLowMask);
-
-            //255 * n * (normeFade - 1) / (normeFade - n)
-            Vc::float_v vFade = n * (vNormFade - vOne) / (vNormFade - n);
-
-            // Mask in the inner circle of the mask
-            Vc::float_m mask = vNormFade < vOne;
-            vFade.setZero(mask);
-
-            // Mask out the outer circle of the mask
-            vFade(outsideMask) = vOne;
-
-            vFade.store(bufferPointer, Vc::Aligned);
-
-        } else {
-            // Mask out everything outside the circle
-            vOne.store(bufferPointer, Vc::Aligned);
-        }
-
-        currentIndices = currentIndices + increment;
-
-        bufferPointer += Vc::float_v::size();
-    }
-}
-
-
-struct KisGaussCircleMaskGenerator::FastRowProcessor
-{
-    FastRowProcessor(KisGaussCircleMaskGenerator *maskGenerator)
-        : d(maskGenerator->d.data()) {}
-
-    template<Vc::Implementation _impl>
-    void process(float* buffer, int width, float y, float cosa, float sina,
-                 float centerX, float centerY);
-
-    KisGaussCircleMaskGenerator::Private *d;
-};
-
-template<> void KisGaussCircleMaskGenerator::
-FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, int width, float y, float cosa, float sina,
-                                   float centerX, float centerY)
-{
-    float y_ = y - centerY;
-    float sinay_ = sina * y_;
-    float cosay_ = cosa * y_;
-
-    float* bufferPointer = buffer;
-
-    Vc::float_v currentIndices = Vc::float_v::IndexesFromZero();
-
-    Vc::float_v increment(static_cast<float>(Vc::float_v::size()));
-    Vc::float_v vCenterX(centerX);
-    Vc::float_v vCenter(static_cast<float>(d->center));
-
-    Vc::float_v vCosa(cosa);
-    Vc::float_v vSina(sina);
-    Vc::float_v vCosaY_(cosay_);
-    Vc::float_v vSinaY_(sinay_);
-
-    Vc::float_v vYCoeff(static_cast<float>(d->ycoef));
-    Vc::float_v vDistfactor(static_cast<float>(d->distfactor));
-    Vc::float_v vAlphafactor(static_cast<float>(d->alphafactor));
-
-    Vc::float_v vZero(Vc::Zero);
-    Vc::float_v vValMax(255.f);
-
-    for (size_t i=0; i < static_cast<size_t>(width); i+= Vc::float_v::size()){
-
-        Vc::float_v x_ = currentIndices - vCenterX;
-
-        Vc::float_v xr = x_ * vCosa - vSinaY_;
-        Vc::float_v yr = x_ * vSina + vCosaY_;
-
-        Vc::float_v dist = sqrt(pow2(xr) + pow2(yr * vYCoeff));
-
-        // Apply FadeMaker mask and operations
-        Vc::float_m excludeMask = d->fadeMaker.needFade(dist);
-
-        if (!excludeMask.isFull()) {
-            Vc::float_v valDist = dist * vDistfactor;
-            Vc::float_v fullFade = vAlphafactor * (  VcExtraMath::erf(valDist + vCenter) -  VcExtraMath::erf(valDist - vCenter));
-
-            Vc::float_m mask;
-            // Mask in the inner circle of the mask
-            mask = fullFade < vZero;
-            fullFade.setZero(mask);
-
-            // Mask the outer circle
-            mask = fullFade > 254.974f;
-            fullFade(mask) = vValMax;
-
-            // Mask (value - value), precision errors.
-            Vc::float_v vFade = (vValMax - fullFade) / vValMax;
-
-            // return original dist values before vFade transform
-            vFade(excludeMask) = dist;
-            vFade.store(bufferPointer, Vc::Aligned);
-
-        } else {
-          dist.store(bufferPointer, Vc::Aligned);
-      }
-      currentIndices = currentIndices + increment;
-
-      bufferPointer += Vc::float_v::size();
-    }
-}
-
-struct KisCurveCircleMaskGenerator::FastRowProcessor
-{
-    FastRowProcessor(KisCurveCircleMaskGenerator *maskGenerator)
-        : d(maskGenerator->d.data()) {}
-
-    template<Vc::Implementation _impl>
-    void process(float* buffer, int width, float y, float cosa, float sina,
-                 float centerX, float centerY);
-
-    KisCurveCircleMaskGenerator::Private *d;
-};
-
-
-template<> void KisCurveCircleMaskGenerator::
-FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, int width, float y, float cosa, float sina,
-                                   float centerX, float centerY)
-{
-    float y_ = y - centerY;
-    float sinay_ = sina * y_;
-    float cosay_ = cosa * y_;
-
-    float* bufferPointer = buffer;
-
-    qreal* curveDataPointer = d->curveData.data();
-
-    Vc::float_v currentIndices = Vc::float_v::IndexesFromZero();
-
-    Vc::float_v increment((float)Vc::float_v::size());
-    Vc::float_v vCenterX(centerX);
-
-    Vc::float_v vCosa(cosa);
-    Vc::float_v vSina(sina);
-    Vc::float_v vCosaY_(cosay_);
-    Vc::float_v vSinaY_(sinay_);
-
-    Vc::float_v vYCoeff(static_cast<float>(d->ycoef));
-    Vc::float_v vXCoeff(static_cast<float>(d->xcoef));
-    Vc::float_v vCurveResolution(static_cast<float>(d->curveResolution));
-
-    Vc::float_v vCurvedData(Vc::Zero);
-    Vc::float_v vCurvedData1(Vc::Zero);
-
-    Vc::float_v vOne(Vc::One);
-    Vc::float_v vZero(Vc::Zero);
-
-    for (size_t i=0; i < static_cast<size_t>(width); i+= Vc::float_v::size()){
-
-        Vc::float_v x_ = currentIndices - vCenterX;
-
-        Vc::float_v xr = x_ * vCosa - vSinaY_;
-        Vc::float_v yr = x_ * vSina + vCosaY_;
-
-        Vc::float_v dist = pow2(xr * vXCoeff) + pow2(yr * vYCoeff);
-
-        // Apply FadeMaker mask and operations
-        Vc::float_m excludeMask = d->fadeMaker.needFade(dist);
-
-        if (!excludeMask.isFull()) {
-            Vc::float_v valDist = dist * vCurveResolution;
-            // truncate
-            Vc::float_v::IndexType vAlphaValue(valDist);
-            Vc::float_v vFloatAlphaValue = vAlphaValue;
-
-            Vc::float_v alphaValueF = valDist - vFloatAlphaValue;
-
-            Vc::float_m alphaMask = vAlphaValue < vZero;
-            vAlphaValue.setZero(alphaMask);
-
-            vCurvedData.gather(curveDataPointer,vAlphaValue);
-            vCurvedData1.gather(curveDataPointer,vAlphaValue + 1);
-//            Vc::float_v vCurvedData1(curveDataPointer,vAlphaValue + 1);
-
-            // vAlpha
-            Vc::float_v fullFade = (
-                (vOne - alphaValueF) * vCurvedData +
-                alphaValueF * vCurvedData1);
-
-            Vc::float_m mask;
-            // Mask in the inner circle of the mask
-            mask = fullFade < vZero;
-            fullFade.setZero(mask);
-
-            // Mask outer circle of mask
-            mask = fullFade >= vOne;
-            Vc::float_v vFade = (vOne - fullFade);
-            vFade.setZero(mask);
-
-            // return original dist values before vFade transform
-            vFade(excludeMask) = dist;
-            vFade.store(bufferPointer, Vc::Aligned);
-
-        } else {
-          dist.store(bufferPointer, Vc::Aligned);
-      }
-      currentIndices = currentIndices + increment;
-
-      bufferPointer += Vc::float_v::size();
-    }
-}
-
-struct KisGaussRectangleMaskGenerator::FastRowProcessor
-{
-    FastRowProcessor(KisGaussRectangleMaskGenerator *maskGenerator)
-        : d(maskGenerator->d.data()) {}
-
-    template<Vc::Implementation _impl>
-    void process(float* buffer, int width, float y, float cosa, float sina,
-                 float centerX, float centerY);
-
-    KisGaussRectangleMaskGenerator::Private *d;
-};
-
-struct KisRectangleMaskGenerator::FastRowProcessor
-{
-    FastRowProcessor(KisRectangleMaskGenerator *maskGenerator)
-        : d(maskGenerator->d.data()) {}
-
-    template<Vc::Implementation _impl>
-    void process(float* buffer, int width, float y, float cosa, float sina,
-                 float centerX, float centerY);
-
-    KisRectangleMaskGenerator::Private *d;
-};
-
-template<> void KisRectangleMaskGenerator::
-FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, int width, float y, float cosa, float sina,
-                                   float centerX, float centerY)
-{
-    const bool useSmoothing = d->copyOfAntialiasEdges;
-
-    float y_ = y - centerY;
-    float sinay_ = sina * y_;
-    float cosay_ = cosa * y_;
-
-    float* bufferPointer = buffer;
-
-    Vc::float_v currentIndices = Vc::float_v::IndexesFromZero();
-
-    Vc::float_v increment((float)Vc::float_v::size());
-    Vc::float_v vCenterX(centerX);
-
-    Vc::float_v vCosa(cosa);
-    Vc::float_v vSina(sina);
-    Vc::float_v vCosaY_(cosay_);
-    Vc::float_v vSinaY_(sinay_);
-
-    Vc::float_v vXCoeff(static_cast<float>(d->xcoeff));
-    Vc::float_v vYCoeff(static_cast<float>(d->ycoeff));
-
-    Vc::float_v vTransformedFadeX(static_cast<float>(d->transformedFadeX));
-    Vc::float_v vTransformedFadeY(static_cast<float>(d->transformedFadeY));
-
-    Vc::float_v vOne(Vc::One);
-    Vc::float_v vZero(Vc::Zero);
-    Vc::float_v vTolerance(10000.f);
-
-    for (size_t i=0; i < static_cast<size_t>(width); i+= Vc::float_v::size()){
-
-        Vc::float_v x_ = currentIndices - vCenterX;
-
-        Vc::float_v xr = Vc::abs(x_ * vCosa - vSinaY_);
-        Vc::float_v yr = Vc::abs(x_ * vSina + vCosaY_);
-
-        Vc::float_v nxr = xr * vXCoeff;
-        Vc::float_v nyr = yr * vYCoeff;
-
-        Vc::float_m outsideMask = (nxr > vOne) || (nyr > vOne);
-
-        if (!outsideMask.isFull()) {
-            if (useSmoothing) {
-                xr = Vc::abs(xr) + vOne;
-                yr = Vc::abs(yr) + vOne;
-            }
-
-            Vc::float_v fxr = xr * vTransformedFadeX;
-            Vc::float_v fyr = yr * vTransformedFadeY;
-
-            Vc::float_v fxrNorm = nxr * (fxr - vOne) / (fxr - nxr);
-            Vc::float_v fyrNorm = nyr * (fyr - vOne) / (fyr - nyr);
-
-            Vc::float_v vFade(vZero);
-
-            Vc::float_m vFadeMask = fxrNorm < fyrNorm;
-            Vc::float_v vMaxVal = vFade;
-            vMaxVal(fxr > vOne) = fxrNorm;
-            vMaxVal(vFadeMask && fyr > vOne) = fyrNorm;
-            vFade = vMaxVal;
-
-            // Mask out the outer circle of the mask
-            vFade(outsideMask) = vOne;
-            vFade.store(bufferPointer, Vc::Aligned);
-        } else {
-            // Mask out everything outside the circle
-            vOne.store(bufferPointer, Vc::Aligned);
-        }
-
-        currentIndices = currentIndices + increment;
-
-        bufferPointer += Vc::float_v::size();
-    }
-}
-
-
-template<> void KisGaussRectangleMaskGenerator::
-FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, int width, float y, float cosa, float sina,
-                                   float centerX, float centerY)
-{
-    float y_ = y - centerY;
-    float sinay_ = sina * y_;
-    float cosay_ = cosa * y_;
-
-    float* bufferPointer = buffer;
-
-    Vc::float_v currentIndices = Vc::float_v::IndexesFromZero();
-
-    Vc::float_v increment((float)Vc::float_v::size());
-    Vc::float_v vCenterX(centerX);
-
-    Vc::float_v vCosa(cosa);
-    Vc::float_v vSina(sina);
-    Vc::float_v vCosaY_(cosay_);
-    Vc::float_v vSinaY_(sinay_);
-
-    Vc::float_v vhalfWidth(static_cast<float>(d->halfWidth));
-    Vc::float_v vhalfHeight(static_cast<float>(d->halfHeight));
-    Vc::float_v vXFade(static_cast<float>(d->xfade));
-    Vc::float_v vYFade(static_cast<float>(d->yfade));
-
-    Vc::float_v vAlphafactor(static_cast<float>(d->alphafactor));
-
-    Vc::float_v vOne(Vc::One);
-    Vc::float_v vZero(Vc::Zero);
-    Vc::float_v vValMax(255.f);
-
-    for (size_t i = 0; i < static_cast<size_t>(width); i += Vc::float_v::size()) {
-        Vc::float_v x_ = currentIndices - vCenterX;
-
-        Vc::float_v xr = x_ * vCosa - vSinaY_;
-        Vc::float_v yr = Vc::abs(x_ * vSina + vCosaY_);
-
-        Vc::float_v vValue;
-
-        // check if we need to apply fader on values
-        Vc::float_m excludeMask = d->fadeMaker.needFade(xr,yr);
-        vValue(excludeMask) = vOne;
-
-        if (!excludeMask.isFull()) {
-            Vc::float_v fullFade = vValMax - (vAlphafactor * (VcExtraMath::erf((vhalfWidth + xr) * vXFade) + VcExtraMath::erf((vhalfWidth - xr) * vXFade))
-                                        * (VcExtraMath::erf((vhalfHeight + yr) * vYFade) + VcExtraMath::erf((vhalfHeight - yr) * vYFade)));
-
-            // apply antialias fader
-            d->fadeMaker.apply2DFader(fullFade,excludeMask,xr,yr);
-
-            Vc::float_m mask;
-
-            // Mask in the inner circle of the mask
-            mask = fullFade < vZero;
-            fullFade.setZero(mask);
-
-            // Mask the outer circle
-            mask = fullFade > 254.974f;
-            fullFade(mask) = vValMax;
-
-            // Mask (value - value), precision errors.
-            Vc::float_v vFade = fullFade / vValMax;
-
-            // return original vValue values before vFade transform
-            vFade(excludeMask) = vValue;
-            vFade.store(bufferPointer, Vc::Aligned);
-
-        } else {
-          vValue.store(bufferPointer, Vc::Aligned);
-      }
-      currentIndices = currentIndices + increment;
-
-      bufferPointer += Vc::float_v::size();
-    }
-}
-
-struct KisCurveRectangleMaskGenerator::FastRowProcessor
+MaskApplicatorFactory<KisCurveRectangleMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisCurveRectangleMaskGenerator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
 {
-    FastRowProcessor(KisCurveRectangleMaskGenerator *maskGenerator)
-        : d(maskGenerator->d.data()) {}
-
-    template<Vc::Implementation _impl>
-    void process(float* buffer, int width, float y, float cosa, float sina,
-                 float centerX, float centerY);
-
-    KisCurveRectangleMaskGenerator::Private *d;
-};
-
-template<> void KisCurveRectangleMaskGenerator::
-FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, int width, float y, float cosa, float sina,
-                                   float centerX, float centerY)
-{
-    float y_ = y - centerY;
-    float sinay_ = sina * y_;
-    float cosay_ = cosa * y_;
-
-    float* bufferPointer = buffer;
-
-    qreal* curveDataPointer = d->curveData.data();
-
-    Vc::float_v currentIndices = Vc::float_v::IndexesFromZero();
-
-    Vc::float_v increment((float)Vc::float_v::size());
-    Vc::float_v vCenterX(centerX);
-
-    Vc::float_v vCosa(cosa);
-    Vc::float_v vSina(sina);
-    Vc::float_v vCosaY_(cosay_);
-    Vc::float_v vSinaY_(sinay_);
-
-    Vc::float_v vYCoeff(static_cast<float>(d->ycoeff));
-    Vc::float_v vXCoeff(static_cast<float>(d->xcoeff));
-    Vc::float_v vCurveResolution(static_cast<float>(d->curveResolution));
-
-    Vc::float_v vOne(Vc::One);
-    Vc::float_v vZero(Vc::Zero);
-    Vc::float_v vValMax(255.f);
-
-    for (size_t i = 0; i < static_cast<size_t>(width); i += Vc::float_v::size()) {
-        Vc::float_v x_ = currentIndices - vCenterX;
-
-        Vc::float_v xr = x_ * vCosa - vSinaY_;
-        Vc::float_v yr = Vc::abs(x_ * vSina + vCosaY_);
-
-        Vc::float_v vValue;
-
-        // check if we need to apply fader on values
-        Vc::float_m excludeMask = d->fadeMaker.needFade(xr,yr);
-        vValue(excludeMask) = vOne;
-
-        if (!excludeMask.isFull()) {
-            // We need to mask the extra area given for aliniation
-            // the next operation should never give values above 1
-            Vc::float_v preSIndex = Vc::abs(xr) * vXCoeff;
-            Vc::float_v preTIndex = Vc::abs(yr) * vYCoeff;
-
-            preSIndex(preSIndex > vOne) = vOne;
-            preTIndex(preTIndex > vOne) = vOne;
-
-            Vc::float_v::IndexType sIndex( round(preSIndex * vCurveResolution));
-            Vc::float_v::IndexType tIndex( round(preTIndex * vCurveResolution));
-
-            Vc::float_v::IndexType sIndexInverted = vCurveResolution - sIndex;
-            Vc::float_v::IndexType tIndexInverted = vCurveResolution - tIndex;
-
-            Vc::float_v vCurvedDataSIndex(curveDataPointer, sIndex);
-            Vc::float_v vCurvedDataTIndex(curveDataPointer, tIndex);
-            Vc::float_v vCurvedDataSIndexInv(curveDataPointer, sIndexInverted);
-            Vc::float_v vCurvedDataTIndexInv(curveDataPointer, tIndexInverted);
-
-            Vc::float_v fullFade = vValMax * (vOne - (vCurvedDataSIndex * (vOne - vCurvedDataSIndexInv) *
-                                    vCurvedDataTIndex * (vOne - vCurvedDataTIndexInv)));
-
-            // apply antialias fader
-            d->fadeMaker.apply2DFader(fullFade,excludeMask,xr,yr);
-
-            Vc::float_m mask;
-
-            // Mask in the inner circle of the mask
-            mask = fullFade < vZero;
-            fullFade.setZero(mask);
-
-            // Mask the outer circle
-            mask = fullFade > 254.974f;
-            fullFade(mask) = vValMax;
-
-            // Mask (value - value), precision errors.
-            Vc::float_v vFade = fullFade / vValMax;
-
-            // return original vValue values before vFade transform
-            vFade(excludeMask) = vValue;
-            vFade.store(bufferPointer, Vc::Aligned);
-
-        } else {
-          vValue.store(bufferPointer, Vc::Aligned);
-      }
-      currentIndices = currentIndices + increment;
-
-      bufferPointer += Vc::float_v::size();
-    }
+    return new KisBrushMaskVectorApplicator<KisCurveRectangleMaskGenerator, Vc::CurrentImplementation::current()>(maskGenerator);
 }
-
-#endif /* defined HAVE_VC */
diff --git a/libs/image/kis_brush_mask_applicator_factories.h b/libs/image/kis_brush_mask_applicator_factories.h
index 0e7e06d599..60592e4516 100644
--- a/libs/image/kis_brush_mask_applicator_factories.h
+++ b/libs/image/kis_brush_mask_applicator_factories.h
@@ -1,5 +1,6 @@
 /*
  *  SPDX-FileCopyrightText: 2012 Dmitry Kazakov <dimula73 at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -11,26 +12,10 @@
 
 class KisBrushMaskApplicatorBase;
 
-template<class MaskGenerator, Vc::Implementation _impl>
-struct KisBrushMaskScalarApplicator;
-
-#ifdef HAVE_VC
-
-template<class MaskGenerator, Vc::Implementation _impl>
-struct KisBrushMaskVectorApplicator;
-
-#else /* HAVE_VC */
-
-#define KisBrushMaskVectorApplicator KisBrushMaskScalarApplicator
-
-#endif /* HAVE_VC */
-
-template<class MaskGenerator,
-         template<class U, Vc::Implementation V> class Applicator>
-struct MaskApplicatorFactory
-{
-    typedef MaskGenerator* ParamType;
-    typedef KisBrushMaskApplicatorBase* ReturnType;
+template<class MaskGenerator>
+struct MaskApplicatorFactory {
+    using ParamType = MaskGenerator *;
+    using ReturnType = KisBrushMaskApplicatorBase *;
 
     template<Vc::Implementation _impl>
     static ReturnType create(ParamType maskGenerator);
diff --git a/libs/image/kis_brush_mask_applicator_factories_Scalar.cpp b/libs/image/kis_brush_mask_applicator_factories_Scalar.cpp
new file mode 100644
index 0000000000..6cf142561f
--- /dev/null
+++ b/libs/image/kis_brush_mask_applicator_factories_Scalar.cpp
@@ -0,0 +1,73 @@
+/*
+ *  SPDX-FileCopyrightText: 2012 Dmitry Kazakov <dimula73 at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
+ *
+ *  SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "kis_brush_mask_applicator_factories.h"
+
+#include "kis_circle_mask_generator.h"
+#include "kis_curve_circle_mask_generator.h"
+#include "kis_curve_rect_mask_generator.h"
+#include "kis_gauss_circle_mask_generator.h"
+#include "kis_gauss_rect_mask_generator.h"
+#include "kis_rect_mask_generator.h"
+
+#include "kis_brush_mask_scalar_applicator.h"
+
+template<>
+template<>
+MaskApplicatorFactory<KisMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisMaskGenerator>::create<Vc::ScalarImpl>(ParamType maskGenerator)
+{
+    return new KisBrushMaskScalarApplicator<KisMaskGenerator, Vc::ScalarImpl>(maskGenerator);
+}
+
+template<>
+template<>
+MaskApplicatorFactory<KisCircleMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisCircleMaskGenerator>::create<Vc::ScalarImpl>(ParamType maskGenerator)
+{
+    return new KisBrushMaskScalarApplicator<KisCircleMaskGenerator, Vc::ScalarImpl>(maskGenerator);
+}
+
+template<>
+template<>
+MaskApplicatorFactory<KisGaussCircleMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisGaussCircleMaskGenerator>::create<Vc::ScalarImpl>(ParamType maskGenerator)
+{
+    return new KisBrushMaskScalarApplicator<KisGaussCircleMaskGenerator, Vc::ScalarImpl>(maskGenerator);
+}
+
+template<>
+template<>
+MaskApplicatorFactory<KisCurveCircleMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisCurveCircleMaskGenerator>::create<Vc::ScalarImpl>(ParamType maskGenerator)
+{
+    return new KisBrushMaskScalarApplicator<KisCurveCircleMaskGenerator, Vc::ScalarImpl>(maskGenerator);
+}
+
+template<>
+template<>
+MaskApplicatorFactory<KisRectangleMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisRectangleMaskGenerator>::create<Vc::ScalarImpl>(ParamType maskGenerator)
+{
+    return new KisBrushMaskScalarApplicator<KisRectangleMaskGenerator, Vc::ScalarImpl>(maskGenerator);
+}
+
+template<>
+template<>
+MaskApplicatorFactory<KisGaussRectangleMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisGaussRectangleMaskGenerator>::create<Vc::ScalarImpl>(ParamType maskGenerator)
+{
+    return new KisBrushMaskScalarApplicator<KisGaussRectangleMaskGenerator, Vc::ScalarImpl>(maskGenerator);
+}
+
+template<>
+template<>
+MaskApplicatorFactory<KisCurveRectangleMaskGenerator>::ReturnType
+MaskApplicatorFactory<KisCurveRectangleMaskGenerator>::create<Vc::ScalarImpl>(ParamType maskGenerator)
+{
+    return new KisBrushMaskScalarApplicator<KisCurveRectangleMaskGenerator, Vc::ScalarImpl>(maskGenerator);
+}
diff --git a/libs/image/kis_brush_mask_applicators.h b/libs/image/kis_brush_mask_applicators.h
deleted file mode 100644
index 7f51067bbc..0000000000
--- a/libs/image/kis_brush_mask_applicators.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- *  SPDX-FileCopyrightText: 2012 Sven Langkamp <sven.langkamp at gmail.com>
- *  SPDX-FileCopyrightText: 2012 Dmitry Kazakov <dimula73 at gmail.com>
- *
- *  SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#ifndef __KIS_BRUSH_MASK_APPLICATORS_H
-#define __KIS_BRUSH_MASK_APPLICATORS_H
-
-#include "kis_brush_mask_applicator_base.h"
-#include "kis_global.h"
-#include "kis_random_source.h"
-
-// 3x3 supersampling
-#define SUPERSAMPLING 3
-
-
-template<class MaskGenerator, Vc::Implementation _impl>
-struct KisBrushMaskScalarApplicator : public KisBrushMaskApplicatorBase
-{
-    KisBrushMaskScalarApplicator(MaskGenerator *maskGenerator)
-        : m_maskGenerator(maskGenerator)
-    {
-    }
-
-    void process(const QRect &rect) override {
-        processScalar(rect);
-    }
-
-protected:
-    void processScalar(const QRect &rect);
-
-protected:
-    MaskGenerator *m_maskGenerator;
-    KisRandomSource m_randomSource; // TODO: make it more deterministic for LoD
-};
-
-#if defined HAVE_VC
-
-template<class MaskGenerator, Vc::Implementation _impl>
-struct KisBrushMaskVectorApplicator : public KisBrushMaskScalarApplicator<MaskGenerator, _impl>
-{
-    KisBrushMaskVectorApplicator(MaskGenerator *maskGenerator)
-        : KisBrushMaskScalarApplicator<MaskGenerator, _impl>(maskGenerator)
-    {
-    }
-
-    void process(const QRect &rect) {
-        startProcessing(rect, TypeHelper<MaskGenerator, _impl>());
-    }
-
-protected:
-    void processVector(const QRect &rect);
-
-private:
-    template<class U, Vc::Implementation V> struct TypeHelper {};
-
-private:
-    template<class U>
-    inline void startProcessing(const QRect &rect, TypeHelper<U, Vc::ScalarImpl>) {
-        KisBrushMaskScalarApplicator<MaskGenerator, _impl>::processScalar(rect);
-    }
-
-    template<class U, Vc::Implementation V>
-    inline void startProcessing(const QRect &rect, TypeHelper<U, V>) {
-        MaskGenerator *m_maskGenerator = KisBrushMaskScalarApplicator<MaskGenerator, _impl>::m_maskGenerator;
-
-        if (m_maskGenerator->shouldVectorize()) {
-            processVector(rect);
-        } else {
-            KisBrushMaskScalarApplicator<MaskGenerator, _impl>::processScalar(rect);
-        }
-    }
-};
-
-template<class MaskGenerator, Vc::Implementation _impl>
-void KisBrushMaskVectorApplicator<MaskGenerator, _impl>::processVector(const QRect &rect)
-{
-    const MaskProcessingData *m_d = KisBrushMaskApplicatorBase::m_d;
-    MaskGenerator *m_maskGenerator = KisBrushMaskScalarApplicator<MaskGenerator, _impl>::m_maskGenerator;
-
-    qreal random = 1.0;
-    quint8* dabPointer = m_d->device->data() + rect.y() * rect.width() * m_d->pixelSize;
-    quint8 alphaValue = OPACITY_TRANSPARENT_U8;
-    // this offset is needed when brush size is smaller then fixed device size
-    int offset = (m_d->device->bounds().width() - rect.width()) * m_d->pixelSize;
-
-    int width = rect.width();
-
-    // We need to calculate with a multiple of the width of the simd register
-    size_t alignOffset = 0;
-    if (width % Vc::float_v::size() != 0) {
-        alignOffset = Vc::float_v::size() - (width % Vc::float_v::size());
-    }
-    size_t simdWidth = width + alignOffset;
-
-    float *buffer = Vc::malloc<float, Vc::AlignOnCacheline>(simdWidth);
-
-    typename MaskGenerator::FastRowProcessor processor(m_maskGenerator);
-
-    for (int y = rect.y(); y < rect.y() + rect.height(); y++) {
-
-        processor.template process<_impl>(buffer, simdWidth, y, m_d->cosa, m_d->sina, m_d->centerX, m_d->centerY);
-
-        if (m_d->randomness != 0.0 || m_d->density != 1.0) {
-            for (int x = 0; x < width; x++) {
-
-                if (m_d->randomness!= 0.0){
-                    random = (1.0 - m_d->randomness) + m_d->randomness * KisBrushMaskScalarApplicator<MaskGenerator, _impl>::m_randomSource.generateNormalized();
-                }
-
-                alphaValue = quint8( (OPACITY_OPAQUE_U8 - buffer[x]*255) * random);
-
-                // avoid computation of random numbers if density is full
-                if (m_d->density != 1.0){
-                    // compute density only for visible pixels of the mask
-                    if (alphaValue != OPACITY_TRANSPARENT_U8){
-                        if ( !(m_d->density >= KisBrushMaskScalarApplicator<MaskGenerator, _impl>::m_randomSource.generateNormalized()) ){
-                            alphaValue = OPACITY_TRANSPARENT_U8;
-                        }
-                    }
-                }
-
-                if (m_d->color) {
-                    memcpy(dabPointer, m_d->color, m_d->pixelSize);
-                }
-
-                m_d->colorSpace->applyAlphaU8Mask(dabPointer, &alphaValue, 1);
-                dabPointer += m_d->pixelSize;
-            }
-        } else if (m_d->color) {
-            m_d->colorSpace->fillInverseAlphaNormedFloatMaskWithColor(dabPointer, buffer, m_d->color, width);
-            dabPointer += width * m_d->pixelSize;
-        } else {
-            m_d->colorSpace->applyInverseNormedFloatMask(dabPointer, buffer, width);
-            dabPointer += width * m_d->pixelSize;
-        }//endfor x
-        dabPointer += offset;
-    }//endfor y
-    Vc::free(buffer);
-}
-
-#endif /* defined HAVE_VC */
-
-template<class MaskGenerator, Vc::Implementation _impl>
-void KisBrushMaskScalarApplicator<MaskGenerator, _impl>::processScalar(const QRect &rect)
-{
-    const MaskProcessingData *m_d = KisBrushMaskApplicatorBase::m_d;
-    MaskGenerator *m_maskGenerator = KisBrushMaskScalarApplicator<MaskGenerator, _impl>::m_maskGenerator;
-
-    qreal random = 1.0;
-    quint8* dabPointer = m_d->device->data() + rect.y() * rect.width() * m_d->pixelSize;
-    quint8 alphaValue = OPACITY_TRANSPARENT_U8;
-    // this offset is needed when brush size is smaller then fixed device size
-    int offset = (m_d->device->bounds().width() - rect.width()) * m_d->pixelSize;
-    int supersample = (m_maskGenerator->shouldSupersample() ? SUPERSAMPLING : 1);
-    double invss = 1.0 / supersample;
-    int samplearea = pow2(supersample);
-    for (int y = rect.y(); y < rect.y() + rect.height(); y++) {
-        for (int x = rect.x(); x < rect.x() + rect.width(); x++) {
-            int value = 0;
-            for (int sy = 0; sy < supersample; sy++) {
-                for (int sx = 0; sx < supersample; sx++) {
-                    double x_ = x + sx * invss - m_d->centerX;
-                    double y_ = y + sy * invss - m_d->centerY;
-                    double maskX = m_d->cosa * x_ - m_d->sina * y_;
-                    double maskY = m_d->sina * x_ + m_d->cosa * y_;
-                    value += m_maskGenerator->valueAt(maskX, maskY);
-                }
-            }
-            if (supersample != 1) value /= samplearea;
-
-            if (m_d->randomness!= 0.0){
-                random = (1.0 - m_d->randomness) + m_d->randomness * m_randomSource.generateNormalized();
-            }
-
-            alphaValue = quint8( (OPACITY_OPAQUE_U8 - value) * random);
-
-            // avoid computation of random numbers if density is full
-            if (m_d->density != 1.0){
-                // compute density only for visible pixels of the mask
-                if (alphaValue != OPACITY_TRANSPARENT_U8){
-                    if ( !(m_d->density >= m_randomSource.generateNormalized()) ){
-                        alphaValue = OPACITY_TRANSPARENT_U8;
-                    }
-                }
-            }
-
-            if (m_d->color) {
-                memcpy(dabPointer, m_d->color, static_cast<size_t>(m_d->pixelSize));
-            }
-
-            m_d->colorSpace->applyAlphaU8Mask(dabPointer, &alphaValue, 1);
-            dabPointer += m_d->pixelSize;
-        }//endfor x
-        dabPointer += offset;
-    }//endfor y
-}
-
-#endif /* __KIS_BRUSH_MASK_APPLICATORS_H */
diff --git a/libs/image/kis_brush_mask_applicator_factories.cpp b/libs/image/kis_brush_mask_processor_factories.cpp
similarity index 58%
copy from libs/image/kis_brush_mask_applicator_factories.cpp
copy to libs/image/kis_brush_mask_processor_factories.cpp
index 11f5688c5f..3989df79ce 100644
--- a/libs/image/kis_brush_mask_applicator_factories.cpp
+++ b/libs/image/kis_brush_mask_processor_factories.cpp
@@ -1,100 +1,44 @@
 /*
  *  SPDX-FileCopyrightText: 2012 Dmitry Kazakov <dimula73 at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#include "kis_brush_mask_applicator_factories.h"
-#include "vc_extra_math.h"
+#include <compositeops/KoVcMultiArchBuildSupport.h>
+
+#if defined HAVE_VC
 
 #include "kis_circle_mask_generator.h"
 #include "kis_circle_mask_generator_p.h"
-#include "kis_gauss_circle_mask_generator_p.h"
+#include "kis_curve_circle_mask_generator.h"
 #include "kis_curve_circle_mask_generator_p.h"
-#include "kis_gauss_rect_mask_generator_p.h"
+#include "kis_curve_rect_mask_generator.h"
 #include "kis_curve_rect_mask_generator_p.h"
+#include "kis_gauss_circle_mask_generator.h"
+#include "kis_gauss_circle_mask_generator_p.h"
+#include "kis_gauss_rect_mask_generator.h"
+#include "kis_gauss_rect_mask_generator_p.h"
+#include "kis_rect_mask_generator.h"
 #include "kis_rect_mask_generator_p.h"
 
-#include "kis_brush_mask_applicators.h"
 #include "kis_brush_mask_applicator_base.h"
+#include "kis_brush_mask_vector_applicator.h"
+
+#include "vc_extra_math.h"
 
 #define a(_s) #_s
 #define b(_s) a(_s)
 
 template<>
 template<>
-MaskApplicatorFactory<KisMaskGenerator, KisBrushMaskScalarApplicator>::ReturnType
-MaskApplicatorFactory<KisMaskGenerator, KisBrushMaskScalarApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
-{
-    return new KisBrushMaskScalarApplicator<KisMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
-}
-
-template<>
-template<>
-MaskApplicatorFactory<KisCircleMaskGenerator, KisBrushMaskVectorApplicator>::ReturnType
-MaskApplicatorFactory<KisCircleMaskGenerator, KisBrushMaskVectorApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
-{
-    return new KisBrushMaskVectorApplicator<KisCircleMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
-}
-
-template<>
-template<>
-MaskApplicatorFactory<KisGaussCircleMaskGenerator, KisBrushMaskVectorApplicator>::ReturnType
-MaskApplicatorFactory<KisGaussCircleMaskGenerator, KisBrushMaskVectorApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
-{
-    return new KisBrushMaskVectorApplicator<KisGaussCircleMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
-}
-
-template<>
-template<>
-MaskApplicatorFactory<KisCurveCircleMaskGenerator, KisBrushMaskVectorApplicator>::ReturnType
-MaskApplicatorFactory<KisCurveCircleMaskGenerator, KisBrushMaskVectorApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
-{
-    return new KisBrushMaskVectorApplicator<KisCurveCircleMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
-}
-
-template<>
-template<>
-MaskApplicatorFactory<KisRectangleMaskGenerator, KisBrushMaskVectorApplicator>::ReturnType
-MaskApplicatorFactory<KisRectangleMaskGenerator, KisBrushMaskVectorApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
-{
-    return new KisBrushMaskVectorApplicator<KisRectangleMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
-}
-
-template<>
-template<>
-MaskApplicatorFactory<KisGaussRectangleMaskGenerator, KisBrushMaskVectorApplicator>::ReturnType
-MaskApplicatorFactory<KisGaussRectangleMaskGenerator, KisBrushMaskVectorApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
-{
-    return new KisBrushMaskVectorApplicator<KisGaussRectangleMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
-}
-
-template<>
-template<>
-MaskApplicatorFactory<KisCurveRectangleMaskGenerator, KisBrushMaskVectorApplicator>::ReturnType
-MaskApplicatorFactory<KisCurveRectangleMaskGenerator, KisBrushMaskVectorApplicator>::create<Vc::CurrentImplementation::current()>(ParamType maskGenerator)
-{
-    return new KisBrushMaskVectorApplicator<KisCurveRectangleMaskGenerator,Vc::CurrentImplementation::current()>(maskGenerator);
-}
-
-
-#if defined HAVE_VC
-
-struct KisCircleMaskGenerator::FastRowProcessor
-{
-    FastRowProcessor(KisCircleMaskGenerator *maskGenerator)
-        : d(maskGenerator->d.data()) {}
-
-    template<Vc::Implementation _impl>
-    void process(float* buffer, int width, float y, float cosa, float sina,
-                 float centerX, float centerY);
-
-    KisCircleMaskGenerator::Private *d;
-};
-
-template<> void KisCircleMaskGenerator::
-FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, int width, float y, float cosa, float sina,
-                                   float centerX, float centerY)
+void FastRowProcessor<KisCircleMaskGenerator>::process<Vc::CurrentImplementation::current()>(float *buffer,
+                                                                                             int width,
+                                                                                             float y,
+                                                                                             float cosa,
+                                                                                             float sina,
+                                                                                             float centerX,
+                                                                                             float centerY)
 {
     const bool useSmoothing = d->copyOfAntialiasEdges;
 
@@ -102,7 +46,7 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
     float sinay_ = sina * y_;
     float cosay_ = cosa * y_;
 
-    float* bufferPointer = buffer;
+    float *bufferPointer = buffer;
 
     Vc::float_v currentIndices = Vc::float_v::IndexesFromZero();
 
@@ -122,8 +66,7 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
 
     Vc::float_v vOne(Vc::One);
 
-    for (size_t i=0; i < static_cast<size_t>(width); i+= Vc::float_v::size()){
-
+    for (size_t i = 0; i < static_cast<size_t>(width); i += Vc::float_v::size()) {
         Vc::float_v x_ = currentIndices - vCenterX;
 
         Vc::float_v xr = x_ * vCosa - vSinaY_;
@@ -141,7 +84,7 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
             Vc::float_m vNormLowMask = vNormFade < vOne;
             vNormFade.setZero(vNormLowMask);
 
-            //255 * n * (normeFade - 1) / (normeFade - n)
+            // 255 * n * (normeFade - 1) / (normeFade - n)
             Vc::float_v vFade = n * (vNormFade - vOne) / (vNormFade - n);
 
             // Mask in the inner circle of the mask
@@ -164,28 +107,21 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
     }
 }
 
-
-struct KisGaussCircleMaskGenerator::FastRowProcessor
-{
-    FastRowProcessor(KisGaussCircleMaskGenerator *maskGenerator)
-        : d(maskGenerator->d.data()) {}
-
-    template<Vc::Implementation _impl>
-    void process(float* buffer, int width, float y, float cosa, float sina,
-                 float centerX, float centerY);
-
-    KisGaussCircleMaskGenerator::Private *d;
-};
-
-template<> void KisGaussCircleMaskGenerator::
-FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, int width, float y, float cosa, float sina,
-                                   float centerX, float centerY)
+template<>
+template<>
+void FastRowProcessor<KisGaussCircleMaskGenerator>::process<Vc::CurrentImplementation::current()>(float *buffer,
+                                                                                                  int width,
+                                                                                                  float y,
+                                                                                                  float cosa,
+                                                                                                  float sina,
+                                                                                                  float centerX,
+                                                                                                  float centerY)
 {
     float y_ = y - centerY;
     float sinay_ = sina * y_;
     float cosay_ = cosa * y_;
 
-    float* bufferPointer = buffer;
+    float *bufferPointer = buffer;
 
     Vc::float_v currentIndices = Vc::float_v::IndexesFromZero();
 
@@ -205,8 +141,7 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
     Vc::float_v vZero(Vc::Zero);
     Vc::float_v vValMax(255.f);
 
-    for (size_t i=0; i < static_cast<size_t>(width); i+= Vc::float_v::size()){
-
+    for (size_t i = 0; i < static_cast<size_t>(width); i += Vc::float_v::size()) {
         Vc::float_v x_ = currentIndices - vCenterX;
 
         Vc::float_v xr = x_ * vCosa - vSinaY_;
@@ -219,7 +154,8 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
 
         if (!excludeMask.isFull()) {
             Vc::float_v valDist = dist * vDistfactor;
-            Vc::float_v fullFade = vAlphafactor * (  VcExtraMath::erf(valDist + vCenter) -  VcExtraMath::erf(valDist - vCenter));
+            Vc::float_v fullFade =
+                vAlphafactor * (VcExtraMath::erf(valDist + vCenter) - VcExtraMath::erf(valDist - vCenter));
 
             Vc::float_m mask;
             // Mask in the inner circle of the mask
@@ -238,38 +174,31 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
             vFade.store(bufferPointer, Vc::Aligned);
 
         } else {
-          dist.store(bufferPointer, Vc::Aligned);
-      }
-      currentIndices = currentIndices + increment;
+            dist.store(bufferPointer, Vc::Aligned);
+        }
+        currentIndices = currentIndices + increment;
 
-      bufferPointer += Vc::float_v::size();
+        bufferPointer += Vc::float_v::size();
     }
 }
 
-struct KisCurveCircleMaskGenerator::FastRowProcessor
-{
-    FastRowProcessor(KisCurveCircleMaskGenerator *maskGenerator)
-        : d(maskGenerator->d.data()) {}
-
-    template<Vc::Implementation _impl>
-    void process(float* buffer, int width, float y, float cosa, float sina,
-                 float centerX, float centerY);
-
-    KisCurveCircleMaskGenerator::Private *d;
-};
-
-
-template<> void KisCurveCircleMaskGenerator::
-FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, int width, float y, float cosa, float sina,
-                                   float centerX, float centerY)
+template<>
+template<>
+void FastRowProcessor<KisCurveCircleMaskGenerator>::process<Vc::CurrentImplementation::current()>(float *buffer,
+                                                                                                  int width,
+                                                                                                  float y,
+                                                                                                  float cosa,
+                                                                                                  float sina,
+                                                                                                  float centerX,
+                                                                                                  float centerY)
 {
     float y_ = y - centerY;
     float sinay_ = sina * y_;
     float cosay_ = cosa * y_;
 
-    float* bufferPointer = buffer;
+    float *bufferPointer = buffer;
 
-    qreal* curveDataPointer = d->curveData.data();
+    qreal *curveDataPointer = d->curveData.data();
 
     Vc::float_v currentIndices = Vc::float_v::IndexesFromZero();
 
@@ -291,8 +220,7 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
     Vc::float_v vOne(Vc::One);
     Vc::float_v vZero(Vc::Zero);
 
-    for (size_t i=0; i < static_cast<size_t>(width); i+= Vc::float_v::size()){
-
+    for (size_t i = 0; i < static_cast<size_t>(width); i += Vc::float_v::size()) {
         Vc::float_v x_ = currentIndices - vCenterX;
 
         Vc::float_v xr = x_ * vCosa - vSinaY_;
@@ -314,14 +242,12 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
             Vc::float_m alphaMask = vAlphaValue < vZero;
             vAlphaValue.setZero(alphaMask);
 
-            vCurvedData.gather(curveDataPointer,vAlphaValue);
-            vCurvedData1.gather(curveDataPointer,vAlphaValue + 1);
-//            Vc::float_v vCurvedData1(curveDataPointer,vAlphaValue + 1);
+            vCurvedData.gather(curveDataPointer, vAlphaValue);
+            vCurvedData1.gather(curveDataPointer, vAlphaValue + 1);
+            //            Vc::float_v vCurvedData1(curveDataPointer,vAlphaValue + 1);
 
             // vAlpha
-            Vc::float_v fullFade = (
-                (vOne - alphaValueF) * vCurvedData +
-                alphaValueF * vCurvedData1);
+            Vc::float_v fullFade = ((vOne - alphaValueF) * vCurvedData + alphaValueF * vCurvedData1);
 
             Vc::float_m mask;
             // Mask in the inner circle of the mask
@@ -338,41 +264,23 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
             vFade.store(bufferPointer, Vc::Aligned);
 
         } else {
-          dist.store(bufferPointer, Vc::Aligned);
-      }
-      currentIndices = currentIndices + increment;
+            dist.store(bufferPointer, Vc::Aligned);
+        }
+        currentIndices = currentIndices + increment;
 
-      bufferPointer += Vc::float_v::size();
+        bufferPointer += Vc::float_v::size();
     }
 }
 
-struct KisGaussRectangleMaskGenerator::FastRowProcessor
-{
-    FastRowProcessor(KisGaussRectangleMaskGenerator *maskGenerator)
-        : d(maskGenerator->d.data()) {}
-
-    template<Vc::Implementation _impl>
-    void process(float* buffer, int width, float y, float cosa, float sina,
-                 float centerX, float centerY);
-
-    KisGaussRectangleMaskGenerator::Private *d;
-};
-
-struct KisRectangleMaskGenerator::FastRowProcessor
-{
-    FastRowProcessor(KisRectangleMaskGenerator *maskGenerator)
-        : d(maskGenerator->d.data()) {}
-
-    template<Vc::Implementation _impl>
-    void process(float* buffer, int width, float y, float cosa, float sina,
-                 float centerX, float centerY);
-
-    KisRectangleMaskGenerator::Private *d;
-};
-
-template<> void KisRectangleMaskGenerator::
-FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, int width, float y, float cosa, float sina,
-                                   float centerX, float centerY)
+template<>
+template<>
+void FastRowProcessor<KisRectangleMaskGenerator>::process<Vc::CurrentImplementation::current()>(float *buffer,
+                                                                                                int width,
+                                                                                                float y,
+                                                                                                float cosa,
+                                                                                                float sina,
+                                                                                                float centerX,
+                                                                                                float centerY)
 {
     const bool useSmoothing = d->copyOfAntialiasEdges;
 
@@ -380,7 +288,7 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
     float sinay_ = sina * y_;
     float cosay_ = cosa * y_;
 
-    float* bufferPointer = buffer;
+    float *bufferPointer = buffer;
 
     Vc::float_v currentIndices = Vc::float_v::IndexesFromZero();
 
@@ -402,8 +310,7 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
     Vc::float_v vZero(Vc::Zero);
     Vc::float_v vTolerance(10000.f);
 
-    for (size_t i=0; i < static_cast<size_t>(width); i+= Vc::float_v::size()){
-
+    for (size_t i = 0; i < static_cast<size_t>(width); i += Vc::float_v::size()) {
         Vc::float_v x_ = currentIndices - vCenterX;
 
         Vc::float_v xr = Vc::abs(x_ * vCosa - vSinaY_);
@@ -448,16 +355,21 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
     }
 }
 
-
-template<> void KisGaussRectangleMaskGenerator::
-FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, int width, float y, float cosa, float sina,
-                                   float centerX, float centerY)
+template<>
+template<>
+void FastRowProcessor<KisGaussRectangleMaskGenerator>::process<Vc::CurrentImplementation::current()>(float *buffer,
+                                                                                                     int width,
+                                                                                                     float y,
+                                                                                                     float cosa,
+                                                                                                     float sina,
+                                                                                                     float centerX,
+                                                                                                     float centerY)
 {
     float y_ = y - centerY;
     float sinay_ = sina * y_;
     float cosay_ = cosa * y_;
 
-    float* bufferPointer = buffer;
+    float *bufferPointer = buffer;
 
     Vc::float_v currentIndices = Vc::float_v::IndexesFromZero();
 
@@ -489,15 +401,17 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
         Vc::float_v vValue;
 
         // check if we need to apply fader on values
-        Vc::float_m excludeMask = d->fadeMaker.needFade(xr,yr);
+        Vc::float_m excludeMask = d->fadeMaker.needFade(xr, yr);
         vValue(excludeMask) = vOne;
 
         if (!excludeMask.isFull()) {
-            Vc::float_v fullFade = vValMax - (vAlphafactor * (VcExtraMath::erf((vhalfWidth + xr) * vXFade) + VcExtraMath::erf((vhalfWidth - xr) * vXFade))
-                                        * (VcExtraMath::erf((vhalfHeight + yr) * vYFade) + VcExtraMath::erf((vhalfHeight - yr) * vYFade)));
+            Vc::float_v fullFade = vValMax
+                - (vAlphafactor
+                   * (VcExtraMath::erf((vhalfWidth + xr) * vXFade) + VcExtraMath::erf((vhalfWidth - xr) * vXFade))
+                   * (VcExtraMath::erf((vhalfHeight + yr) * vYFade) + VcExtraMath::erf((vhalfHeight - yr) * vYFade)));
 
             // apply antialias fader
-            d->fadeMaker.apply2DFader(fullFade,excludeMask,xr,yr);
+            d->fadeMaker.apply2DFader(fullFade, excludeMask, xr, yr);
 
             Vc::float_m mask;
 
@@ -517,37 +431,31 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
             vFade.store(bufferPointer, Vc::Aligned);
 
         } else {
-          vValue.store(bufferPointer, Vc::Aligned);
-      }
-      currentIndices = currentIndices + increment;
+            vValue.store(bufferPointer, Vc::Aligned);
+        }
+        currentIndices = currentIndices + increment;
 
-      bufferPointer += Vc::float_v::size();
+        bufferPointer += Vc::float_v::size();
     }
 }
 
-struct KisCurveRectangleMaskGenerator::FastRowProcessor
-{
-    FastRowProcessor(KisCurveRectangleMaskGenerator *maskGenerator)
-        : d(maskGenerator->d.data()) {}
-
-    template<Vc::Implementation _impl>
-    void process(float* buffer, int width, float y, float cosa, float sina,
-                 float centerX, float centerY);
-
-    KisCurveRectangleMaskGenerator::Private *d;
-};
-
-template<> void KisCurveRectangleMaskGenerator::
-FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, int width, float y, float cosa, float sina,
-                                   float centerX, float centerY)
+template<>
+template<>
+void FastRowProcessor<KisCurveRectangleMaskGenerator>::process<Vc::CurrentImplementation::current()>(float *buffer,
+                                                                                                     int width,
+                                                                                                     float y,
+                                                                                                     float cosa,
+                                                                                                     float sina,
+                                                                                                     float centerX,
+                                                                                                     float centerY)
 {
     float y_ = y - centerY;
     float sinay_ = sina * y_;
     float cosay_ = cosa * y_;
 
-    float* bufferPointer = buffer;
+    float *bufferPointer = buffer;
 
-    qreal* curveDataPointer = d->curveData.data();
+    qreal *curveDataPointer = d->curveData.data();
 
     Vc::float_v currentIndices = Vc::float_v::IndexesFromZero();
 
@@ -576,7 +484,7 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
         Vc::float_v vValue;
 
         // check if we need to apply fader on values
-        Vc::float_m excludeMask = d->fadeMaker.needFade(xr,yr);
+        Vc::float_m excludeMask = d->fadeMaker.needFade(xr, yr);
         vValue(excludeMask) = vOne;
 
         if (!excludeMask.isFull()) {
@@ -588,8 +496,8 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
             preSIndex(preSIndex > vOne) = vOne;
             preTIndex(preTIndex > vOne) = vOne;
 
-            Vc::float_v::IndexType sIndex( round(preSIndex * vCurveResolution));
-            Vc::float_v::IndexType tIndex( round(preTIndex * vCurveResolution));
+            Vc::float_v::IndexType sIndex(round(preSIndex * vCurveResolution));
+            Vc::float_v::IndexType tIndex(round(preTIndex * vCurveResolution));
 
             Vc::float_v::IndexType sIndexInverted = vCurveResolution - sIndex;
             Vc::float_v::IndexType tIndexInverted = vCurveResolution - tIndex;
@@ -599,11 +507,13 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
             Vc::float_v vCurvedDataSIndexInv(curveDataPointer, sIndexInverted);
             Vc::float_v vCurvedDataTIndexInv(curveDataPointer, tIndexInverted);
 
-            Vc::float_v fullFade = vValMax * (vOne - (vCurvedDataSIndex * (vOne - vCurvedDataSIndexInv) *
-                                    vCurvedDataTIndex * (vOne - vCurvedDataTIndexInv)));
+            Vc::float_v fullFade = vValMax
+                * (vOne
+                   - (vCurvedDataSIndex * (vOne - vCurvedDataSIndexInv) * vCurvedDataTIndex
+                      * (vOne - vCurvedDataTIndexInv)));
 
             // apply antialias fader
-            d->fadeMaker.apply2DFader(fullFade,excludeMask,xr,yr);
+            d->fadeMaker.apply2DFader(fullFade, excludeMask, xr, yr);
 
             Vc::float_m mask;
 
@@ -623,11 +533,11 @@ FastRowProcessor::process<Vc::CurrentImplementation::current()>(float* buffer, i
             vFade.store(bufferPointer, Vc::Aligned);
 
         } else {
-          vValue.store(bufferPointer, Vc::Aligned);
-      }
-      currentIndices = currentIndices + increment;
+            vValue.store(bufferPointer, Vc::Aligned);
+        }
+        currentIndices = currentIndices + increment;
 
-      bufferPointer += Vc::float_v::size();
+        bufferPointer += Vc::float_v::size();
     }
 }
 
diff --git a/libs/image/kis_brush_mask_scalar_applicator.h b/libs/image/kis_brush_mask_scalar_applicator.h
new file mode 100644
index 0000000000..51ca1a0656
--- /dev/null
+++ b/libs/image/kis_brush_mask_scalar_applicator.h
@@ -0,0 +1,92 @@
+/*
+ *  SPDX-FileCopyrightText: 2012 Sven Langkamp <sven.langkamp at gmail.com>
+ *  SPDX-FileCopyrightText: 2012 Dmitry Kazakov <dimula73 at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
+ *
+ *  SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef KIS_BRUSH_SCALAR_APPLICATOR_H
+#define KIS_BRUSH_SCALAR_APPLICATOR_H
+
+#include "kis_brush_mask_applicator_base.h"
+#include "kis_global.h"
+#include "kis_random_source.h"
+
+// 3x3 supersampling
+#define SUPERSAMPLING 3
+
+template<class MaskGenerator, Vc::Implementation impl>
+struct KisBrushMaskScalarApplicator : public KisBrushMaskApplicatorBase {
+    KisBrushMaskScalarApplicator(MaskGenerator *maskGenerator)
+        : m_maskGenerator(maskGenerator)
+    {
+    }
+
+    void process(const QRect &rect) override
+    {
+        processScalar(rect);
+    }
+
+protected:
+    void processScalar(const QRect &rect)
+    {
+        const MaskProcessingData *m_d = KisBrushMaskApplicatorBase::m_d;
+        MaskGenerator *m_maskGenerator = KisBrushMaskScalarApplicator<MaskGenerator, impl>::m_maskGenerator;
+
+        qreal random = 1.0;
+        quint8 *dabPointer = m_d->device->data() + rect.y() * rect.width() * m_d->pixelSize;
+        quint8 alphaValue = OPACITY_TRANSPARENT_U8;
+        // this offset is needed when brush size is smaller then fixed device size
+        int offset = (m_d->device->bounds().width() - rect.width()) * m_d->pixelSize;
+        int supersample = (m_maskGenerator->shouldSupersample() ? SUPERSAMPLING : 1);
+        double invss = 1.0 / supersample;
+        int samplearea = pow2(supersample);
+        for (int y = rect.y(); y < rect.y() + rect.height(); y++) {
+            for (int x = rect.x(); x < rect.x() + rect.width(); x++) {
+                int value = 0;
+                for (int sy = 0; sy < supersample; sy++) {
+                    for (int sx = 0; sx < supersample; sx++) {
+                        double x_ = x + sx * invss - m_d->centerX;
+                        double y_ = y + sy * invss - m_d->centerY;
+                        double maskX = m_d->cosa * x_ - m_d->sina * y_;
+                        double maskY = m_d->sina * x_ + m_d->cosa * y_;
+                        value += m_maskGenerator->valueAt(maskX, maskY);
+                    }
+                }
+                if (supersample != 1)
+                    value /= samplearea;
+
+                if (m_d->randomness != 0.0) {
+                    random = (1.0 - m_d->randomness) + m_d->randomness * m_randomSource.generateNormalized();
+                }
+
+                alphaValue = quint8((OPACITY_OPAQUE_U8 - value) * random);
+
+                // avoid computation of random numbers if density is full
+                if (m_d->density != 1.0) {
+                    // compute density only for visible pixels of the mask
+                    if (alphaValue != OPACITY_TRANSPARENT_U8) {
+                        if (!(m_d->density >= m_randomSource.generateNormalized())) {
+                            alphaValue = OPACITY_TRANSPARENT_U8;
+                        }
+                    }
+                }
+
+                if (m_d->color) {
+                    memcpy(dabPointer, m_d->color, static_cast<size_t>(m_d->pixelSize));
+                }
+
+                m_d->colorSpace->applyAlphaU8Mask(dabPointer, &alphaValue, 1);
+                dabPointer += m_d->pixelSize;
+            } // endfor x
+            dabPointer += offset;
+        } // endfor y
+    }
+
+protected:
+    MaskGenerator *m_maskGenerator;
+    KisRandomSource m_randomSource; // TODO: make it more deterministic for LoD
+};
+
+#endif /* KIS_BRUSH_SCALAR_APPLICATOR_H */
diff --git a/libs/image/kis_brush_mask_vector_applicator.h b/libs/image/kis_brush_mask_vector_applicator.h
new file mode 100644
index 0000000000..dc53a369a1
--- /dev/null
+++ b/libs/image/kis_brush_mask_vector_applicator.h
@@ -0,0 +1,143 @@
+/*
+ *  SPDX-FileCopyrightText: 2012 Sven Langkamp <sven.langkamp at gmail.com>
+ *  SPDX-FileCopyrightText: 2012 Dmitry Kazakov <dimula73 at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
+ *
+ *  SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef KIS_BRUSH_VECTOR_APPLICATOR_H
+#define KIS_BRUSH_VECTOR_APPLICATOR_H
+
+#include <config-vc.h>
+
+#if defined HAVE_VC
+
+#include <KoVcMultiArchBuildSupport.h>
+
+#include "kis_brush_mask_scalar_applicator.h"
+
+template<class V>
+struct FastRowProcessor {
+    FastRowProcessor(V *maskGenerator)
+        : d(maskGenerator->d.data())
+    {
+    }
+
+    template<Vc::Implementation _impl>
+    void process(float *buffer, int width, float y, float cosa, float sina, float centerX, float centerY);
+
+    typename V::Private *d;
+};
+
+template<class MaskGenerator, Vc::Implementation _impl>
+struct KisBrushMaskVectorApplicator : public KisBrushMaskScalarApplicator<MaskGenerator, _impl> {
+    KisBrushMaskVectorApplicator(MaskGenerator *maskGenerator)
+        : KisBrushMaskScalarApplicator<MaskGenerator, _impl>(maskGenerator)
+    {
+    }
+
+    void process(const QRect &rect) override
+    {
+        startProcessing(rect, TypeHelper<MaskGenerator, _impl>());
+    }
+
+protected:
+    void processVector(const QRect &rect);
+
+private:
+    template<class U, Vc::Implementation V>
+    struct TypeHelper {
+    };
+
+private:
+    template<class U>
+    inline void startProcessing(const QRect &rect, TypeHelper<U, Vc::ScalarImpl>)
+    {
+        KisBrushMaskScalarApplicator<MaskGenerator, _impl>::processScalar(rect);
+    }
+
+    template<class U, Vc::Implementation V>
+    inline void startProcessing(const QRect &rect, TypeHelper<U, V>)
+    {
+        MaskGenerator *m_maskGenerator = KisBrushMaskScalarApplicator<MaskGenerator, _impl>::m_maskGenerator;
+
+        if (m_maskGenerator->shouldVectorize()) {
+            processVector(rect);
+        } else {
+            KisBrushMaskScalarApplicator<MaskGenerator, _impl>::processScalar(rect);
+        }
+    }
+};
+
+template<class MaskGenerator, Vc::Implementation impl>
+void KisBrushMaskVectorApplicator<MaskGenerator, impl>::processVector(const QRect &rect)
+{
+    const MaskProcessingData *m_d = KisBrushMaskApplicatorBase::m_d;
+    MaskGenerator *m_maskGenerator = KisBrushMaskScalarApplicator<MaskGenerator, impl>::m_maskGenerator;
+
+    qreal random = 1.0;
+    quint8 *dabPointer = m_d->device->data() + rect.y() * rect.width() * m_d->pixelSize;
+    quint8 alphaValue = OPACITY_TRANSPARENT_U8;
+    // this offset is needed when brush size is smaller then fixed device size
+    int offset = (m_d->device->bounds().width() - rect.width()) * m_d->pixelSize;
+
+    int width = rect.width();
+
+    // We need to calculate with a multiple of the width of the simd register
+    size_t alignOffset = 0;
+    if (width % Vc::float_v::size() != 0) {
+        alignOffset = Vc::float_v::size() - (width % Vc::float_v::size());
+    }
+    size_t simdWidth = width + alignOffset;
+
+    float *buffer = Vc::malloc<float, Vc::AlignOnCacheline>(simdWidth);
+
+    FastRowProcessor<MaskGenerator> processor(m_maskGenerator);
+
+    for (int y = rect.y(); y < rect.y() + rect.height(); y++) {
+        processor.template process<impl>(buffer, simdWidth, y, m_d->cosa, m_d->sina, m_d->centerX, m_d->centerY);
+
+        if (m_d->randomness != 0.0 || m_d->density != 1.0) {
+            for (int x = 0; x < width; x++) {
+                if (m_d->randomness != 0.0) {
+                    random = (1.0 - m_d->randomness)
+                        + m_d->randomness
+                            * KisBrushMaskScalarApplicator<MaskGenerator, impl>::m_randomSource.generateNormalized();
+                }
+
+                alphaValue = quint8((OPACITY_OPAQUE_U8 - buffer[x] * 255) * random);
+
+                // avoid computation of random numbers if density is full
+                if (m_d->density != 1.0) {
+                    // compute density only for visible pixels of the mask
+                    if (alphaValue != OPACITY_TRANSPARENT_U8) {
+                        if (!(m_d->density >= KisBrushMaskScalarApplicator<MaskGenerator, impl>::m_randomSource
+                                                  .generateNormalized())) {
+                            alphaValue = OPACITY_TRANSPARENT_U8;
+                        }
+                    }
+                }
+
+                if (m_d->color) {
+                    memcpy(dabPointer, m_d->color, m_d->pixelSize);
+                }
+
+                m_d->colorSpace->applyAlphaU8Mask(dabPointer, &alphaValue, 1);
+                dabPointer += m_d->pixelSize;
+            }
+        } else if (m_d->color) {
+            m_d->colorSpace->fillInverseAlphaNormedFloatMaskWithColor(dabPointer, buffer, m_d->color, width);
+            dabPointer += width * m_d->pixelSize;
+        } else {
+            m_d->colorSpace->applyInverseNormedFloatMask(dabPointer, buffer, width);
+            dabPointer += width * m_d->pixelSize;
+        } // endfor x
+        dabPointer += offset;
+    } // endfor y
+    Vc::free(buffer);
+}
+
+#endif /* defined HAVE_VC */
+
+#endif /* KIS_BRUSH_VECTOR_APPLICATOR_H */
diff --git a/libs/image/kis_circle_mask_generator.cpp b/libs/image/kis_circle_mask_generator.cpp
index 242ef11120..940c362770 100644
--- a/libs/image/kis_circle_mask_generator.cpp
+++ b/libs/image/kis_circle_mask_generator.cpp
@@ -8,25 +8,6 @@
 
 #include <cmath>
 
-#include <config-vc.h>
-#ifdef HAVE_VC
-#if defined(__clang__)
-#pragma GCC diagnostic ignored "-Wundef"
-#pragma GCC diagnostic ignored "-Wlocal-type-template-args"
-#endif
-#if defined _MSC_VER
-// Lets shut up the "possible loss of data" and "forcing value to bool 'true' or 'false'
-#pragma warning ( push )
-#pragma warning ( disable : 4244 )
-#pragma warning ( disable : 4800 )
-#endif
-#include <Vc/Vc>
-#include <Vc/IO>
-#if defined _MSC_VER
-#pragma warning ( pop )
-#endif
-#endif
-
 #include <QDomDocument>
 
 #include "kis_fast_math.h"
@@ -46,14 +27,14 @@ KisCircleMaskGenerator::KisCircleMaskGenerator(qreal diameter, qreal ratio, qrea
     // store the variable locally to allow vector implementation read it easily
     d->copyOfAntialiasEdges = antialiasEdges;
 
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCircleMaskGenerator> >(this));
 }
 
 KisCircleMaskGenerator::KisCircleMaskGenerator(const KisCircleMaskGenerator &rhs)
     : KisMaskGenerator(rhs),
       d(new Private(*rhs.d))
 {
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCircleMaskGenerator> >(this));
 }
 
 KisMaskGenerator* KisCircleMaskGenerator::clone() const
@@ -121,5 +102,5 @@ void KisCircleMaskGenerator::setSoftness(qreal softness)
 
 void KisCircleMaskGenerator::resetMaskApplicator(bool forceScalar)
 {
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this,forceScalar));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCircleMaskGenerator> >(this,forceScalar));
 }
diff --git a/libs/image/kis_circle_mask_generator.h b/libs/image/kis_circle_mask_generator.h
index 4d93fc5194..fa55bcdecb 100644
--- a/libs/image/kis_circle_mask_generator.h
+++ b/libs/image/kis_circle_mask_generator.h
@@ -1,5 +1,6 @@
 /*
  *  SPDX-FileCopyrightText: 2008-2009 Cyrille Berger <cberger at cberger.net>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -9,17 +10,17 @@
 
 #include "kritaimage_export.h"
 
-#include "kis_mask_generator.h"
+#include "kis_base_mask_generator.h"
 #include <QScopedPointer>
 
+template <typename V>
+class FastRowProcessor;
 
 /**
  * Create, serialize and deserialize an elliptical 8-bit mask.
  */
 class KRITAIMAGE_EXPORT KisCircleMaskGenerator : public KisMaskGenerator
 {
-public:
-    struct FastRowProcessor;
 public:
     KisCircleMaskGenerator(qreal radius, qreal ratio, qreal fh, qreal fv, int spikes, bool antialiasEdges);
     KisCircleMaskGenerator(const KisCircleMaskGenerator &rhs);
@@ -46,6 +47,8 @@ private:
 private:
     struct Private;
     const QScopedPointer<Private> d;
+
+    friend class FastRowProcessor<KisCircleMaskGenerator>;
 };
 
 #endif
diff --git a/libs/image/kis_curve_circle_mask_generator.cpp b/libs/image/kis_curve_circle_mask_generator.cpp
index 787ce89129..b41960740d 100644
--- a/libs/image/kis_curve_circle_mask_generator.cpp
+++ b/libs/image/kis_curve_circle_mask_generator.cpp
@@ -4,37 +4,14 @@
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#include <compositeops/KoVcMultiArchBuildSupport.h> //MSVC requires that Vc come first
 #include <cmath>
 
-#include <config-vc.h>
-#ifdef HAVE_VC
-#if defined(__clang__)
-#pragma GCC diagnostic ignored "-Wundef"
-#pragma GCC diagnostic ignored "-Wlocal-type-template-args"
-#endif
-#if defined _MSC_VER
-// Lets shut up the "possible loss of data" and "forcing value to bool 'true' or 'false'
-#pragma warning ( push )
-#pragma warning ( disable : 4244 )
-#pragma warning ( disable : 4800 )
-#endif
-#include <Vc/Vc>
-#include <Vc/IO>
-#if defined _MSC_VER
-#pragma warning ( pop )
-#endif
-#endif
-
 #include <QDomDocument>
 #include <QVector>
 #include <QPointF>
 
 #include <KoColorSpaceConstants.h>
 
-#include "kis_fast_math.h"
-
-#include "kis_base_mask_generator.h"
 #include "kis_antialiasing_fade_maker.h"
 #include "kis_brush_mask_applicator_factories.h"
 
@@ -55,14 +32,14 @@ KisCurveCircleMaskGenerator::KisCurveCircleMaskGenerator(qreal diameter, qreal r
 
     setScale(1.0, 1.0);
 
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCurveCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCurveCircleMaskGenerator> >(this));
 }
 
 KisCurveCircleMaskGenerator::KisCurveCircleMaskGenerator(const KisCurveCircleMaskGenerator &rhs)
     : KisMaskGenerator(rhs),
       d(new Private(*rhs.d))
 {
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCurveCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCurveCircleMaskGenerator> >(this));
 }
 
 KisCurveCircleMaskGenerator::~KisCurveCircleMaskGenerator()
@@ -171,5 +148,5 @@ void KisCurveCircleMaskGenerator::transformCurveForSoftness(qreal softness,const
 
 void KisCurveCircleMaskGenerator::resetMaskApplicator(bool forceScalar)
 {
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCurveCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this,forceScalar));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCurveCircleMaskGenerator> >(this,forceScalar));
 }
diff --git a/libs/image/kis_curve_circle_mask_generator.h b/libs/image/kis_curve_circle_mask_generator.h
index 7e58497294..205d76e7ca 100644
--- a/libs/image/kis_curve_circle_mask_generator.h
+++ b/libs/image/kis_curve_circle_mask_generator.h
@@ -1,5 +1,6 @@
 /*
  *  SPDX-FileCopyrightText: 2010 Lukáš Tvrdý <lukast.dev at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -12,7 +13,7 @@
 #include <QScopedPointer>
 
 #include "kritaimage_export.h"
-#include "kis_mask_generator.h"
+#include "kis_base_mask_generator.h"
 
 class KisCubicCurve;
 class QDomElement;
@@ -20,6 +21,8 @@ class QDomDocument;
 
 class QPointF;
 
+template<typename V>
+class FastRowProcessor;
 
 /**
  * This mask generator use softness/hardness defined by user curve
@@ -27,8 +30,6 @@ class QPointF;
  */
 class KRITAIMAGE_EXPORT KisCurveCircleMaskGenerator : public KisMaskGenerator
 {
-public:
-    struct FastRowProcessor;
 public:
 
     KisCurveCircleMaskGenerator(qreal radius, qreal ratio, qreal fh, qreal fv, int spikes,const KisCubicCurve& curve, bool antialiasEdges);
@@ -59,6 +60,8 @@ private:
 private:
     struct Private;
     const QScopedPointer<Private> d;
+
+    friend class FastRowProcessor<KisCurveCircleMaskGenerator>;
 };
 
 #endif
diff --git a/libs/image/kis_curve_rect_mask_generator.cpp b/libs/image/kis_curve_rect_mask_generator.cpp
index c02d12a206..f374326c22 100644
--- a/libs/image/kis_curve_rect_mask_generator.cpp
+++ b/libs/image/kis_curve_rect_mask_generator.cpp
@@ -4,29 +4,8 @@
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#include <compositeops/KoVcMultiArchBuildSupport.h> //MSVC requires that Vc come first
-
 #include <cmath>
 
-#include <config-vc.h>
-#ifdef HAVE_VC
-#if defined(__clang__)
-#pragma GCC diagnostic ignored "-Wundef"
-#pragma GCC diagnostic ignored "-Wlocal-type-template-args"
-#endif
-#if defined _MSC_VER
-// Lets shut up the "possible loss of data" and "forcing value to bool 'true' or 'false'
-#pragma warning ( push )
-#pragma warning ( disable : 4244 )
-#pragma warning ( disable : 4800 )
-#endif
-#include <Vc/Vc>
-#include <Vc/IO>
-#if defined _MSC_VER
-#pragma warning ( pop )
-#endif
-#endif
-
 #include <QDomDocument>
 #include <QVector>
 #include <QPointF>
@@ -38,6 +17,7 @@
 
 #include "kis_curve_rect_mask_generator.h"
 #include "kis_curve_rect_mask_generator_p.h"
+#include "kis_curve_circle_mask_generator.h"
 #include "kis_cubic_curve.h"
 
 
@@ -52,14 +32,14 @@ KisCurveRectangleMaskGenerator::KisCurveRectangleMaskGenerator(qreal diameter, q
 
     setScale(1.0, 1.0);
 
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCurveRectangleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCurveRectangleMaskGenerator>>(this));
 }
 
 KisCurveRectangleMaskGenerator::KisCurveRectangleMaskGenerator(const KisCurveRectangleMaskGenerator &rhs)
     : KisMaskGenerator(rhs),
       d(new Private(*rhs.d))
 {
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCurveRectangleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCurveRectangleMaskGenerator>>(this));
 }
 
 KisMaskGenerator* KisCurveRectangleMaskGenerator::clone() const
@@ -144,6 +124,6 @@ KisBrushMaskApplicatorBase* KisCurveRectangleMaskGenerator::applicator()
 
 void KisCurveRectangleMaskGenerator::resetMaskApplicator(bool forceScalar)
 {
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCurveRectangleMaskGenerator, KisBrushMaskVectorApplicator> >(this,forceScalar));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCurveRectangleMaskGenerator>>(this,forceScalar));
 }
 
diff --git a/libs/image/kis_curve_rect_mask_generator.h b/libs/image/kis_curve_rect_mask_generator.h
index 3d613032ed..4f05d63b54 100644
--- a/libs/image/kis_curve_rect_mask_generator.h
+++ b/libs/image/kis_curve_rect_mask_generator.h
@@ -1,5 +1,6 @@
 /*
  *  SPDX-FileCopyrightText: 2010 Lukáš Tvrdý <lukast.dev at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -13,15 +14,16 @@ class KisCubicCurve;
 class QDomElement;
 class QDomDocument;
 
-#include "kis_mask_generator.h"
+#include "kis_base_mask_generator.h"
+
+template<typename V>
+class FastRowProcessor;
 
 /**
  * Curve based softness for this rectangular mask generator
  */
 class KRITAIMAGE_EXPORT KisCurveRectangleMaskGenerator : public KisMaskGenerator
 {
-public:
-    struct FastRowProcessor;
 public:
 
     KisCurveRectangleMaskGenerator(qreal radius, qreal ratio, qreal fh, qreal fv, int spikes, const KisCubicCurve& curve, bool antialiasEdges);
@@ -44,6 +46,8 @@ public:
 private:
     struct Private;
     const QScopedPointer<Private> d;
+
+    friend class FastRowProcessor<KisCurveRectangleMaskGenerator>;
 };
 
 #endif
diff --git a/libs/image/kis_gauss_circle_mask_generator.cpp b/libs/image/kis_gauss_circle_mask_generator.cpp
index 476413088f..fbd5bf07ae 100644
--- a/libs/image/kis_gauss_circle_mask_generator.cpp
+++ b/libs/image/kis_gauss_circle_mask_generator.cpp
@@ -5,28 +5,8 @@
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#include <compositeops/KoVcMultiArchBuildSupport.h> //MSVC requires that Vc come first
 #include <cmath>
 
-#include <config-vc.h>
-#ifdef HAVE_VC
-#if defined(__clang__)
-#pragma GCC diagnostic ignored "-Wundef"
-#pragma GCC diagnostic ignored "-Wlocal-type-template-args"
-#endif
-#if defined _MSC_VER
-// Lets shut up the "possible loss of data" and "forcing value to bool 'true' or 'false'
-#pragma warning ( push )
-#pragma warning ( disable : 4244 )
-#pragma warning ( disable : 4800 )
-#endif
-#include <Vc/Vc>
-#include <Vc/IO>
-#if defined _MSC_VER
-#pragma warning ( pop )
-#endif
-#endif
-
 #include <QDomDocument>
 #include <QVector>
 #include <QPointF>
@@ -64,7 +44,7 @@ KisGaussCircleMaskGenerator::KisGaussCircleMaskGenerator(qreal diameter, qreal r
     d->center = (2.5 * (6761.0*d->fade-10000.0))/(M_SQRT_2*6761.0*d->fade);
     d->alphafactor = 255.0 / (2.0 * erf(d->center));
 
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussCircleMaskGenerator>>(this));
 
 }
 
@@ -72,7 +52,7 @@ KisGaussCircleMaskGenerator::KisGaussCircleMaskGenerator(const KisGaussCircleMas
     : KisMaskGenerator(rhs),
       d(new Private(*rhs.d))
 {
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussCircleMaskGenerator>>(this));
 }
 
 KisMaskGenerator* KisGaussCircleMaskGenerator::clone() const
@@ -129,5 +109,5 @@ quint8 KisGaussCircleMaskGenerator::valueAt(qreal x, qreal y) const
 
 void KisGaussCircleMaskGenerator::resetMaskApplicator(bool forceScalar)
 {
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this,forceScalar));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussCircleMaskGenerator>>(this,forceScalar));
 }
diff --git a/libs/image/kis_gauss_circle_mask_generator.h b/libs/image/kis_gauss_circle_mask_generator.h
index 604ad64ab3..ab431e81a6 100644
--- a/libs/image/kis_gauss_circle_mask_generator.h
+++ b/libs/image/kis_gauss_circle_mask_generator.h
@@ -1,6 +1,7 @@
 /*
  *  SPDX-FileCopyrightText: 2010 Lukáš Tvrdý <lukast.dev at gmail.com>
  *  SPDX-FileCopyrightText: 2011 Geoffry Song <goffrie at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -10,18 +11,18 @@
 
 #include "kritaimage_export.h"
 
-#include "kis_mask_generator.h"
+#include "kis_base_mask_generator.h"
 #include <QScopedPointer>
 
+template<typename V>
+class FastRowProcessor;
+
 /**
  * This mask generator uses a Gaussian-blurred circle
  */
 class KRITAIMAGE_EXPORT KisGaussCircleMaskGenerator : public KisMaskGenerator
 {
 public:
-    struct FastRowProcessor;
-public:
-
     KisGaussCircleMaskGenerator(qreal diameter, qreal ratio, qreal fh, qreal fv, int spikes, bool antialiasEdges);
     KisGaussCircleMaskGenerator(const KisGaussCircleMaskGenerator &rhs);
     ~KisGaussCircleMaskGenerator() override;
@@ -45,6 +46,8 @@ private:
 private:
     struct Private;
     const QScopedPointer<Private> d;
+
+    friend class FastRowProcessor<KisGaussCircleMaskGenerator>;
 };
 
 #endif
diff --git a/libs/image/kis_gauss_rect_mask_generator.cpp b/libs/image/kis_gauss_rect_mask_generator.cpp
index d5c6bb8aa1..80676cd82f 100644
--- a/libs/image/kis_gauss_rect_mask_generator.cpp
+++ b/libs/image/kis_gauss_rect_mask_generator.cpp
@@ -1,32 +1,14 @@
 /*
  *  SPDX-FileCopyrightText: 2010 Lukáš Tvrdý <lukast.dev at gmail.com>
  *  SPDX-FileCopyrightText: 2011 Geoffry Song <goffrie at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#include <compositeops/KoVcMultiArchBuildSupport.h> //MSVC requires that Vc come first
 #include <cmath>
 #include <algorithm>
 
-#include <config-vc.h>
-#ifdef HAVE_VC
-#if defined(__clang__)
-#pragma GCC diagnostic ignored "-Wundef"
-#pragma GCC diagnostic ignored "-Wlocal-type-template-args"
-#endif
-#if defined _MSC_VER
-// Lets shut up the "possible loss of data" and "forcing value to bool 'true' or 'false'
-#pragma warning ( push )
-#pragma warning ( disable : 4244 )
-#pragma warning ( disable : 4800 )
-#endif
-#include <Vc/Vc>
-#include <Vc/IO>
-#if defined _MSC_VER
-#pragma warning ( pop )
-#endif
-#endif
 
 #include <QDomDocument>
 #include <QVector>
@@ -58,14 +40,14 @@ KisGaussRectangleMaskGenerator::KisGaussRectangleMaskGenerator(qreal diameter, q
 {
     setScale(1.0, 1.0);
 
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussRectangleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussRectangleMaskGenerator>>(this));
 }
 
 KisGaussRectangleMaskGenerator::KisGaussRectangleMaskGenerator(const KisGaussRectangleMaskGenerator &rhs)
     : KisMaskGenerator(rhs),
       d(new Private(*rhs.d))
 {
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussRectangleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussRectangleMaskGenerator>>(this));
 }
 
 KisMaskGenerator* KisGaussRectangleMaskGenerator::clone() const
@@ -130,5 +112,5 @@ KisBrushMaskApplicatorBase* KisGaussRectangleMaskGenerator::applicator()
 
 void KisGaussRectangleMaskGenerator::resetMaskApplicator(bool forceScalar)
 {
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussRectangleMaskGenerator, KisBrushMaskVectorApplicator> >(this,forceScalar));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussRectangleMaskGenerator>>(this,forceScalar));
 }
diff --git a/libs/image/kis_gauss_rect_mask_generator.h b/libs/image/kis_gauss_rect_mask_generator.h
index ce96a5091f..1594e80f48 100644
--- a/libs/image/kis_gauss_rect_mask_generator.h
+++ b/libs/image/kis_gauss_rect_mask_generator.h
@@ -1,6 +1,7 @@
 /*
  *  SPDX-FileCopyrightText: 2010 Lukáš Tvrdý <lukast.dev at gmail.com>
  *  SPDX-FileCopyrightText: 2011 Geoffry Song <goffrie at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -10,15 +11,16 @@
 
 #include "kritaimage_export.h"
 
-#include "kis_mask_generator.h"
+#include "kis_base_mask_generator.h"
+
+template<typename V>
+class FastRowProcessor;
 
 /**
  * This mask generator uses a Gaussian-blurred rectangle
  */
 class KRITAIMAGE_EXPORT KisGaussRectangleMaskGenerator : public KisMaskGenerator
 {
-public:
-    struct FastRowProcessor;
 public:
 
     KisGaussRectangleMaskGenerator(qreal diameter, qreal ratio, qreal fh, qreal fv, int spikes, bool antialiasEdges);
@@ -36,6 +38,8 @@ public:
 private:
     struct Private;
     const QScopedPointer<Private> d;
+
+    friend class FastRowProcessor<KisGaussRectangleMaskGenerator>;
 };
 
 #endif
diff --git a/libs/image/kis_rect_mask_generator.cpp b/libs/image/kis_rect_mask_generator.cpp
index c26832d318..f9cf0822ec 100644
--- a/libs/image/kis_rect_mask_generator.cpp
+++ b/libs/image/kis_rect_mask_generator.cpp
@@ -1,32 +1,13 @@
 /*
  *  SPDX-FileCopyrightText: 2004, 2007-2010 Cyrille Berger <cberger at cberger.net>
  *  SPDX-FileCopyrightText: 2018 Ivan Santa Maria <ghevan at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#include <compositeops/KoVcMultiArchBuildSupport.h> //MSVC requires that Vc come first
 #include <cmath>
 
-#include <config-vc.h>
-#ifdef HAVE_VC
-#if defined(__clang__)
-#pragma GCC diagnostic ignored "-Wundef"
-#pragma GCC diagnostic ignored "-Wlocal-type-template-args"
-#endif
-#if defined _MSC_VER
-// Lets shut up the "possible loss of data" and "forcing value to bool 'true' or 'false'
-#pragma warning ( push )
-#pragma warning ( disable : 4244 )
-#pragma warning ( disable : 4800 )
-#endif
-#include <Vc/Vc>
-#include <Vc/IO>
-#if defined _MSC_VER
-#pragma warning ( pop )
-#endif
-#endif
-
 
 #include <QDomDocument>
 
@@ -47,14 +28,14 @@ KisRectangleMaskGenerator::KisRectangleMaskGenerator(qreal radius, qreal ratio,
 
     // store the variable locally to allow vector implementation read it easily
     d->copyOfAntialiasEdges = antialiasEdges;
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisRectangleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisRectangleMaskGenerator>>(this));
 }
 
 KisRectangleMaskGenerator::KisRectangleMaskGenerator(const KisRectangleMaskGenerator &rhs)
     : KisMaskGenerator(rhs),
       d(new Private(*rhs.d))
 {
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisRectangleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisRectangleMaskGenerator>>(this));
 }
 
 KisMaskGenerator* KisRectangleMaskGenerator::clone() const
@@ -99,7 +80,7 @@ KisBrushMaskApplicatorBase* KisRectangleMaskGenerator::applicator()
 
 void KisRectangleMaskGenerator::resetMaskApplicator(bool forceScalar)
 {
-    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisRectangleMaskGenerator, KisBrushMaskVectorApplicator> >(this,forceScalar));
+    d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisRectangleMaskGenerator>>(this,forceScalar));
 }
 
 quint8 KisRectangleMaskGenerator::valueAt(qreal x, qreal y) const
diff --git a/libs/image/kis_rect_mask_generator.h b/libs/image/kis_rect_mask_generator.h
index 84fe295acc..01b8210994 100644
--- a/libs/image/kis_rect_mask_generator.h
+++ b/libs/image/kis_rect_mask_generator.h
@@ -1,6 +1,7 @@
 /*
  *  SPDX-FileCopyrightText: 2008-2009 Cyrille Berger <cberger at cberger.net>
  *  SPDX-FileCopyrightText: 2018 Ivan Santa Maria <ghevan at gmail.com>
+ *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy at amyspark.me>
  *
  *  SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -8,18 +9,20 @@
 #ifndef _KIS_RECT_MASK_GENERATOR_H_
 #define _KIS_RECT_MASK_GENERATOR_H_
 
-#include <QScopedPointer>
 #include "kritaimage_export.h"
 
-#include "kis_mask_generator.h"
+#include <QScopedPointer>
+
+#include "kis_base_mask_generator.h"
+
+template<typename V>
+class FastRowProcessor;
 
 /**
  * Represent, serialize and deserialize a rectangular 8-bit mask.
  */
 class KRITAIMAGE_EXPORT KisRectangleMaskGenerator : public KisMaskGenerator
 {
-public:
-    struct FastRowProcessor;
 public:
 
     KisRectangleMaskGenerator(qreal radius, qreal ratio, qreal fh, qreal fv, int spikes, bool antialiasEdges);
@@ -39,6 +42,8 @@ public:
 private:
     struct Private;
     const QScopedPointer<Private> d;
+
+    friend class FastRowProcessor<KisRectangleMaskGenerator>;
 };
 
 #endif


More information about the kimageshop mailing list