Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_indirect_painting_support.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2004 Bart Coppens <kde@bartcoppens.be>
3 * SPDX-FileCopyrightText: 2010 Dmitry Kazakov <dimula73@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
9
10#include <QReadWriteLock>
11
12#include <KoCompositeOp.h>
13#include "kis_layer.h"
14#include "kis_paint_layer.h"
15#include "kis_paint_device.h"
16#include "kis_selection.h"
17#include "kis_painter.h"
21#include "kis_transaction.h"
22#include "kis_pointer_utils.h"
23
24
25struct Q_DECL_HIDDEN KisIndirectPaintingSupport::Private {
26 // To simulate the indirect painting
28 QString compositeOp;
30 QBitArray channelFlags;
32
33 QReadWriteLock lock;
34 bool finalMergeInProgress = true;
35};
36
37
42
47
49{
50 Q_UNUSED(color);
51}
52
54{
55 d->temporaryTarget = t;
56}
57
59{
60 d->compositeOp = id;
61}
62
64{
65 d->compositeOpacity = o;
66}
67
69{
70 d->channelFlags = channelFlags;
71}
72
77
79{
80 d->lock.lockForRead();
81}
82
84{
85 d->lock.lockForWrite();
86 d->finalMergeInProgress = true;
87}
88
90{
91 d->lock.unlock();
92 d->finalMergeInProgress = false;
93}
94
96{
97 return d->temporaryTarget;
98}
99
101{
102 return true;
103}
104
109
111{
112 return d->compositeOp;
113}
114
116{
117 return d->selection;
118}
119
121{
122 return d->temporaryTarget;
123}
124
126{
127 painter->setOpacityF(d->compositeOpacity);
128 painter->setCompositeOpId(d->compositeOp);
129 painter->setChannelFlags(d->channelFlags);
130 painter->setSelection(d->selection);
131}
132
133void KisIndirectPaintingSupport::mergeToLayer(KisNodeSP layer, KUndo2Command *parentCommand, const KUndo2MagicString &transactionText, int timedID)
134{
136 mergeToLayerThreaded(layer, parentCommand, transactionText, timedID, &jobs);
137
146 executor.addRunnableJobs(implicitCastList<KisRunnableStrokeJobDataBase*>(jobs));
147}
148
150{
157 WriteLockerSP sharedWriteLock(new WriteLocker(this, std::defer_lock));
158
163 [sharedWriteLock] () {
164 sharedWriteLock->relock();
165 });
166
167 mergeToLayerImpl(layer->paintDevice(), parentCommand, transactionText,
168 timedID, true, sharedWriteLock,
169 jobs);
170}
171
172void KisIndirectPaintingSupport::mergeToLayerImpl(KisPaintDeviceSP dst, KUndo2Command *parentCommand, const KUndo2MagicString &transactionText, int timedID, bool cleanResources,
174{
175 struct SharedState {
176 QScopedPointer<KisTransaction> transaction;
177 };
178
179 QSharedPointer<SharedState> sharedState(new SharedState());
180
182 [sharedState, sharedWriteLock, dst, parentCommand, transactionText, timedID] () {
183 Q_UNUSED(sharedWriteLock); // just a RAII holder object for the lock
184
188 if (parentCommand) {
189 sharedState->transaction.reset(
190 new KisTransaction(transactionText, dst, parentCommand, timedID));
191 }
192 }
193 );
194
195 KisPaintDeviceSP src = d->temporaryTarget;
196 Q_FOREACH (const QRect &rc, src->region().rects()) {
198 [this, rc, src, dst, sharedState, sharedWriteLock] () {
199 Q_UNUSED(sharedWriteLock); // just a RAII holder object for the lock
200
206 KisPainter gc(dst);
208 this->writeMergeData(&gc, src, rc);
209 }
210 );
211 }
212
214 [this, sharedState, sharedWriteLock, cleanResources] () {
215 Q_UNUSED(sharedWriteLock); // just a RAII holder object for the lock
216
217 if (cleanResources) {
219 }
220
221 if (sharedState->transaction) {
222 // the internal command is stored using
223 // the link to the parent command
224 (void) sharedState->transaction->endAndTake();
225 }
226 }
227 );
228}
229
231{
232 painter->bitBlt(rc.topLeft(), src, rc);
233}
234
236{
237 d->temporaryTarget = 0;
238 d->selection = 0;
239 d->compositeOp = COMPOSITE_OVER;
240 d->compositeOpacity = OPACITY_OPAQUE_F;
241 d->channelFlags.clear();
242}
243
249
251{
252 m_lock->lockTemporaryTargetForWrite();
253}
const qreal OPACITY_OPAQUE_F
const QString COMPOSITE_OVER
void addRunnableJobs(const QVector< KisRunnableStrokeJobDataBase * > &list) override
void setSelection(KisSelectionSP selection)
void setOpacityF(qreal opacity)
void bitBlt(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
void setChannelFlags(QBitArray channelFlags)
void setCompositeOpId(const KoCompositeOp *op)
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)
QSharedPointer< T > toQShared(T *ptr)
void addJobConcurrent(QVector< Job * > &jobs, Func func)
void addJobSequential(QVector< Job * > &jobs, Func func)
void addJobBarrier(QVector< Job * > &jobs, Func func)
virtual KisPaintDeviceSP paintDevice() const =0
virtual void writeMergeData(KisPainter *painter, KisPaintDeviceSP src, const QRect &rc)
void setTemporaryChannelFlags(const QBitArray &channelFlags)
virtual void mergeToLayerThreaded(KisNodeSP layer, KUndo2Command *parentCommand, const KUndo2MagicString &transactionText, int timedID, QVector< KisRunnableStrokeJobData * > *jobs)
virtual void setCurrentColor(const KoColor &color)
void setupTemporaryPainter(KisPainter *painter) const
void mergeToLayerImpl(KisPaintDeviceSP dst, KUndo2Command *parentCommand, const KUndo2MagicString &transactionText, int timedID, bool cleanResources, WriteLockerSP sharedWriteLock, QVector< KisRunnableStrokeJobData * > *jobs)
void mergeToLayer(KisNodeSP layer, KUndo2Command *parentCommand, const KUndo2MagicString &transactionText, int timedID)
void setTemporarySelection(KisSelectionSP selection)
void setTemporaryCompositeOp(const QString &id)