Krita Source Code Documentation
Loading...
Searching...
No Matches
KisSafeNodeProjectionStore.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2019 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <QCoreApplication>
10#include <QMutex>
11#include <QMutexLocker>
12#include <QVector>
13#include <KoColorSpace.h>
14
15#include "kis_image.h"
16#include "kis_paint_device.h"
17#include "kis_selection.h"
19
20/**********************************************************************/
21/* StoreImplementationInterface */
22/**********************************************************************/
23
25{
27 virtual StoreImplementationInterface* clone() const = 0;
28 virtual bool releaseDevice() = 0;
29 virtual void discardCaches() = 0;
30 virtual void recycleProjectionsInSafety() = 0;
31};
32
33
34/**********************************************************************/
35/* StoreImplementation */
36/**********************************************************************/
37
38template <typename DeviceSP>
40{
41 bool releaseDevice() override {
42 bool hasDeletedProjection = false;
43
44 if (m_projection) {
46 m_projection = 0;
47 hasDeletedProjection = true;
48
49// qDebug() << "release a device";
50 }
51 return hasDeletedProjection;
52 }
53
54 virtual void discardCaches() override {
55// qDebug() << "discard caches";
56 m_dirtyProjections.clear();
57 }
58
59 virtual void recycleProjectionsInSafety() override {
60// qDebug() << "recycle caches";
61 Q_FOREACH (DeviceSP projection, m_dirtyProjections) {
62 projection->clear();
63 m_cleanProjections.append(projection);
64 }
65 m_dirtyProjections.clear();
66 }
67
68protected:
69 DeviceSP m_projection;
72};
73
74
75/**********************************************************************/
76/* StoreImplementationForDevice */
77/**********************************************************************/
78
80{
83 m_projection = new KisPaintDevice(prototype);
84 }
85
91
93 if(!m_projection ||
94 *m_projection->colorSpace() != *prototype->colorSpace()) {
95
96 if (!m_cleanProjections.isEmpty()) {
98 m_projection->makeCloneFromRough(prototype, prototype->extent());
99 } else {
100 m_projection = new KisPaintDevice(*prototype);
101 }
102
104 }
105 return m_projection;
106 }
107};
108
109
110/**********************************************************************/
111/* StoreImplementationForSelection */
112/**********************************************************************/
113
115{
118 m_projection = new KisSelection(prototype);
119 }
120
126
128 if(!m_projection) {
129 if (!m_cleanProjections.isEmpty()) {
130 m_projection = m_cleanProjections.takeLast();
132 } else {
133 m_projection = new KisSelection(*prototype);
134 }
135
137 }
138 return m_projection;
139 }
140};
141
142
143/**********************************************************************/
144/* KisSafeNodeProjectionStoreBase */
145/**********************************************************************/
146
148{
149 mutable QMutex lock;
151 QScopedPointer<StoreImplementationInterface> store;
152};
153
155 : m_d(new Private)
156{
157 m_d->store.reset(storeImpl);
158 moveToThread(qApp->thread());
160}
161
163 : QObject(),
164 KisShared(),
165 m_d(new Private)
166{
167 {
168 QMutexLocker rhsLocker(&rhs.m_d->lock);
169
170 m_d->image = rhs.m_d->image;
171 m_d->store.reset(rhs.m_d->store->clone());
172 }
173
174 moveToThread(qApp->thread());
176}
177
181
183{
184 QMutexLocker locker(&m_d->lock);
185 if (m_d->store->releaseDevice()) {
186 locker.unlock();
188 }
189}
190
192{
193 m_d->image = image;
194}
195
197{
206 KisImageSP image = m_d->image;
207
208 if (image) {
210 } else {
212 }
213}
214
216{
217 QMutexLocker locker(&m_d->lock);
218 m_d->store->discardCaches();
219}
220
222{
223 QMutexLocker locker(&m_d->lock);
224 m_d->store->recycleProjectionsInSafety();
225}
226
227
228/**********************************************************************/
229/* KisSafeNodeProjectionStore */
230/**********************************************************************/
231
236
241
243{
244 QMutexLocker locker(&m_d->lock);
245 StoreImplementationForDevice *store = dynamic_cast<StoreImplementationForDevice*>(m_d->store.data());
246 KIS_ASSERT(store);
247
248 return store->getDeviceLazy(prototype);
249}
250
251
252/**********************************************************************/
253/* KisSafeSelectionNodeProjectionStore */
254/**********************************************************************/
255
260
265
267{
268 QMutexLocker locker(&m_d->lock);
269 StoreImplementationForSelection *store = dynamic_cast<StoreImplementationForSelection*>(m_d->store.data());
270 KIS_ASSERT(store);
271
272 return store->getDeviceLazy(prototype);
273}
274
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void addSpontaneousJob(KisSpontaneousJob *spontaneousJob)
void makeCloneFromRough(KisPaintDeviceSP src, const QRect &minimalRect)
QRect extent() const
void setProjectionDevice(bool value)
const KoColorSpace * colorSpace() const
KisSafeNodeProjectionStoreBase(const KisSafeNodeProjectionStoreBase &rhs)
KisPaintDeviceSP getDeviceLazy(KisPaintDeviceSP prototype)
KisSelectionSP getDeviceLazy(KisSelectionSP prototype)
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
QScopedPointer< StoreImplementationInterface > store
KisPixelSelectionSP pixelSelection
QRect selectedRect() const
StoreImplementationInterface * clone() const override
StoreImplementationForDevice(const KisPaintDevice &prototype)
KisPaintDeviceSP getDeviceLazy(KisPaintDeviceSP prototype)
StoreImplementationInterface * clone() const override
KisSelectionSP getDeviceLazy(KisSelectionSP prototype)
StoreImplementationForSelection(const KisSelection &prototype)
virtual void recycleProjectionsInSafety()=0
virtual StoreImplementationInterface * clone() const =0
virtual bool releaseDevice()=0
virtual void discardCaches()=0
virtual void discardCaches() override
QVector< DeviceSP > m_cleanProjections
QVector< DeviceSP > m_dirtyProjections
virtual void recycleProjectionsInSafety() override