Commit 2284ea83 authored by Boudewijn Rempt's avatar Boudewijn Rempt

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

parents 9e4a9b68 310d1a3c
......@@ -58,6 +58,25 @@
#endif
bool KisConvolutionPainter::useFFTImplemenation(const KisConvolutionKernelSP kernel) const
{
bool result = false;
#ifdef HAVE_FFTW3
#define THRESHOLD_SIZE 5
result =
m_enginePreference == FFTW ||
(m_enginePreference == NONE &&
kernel->width() > THRESHOLD_SIZE &&
kernel->height() > THRESHOLD_SIZE);
#else
Q_UNUSED(kernel);
#endif
return result;
}
template<class factory>
KisConvolutionWorker<factory>* KisConvolutionPainter::createWorker(const KisConvolutionKernelSP kernel,
KisPainter *painter,
......@@ -66,17 +85,10 @@ KisConvolutionWorker<factory>* KisConvolutionPainter::createWorker(const KisConv
KisConvolutionWorker<factory> *worker;
#ifdef HAVE_FFTW3
#define THRESHOLD_SIZE 5
if(m_enginePreference == SPATIAL ||
(m_enginePreference != FFTW &&
kernel->width() <= THRESHOLD_SIZE &&
kernel->height() <= THRESHOLD_SIZE)) {
worker = new KisConvolutionWorkerSpatial<factory>(painter, progress);
}
else {
if (useFFTImplemenation(kernel)) {
worker = new KisConvolutionWorkerFFT<factory>(painter, progress);
} else {
worker = new KisConvolutionWorkerSpatial<factory>(painter, progress);
}
#else
Q_UNUSED(kernel);
......@@ -156,3 +168,8 @@ void KisConvolutionPainter::applyMatrix(const KisConvolutionKernelSP kernel, con
}
}
}
bool KisConvolutionPainter::needsTransaction(const KisConvolutionKernelSP kernel) const
{
return !useFFTImplemenation(kernel);
}
......@@ -67,6 +67,13 @@ public:
void applyMatrix(const KisConvolutionKernelSP kernel, const KisPaintDeviceSP src, QPoint srcPos, QPoint dstPos, QSize areaSize,
KisConvolutionBorderOp borderOp = BORDER_REPEAT);
/**
* The caller should ask if the painter needs an explicit transaction iff
* the source and destination devices coincide. Otherwise, the transaction is
* just not needed.
*/
bool needsTransaction(const KisConvolutionKernelSP kernel) const;
protected:
friend class KisConvolutionPainterTest;
enum TestingEnginePreference {
......@@ -85,6 +92,8 @@ private:
KisPainter *painter,
KoUpdater *progress);
bool useFFTImplemenation(const KisConvolutionKernelSP kernel) const;
private:
TestingEnginePreference m_enginePreference;
};
......
......@@ -74,10 +74,13 @@ QRect KisFilterMask::decorateRect(KisPaintDeviceSP &src,
KisFilterConfigurationSP filterConfig = filter();
Q_ASSERT(nodeProgressProxy());
Q_ASSERT_X(src != dst, "KisFilterMask::decorateRect",
"src must be != dst, because we can't create transactions "
"during merge, as it breaks reentrancy");
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(nodeProgressProxy(), rc);
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(
src != dst &&
"KisFilterMask::decorateRect: "
"src must be != dst, because we can't create transactions "
"during merge, as it breaks reentrancy",
rc);
if (!filterConfig) {
return QRect();
......
......@@ -21,6 +21,7 @@
#include "kis_global.h"
#include "kis_convolution_kernel.h"
#include <kis_convolution_painter.h>
#include <kis_transaction.h>
#include <QRect>
......@@ -103,7 +104,8 @@ void KisGaussianKernel::applyGaussian(KisPaintDeviceSP device,
const QRect& rect,
qreal xRadius, qreal yRadius,
const QBitArray &channelFlags,
KoUpdater *progressUpdater)
KoUpdater *progressUpdater,
bool createTransaction)
{
QPoint srcTopLeft = rect.topLeft();
......@@ -135,6 +137,12 @@ void KisGaussianKernel::applyGaussian(KisPaintDeviceSP device,
painter.setProgress(progressUpdater);
KisConvolutionKernelSP kernelHoriz = KisGaussianKernel::createHorizontalKernel(xRadius);
QScopedPointer<KisTransaction> transaction;
if (createTransaction && painter.needsTransaction(kernelHoriz)) {
transaction.reset(new KisTransaction(device));
}
painter.applyMatrix(kernelHoriz, device, srcTopLeft, srcTopLeft, rect.size(), BORDER_REPEAT);
} else if (yRadius > 0.0) {
......@@ -143,6 +151,12 @@ void KisGaussianKernel::applyGaussian(KisPaintDeviceSP device,
painter.setProgress(progressUpdater);
KisConvolutionKernelSP kernelVertical = KisGaussianKernel::createVerticalKernel(yRadius);
QScopedPointer<KisTransaction> transaction;
if (createTransaction && painter.needsTransaction(kernelVertical)) {
transaction.reset(new KisTransaction(device));
}
painter.applyMatrix(kernelVertical, device, srcTopLeft, srcTopLeft, rect.size(), BORDER_REPEAT);
}
}
......@@ -234,17 +248,10 @@ void KisGaussianKernel::applyLoG(KisPaintDeviceSP device,
Eigen::Matrix<qreal, Eigen::Dynamic, Eigen::Dynamic> KisGaussianKernel::createDilateMatrix(qreal radius)
{
int kernelSize = 2 * std::ceil(radius) + 1;
const int kernelSize = 2 * std::ceil(radius) + 1;
Eigen::Matrix<qreal, Eigen::Dynamic, Eigen::Dynamic> matrix(kernelSize, kernelSize);
struct UnionFade {
quint8 value(qreal) const {
return 255;
}
};
const qreal fadeStart = radius - 1.0;
const qreal fadeStart = qMax(1.0, radius - 1.0);
/**
* The kernel size should always be odd, then the position of the
......@@ -275,8 +282,10 @@ Eigen::Matrix<qreal, Eigen::Dynamic, Eigen::Dynamic> KisGaussianKernel::createDi
return matrix;
}
void KisGaussianKernel::applyDilate(KisPaintDeviceSP device, const QRect &rect, qreal radius, const QBitArray &channelFlags, KoUpdater *progressUpdater)
void KisGaussianKernel::applyDilate(KisPaintDeviceSP device, const QRect &rect, qreal radius, const QBitArray &channelFlags, KoUpdater *progressUpdater, bool createTransaction)
{
KIS_SAFE_ASSERT_RECOVER_RETURN(device->colorSpace()->pixelSize() == 1);
QPoint srcTopLeft = rect.topLeft();
KisConvolutionPainter painter(device);
......@@ -287,14 +296,19 @@ void KisGaussianKernel::applyDilate(KisPaintDeviceSP device, const QRect &rect,
KisConvolutionKernelSP kernel =
KisConvolutionKernel::fromMatrix(matrix,
0,
0);
1.0);
QScopedPointer<KisTransaction> transaction;
if (createTransaction && painter.needsTransaction(kernel)) {
transaction.reset(new KisTransaction(device));
}
painter.applyMatrix(kernel, device, srcTopLeft, srcTopLeft, rect.size(), BORDER_REPEAT);
}
#include "kis_sequential_iterator.h"
void KisGaussianKernel::applyErodeU8(KisPaintDeviceSP device, const QRect &rect, qreal radius, const QBitArray &channelFlags, KoUpdater *progressUpdater)
void KisGaussianKernel::applyErodeU8(KisPaintDeviceSP device, const QRect &rect, qreal radius, const QBitArray &channelFlags, KoUpdater *progressUpdater, bool createTransaction)
{
KIS_SAFE_ASSERT_RECOVER_RETURN(device->colorSpace()->pixelSize() == 1);
......@@ -306,7 +320,7 @@ void KisGaussianKernel::applyErodeU8(KisPaintDeviceSP device, const QRect &rect,
}
}
applyDilate(device, rect, radius, channelFlags, progressUpdater);
applyDilate(device, rect, radius, channelFlags, progressUpdater, createTransaction);
{
KisSequentialIterator dstIt(device, rect);
......
......@@ -48,7 +48,8 @@ public:
const QRect& rect,
qreal xRadius, qreal yRadius,
const QBitArray &channelFlags,
KoUpdater *updater);
KoUpdater *updater,
bool createTransaction = false);
static Eigen::Matrix<qreal, Eigen::Dynamic, Eigen::Dynamic> createLoGMatrix(qreal radius, qreal coeff = 1.0);
......@@ -65,13 +66,15 @@ public:
const QRect& rect,
qreal radius,
const QBitArray &channelFlags,
KoUpdater *progressUpdater);
KoUpdater *progressUpdater,
bool createTransaction = false);
static void applyErodeU8(KisPaintDeviceSP device,
const QRect& rect,
qreal radius,
const QBitArray &channelFlags,
KoUpdater *progressUpdater);
KoUpdater *progressUpdater,
bool createTransaction = false);
};
#endif /* __KIS_GAUSSIAN_KERNEL_H */
......@@ -399,7 +399,7 @@ void KisLsBevelEmbossFilter::applyBevelEmboss(KisPaintDeviceSP srcDevice,
}
if (config->soften()) {
KisLsUtils::applyGaussian(bumpmapSelection, d.applyGaussianRect, config->soften());
KisLsUtils::applyGaussianWithTransaction(bumpmapSelection, d.applyGaussianRect, config->soften());
}
......
......@@ -147,7 +147,7 @@ void applyDropShadow(KisPaintDeviceSP srcDevice,
* Spread and blur the selection
*/
if (d.spread_size) {
KisLsUtils::applyGaussian(selection, d.blurNeedRect, d.spread_size);
KisLsUtils::applyGaussianWithTransaction(selection, d.blurNeedRect, d.spread_size);
// TODO: find out why in libpsd we pass false here. If we do so,
// the result is fully black, which is not expected
......@@ -157,7 +157,7 @@ void applyDropShadow(KisPaintDeviceSP srcDevice,
//selection->convertToQImage(0, QRect(0,0,300,300)).save("1_selection_spread.png");
if (d.blur_size) {
KisLsUtils::applyGaussian(selection, d.noiseNeedRect, d.blur_size);
KisLsUtils::applyGaussianWithTransaction(selection, d.noiseNeedRect, d.blur_size);
}
//selection->convertToQImage(0, QRect(0,0,300,300)).save("2_selection_blur.png");
......
......@@ -144,7 +144,7 @@ void applySatin(KisPaintDeviceSP srcDevice,
KisPixelSelectionSP tempSelection = new KisPixelSelection(*selection);
KisLsUtils::applyGaussian(tempSelection, d.satinNeedRect, d.blur_size);
KisLsUtils::applyGaussianWithTransaction(tempSelection, d.satinNeedRect, d.blur_size);
//tempSelection->convertToQImage(0, QRect(0,0,300,300)).save("2_selection_blurred.png");
......
......@@ -91,12 +91,12 @@ void KisLsStrokeFilter::applyStroke(KisPaintDeviceSP srcDevice,
knockOutSelection->makeCloneFromRough(selection, needRect);
if (config->position() == psd_stroke_outside) {
KisGaussianKernel::applyDilate(selection, needRect, 2 * config->size(), QBitArray(), 0);
KisGaussianKernel::applyDilate(selection, needRect, 2 * config->size(), QBitArray(), 0, true);
} else if (config->position() == psd_stroke_inside) {
KisGaussianKernel::applyErodeU8(knockOutSelection, needRect, 2 * config->size(), QBitArray(), 0);
KisGaussianKernel::applyErodeU8(knockOutSelection, needRect, 2 * config->size(), QBitArray(), 0, true);
} else if (config->position() == psd_stroke_center) {
KisGaussianKernel::applyDilate(selection, needRect, config->size(), QBitArray(), 0);
KisGaussianKernel::applyErodeU8(knockOutSelection, needRect, config->size(), QBitArray(), 0);
KisGaussianKernel::applyDilate(selection, needRect, config->size(), QBitArray(), 0, true);
KisGaussianKernel::applyErodeU8(knockOutSelection, needRect, config->size(), QBitArray(), 0, true);
}
KisPainter gc(selection);
......
......@@ -109,13 +109,13 @@ namespace KisLsUtils
return rc.adjusted(-halfSize, -halfSize, halfSize, halfSize);
}
void applyGaussian(KisPixelSelectionSP selection,
const QRect &applyRect,
qreal radius)
void applyGaussianWithTransaction(KisPixelSelectionSP selection,
const QRect &applyRect,
qreal radius)
{
KisGaussianKernel::applyGaussian(selection, applyRect,
radius, radius,
QBitArray(), 0);
QBitArray(), 0, true);
}
namespace Private {
......
......@@ -42,9 +42,9 @@ namespace KisLsUtils
void findEdge(KisPixelSelectionSP selection, const QRect &applyRect, const bool edgeHidden);
QRect growRectFromRadius(const QRect &rc, int radius);
void applyGaussian(KisPixelSelectionSP selection,
const QRect &applyRect,
qreal radius);
void applyGaussianWithTransaction(KisPixelSelectionSP selection,
const QRect &applyRect,
qreal radius);
static const int FULL_PERCENT_RANGE = 100;
void adjustRange(KisPixelSelectionSP selection, const QRect &applyRect, const int range);
......
......@@ -351,9 +351,11 @@ void KisAnimationFrameCache::dropLowQualityFrames(const KisTimeRange &range, con
auto it = m_d->newFrames.upperBound(range.start());
// the vector is guaranteed to be non-empty,
// so decrementing iterator is safe
if (it != m_d->newFrames.begin()) it--;
while (it.key() <= range.end()) {
while (it != m_d->newFrames.end() && it.key() <= range.end()) {
const int frameId = it.key();
const int frameLength = it.value();
......
......@@ -37,6 +37,7 @@
#include <QGroupBox>
#include <QClipboard>
#include <QProcess>
#include <QDialogButtonBox>
#include <kconfig.h>
#include <kconfiggroup.h>
......@@ -237,10 +238,9 @@ void KCheckAccelerators::createDialog(QWidget *actWin, bool automatic)
connect(disableAutoCheck, SIGNAL(toggled(bool)), SLOT(slotDisableCheck(bool)));
layout->addWidget(disableAutoCheck);
}
QPushButton *btnClose = new QPushButton(i18nc("@action:button", "Close"), drklash);
btnClose->setDefault(true);
layout->addWidget(btnClose);
connect(btnClose, SIGNAL(clicked()), drklash, SLOT(close()));
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, drklash);
layout->addWidget(buttonBox);
connect(buttonBox, SIGNAL(rejected()), drklash, SLOT(close()));
if (disableAutoCheck) {
disableAutoCheck->setFocus();
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment