Commit a27c392d authored by Boudewijn Rempt's avatar Boudewijn Rempt

Merge remote-tracking branch 'origin' into rempt/T379-resource-management

parents a7b2232a 006d9da9
......@@ -207,6 +207,7 @@ endif (ENABLE_PYTHON_DEPS OR NOT MINGW)
if (MSVC OR MINGW)
add_subdirectory( ext_drmingw )
add_subdirectory( ext_ffmpeg )
endif (MSVC OR MINGW)
if (NOT APPLE)
......
SET(PREFIX_ext_ffmpeg "${EXTPREFIX}" )
if(MSVC OR MINGW)
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
ExternalProject_Add( ext_ffmpeg
DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
URL https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-4.0-win64-static.zip
URL_MD5 bf496481c6991c529e2e94a8e0fa3113
INSTALL_DIR ${PREFIX_ext_ffmpeg}
CONFIGURE_COMMAND ""
BUILD_COMMAND ${CMAKE_COMMAND} -E echo deploying ffmpeg3 64-bit binary
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy <SOURCE_DIR>/bin/ffmpeg.exe ${PREFIX_ext_ffmpeg}/bin/ffmpeg.exe
COMMAND ${CMAKE_COMMAND} -E copy <SOURCE_DIR>/LICENSE.txt ${PREFIX_ext_ffmpeg}/bin/ffmpeg_LICENSE.txt
COMMAND ${CMAKE_COMMAND} -E copy <SOURCE_DIR>/README.txt ${PREFIX_ext_ffmpeg}/bin/ffmpeg_README.txt
UPDATE_COMMAND ""
)
else("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
ExternalProject_Add( ext_ffmpeg
DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
URL https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-4.0-win32-static.zip
URL_MD5 a969a969e3404fe35100e85a37186e5f
INSTALL_DIR ${PREFIX_ext_ffmpeg}
CONFIGURE_COMMAND ""
BUILD_COMMAND ${CMAKE_COMMAND} -E echo deploying ffmpeg3 32-bit binary
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy <SOURCE_DIR>/bin/ffmpeg.exe ${PREFIX_ext_ffmpeg}/bin/ffmpeg.exe
COMMAND ${CMAKE_COMMAND} -E copy <SOURCE_DIR>/LICENSE.txt ${PREFIX_ext_ffmpeg}/bin/ffmpeg_LICENSE.txt
COMMAND ${CMAKE_COMMAND} -E copy <SOURCE_DIR>/README.txt ${PREFIX_ext_ffmpeg}/bin/ffmpeg_README.txt
UPDATE_COMMAND ""
)
endif("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
endif()
......@@ -3,8 +3,8 @@ SET(PREFIX_ext_gmic "${EXTPREFIX}" )
# Download the gmic sources
ExternalProject_Add( ext_gmic_base
DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
URL https://gmic.eu/files/source/gmic_2.2.0.tar.gz
URL_HASH SHA1=caf72b80da8bd3e31111cff8407b005e7115d2c2
URL https://gmic.eu/files/source/gmic_2.2.3.tar.gz
URL_HASH SHA1=43f975a462a842be5eeff70d8d372476547163b0
SOURCE_DIR gmic
......@@ -19,8 +19,8 @@ ExternalProject_Add( ext_gmic_base
# FIXME: Forcing CMAKE_BUILD_TYPE to Release
ExternalProject_Add( ext_gmic_qt
DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
URL https://github.com/c-koi/gmic-qt/archive/v.220.tar.gz
URL_HASH SHA1=2b3731e7c90c79d298758b7702a68c1468035429
URL https://github.com/c-koi/gmic-qt/archive/v.2.2.3.tar.gz
URL_HASH SHA1=a3c889de09031d34754c9bb3bd1004a2f67713c6
PATCH_COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/desktop_icon.diff
SOURCE_DIR gmic-qt
......
......@@ -5,12 +5,8 @@ message(STATUS "Using CMake version: ${CMAKE_VERSION}")
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
set(MIN_QT_VERSION 5.6.0)
option(OVERRIDE_QT_VERSION "Use this to make it possible to build with Qt < 5.6.0. There will be bugs." OFF)
if (OVERRIDE_QT_VERSION)
set(MIN_QT_VERSION 5.4.0)
endif()
set(MIN_FRAMEWORKS_VERSION 5.22.0)
set(MIN_FRAMEWORKS_VERSION 5.18.0)
if (POLICY CMP0002)
cmake_policy(SET CMP0002 OLD)
......
......@@ -707,7 +707,7 @@ echo.
set EXT_TARGETS=patch png2ico gettext qt zlib boost eigen3 exiv2 fftw3 ilmbase
set EXT_TARGETS=%EXT_TARGETS% jpeg lcms2 ocio openexr png tiff gsl vc libraw
set EXT_TARGETS=%EXT_TARGETS% giflib freetype poppler kwindowsystem drmingw gmic
set EXT_TARGETS=%EXT_TARGETS% python sip pyqt
set EXT_TARGETS=%EXT_TARGETS% python sip pyqt ffmpeg
for %%a in (%EXT_TARGETS%) do (
echo Building ext_%%a...
......
########### next target ###############
set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
include_directories(
${CMAKE_SOURCE_DIR}/libs/image/metadata
${CMAKE_SOURCE_DIR}/sdk/tests
include_directories(
${CMAKE_SOURCE_DIR}/libs/image/metadata
${CMAKE_SOURCE_DIR}/sdk/tests
)
include_directories(SYSTEM
${EIGEN3_INCLUDE_DIR}
......@@ -28,4 +28,3 @@ ecm_add_tests(
NAME_PREFIX "krita-libbrush-"
LINK_LIBRARIES kritaimage kritalibbrush Qt5::Test
)
......@@ -83,6 +83,22 @@ public:
return false;
}
qreal getRadius(){
return m_radius;
}
qreal getAntialiasingFadeStart(){
return m_antialiasingFadeStart;
}
qreal getFadeStartValue() {
return m_fadeStartValue;
}
qreal getAntialiasingFadeCoeff(){
return m_antialiasingFadeCoeff;
}
private:
qreal m_radius;
quint8 m_fadeStartValue;
......
......@@ -20,6 +20,7 @@
#include "kis_circle_mask_generator.h"
#include "kis_circle_mask_generator_p.h"
#include "kis_gauss_circle_mask_generator_p.h"
#include "kis_brush_mask_applicators.h"
#include "kis_brush_mask_applicator_base.h"
......@@ -42,6 +43,14 @@ MaskApplicatorFactory<KisCircleMaskGenerator, KisBrushMaskVectorApplicator>::cre
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);
}
#if defined HAVE_VC
struct KisCircleMaskGenerator::FastRowProcessor
......@@ -134,4 +143,105 @@ 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)
{
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 vCenter(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(d->ycoef);
Vc::float_v vDistfactor(d->distfactor);
Vc::float_v vAlphafactor(d->alphafactor);
Vc::float_v vFadeRadius(d->fadeMaker.getRadius());
Vc::float_v vFadeStartValue(d->fadeMaker.getFadeStartValue());
Vc::float_v vFadeAFadeStart(d->fadeMaker.getAntialiasingFadeStart());
Vc::float_v vFadeAFadeCoeff(d->fadeMaker.getAntialiasingFadeCoeff());
Vc::float_v vOne(Vc::One);
Vc::float_v vZero(Vc::Zero);
Vc::float_v vValMax(255.f);
for (int i=0; i < 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));
// BEGIN FadeMaker needFade vectorized
// follow fademaker rules for outsideMask
Vc::float_m outsideMask = dist > vFadeRadius;
dist(outsideMask) = vOne;
Vc::float_m fadeStartMask = dist > vFadeAFadeStart;
dist((outsideMask ^ fadeStartMask) & fadeStartMask) = (vFadeStartValue + (dist - vFadeAFadeStart) * vFadeAFadeCoeff) / vValMax;
Vc::float_m excludeMask = outsideMask | fadeStartMask;
if (!excludeMask.isFull()) {
Vc::float_v valDist = dist * vDistfactor;
Vc::float_v fullFade = vAlphafactor * ( d->vErf(valDist + vCenter) - d->vErf(valDist - vCenter));
Vc::float_m mask;
// Mask in the inner circe of the mask
mask = fullFade < vZero;
fullFade.setZero(mask);
// Mask (value - value), presicion errors.
mask = fullFade >= vValMax;
Vc::float_v vFade = (vValMax - fullFade) / vValMax;
vFade(mask) = vZero;
// filter nan and inf. Vc uses float, imprecission errors are frequent
mask = Vc::isfinite(vFade);
vFade(!mask) = vOne;
// Mask the inner circe of the mask
mask = vFade < vZero;
vFade(mask) = vZero;
// 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();
}
}
#endif /* defined HAVE_VC */
......@@ -139,3 +139,8 @@ void KisCircleMaskGenerator::setSoftness(qreal softness)
d->transformedFadeX = d->xfadecoef * safeSoftnessCoeff;
d->transformedFadeY = d->yfadecoef * safeSoftnessCoeff;
}
void KisCircleMaskGenerator::resetMaskApplicator(bool forceScalar)
{
d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this,forceScalar));
}
......@@ -49,6 +49,8 @@ public:
void setSoftness(qreal softness) override;
void setScale(qreal scaleX, qreal scaleY) override;
void resetMaskApplicator(bool forceScalar);
private:
qreal norme(qreal a, qreal b) const {
......
......@@ -20,6 +20,25 @@
#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>
......@@ -29,8 +48,11 @@
#include "kis_fast_math.h"
#include "kis_base_mask_generator.h"
#include "kis_gauss_circle_mask_generator.h"
#include "kis_antialiasing_fade_maker.h"
#include "kis_brush_mask_applicator_factories.h"
#include "kis_brush_mask_applicator_base.h"
#include "kis_gauss_circle_mask_generator.h"
#include "kis_gauss_circle_mask_generator_p.h"
#define M_SQRT_2 1.41421356237309504880
......@@ -41,47 +63,28 @@
#endif
struct Q_DECL_HIDDEN KisGaussCircleMaskGenerator::Private
{
Private(bool enableAntialiasing)
: fadeMaker(*this, enableAntialiasing)
{
}
Private(const Private &rhs)
: ycoef(rhs.ycoef),
fade(rhs.fade),
center(rhs.center),
distfactor(rhs.distfactor),
alphafactor(rhs.alphafactor),
fadeMaker(rhs.fadeMaker, *this)
{
}
qreal ycoef;
qreal fade;
qreal center, distfactor, alphafactor;
KisAntialiasingFadeMaker1D<Private> fadeMaker;
inline quint8 value(qreal dist) const;
};
KisGaussCircleMaskGenerator::KisGaussCircleMaskGenerator(qreal diameter, qreal ratio, qreal fh, qreal fv, int spikes, bool antialiasEdges)
: KisMaskGenerator(diameter, ratio, fh, fv, spikes, antialiasEdges, CIRCLE, GaussId),
d(new Private(antialiasEdges))
{
d->ycoef = 1.0 / ratio;
d->fade = 1.0 - (fh + fv) / 2.0;
if (d->fade == 0.0) d->fade = 1e-6;
else if (d->fade == 1.0) d->fade = 1.0 - 1e-6; // would become undefined for fade == 0 or 1
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));
}
KisGaussCircleMaskGenerator::KisGaussCircleMaskGenerator(const KisGaussCircleMaskGenerator &rhs)
: KisMaskGenerator(rhs),
d(new Private(*rhs.d))
{
d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this));
}
KisMaskGenerator* KisGaussCircleMaskGenerator::clone() const
......@@ -109,6 +112,21 @@ inline quint8 KisGaussCircleMaskGenerator::Private::value(qreal dist) const
return (quint8) 255 - ret;
}
bool KisGaussCircleMaskGenerator::shouldSupersample() const
{
return effectiveSrcWidth() < 10 || effectiveSrcHeight() < 10;
}
bool KisGaussCircleMaskGenerator::shouldVectorize() const
{
return !shouldSupersample() && spikes() == 2;
}
KisBrushMaskApplicatorBase* KisGaussCircleMaskGenerator::applicator()
{
return d->applicator.data();
}
quint8 KisGaussCircleMaskGenerator::valueAt(qreal x, qreal y) const
{
if (isEmpty()) return 255;
......@@ -125,3 +143,8 @@ quint8 KisGaussCircleMaskGenerator::valueAt(qreal x, qreal y) const
return d->value(dist);
}
void KisGaussCircleMaskGenerator::resetMaskApplicator(bool forceScalar)
{
d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisGaussCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this,forceScalar));
}
......@@ -20,16 +20,18 @@
#ifndef _KIS_GAUSS_MASK_GENERATOR_H_
#define _KIS_GAUSS_MASK_GENERATOR_H_
#include <QScopedPointer>
#include "kritaimage_export.h"
#include "kis_mask_generator.h"
#include <QScopedPointer>
/**
* 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);
......@@ -41,6 +43,13 @@ public:
void setScale(qreal scaleX, qreal scaleY) override;
bool shouldSupersample() const override;
bool shouldVectorize() const override;
KisBrushMaskApplicatorBase* applicator() override;
void resetMaskApplicator(bool forceScalar);
private:
qreal norme(qreal a, qreal b) const {
......
/*
* Copyright (c) 2008-2009 Cyrille Berger <cberger@cberger.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _KIS_GAUSS_MASK_GENERATOR_P_H_
#define _KIS_GAUSS_MASK_GENERATOR_P_H_
#include "kis_antialiasing_fade_maker.h"
struct Q_DECL_HIDDEN KisGaussCircleMaskGenerator::Private
{
Private(bool enableAntialiasing)
: fadeMaker(*this, enableAntialiasing)
{
}
Private(const Private &rhs)
: ycoef(rhs.ycoef),
fade(rhs.fade),
center(rhs.center),
distfactor(rhs.distfactor),
alphafactor(rhs.alphafactor),
fadeMaker(rhs.fadeMaker, *this)
{
}
qreal ycoef;
qreal fade;
qreal center;
qreal distfactor;
qreal alphafactor;
KisAntialiasingFadeMaker1D<Private> fadeMaker;
QScopedPointer<KisBrushMaskApplicatorBase> applicator;
inline quint8 value(qreal dist) const;
#if defined HAVE_VC
// vectorized erf function, precision 1e-5
Vc::float_v vErf(Vc::float_v x) {
Vc::float_v xa = abs(x);
Vc::float_v sign(Vc::One);
Vc::float_m invertMask = x < 0.f;
sign(invertMask) = -1.f;
// CONSTANTS
float a1 = 0.254829592;
float a2 = -0.284496736;
float a3 = 1.421413741;
float a4 = -1.453152027;
float a5 = 1.061405429;
float p = 0.3275911;
Vc::float_v t = 1.0f / (1.0f + p * xa);
Vc::float_v y = 1.0f - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * exp(-xa * xa);
return sign * y;
}
#endif /* defined HAVE_VC */
};
#endif /* _KIS_GAUSS_MASK_GENERATOR_P_H_ */
......@@ -53,6 +53,7 @@
#include "kis_meta_data_merge_strategy_registry.h"
#include "kis_name_server.h"
#include "kis_paint_layer.h"
#include "kis_projection_leaf.h"
#include "kis_painter.h"
#include "kis_selection.h"
#include "kis_transaction.h"
......@@ -1313,11 +1314,15 @@ bool KisImage::startIsolatedMode(KisNodeSP node)
m_node(node),
m_image(image)
{
this->enableJob(JOB_INIT);
this->enableJob(JOB_INIT, true, KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::EXCLUSIVE);
setClearsRedoOnStart(false);
}
void initStrokeCallback() {
// pass-though node don't have any projection prepared, so we should
// explicitly regenerate it before activating isolated mode.
m_node->projectionLeaf()->explicitlyRegeneratePassThroughProjection();
m_image->m_d->isolatedRootNode = m_node;
emit m_image->sigIsolatedModeChanged();
......
......@@ -309,32 +309,65 @@ QRect KisMask::needRect(const QRect &rect, PositionToFilthy pos) const
{
Q_UNUSED(pos);
QRect resultRect = rect;
if (m_d->selection)
resultRect &= m_d->selection->selectedRect();
if (m_d->selection) {
QRect selectionExtent = m_d->selection->selectedRect();
// copy for thread safety!
KisPaintDeviceSP temporaryTarget = this->temporaryTarget();
if (temporaryTarget) {
selectionExtent |= temporaryTarget->extent();
}
resultRect &= selectionExtent;
}
return resultRect;
}
QRect KisMask::changeRect(const QRect &rect, PositionToFilthy pos) const
{
Q_UNUSED(pos);
QRect resultRect = rect;
if (m_d->selection)
resultRect &= m_d->selection->selectedRect();
return resultRect;
return KisMask::needRect(rect, pos);
}
QRect KisMask::extent() const
{
return m_d->selection ? m_d->selection->selectedRect() :
parent() ? parent()->extent() : QRect();
QRect resultRect;
if (m_d->selection) {
resultRect = m_d->selection->selectedRect();
// copy for thread safety!
KisPaintDeviceSP temporaryTarget = this->temporaryTarget();
if (temporaryTarget) {
resultRect |= temporaryTarget->extent();
}
} else if (KisNodeSP parent = this->parent()) {
resultRect = parent->extent();
}
return resultRect;
}
QRect KisMask::exactBounds() const
{
return m_d->selection ? m_d->selection->selectedExactRect() :
parent() ? parent()->exactBounds() : QRect();
QRect resultRect;
if (m_d->selection) {
resultRect = m_d->selection->selectedExactRect();
// copy for thread safety!
KisPaintDeviceSP temporaryTarget = this->temporaryTarget();
if (temporaryTarget) {
resultRect |= temporaryTarget->exactBounds();
}
} else if (KisNodeSP parent = this->parent()) {
resultRect = parent->exactBounds();
}
return resultRect;
}
qint32 KisMask::x() const
......
......@@ -124,6 +124,8 @@ ecm_add_tests(
kis_marker_painter_test.cpp
kis_lazy_brush_test.cpp
kis_colorize_mask_test.cpp
kis_mask_similarity_test.cpp
KisMaskGeneratorBenchmark.cpp
NAME_PREFIX "krita-image-"
LINK_LIBRARIES kritaimage Qt5::Test)
......
/*
* Copyright (c) 2018 Iván Santa María <ghevan@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <QTest>
#include <KoColor.h>
#include <QElapsedTimer>
#include "KisMaskGeneratorBenchmark.h"
#include "kis_mask_similarity_test.h"
#include "kis_brush_mask_applicator_base.h"
#include "kis_mask_generator.h"
#include "krita_utils.h"
#include "testutil.h"
class KisMaskGeneratorBenchmarkTester
{
public:
KisMaskGeneratorBenchmarkTester(KisBrushMaskApplicatorBase *_applicatorBase, QRect _bounds)
: applicatorBase(_applicatorBase)
, m_bounds(_bounds)
{
KisFixedPaintDeviceSP m_paintDev = new KisFixedPaintDevice(m_colorSpace);
m_paintDev->setRect(m_bounds);
m_paintDev->initialize(255);
MaskProcessingData data(m_paintDev, m_colorSpace,
0.0, 1.0,
m_bounds.width() / 2.0, m_bounds.height() / 2.0,0);
// Start Benchmark
applicatorBase->initializeData(&data);
QElapsedTimer maskGenerationTime;
maskGenerationTime.start();
QBENCHMARK {
applicatorBase->process(m_bounds);
}
}
protected:
const KoColorSpace *m_colorSpace = KoColorSpaceRegistry::instance()->rgb8();
QRect m_bounds;
KisBrushMaskApplicatorBase *applicatorBase;
KisFixedPaintDeviceSP m_paintDev;
};
void KisMaskGeneratorBenchmark::testDefaultScalarMask()
{
QRect bounds(0,0,1000,1000);
{
KisCircleMaskGenerator circScalar(1000, 1.0, 0.5, 0.5, 2, true);
circScalar.resetMaskApplicator(true); // Force usage of scalar backend
KisMaskGeneratorBenchmarkTester(circScalar.applicator(), bounds);
}
}
void KisMaskGeneratorBenchmark::testDefaultVectorMask()
{
QRect bounds(0,0,1000,1000);
{
KisCircleMaskGenerator circVectr(1000, 1.0, 0.5, 0.5, 2, true);
KisMaskGeneratorBenchmarkTester(circVectr.applicator(), bounds);
}
}
void KisMaskGeneratorBenchmark::testCircularGaussScalarMask()
{
QRect bounds(0,0,1000,1000);