Commit 59cd1c2c authored by Boudewijn Rempt's avatar Boudewijn Rempt

Merge branch 'master' into rempt/T379-resource-management

parents 98f30cf5 ab670ba3
......@@ -44,6 +44,8 @@ struct Q_DECL_HIDDEN KisGeneratorLayer::Private
}
KisThreadSafeSignalCompressor updateSignalCompressor;
QRect preparedRect;
KisFilterConfigurationSP preparedForFilter;
};
......@@ -72,6 +74,7 @@ KisGeneratorLayer::~KisGeneratorLayer()
void KisGeneratorLayer::setFilter(KisFilterConfigurationSP filterConfig)
{
KisSelectionBasedLayer::setFilter(filterConfig);
m_d->preparedRect = QRect();
update();
}
......@@ -93,32 +96,43 @@ void KisGeneratorLayer::slotDelayedStaticUpdate()
void KisGeneratorLayer::update()
{
KisImageSP image = this->image().toStrongRef();
const QRect updateRect = extent() | image->bounds();
KisFilterConfigurationSP filterConfig = filter();
KIS_SAFE_ASSERT_RECOVER_RETURN(filterConfig);
if (!filterConfig) {
warnImage << "BUG: No Filter configuration in KisGeneratorLayer";
return;
if (filterConfig != m_d->preparedForFilter) {
resetCache();
}
const QRegion processRegion(QRegion(updateRect) - m_d->preparedRect);
if (processRegion.isEmpty()) return;
KisGeneratorSP f = KisGeneratorRegistry::instance()->value(filterConfig->name());
if (!f) return;
KIS_SAFE_ASSERT_RECOVER_RETURN(f);
QRect processRect = exactBounds();
KisPaintDeviceSP originalDevice = original();
resetCache();
QVector<QRect> dirtyRegion;
KisPaintDeviceSP originalDevice = original();
Q_FOREACH (const QRect &rc, processRegion) {
KisProcessingInformation dstCfg(originalDevice,
rc.topLeft(),
KisSelectionSP());
f->generate(dstCfg, rc.size(), filterConfig.data());
KisProcessingInformation dstCfg(originalDevice,
processRect.topLeft(),
KisSelectionSP());
dirtyRegion << rc;
f->generate(dstCfg, processRect.size(), filterConfig.data());
}
m_d->preparedRect = updateRect;
m_d->preparedForFilter = filterConfig;
// HACK ALERT!!!
// this avoids cyclic loop with KisRecalculateGeneratorLayerJob::run()
KisSelectionBasedLayer::setDirty(QVector<QRect>() << extent());
KisSelectionBasedLayer::setDirty(dirtyRegion);
}
bool KisGeneratorLayer::accept(KisNodeVisitor & v)
......@@ -150,12 +164,21 @@ KisBaseNode::PropertyList KisGeneratorLayer::sectionModelProperties() const
void KisGeneratorLayer::setX(qint32 x)
{
KisSelectionBasedLayer::setX(x);
m_d->preparedRect = QRect();
m_d->updateSignalCompressor.start();
}
void KisGeneratorLayer::setY(qint32 y)
{
KisSelectionBasedLayer::setY(y);
m_d->preparedRect = QRect();
m_d->updateSignalCompressor.start();
}
void KisGeneratorLayer::resetCache()
{
KisSelectionBasedLayer::resetCache();
m_d->preparedRect = QRect();
m_d->updateSignalCompressor.start();
}
......
......@@ -72,6 +72,8 @@ public:
void setX(qint32 x) override;
void setY(qint32 y) override;
void resetCache() override;
private Q_SLOTS:
void slotDelayedStaticUpdate();
......
......@@ -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->constData() + dabX * pixelSize + dabY * dabRowStride;
localParamInfo.srcRowStart = dab.device->constData() + dabX * srcPixelSize + 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->constData() + dabX * pixelSize + dabY * dabRowStride;
localParamInfo.srcRowStart = dab.device->constData() + dabX * srcPixelSize + dabY * dabRowStride;
localParamInfo.srcRowStride = dabRowStride;
localParamInfo.setOpacityAndAverage(dab.opacity, dab.averageOpacity);
localParamInfo.flow = dab.flow;
......
......@@ -295,25 +295,48 @@ void KisSelectionBasedLayer::setDirty()
QRect KisSelectionBasedLayer::extent() const
{
Q_ASSERT(image());
KisImageSP imageSP = image().toStrongRef();
if (!imageSP) {
return 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 {
KisImageSP image = this->image().toStrongRef();
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(image, QRect());
resultRect = image->bounds();
}
return m_d->selection ?
m_d->selection->selectedRect() : imageSP->bounds();
return resultRect;
}
QRect KisSelectionBasedLayer::exactBounds() const
{
Q_ASSERT(image());
KisImageSP imageSP = image().toStrongRef();
if (!imageSP) {
return 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 {
KisImageSP image = this->image().toStrongRef();
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(image, QRect());
resultRect = image->bounds();
}
return m_d->selection ?
m_d->selection->selectedExactRect() : imageSP->bounds();
return resultRect;
}
QImage KisSelectionBasedLayer::createThumbnail(qint32 w, qint32 h)
......
......@@ -73,7 +73,7 @@ public:
* resets cached projection of lower layer to a new device
* @return void
*/
void resetCache();
virtual void resetCache();
/**
* for KisLayer::setDirty(const QRegion&)
......
......@@ -477,6 +477,21 @@ bool KisKraLoadVisitor::loadPaintDevice(KisPaintDeviceSP device, const QString&
template<class DevicePolicy>
bool KisKraLoadVisitor::loadPaintDeviceFrame(KisPaintDeviceSP device, const QString &location, DevicePolicy policy)
{
{
const int pixelSize = device->colorSpace()->pixelSize();
KoColor color(Qt::transparent, device->colorSpace());
if (m_store->open(location + ".defaultpixel")) {
if (m_store->size() == pixelSize) {
m_store->read((char*)color.data(), pixelSize);
}
m_store->close();
}
policy.setDefaultPixel(device, color);
}
if (m_store->open(location)) {
if (!policy.read(device, m_store->device())) {
m_warningMessages << i18n("Could not read pixel data: %1.", location);
......@@ -489,15 +504,6 @@ bool KisKraLoadVisitor::loadPaintDeviceFrame(KisPaintDeviceSP device, const QStr
m_warningMessages << i18n("Could not load pixel data: %1.", location);
return true;
}
if (m_store->open(location + ".defaultpixel")) {
int pixelSize = device->colorSpace()->pixelSize();
if (m_store->size() == pixelSize) {
KoColor color(Qt::transparent, device->colorSpace());
m_store->read((char*)color.data(), pixelSize);
policy.setDefaultPixel(device, color);
}
m_store->close();
}
return true;
}
......@@ -580,6 +586,13 @@ bool KisKraLoadVisitor::loadMetaData(KisNode* node)
bool KisKraLoadVisitor::loadSelection(const QString& location, KisSelectionSP dstSelection)
{
// by default the selection is expected to be fully transparent
{
KisPixelSelectionSP pixelSelection = dstSelection->pixelSelection();
KoColor transparent(Qt::transparent, pixelSelection->colorSpace());
pixelSelection->setDefaultPixel(transparent);
}
// Pixel selection
bool result = true;
QString pixelSelectionLocation = location + DOT_PIXEL_SELECTION;
......
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