koffice/krita/image
Dmitry Kazakov
dimula73 at gmail.com
Sun Nov 21 23:05:03 CET 2010
SVN commit 1199447 by dkazakov:
Fixed a full refresh for Clone layers
Now the Async Merger knows about one more type of layer position:
N_EXTRA. Such layer will be counted in a need rect chain and will be
updated (original+projection), but it will not be merged into the
final projection of the image. This is done for preliminary updates of
the sources of Clone layers.
Btw, i would suggest everyone to perform 'make clean' in
./krita/image/ folder, because many parts of walkers are
inlined. There is no need to do a full clean, just in ./image/
directory.
CCMAIL:kimageshop at kde.org
BUG:257532
M +13 -0 kis_async_merger.h
M +8 -7 kis_base_rects_walker.h
M +27 -0 kis_full_refresh_walker.h
M +4 -4 kis_node.h
M +70 -0 tests/kis_async_merger_test.cpp
M +1 -0 tests/kis_async_merger_test.h
--- trunk/koffice/krita/image/kis_async_merger.h #1199446:1199447
@@ -189,6 +189,19 @@
QRect applyRect = item.m_applyRect;
+ if(item.m_position & KisMergeWalker::N_EXTRA) {
+ // The type of layers that will not go to projection.
+
+ DEBUG_NODE_ACTION("Updating", "N_EXTRA", currentNode, applyRect);
+ KisUpdateOriginalVisitor originalVisitor(applyRect,
+ m_currentProjection);
+ currentNode->accept(originalVisitor);
+ currentNode->updateProjection(applyRect);
+
+ continue;
+ }
+
+
if(!m_currentProjection)
setupProjection(currentNode, applyRect, useTempProjections);
--- trunk/koffice/krita/image/kis_base_rects_walker.h #1199446:1199447
@@ -41,16 +41,17 @@
N_NORMAL = 0x00,
N_TOPMOST = 0x01,
N_BOTTOMMOST = 0x02,
+ N_EXTRA = 0x04,
- N_ABOVE_FILTHY = 0x04,
- N_FILTHY_ORIGINAL = 0x08, // not used actually
- N_FILTHY_PROJECTION = 0x10,
- N_FILTHY = 0x20,
- N_BELOW_FILTHY = 0x40
+ N_ABOVE_FILTHY = 0x08,
+ N_FILTHY_ORIGINAL = 0x10, // not used actually
+ N_FILTHY_PROJECTION = 0x20,
+ N_FILTHY = 0x40,
+ N_BELOW_FILTHY = 0x80
};
- #define GRAPH_POSITION_MASK 0x03
- #define POSITION_TO_FILTHY_MASK 0x7C
+ #define GRAPH_POSITION_MASK 0x07
+ #define POSITION_TO_FILTHY_MASK 0xF8
struct JobItem {
KisNodeSP m_node;
--- trunk/koffice/krita/image/kis_full_refresh_walker.h #1199446:1199447
@@ -21,8 +21,10 @@
#include "kis_node.h"
#include "kis_types.h"
+#include "kis_clone_layer.h"
#include "kis_base_rects_walker.h"
+
class KRITAIMAGE_EXPORT KisFullRefreshWalker : public KisBaseRectsWalker
{
@@ -116,6 +118,31 @@
startTrip(currentNode);
} while ((currentNode = currentNode->prevSibling()));
}
+
+ void registerNeedRect(KisNodeSP node, NodePosition position) {
+ KisBaseRectsWalker::registerNeedRect(node, position);
+
+ KisCloneLayerSP cloneLayer = qobject_cast<KisCloneLayer*>(node.data());
+ if(cloneLayer) {
+ /**
+ * We need to check whether the source of the clone is going
+ * to be updated after the clone itself. If so we need to
+ * pre-update it manually. This can be checked by the precedence
+ * of the source in the nodes stack
+ */
+ if(isRegistered(cloneLayer->copyFrom())) {
+ registerNeedRect(cloneLayer->copyFrom(), N_EXTRA | N_FILTHY);
+ }
+ }
+ }
+
+ bool isRegistered(KisNodeSP node) {
+ foreach(const JobItem &item, nodeStack()) {
+ if(item.m_node == node)
+ return true;
+ }
+ return false;
+ }
};
--- trunk/koffice/krita/image/kis_node.h #1199446:1199447
@@ -49,10 +49,10 @@
* when changing this struct
*/
enum PositionToFilthy {
- N_ABOVE_FILTHY = 0x04,
- N_FILTHY_PROJECTION = 0x10,
- N_FILTHY = 0x20,
- N_BELOW_FILTHY = 0x40
+ N_ABOVE_FILTHY = 0x08,
+ N_FILTHY_PROJECTION = 0x20,
+ N_FILTHY = 0x40,
+ N_BELOW_FILTHY = 0x80
};
/**
--- trunk/koffice/krita/image/tests/kis_async_merger_test.cpp #1199446:1199447
@@ -19,6 +19,7 @@
#include "kis_async_merger_test.h"
#include "kis_merge_walker.h"
+#include "kis_full_refresh_walker.h"
#include "kis_async_merger.h"
#include <qtest_kde.h>
@@ -28,6 +29,7 @@
#include "kis_paint_layer.h"
#include "kis_group_layer.h"
#include "kis_adjustment_layer.h"
+#include "kis_filter_mask.h"
#include "kis_selection.h"
#include "filter/kis_filter.h"
@@ -164,7 +166,75 @@
QVERIFY(groupLayer->original() == paintLayer1->projection());
}
+ /*
+ +--------------+
+ |root |
+ | paint 1 |
+ | invert_mask |
+ | clone_of_1 |
+ +--------------+
+ */
+void KisAsyncMergerTest::testFullRefreshWithClones()
+{
+ const KoColorSpace *colorSpace = KoColorSpaceRegistry::instance()->rgb8();
+ KisImageSP image = new KisImage(0, 128, 128, colorSpace, "clones test");
+
+ KisPaintDeviceSP device1 = new KisPaintDevice(colorSpace);
+ device1->fill(image->bounds(), KoColor( Qt::white, colorSpace));
+
+ KisFilterSP filter = KisFilterRegistry::instance()->value("invert");
+ Q_ASSERT(filter);
+ KisFilterConfiguration *configuration = filter->defaultConfiguration(0);
+ Q_ASSERT(configuration);
+
+ KisLayerSP paintLayer1 = new KisPaintLayer(image, "paint1", OPACITY_OPAQUE_U8, device1);
+ KisFilterMaskSP invertMask1 = new KisFilterMask();
+ invertMask1->setFilter(configuration);
+
+ KisLayerSP cloneLayer1 = new KisCloneLayer(paintLayer1, image, "clone_of_1", OPACITY_OPAQUE_U8);
+ /**
+ * The clone layer must have a projection to allow us
+ * to read what it got from its source. Just shift it.
+ */
+ cloneLayer1->setX(10);
+ cloneLayer1->setY(10);
+
+ image->addNode(cloneLayer1, image->rootLayer());
+ image->addNode(paintLayer1, image->rootLayer());
+ image->addNode(invertMask1, paintLayer1);
+
+ QRect cropRect(image->bounds());
+
+ KisFullRefreshWalker walker(cropRect);
+ KisAsyncMerger merger;
+
+ walker.collectRects(image->rootLayer(), image->bounds());
+ merger.startMerge(walker);
+
+ QRect filledRect(10, 10,
+ image->width() - cloneLayer1->x(),
+ image->height() - cloneLayer1->y());
+
+ const int pixelSize = device1->pixelSize();
+ const int numPixels = filledRect.width() * filledRect.height();
+
+ QByteArray bytes(numPixels * pixelSize, 13);
+ cloneLayer1->projection()->readBytes((quint8*)bytes.data(), filledRect);
+
+ KoColor desiredPixel(Qt::black, colorSpace);
+ quint8 *srcPtr = (quint8*)bytes.data();
+ quint8 *dstPtr = desiredPixel.data();
+ for(int i = 0; i < numPixels; i++) {
+ if(memcmp(srcPtr, dstPtr, pixelSize)) {
+ qDebug() << "expected:" << dstPtr[0] << dstPtr[1] << dstPtr[2] << dstPtr[3];
+ qDebug() << "result: " << srcPtr[0] << srcPtr[1] << srcPtr[2] << srcPtr[3];
+ QFAIL("Failed to compare pixels");
+ }
+ srcPtr += pixelSize;
+ }
+}
+
QTEST_KDEMAIN(KisAsyncMergerTest, NoGUI)
#include "kis_async_merger_test.moc"
--- trunk/koffice/krita/image/tests/kis_async_merger_test.h #1199446:1199447
@@ -28,6 +28,7 @@
private slots:
void testMerger();
void debugObligeChild();
+ void testFullRefreshWithClones();
private:
};
More information about the kimageshop
mailing list