Krita Source Code Documentation
Loading...
Searching...
No Matches
KisAsyncMerger Class Reference

#include <kis_async_merger.h>

Public Member Functions

void startMerge (KisBaseRectsWalker &walker, bool notifyClones=true)
 

Private Member Functions

bool compositeWithProjection (KisProjectionLeafSP leaf, const QRect &rect)
 
void doNotifyClones (KisBaseRectsWalker &walker)
 
void resetProjection ()
 
void setupProjection (KisProjectionLeafSP currentLeaf, const QRect &rect, bool useTempProjection)
 
void writeProjection (KisProjectionLeafSP topmostLeaf, bool useTempProjection, const QRect &rect)
 

Private Attributes

KisPaintDeviceSP m_cachedPaintDevice
 
KisPaintDeviceSP m_currentProjection
 
KisPaintDeviceSP m_finalProjection
 

Detailed Description

Definition at line 16 of file kis_async_merger.h.

Member Function Documentation

◆ compositeWithProjection()

bool KisAsyncMerger::compositeWithProjection ( KisProjectionLeafSP leaf,
const QRect & rect )
inlineprivate

Definition at line 316 of file kis_async_merger.cpp.

316 {
317
318 if (!m_currentProjection) return true;
319 if (!leaf->visible()) return true;
320
322 leaf->projectionPlane()->apply(&gc, rect);
323
324 DEBUG_NODE_ACTION("Compositing projection", "", leaf, rect);
325 return true;
326}
KisPaintDeviceSP m_currentProjection
#define DEBUG_NODE_ACTION(message, type, leaf, rect)

References DEBUG_NODE_ACTION, and m_currentProjection.

◆ doNotifyClones()

void KisAsyncMerger::doNotifyClones ( KisBaseRectsWalker & walker)
inlineprivate

Definition at line 328 of file kis_async_merger.cpp.

328 {
330 walker.cloneNotifications();
331
332 KisBaseRectsWalker::CloneNotificationsVector::iterator it;
333
334 for(it = vector.begin(); it != vector.end(); ++it) {
335 (*it).notify();
336 }
337}
CloneNotificationsVector & cloneNotifications()

References KisBaseRectsWalker::cloneNotifications().

◆ resetProjection()

void KisAsyncMerger::resetProjection ( )
inlineprivate

Definition at line 272 of file kis_async_merger.cpp.

272 {
275}
KisPaintDeviceSP m_finalProjection

References m_currentProjection, and m_finalProjection.

◆ setupProjection()

void KisAsyncMerger::setupProjection ( KisProjectionLeafSP currentLeaf,
const QRect & rect,
bool useTempProjection )
inlineprivate

It happened so that our parent uses our own projection as its original. It means obligeChild mechanism works. We won't initialise m_currentProjection. This will cause writeProjection() and compositeWithProjection() do nothing when called.

Definition at line 277 of file kis_async_merger.cpp.

277 {
278 KisPaintDeviceSP parentOriginal = currentLeaf->parent()->lazyDestinationForSubtreeComposition();
279
280 if (parentOriginal) {
281 if (useTempProjection) {
283 m_cachedPaintDevice = new KisPaintDevice(parentOriginal->colorSpace());
285 m_currentProjection->prepareClone(parentOriginal);
286 m_finalProjection = parentOriginal;
287 }
288 else {
289 parentOriginal->clear(rect);
290 m_finalProjection = m_currentProjection = parentOriginal;
291 }
292 }
293 else {
301 /* NOP */
302 }
303}
KisPaintDeviceSP m_cachedPaintDevice
virtual void clear()
const KoColorSpace * colorSpace() const
void prepareClone(KisPaintDeviceSP src)

References KisPaintDevice::clear(), KisPaintDevice::colorSpace(), m_cachedPaintDevice, m_currentProjection, m_finalProjection, and KisPaintDevice::prepareClone().

◆ startMerge()

void KisAsyncMerger::startMerge ( KisBaseRectsWalker & walker,
bool notifyClones = true )

In some unidentified cases the nodes might be removed while the updates are still running. We have no proof of it yet, so just add a safety assert here.

Definition at line 172 of file kis_async_merger.cpp.

172 {
173 KisMergeWalker::LeafStack &leafStack = walker.leafStack();
174
175 const bool useTempProjections = walker.needRectVaries();
176
177 while(!leafStack.isEmpty()) {
178 KisMergeWalker::JobItem item = leafStack.pop();
179 KisProjectionLeafSP currentLeaf = item.m_leaf;
180
187 KIS_SAFE_ASSERT_RECOVER_RETURN(currentLeaf->node());
188
189 // All the masks should be filtered by the walkers
190 KIS_SAFE_ASSERT_RECOVER_RETURN(currentLeaf->isLayer());
191
192 QRect applyRect = item.m_applyRect;
193
194 if (currentLeaf->isRoot()) {
195 currentLeaf->projectionPlane()->recalculate(applyRect, walker.startNode(), item.m_renderFlags);
196 continue;
197 }
198
200 // The type of layers that will not go to projection.
201
202 DEBUG_NODE_ACTION("Updating", "N_EXTRA", currentLeaf, applyRect);
203 KisUpdateOriginalVisitor originalVisitor(applyRect,
205 currentLeaf->accept(originalVisitor);
206 currentLeaf->projectionPlane()->recalculate(applyRect, currentLeaf->node(), item.m_renderFlags);
207
208 continue;
209 }
210
211
212 if (!m_currentProjection) {
213 setupProjection(currentLeaf, applyRect, useTempProjections);
214 }
215
216 KisUpdateOriginalVisitor originalVisitor(applyRect,
218
220 DEBUG_NODE_ACTION("Updating", "N_FILTHY", currentLeaf, applyRect);
221 if (currentLeaf->shouldBeRendered()) {
222 currentLeaf->accept(originalVisitor);
223 currentLeaf->projectionPlane()->recalculate(applyRect, walker.startNode(), item.m_renderFlags);
224 }
225 }
227 DEBUG_NODE_ACTION("Updating", "N_ABOVE_FILTHY", currentLeaf, applyRect);
228 if(currentLeaf->dependsOnLowerNodes()) {
229 if (currentLeaf->shouldBeRendered()) {
230 currentLeaf->accept(originalVisitor);
231 currentLeaf->projectionPlane()->recalculate(applyRect, currentLeaf->node(), item.m_renderFlags);
232 }
233 }
234 }
236 DEBUG_NODE_ACTION("Updating", "N_FILTHY_PROJECTION", currentLeaf, applyRect);
237 if (currentLeaf->shouldBeRendered()) {
238 currentLeaf->projectionPlane()->recalculate(applyRect, walker.startNode(), item.m_renderFlags);
239 }
240 }
241 else /*if(item.m_position & KisMergeWalker::N_BELOW_FILTHY)*/ {
242 DEBUG_NODE_ACTION("Updating", "N_BELOW_FILTHY", currentLeaf, applyRect);
243 /* nothing to do */
244 }
245
246 compositeWithProjection(currentLeaf, applyRect);
247
249 writeProjection(currentLeaf, useTempProjections, applyRect);
251 }
252
253 // FIXME: remove it from the inner loop and/or change to a warning!
254 Q_ASSERT(currentLeaf->projection()->defaultBounds()->currentLevelOfDetail() ==
255 walker.levelOfDetail());
256 }
257
258 if(notifyClones) {
259 doNotifyClones(walker);
260 }
261
263 warnImage << "BUG: The walker hasn't reached the root layer!";
264 warnImage << " Start node:" << walker.startNode() << "Requested rect:" << walker.requestedRect();
265 warnImage << " An inconsistency in the walkers occurred!";
266 warnImage << " Please report a bug describing how you got this message.";
267 // reset projection to avoid artifacts in next merges and allow people to work further
269 }
270}
void doNotifyClones(KisBaseRectsWalker &walker)
bool compositeWithProjection(KisProjectionLeafSP leaf, const QRect &rect)
void writeProjection(KisProjectionLeafSP topmostLeaf, bool useTempProjection, const QRect &rect)
void setupProjection(KisProjectionLeafSP currentLeaf, const QRect &rect, bool useTempProjection)
KisNodeSP startNode() const
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define warnImage
Definition kis_debug.h:88

References compositeWithProjection(), DEBUG_NODE_ACTION, doNotifyClones(), KIS_SAFE_ASSERT_RECOVER_RETURN, KisBaseRectsWalker::leafStack(), KisBaseRectsWalker::levelOfDetail(), KisBaseRectsWalker::JobItem::m_applyRect, m_currentProjection, KisBaseRectsWalker::JobItem::m_leaf, KisBaseRectsWalker::JobItem::m_position, KisBaseRectsWalker::JobItem::m_renderFlags, KisBaseRectsWalker::N_ABOVE_FILTHY, KisBaseRectsWalker::N_EXTRA, KisBaseRectsWalker::N_FILTHY, KisBaseRectsWalker::N_FILTHY_PROJECTION, KisBaseRectsWalker::N_TOPMOST, KisBaseRectsWalker::needRectVaries(), KisBaseRectsWalker::requestedRect(), resetProjection(), setupProjection(), KisBaseRectsWalker::startNode(), warnImage, and writeProjection().

◆ writeProjection()

void KisAsyncMerger::writeProjection ( KisProjectionLeafSP topmostLeaf,
bool useTempProjection,
const QRect & rect )
inlineprivate

Definition at line 305 of file kis_async_merger.cpp.

305 {
306 Q_UNUSED(useTempProjection);
307 Q_UNUSED(topmostLeaf);
308 if (!m_currentProjection) return;
309
312 }
313 DEBUG_NODE_ACTION("Writing projection", "", topmostLeaf->parent(), rect);
314}
static void copyAreaOptimized(const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect)

References KisPainter::copyAreaOptimized(), DEBUG_NODE_ACTION, m_currentProjection, and m_finalProjection.

Member Data Documentation

◆ m_cachedPaintDevice

KisPaintDeviceSP KisAsyncMerger::m_cachedPaintDevice
private

Creation of the paint device is quite expensive, so we'll just save the pointer to our temporary device here and will get it when needed. This variable must not be used anywhere out of setupProjection()

Definition at line 52 of file kis_async_merger.h.

◆ m_currentProjection

KisPaintDeviceSP KisAsyncMerger::m_currentProjection
private

The place where intermediate results of layer's merge are going. It may be equal to m_finalProjection. In this case the projection will be written directly to the original of the parent layer

Definition at line 35 of file kis_async_merger.h.

◆ m_finalProjection

KisPaintDeviceSP KisAsyncMerger::m_finalProjection
private

The final destination of every projection of all the layers. It is equal to the original of a parental node. NOTE: This pointer is cached here to avoid race conditions

Definition at line 44 of file kis_async_merger.h.


The documentation for this class was generated from the following files: