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

#include <KisFrameCacheStore.h>

+ Inheritance diagram for KisFrameCacheStore:

Public Member Functions

void forgetFrame (int frameId)
 
QRect frameDirtyRect (int frameId) const
 
int frameLevelOfDetail (int frameId) const
 
bool hasFrame (int frameId) const
 
 KisFrameCacheStore ()
 
 KisFrameCacheStore (const QString &frameCachePath)
 
KisOpenGLUpdateInfoSP loadFrame (int frameId, const KisOpenGLUpdateInfoBuilder &builder)
 
void moveFrame (int srcFrameId, int dstFrameId)
 
 Private (const QString &frameCachePath)
 
void saveFrame (int frameId, KisOpenGLUpdateInfoSP info, const QRect &imageBounds)
 
 ~KisFrameCacheStore ()
 
- Public Member Functions inherited from Private
 Private (KisCanvas2 *c)
 

Public Attributes

KisFrameDataSerializer::Frame lastLoadedBaseFrame
 
FrameInfoSP lastLoadedBaseFrameInfo
 
KisFrameDataSerializer::Frame lastSavedFullFrame
 
int lastSavedFullFrameId = -1
 
QMap< int, FrameInfoSP > savedFrames
 
KisFrameDataSerializer serializer
 
- Public Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 

Private Attributes

const QScopedPointer< Privatem_d
 

Detailed Description

KisFrameCacheStore is a middle-level class for reading/writing animation frames on disk. Its main responsibilities:

1) Convert frames from KisOpenGLUpdateInfo format into a serializable KisFrameDataSerializer::Frame format.

2) Calculate differences between the frames and decide which frame will be a keyframe for other frames.

3) The keyframes will be used as a base for difference calculation and stored in a short in-memory cache to avoid fetching them from disk too often.

4) The in-memory cache of the keyframes is stored in serializable KisFrameDataSerializer::Frame format.

Definition at line 116 of file KisFrameCacheStore.cpp.

Constructor & Destructor Documentation

◆ KisFrameCacheStore() [1/2]

KisFrameCacheStore::KisFrameCacheStore ( )

Definition at line 136 of file KisFrameCacheStore.cpp.

137 : KisFrameCacheStore(QString())
138{
139}

◆ KisFrameCacheStore() [2/2]

KisFrameCacheStore::KisFrameCacheStore ( const QString & frameCachePath)

Definition at line 141 of file KisFrameCacheStore.cpp.

142 : m_d(new Private(frameCachePath))
143{
144}
const QScopedPointer< Private > m_d

◆ ~KisFrameCacheStore()

KisFrameCacheStore::~KisFrameCacheStore ( )

Definition at line 147 of file KisFrameCacheStore.cpp.

148{
149}

Member Function Documentation

◆ forgetFrame()

void KisFrameCacheStore::forgetFrame ( int frameId)

Definition at line 345 of file KisFrameCacheStore.cpp.

346{
347 KIS_SAFE_ASSERT_RECOVER_NOOP(m_d->savedFrames.contains(frameId));
348
349 if (m_d->lastSavedFullFrameId == frameId) {
350 m_d->lastSavedFullFrame = KisFrameDataSerializer::Frame();
351 m_d->lastSavedFullFrameId = -1;
352 }
353
354 m_d->savedFrames.remove(frameId);
355}
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130

References KIS_SAFE_ASSERT_RECOVER_NOOP, and m_d.

◆ frameDirtyRect()

QRect KisFrameCacheStore::frameDirtyRect ( int frameId) const

Definition at line 368 of file KisFrameCacheStore.cpp.

369{
370 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(m_d->savedFrames.contains(frameId), QRect());
371 return m_d->savedFrames[frameId]->dirtyImageRect();
372}
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129

References KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, and m_d.

◆ frameLevelOfDetail()

int KisFrameCacheStore::frameLevelOfDetail ( int frameId) const

Definition at line 362 of file KisFrameCacheStore.cpp.

363{
364 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(m_d->savedFrames.contains(frameId), 0);
365 return m_d->savedFrames[frameId]->levelOfDetail();
366}

References KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, and m_d.

◆ hasFrame()

bool KisFrameCacheStore::hasFrame ( int frameId) const

Definition at line 357 of file KisFrameCacheStore.cpp.

358{
359 return m_d->savedFrames.contains(frameId);
360}

References m_d.

◆ loadFrame()

KisOpenGLUpdateInfoSP KisFrameCacheStore::loadFrame ( int frameId,
const KisOpenGLUpdateInfoBuilder & builder )

Definition at line 245 of file KisFrameCacheStore.cpp.

246{
248 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(m_d->savedFrames.contains(frameId), info);
249
250 FrameInfoSP frameInfo = m_d->savedFrames[frameId];
251
252 info->assignDirtyImageRect(frameInfo->dirtyImageRect());
253 info->assignLevelOfDetail(frameInfo->levelOfDetail());
254
256
257 switch (frameInfo->type()) {
258 case FrameFull:
259 frame = m_d->serializer.loadFrame(frameInfo->frameDataId(), builder.textureInfoPool());
260 m_d->lastLoadedBaseFrame = frame.clone();
261 m_d->lastLoadedBaseFrameInfo = frameInfo;
262 break;
263 case FrameCopy: {
264 FrameInfoSP baseFrameInfo = frameInfo->baseFrame();
266
267 if (baseFrameInfo == m_d->lastLoadedBaseFrameInfo) {
268 frame = m_d->lastLoadedBaseFrame.clone();
269 } else {
270 frame = m_d->serializer.loadFrame(baseFrameInfo->frameDataId(), builder.textureInfoPool());
271 m_d->lastLoadedBaseFrame = frame.clone();
272 m_d->lastLoadedBaseFrameInfo = baseFrameInfo;
273 }
274 break;
275 }
276 case FrameDiff: {
277 FrameInfoSP baseFrameInfo = frameInfo->baseFrame();
279
280 if (baseFrameInfo == m_d->lastLoadedBaseFrameInfo) {
281 // noop
282 } else {
283 m_d->lastLoadedBaseFrame = m_d->serializer.loadFrame(baseFrameInfo->frameDataId(), builder.textureInfoPool());
284 m_d->lastLoadedBaseFrameInfo = baseFrameInfo;
285
286 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(m_d->lastLoadedBaseFrame.isValid(), KisOpenGLUpdateInfoSP());
287 }
288
289 const KisFrameDataSerializer::Frame &baseFrame = m_d->lastLoadedBaseFrame;
291
292 frame = m_d->serializer.loadFrame(frameInfo->frameDataId(), builder.textureInfoPool());
293 KisFrameDataSerializer::addFrames(frame, baseFrame);
294 break;
295 }
296 }
297
298 for (auto it = frame.frameTiles.begin(); it != frame.frameTiles.end(); ++it) {
300
301 QRect patchRect = tile.rect;
302
303 if (frameInfo->levelOfDetail()) {
304 patchRect = KisLodTransform::upscaledRect(patchRect, frameInfo->levelOfDetail());
305 }
306
307 const QRect fullSizeTileRect =
308 builder.calculatePhysicalTileRect(tile.col, tile.row,
309 frameInfo->imageBounds(),
310 frameInfo->levelOfDetail());
311
313 new KisTextureTileUpdateInfo(tile.col, tile.row,
314 fullSizeTileRect, patchRect,
315 frameInfo->imageBounds(),
316 frameInfo->levelOfDetail(),
317 builder.textureInfoPool()));
318
319 tileInfo->putPixelData(std::move(tile.data), builder.destinationColorSpace());
320
321 info->tileList << tileInfo;
322 }
323
324 return info;
325}
KisSharedPtr< KisOpenGLUpdateInfo > KisOpenGLUpdateInfoSP
static QRect upscaledRect(const QRect &srcRect, int lod)
KisTextureTileUpdateInfoSPList tileList
void assignLevelOfDetail(int lod)
void assignDirtyImageRect(const QRect &rect)
std::vector< FrameTile > frameTiles
static void addFrames(Frame &dst, const Frame &src)
const KoColorSpace * destinationColorSpace() const
KisTextureTileInfoPoolSP textureInfoPool() const
QRect calculatePhysicalTileRect(int col, int row, const QRect &imageBounds, int levelOfDetail) const

References KisFrameDataSerializer::addFrames(), KisOpenGLUpdateInfo::assignDirtyImageRect(), KisOpenGLUpdateInfo::assignLevelOfDetail(), KisOpenGLUpdateInfoBuilder::calculatePhysicalTileRect(), KisFrameDataSerializer::Frame::clone(), KisFrameDataSerializer::FrameTile::col, KisFrameDataSerializer::FrameTile::data, KisOpenGLUpdateInfoBuilder::destinationColorSpace(), KisFrameDataSerializer::Frame::frameTiles, KisFrameDataSerializer::Frame::isValid(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, m_d, KisFrameDataSerializer::FrameTile::rect, KisFrameDataSerializer::FrameTile::row, KisOpenGLUpdateInfoBuilder::textureInfoPool(), KisOpenGLUpdateInfo::tileList, and KisLodTransformBase::upscaledRect().

◆ moveFrame()

void KisFrameCacheStore::moveFrame ( int srcFrameId,
int dstFrameId )

Definition at line 327 of file KisFrameCacheStore.cpp.

328{
329 KIS_SAFE_ASSERT_RECOVER_RETURN(srcFrameId != dstFrameId);
330
331 KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->savedFrames.contains(srcFrameId));
332
333 KIS_SAFE_ASSERT_RECOVER(!m_d->savedFrames.contains(dstFrameId)) {
334 m_d->savedFrames.remove(dstFrameId);
335 }
336
337 m_d->savedFrames.insert(dstFrameId, m_d->savedFrames[srcFrameId]);
338 m_d->savedFrames.remove(srcFrameId);
339
340 if (m_d->lastSavedFullFrameId == srcFrameId) {
341 m_d->lastSavedFullFrameId = dstFrameId;
342 }
343}
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128

References KIS_SAFE_ASSERT_RECOVER, KIS_SAFE_ASSERT_RECOVER_RETURN, and m_d.

◆ Private()

KisFrameCacheStore::Private ( const QString & frameCachePath)
inline

Definition at line 118 of file KisFrameCacheStore.cpp.

119 : serializer(frameCachePath)
120 {
121 }
KisFrameDataSerializer serializer

◆ saveFrame()

void KisFrameCacheStore::saveFrame ( int frameId,
KisOpenGLUpdateInfoSP info,
const QRect & imageBounds )

The full-copying code is disabled intentionally:

We should never remove user-visible data on basis of statistics. On smaller images, like 32x32 pixels, there might be really subtle changes that are important for the user. So we should use difference instead of dumb copying.

Definition at line 151 of file KisFrameCacheStore.cpp.

152{
153 int pixelSize = 0;
154
155 Q_FOREACH (auto tile, info->tileList) {
156#ifdef SANITY_CHECK
157 if (!pixelSize) {
158 pixelSize = tile->pixelSize();
159 } else {
160 KIS_SAFE_ASSERT_RECOVER_RETURN(pixelSize == tile->pixelSize());
161 }
162#else
163 pixelSize = tile->pixelSize();
164 break;
165#endif
166 }
167
169
170 // TODO: assert that dirty image rect is equal to the full image rect
171 // TODO: assert tile color space coincides with the destination color space
172
174 frame.pixelSize = pixelSize;
175
176 for (auto it = info->tileList.begin(); it != info->tileList.end(); ++it) {
177 KisFrameDataSerializer::FrameTile tile(KisTextureTileInfoPoolSP(0)); // TODO: fix the pool should never be null!
178 tile.col = (*it)->tileCol();
179 tile.row = (*it)->tileRow();
180 tile.rect = (*it)->realPatchRect();
181 tile.data = std::move((*it)->takePixelData());
182
183 KIS_SAFE_ASSERT_RECOVER(tile.data.data()) { continue; }
184
185 frame.frameTiles.push_back(std::move(tile));
186 }
187
188 FrameInfoSP frameInfo;
189
190 if (m_d->lastSavedFullFrame.isValid()) {
191 boost::optional<qreal> uniqueness = KisFrameDataSerializer::estimateFrameUniqueness(m_d->lastSavedFullFrame, frame, 0.01);
192
193
194 if (uniqueness) {
195
204#if 0
205 if (*uniqueness == 0.0) {
206 FrameInfoSP baseFrameInfo = m_d->savedFrames[m_d->lastSavedFullFrameId];
207 frameInfo = toQShared(new FrameInfo(info->dirtyImageRect(),
208 imageBounds,
209 info->levelOfDetail(),
210 m_d->serializer,
211 baseFrameInfo));
212
213 } else
214#endif
215 if (*uniqueness < 0.5) {
216 FrameInfoSP baseFrameInfo = m_d->savedFrames[m_d->lastSavedFullFrameId];
217
218 KisFrameDataSerializer::subtractFrames(frame, m_d->lastSavedFullFrame);
219 frameInfo = toQShared(new FrameInfo(info->dirtyImageRect(),
220 imageBounds,
221 info->levelOfDetail(),
222 m_d->serializer,
223 baseFrameInfo,
224 frame));
225 }
226 }
227 }
228
229 if (!frameInfo) {
230 frameInfo = toQShared(new FrameInfo(info->dirtyImageRect(),
231 imageBounds,
232 info->levelOfDetail(),
233 m_d->serializer,
234 frame));
235 }
236
237 m_d->savedFrames.insert(frameId, frameInfo);
238
239 if (frameInfo->type() == FrameFull) {
240 m_d->lastSavedFullFrame = std::move(frame);
241 m_d->lastSavedFullFrameId = frameId;
242 }
243}
QRect dirtyImageRect() const override
int levelOfDetail() const override
QSharedPointer< KisTextureTileInfoPool > KisTextureTileInfoPoolSP
QSharedPointer< T > toQShared(T *ptr)
static boost::optional< qreal > estimateFrameUniqueness(const Frame &lhs, const Frame &rhs, qreal portion)
static bool subtractFrames(Frame &dst, const Frame &src)

References KisFrameDataSerializer::FrameTile::col, KisFrameDataSerializer::FrameTile::data, DataBuffer::data(), KisOpenGLUpdateInfo::dirtyImageRect(), KisFrameDataSerializer::estimateFrameUniqueness(), KisFrameDataSerializer::Frame::frameTiles, KIS_SAFE_ASSERT_RECOVER, KIS_SAFE_ASSERT_RECOVER_RETURN, KisOpenGLUpdateInfo::levelOfDetail(), m_d, KisFrameDataSerializer::Frame::pixelSize, KisFrameDataSerializer::FrameTile::rect, KisFrameDataSerializer::FrameTile::row, KisFrameDataSerializer::subtractFrames(), KisOpenGLUpdateInfo::tileList, and toQShared().

Member Data Documentation

◆ lastLoadedBaseFrame

KisFrameDataSerializer::Frame KisFrameCacheStore::lastLoadedBaseFrame

Definition at line 130 of file KisFrameCacheStore.cpp.

◆ lastLoadedBaseFrameInfo

FrameInfoSP KisFrameCacheStore::lastLoadedBaseFrameInfo

Definition at line 131 of file KisFrameCacheStore.cpp.

◆ lastSavedFullFrame

KisFrameDataSerializer::Frame KisFrameCacheStore::lastSavedFullFrame

Definition at line 127 of file KisFrameCacheStore.cpp.

◆ lastSavedFullFrameId

int KisFrameCacheStore::lastSavedFullFrameId = -1

Definition at line 128 of file KisFrameCacheStore.cpp.

◆ m_d

const QScopedPointer<Private> KisFrameCacheStore::m_d
private

Definition at line 60 of file KisFrameCacheStore.h.

◆ savedFrames

QMap<int, FrameInfoSP> KisFrameCacheStore::savedFrames

Definition at line 133 of file KisFrameCacheStore.cpp.

◆ serializer

KisFrameDataSerializer KisFrameCacheStore::serializer

Definition at line 125 of file KisFrameCacheStore.cpp.


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