20#ifdef ENABLE_DEBUG_JOIN
21 #define DEBUG_JOIN(baseRect, newRect, alpha) \
22 dbgKrita << "Two rects were joined:\t" \
23 << (baseRect) << "+" << (newRect) << "->" \
24 << ((baseRect) | (newRect)) << "(" << alpha << ")"
27 #define DEBUG_JOIN(baseRect, newRect, alpha)
31#ifdef ENABLE_ACCUMULATOR
32 #define DECLARE_ACCUMULATOR() static qreal _baseAmount=0, _newAmount=0
33 #define ACCUMULATOR_ADD(baseAmount, newAmount) \
34 do {_baseAmount += baseAmount; _newAmount += newAmount;} while (0)
35 #define ACCUMULATOR_DEBUG() \
36 dbgKrita << "Accumulated alpha:" << _newAmount / _baseAmount
38 #define DECLARE_ACCUMULATOR()
39 #define ACCUMULATOR_ADD(baseAmount, newAmount)
40 #define ACCUMULATOR_DEBUG()
45 : m_overrideLevelOfDetail(-1)
52 QMutexLocker locker(&
m_lock);
61 QMutexLocker locker(&
m_lock);
80 updaterContext.
lock();
90 QMutexLocker locker(&
m_lock);
94 bool jobAdded =
false;
98 while(iter.hasNext()) {
101 if ((currentLevelOfDetail < 0 || currentLevelOfDetail == item->levelOfDetail()) &&
109 if ((currentLevelOfDetail < 0 || currentLevelOfDetail == item->levelOfDetail()) &&
119 if (jobAdded)
return true;
133 qint32 numStrokeJobs;
137 if (!numMergeJobs && !numStrokeJobs &&
138 (currentLevelOfDetail < 0 || currentLevelOfDetail == job->levelOfDetail())) {
156 addJob(node, rects, cropRect, levelOfDetail,
168 addJob(node, rects, cropRect, levelOfDetail,
184 const QRect& cropRect,
187 bool dontInvalidateFrames)
191 Q_FOREACH (
const QRect &rc, rects) {
192 if (rc.isEmpty())
continue;
196 if(
trySplitJob(node, rc, cropRect, levelOfDetail, type, dontInvalidateFrames))
continue;
197 if(
tryMergeJob(node, rc, cropRect, levelOfDetail, type, dontInvalidateFrames))
continue;
201 if (dontInvalidateFrames) {
209 if (dontInvalidateFrames) {
217 if (dontInvalidateFrames) {
225 if (dontInvalidateFrames) {
234 walkers.append(walker);
237 if (!walkers.isEmpty()) {
246 QMutexLocker locker(&
m_lock);
253 while(iter.hasPrevious()) {
254 item = iter.previous();
267 QMutexLocker locker(&
m_lock);
273 QMutexLocker locker(&
m_lock);
278 const QRect& cropRect,
281 bool dontInvalidateFrames)
296 for(qint32 i = firstRow; i <= lastRow; i++) {
297 for(qint32 j = firstCol; j <= lastCol; j++) {
300 QRect patchRect = rc & maxPatchRect;
301 splitRects.append(patchRect);
306 addJob(node, splitRects, cropRect, levelOfDetail, type, dontInvalidateFrames);
312 const QRect& cropRect,
315 bool dontInvalidateFrames)
317 QMutexLocker locker(&
m_lock);
332 while(iter.hasPrevious()) {
333 item = iter.previous();
336 if(item->
type() != type)
continue;
338 if(item->
cropRect() != cropRect)
continue;
342 goodCandidate = item;
350 return (
bool)goodCandidate;
355 QMutexLocker locker(&
m_lock);
367 const qreal maxAlpha)
372 while(iter.hasNext()) {
375 if(item == baseWalker)
continue;
376 if(item->
type() != baseWalker->
type())
continue;
393 const QRect& newRect, qreal maxAlpha)
395 QRect unitedRect = baseRect | newRect;
400 qint64 baseWork = qint64(baseRect.width()) * baseRect.height() +
401 qint64(newRect.width()) * newRect.height();
403 qint64 newWork = qint64(unitedRect.width()) * unitedRect.height();
405 qreal alpha = qreal(newWork) / baseWork;
407 if(alpha < maxAlpha) {
414 baseRect = unitedRect;
QRect requestedRect() const
void collectRects(KisNodeSP node, const QRect &requestedRect)
bool clonesDontInvalidateFrames() const
int levelOfDetail() const
void recalculate(const QRect &requestedRect)
virtual UpdateType type() const =0
KisNodeSP startNode() const
int updatePatchWidth() const
qreal maxMergeCollectAlpha() const
int updatePatchHeight() const
qreal maxMergeAlpha() const
qreal maxCollectAlpha() const
@ CLONES_DONT_INVALIDATE_FRAMES
@ ClonesDontInvalidateFrames
void addJob(KisNodeSP node, const QVector< QRect > &rects, const QRect &cropRect, int levelOfDetail, KisBaseRectsWalker::UpdateType type, bool dontInvalidateFrames)
bool processOneJob(KisUpdaterContext &updaterContext)
int overrideLevelOfDetail() const
bool joinRects(QRect &baseRect, const QRect &newRect, qreal maxAlpha)
void addFullRefreshJob(KisNodeSP node, const QVector< QRect > &rects, const QRect &cropRect, int levelOfDetail, KisProjectionUpdateFlags flags)
void collectJobs(KisBaseRectsWalkerSP &baseWalker, QRect baseRect, const qreal maxAlpha)
int m_overrideLevelOfDetail
virtual ~KisSimpleUpdateQueue()
void addSpontaneousJob(KisSpontaneousJob *spontaneousJob)
KisSpontaneousJobsList m_spontaneousJobsList
KisWalkersList m_updatesList
bool tryMergeJob(KisNodeSP node, const QRect &rc, const QRect &cropRect, int levelOfDetail, KisBaseRectsWalker::UpdateType type, bool dontInvalidateFrames)
void processQueue(KisUpdaterContext &updaterContext)
qint32 sizeMetric() const
void addUpdateJob(KisNodeSP node, const QVector< QRect > &rects, const QRect &cropRect, int levelOfDetail, KisProjectionUpdateFlags flags)
bool trySplitJob(KisNodeSP node, const QRect &rc, const QRect &cropRect, int levelOfDetail, KisBaseRectsWalker::UpdateType type, bool dontInvalidateFrames)
qreal m_maxMergeCollectAlpha
virtual bool overrides(const KisSpontaneousJob *otherJob)=0
KisSpontaneousJobsList & getSpontaneousJobsList()
KisWalkersList & getWalkersList()
void getJobsSnapshot(qint32 &numMergeJobs, qint32 &numStrokeJobs)
bool isJobAllowed(KisBaseRectsWalkerSP walker)
void addMergeJob(KisBaseRectsWalkerSP walker)
void addSpontaneousJob(KisSpontaneousJob *spontaneousJob)
int currentLevelOfDetail() const
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
#define DECLARE_ACCUMULATOR()
#define ACCUMULATOR_ADD(baseAmount, newAmount)
#define DEBUG_JOIN(baseRect, newRect, alpha)
#define ACCUMULATOR_DEBUG()
QListIterator< KisBaseRectsWalkerSP > KisWalkersListIterator
QMutableListIterator< KisSpontaneousJob * > KisMutableSpontaneousJobsListIterator
QMutableListIterator< KisBaseRectsWalkerSP > KisMutableWalkersListIterator