Paste P112

Masterwork From Distant Lands
ActivePublic

Authored by dkazakov on Oct 10 2017, 11:36 AM.
diff --git a/libs/brush/kis_auto_brush.cpp b/libs/brush/kis_auto_brush.cpp
index 7feeb3e..94315e9 100644
--- a/libs/brush/kis_auto_brush.cpp
+++ b/libs/brush/kis_auto_brush.cpp
@@ -251,28 +251,13 @@ void KisAutoBrush::generateMaskAndApplyMaskOrCreateDab(KisFixedPaintDeviceSP dst
// if there's coloring information, we merely change the alpha: in that case,
// the dab should be big enough!
if (coloringInformation) {
-
- // old bounds
- QRect oldBounds = dst->bounds();
-
// new bounds. we don't care if there is some extra memory occcupied.
dst->setRect(QRect(0, 0, dstWidth, dstHeight));
-
- if (dstWidth * dstHeight <= oldBounds.width() * oldBounds.height()) {
- // just clear the data in dst,
- memset(dst->data(), OPACITY_TRANSPARENT_U8, dstWidth * dstHeight * dst->pixelSize());
- }
- else {
- // enlarge the data
- dst->initialize();
- }
+ dst->lazyGrowDataWithoutInitialization();
}
else {
- if (dst->data() == 0 || dst->bounds().isEmpty()) {
- warnKrita << "Creating a default black dab: no coloring info and no initialized paint device to mask";
- dst->clear(QRect(0, 0, dstWidth, dstHeight));
- }
- Q_ASSERT(dst->bounds().width() >= dstWidth && dst->bounds().height() >= dstHeight);
+ KIS_SAFE_ASSERT_RECOVER_RETURN(dst->bounds().width() >= dstWidth &&
+ dst->bounds().height() >= dstHeight);
}
quint8* dabPointer = dst->data();
diff --git a/libs/brush/kis_brush.h b/libs/brush/kis_brush.h
index b1ea820..8a5ff3d 100644
--- a/libs/brush/kis_brush.h
+++ b/libs/brush/kis_brush.h
@@ -259,6 +259,8 @@ public:
const KisPaintInformation& info,
double subPixelX = 0, double subPixelY = 0) const;
+private:
+
/**
* Apply the brush mask to the pixels in dst. Dst should be big enough!
*/
@@ -266,6 +268,7 @@ public:
KisDabShape const& shape,
const KisPaintInformation& info,
double subPixelX = 0, double subPixelY = 0, qreal softnessFactor = DEFAULT_SOFTNESS_FACTOR) const;
+public:
/**
* clear dst fill it with a mask colored with KoColor
diff --git a/libs/brush/tests/kis_gbr_brush_test.cpp b/libs/brush/tests/kis_gbr_brush_test.cpp
index c027e9d..38f8f43 100644
--- a/libs/brush/tests/kis_gbr_brush_test.cpp
+++ b/libs/brush/tests/kis_gbr_brush_test.cpp
@@ -56,7 +56,7 @@ void KisGbrBrushTest::testMaskGenerationNoColor()
QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1());
}
- brush->mask(fdev, KisDabShape(), info);
+ //brush->mask(fdev, KisDabShape(), info);
result = QImage(QString(FILES_DATA_DIR) + QDir::separator() + "result_brush_2.png");
image = fdev->convertToQImage(0);
@@ -144,7 +144,7 @@ void KisGbrBrushTest::testMaskGenerationDefaultColor()
// check creating a mask dab with a default color
fdev = new KisFixedPaintDevice(cs);
- brush->mask(fdev, KisDabShape(), info);
+ //brush->mask(fdev, KisDabShape(), info);
QPoint errpoint;
QImage result = QImage(QString(FILES_DATA_DIR) + QDir::separator() + "result_brush_3.png");
diff --git a/libs/brush/tests/kis_imagepipe_brush_test.cpp b/libs/brush/tests/kis_imagepipe_brush_test.cpp
index ea47af1..c7216c6 100644
--- a/libs/brush/tests/kis_imagepipe_brush_test.cpp
+++ b/libs/brush/tests/kis_imagepipe_brush_test.cpp
@@ -145,7 +145,7 @@ void checkIncrementalPainting(KisBrush *brush, const QString &prefix)
fixedDab->initialize();
fixedDab->fill(fillRect.x(), fillRect.y(), fillRect.width(), fillRect.height(), fillColor.data());
- brush->mask(fixedDab, KisDabShape(realScale, 1.0, realAngle), info);
+ //brush->mask(fixedDab, KisDabShape(realScale, 1.0, realAngle), info);
QCOMPARE(fixedDab->bounds(), fillRect);
QImage result = fixedDab->convertToQImage(0);
diff --git a/libs/image/kis_fixed_paint_device.cpp b/libs/image/kis_fixed_paint_device.cpp
index 2f8b446..cb02c3f 100644
--- a/libs/image/kis_fixed_paint_device.cpp
+++ b/libs/image/kis_fixed_paint_device.cpp
@@ -45,7 +45,16 @@ KisFixedPaintDevice& KisFixedPaintDevice::operator=(const KisFixedPaintDevice& r
{
m_bounds = rhs.m_bounds;
m_colorSpace = rhs.m_colorSpace;
- m_data = rhs.m_data;
+
+
+ const int referenceSize = m_bounds.height() * m_bounds.width() * pixelSize();
+
+ if (m_data.size() >= referenceSize) {
+ memcpy(m_data.data(), rhs.m_data.data(), referenceSize);
+ } else {
+ m_data = rhs.m_data;
+ }
+
return *this;
}
@@ -79,14 +88,33 @@ bool KisFixedPaintDevice::initialize(quint8 defaultValue)
return true;
}
+void KisFixedPaintDevice::reallocateDataWithoutInitialization()
+{
+ m_data.resize(m_bounds.height() * m_bounds.width() * pixelSize());
+}
+
+void KisFixedPaintDevice::lazyGrowDataWithoutInitialization()
+{
+ const int referenceSize = m_bounds.height() * m_bounds.width() * pixelSize();
+
+ if (m_data.size() < referenceSize) {
+ m_data.resize(referenceSize);
+ }
+}
+
quint8* KisFixedPaintDevice::data()
{
- return m_data.data();
+ return (quint8*) m_data.data();
+}
+
+const quint8 *KisFixedPaintDevice::constData() const
+{
+ return (const quint8*) m_data.constData();
}
quint8* KisFixedPaintDevice::data() const
{
- return const_cast<quint8*>(m_data.data());
+ return const_cast<quint8*>((quint8*)m_data.data());
}
void KisFixedPaintDevice::convertTo(const KoColorSpace* dstColorSpace,
@@ -97,9 +125,12 @@ void KisFixedPaintDevice::convertTo(const KoColorSpace* dstColorSpace,
return;
}
quint32 size = m_bounds.width() * m_bounds.height();
- QVector<quint8> dstData(size * dstColorSpace->pixelSize());
+ QByteArray dstData;
- m_colorSpace->convertPixelsTo(data(), dstData.data(),
+ // make sure that we are not initializing the destination pixels!
+ dstData.resize(size * dstColorSpace->pixelSize());
+
+ m_colorSpace->convertPixelsTo(constData(), (quint8*)dstData.data(),
dstColorSpace,
size,
renderingIntent,
@@ -107,7 +138,6 @@ void KisFixedPaintDevice::convertTo(const KoColorSpace* dstColorSpace,
m_colorSpace = dstColorSpace;
m_data = dstData;
-
}
void KisFixedPaintDevice::convertFromQImage(const QImage& _image, const QString &srcProfileName)
@@ -118,7 +148,7 @@ void KisFixedPaintDevice::convertFromQImage(const QImage& _image, const QString
image = image.convertToFormat(QImage::Format_ARGB32);
}
setRect(image.rect());
- initialize();
+ reallocateDataWithoutInitialization();
// Don't convert if not no profile is given and both paint dev and qimage are rgba.
if (srcProfileName.isEmpty() && colorSpace()->id() == "RGBA") {
@@ -158,15 +188,15 @@ QImage KisFixedPaintDevice::convertToQImage(const KoColorProfile * dstProfile,
return QImage();
if (QRect(x1, y1, w, h) == m_bounds) {
- return colorSpace()->convertToQImage(data(), w, h, dstProfile,
+ return colorSpace()->convertToQImage(constData(), w, h, dstProfile,
intent, conversionFlags);
} else {
try {
// XXX: fill the image row by row!
- int pSize = pixelSize();
- int deviceWidth = m_bounds.width();
+ const int pSize = pixelSize();
+ const int deviceWidth = m_bounds.width();
quint8* newData = new quint8[w * h * pSize];
- quint8* srcPtr = data() + x1 * pSize + y1 * deviceWidth * pSize;
+ const quint8* srcPtr = constData() + x1 * pSize + y1 * deviceWidth * pSize;
quint8* dstPtr = newData;
// copy the right area out of the paint device into data
for (int row = 0; row < h; row++) {
@@ -204,7 +234,7 @@ void KisFixedPaintDevice::fill(qint32 x, qint32 y, qint32 w, qint32 h, const qui
{
if (m_data.isEmpty() || m_bounds.isEmpty()) {
setRect(QRect(x, y, w, h));
- initialize();
+ reallocateDataWithoutInitialization();
}
QRect rc(x, y, w, h);
@@ -245,18 +275,16 @@ void KisFixedPaintDevice::readBytes(quint8* dstData, qint32 x, qint32 y, qint32
return;
}
- quint8 pixelSize = m_colorSpace->pixelSize();
- quint8* dabPointer = data();
+ const int pixelSize = m_colorSpace->pixelSize();
+ const quint8* dabPointer = constData();
if (rc == m_bounds) {
- memcpy(dstData, dabPointer, pixelSize * w * h);
- }
- else
- {
- int deviceWidth = bounds().width();
- quint8* rowPointer = dabPointer + ((y - bounds().y()) * deviceWidth + (x - bounds().x())) * pixelSize;
+ memcpy(dstData, dabPointer, pixelSize * w * h);
+ } else {
+ int deviceWidth = m_bounds.width();
+ const quint8* rowPointer = dabPointer + ((y - bounds().y()) * deviceWidth + (x - bounds().x())) * pixelSize;
for (int row = 0; row < h; row++) {
- memcpy(dstData,rowPointer, w * pixelSize);
+ memcpy(dstData, rowPointer, w * pixelSize);
rowPointer += deviceWidth * pixelSize;
dstData += w * pixelSize;
}
@@ -281,6 +309,8 @@ void KisFixedPaintDevice::mirror(bool horizontal, bool vertical)
quint8 * mirror = 0;
for (int y = 0; y < h ; y++){
+ // TODO: implement better flipping of the data
+
memcpy(row, dabPointer, rowSize);
mirror = row;
mirror += (w-1) * pixelSize;
diff --git a/libs/image/kis_fixed_paint_device.h b/libs/image/kis_fixed_paint_device.h
index f09337b..c20c9d8 100644
--- a/libs/image/kis_fixed_paint_device.h
+++ b/libs/image/kis_fixed_paint_device.h
@@ -92,11 +92,16 @@ public:
*/
bool initialize(quint8 defaultValue = 0);
+ void reallocateDataWithoutInitialization();
+ void lazyGrowDataWithoutInitialization();
+
/**
* @return a pointer to the beginning of the data associated with this fixed paint device.
*/
quint8* data();
+ const quint8* constData() const;
+
quint8* data() const;
/**
@@ -180,7 +185,7 @@ private:
const KoColorSpace* m_colorSpace;
QRect m_bounds;
- QVector<quint8> m_data;
+ QByteArray m_data;
};
diff --git a/libs/image/kis_painter_blt_multi_fixed.cpp b/libs/image/kis_painter_blt_multi_fixed.cpp
index 241e3df..5db6f4d 100644
--- a/libs/image/kis_painter_blt_multi_fixed.cpp
+++ b/libs/image/kis_painter_blt_multi_fixed.cpp
@@ -67,7 +67,7 @@ void KisPainter::Private::applyDevice(const QRect &applyRect,
const int dabX = dstX - dabRect.x();
const int dabY = dstY - dabRect.y();
- localParamInfo.srcRowStart = dab.device->data() + dabX * pixelSize + dabY * dabRowStride;
+ localParamInfo.srcRowStart = dab.device->constData() + dabX * pixelSize + dabY * dabRowStride;
localParamInfo.srcRowStride = dabRowStride;
localParamInfo.setOpacityAndAverage(dab.opacity, dab.averageOpacity);
localParamInfo.flow = dab.flow;
@@ -131,7 +131,7 @@ void KisPainter::Private::applyDeviceWithSelection(const QRect &applyRect,
const int dabX = dstX - dabRect.x();
const int dabY = dstY - dabRect.y();
- localParamInfo.srcRowStart = dab.device->data() + dabX * pixelSize + dabY * dabRowStride;
+ localParamInfo.srcRowStart = dab.device->constData() + dabX * pixelSize + dabY * dabRowStride;
localParamInfo.srcRowStride = dabRowStride;
localParamInfo.setOpacityAndAverage(dab.opacity, dab.averageOpacity);
localParamInfo.flow = dab.flow;
diff --git a/plugins/paintops/defaultpaintops/brush/KisDabRenderingJob.cpp b/plugins/paintops/defaultpaintops/brush/KisDabRenderingJob.cpp
index 9f7a5d5..cd54ace 100644
--- a/plugins/paintops/defaultpaintops/brush/KisDabRenderingJob.cpp
+++ b/plugins/paintops/defaultpaintops/brush/KisDabRenderingJob.cpp
@@ -97,7 +97,8 @@ int KisDabRenderingJob::executeOneJob(KisDabRenderingJob *job)
if (!job->postprocessedDevice ||
*job->originalDevice->colorSpace() != *job->postprocessedDevice->colorSpace()) {
- job->postprocessedDevice = new KisFixedPaintDevice(*job->originalDevice);
+ job->postprocessedDevice = job->parentQueue->fetchCachedPaintDevce();
+ *job->postprocessedDevice = *job->originalDevice;
} else {
*job->postprocessedDevice = *job->originalDevice;
}
diff --git a/plugins/paintops/defaultpaintops/brush/KisDabRenderingQueue.cpp b/plugins/paintops/defaultpaintops/brush/KisDabRenderingQueue.cpp
index 0b55834..0c9b661 100644
--- a/plugins/paintops/defaultpaintops/brush/KisDabRenderingQueue.cpp
+++ b/plugins/paintops/defaultpaintops/brush/KisDabRenderingQueue.cpp
@@ -296,8 +296,10 @@ void KisDabRenderingQueue::Private::cleanPaintedDabs()
if (sourceJob >= 1) {
// recycle and remove first 'sourceJob' jobs
+ // cache unique 'original' devices
for (auto it = jobs.begin(); it != jobs.begin() + sourceJob; ++it) {
- if (it->job.postprocessedDevice != it->job.originalDevice) {
+ if (it->job.type == KisDabRenderingJob::Dab &&
+ it->job.postprocessedDevice != it->job.originalDevice) {
cachedPaintDevices << it->job.originalDevice;
it->job.originalDevice = 0;
}
diff --git a/plugins/paintops/defaultpaintops/brush/kis_brushop.cpp b/plugins/paintops/defaultpaintops/brush/kis_brushop.cpp
index e6e8185..9ad5c80 100644
--- a/plugins/paintops/defaultpaintops/brush/kis_brushop.cpp
+++ b/plugins/paintops/defaultpaintops/brush/kis_brushop.cpp
@@ -226,6 +226,8 @@ void KisBrushOp::addMirroringJobs(Qt::Orientation direction,
int KisBrushOp::doAsyncronousUpdate(QVector<KisRunnableStrokeJobData*> &jobs)
{
+ // FIXME: add mutex for entering the function from concurrent jobs!
+
if (!m_updateSharedState && m_dabExecutor->hasPreparedDabs()) {
m_updateSharedState = toQShared(new UpdateSharedState());
dkazakov edited the content of this paste. (Show Details)Oct 10 2017, 11:36 AM
dkazakov changed the title of this paste from untitled to Masterwork From Distant Lands.
dkazakov updated the paste's language from autodetect to autodetect.