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

#include <kis_animation_frame_cache.h>

+ Inheritance diagram for KisAnimationFrameCache:

Classes

struct  Private
 

Public Types

enum  CacheStatus { Cached , Uncached }
 

Signals

void changed ()
 

Public Member Functions

void addConvertedFrameData (KisOpenGLUpdateInfoSP info, int time)
 
void dropLowQualityFrames (const KisTimeSpan &range, const QRect &regionOfInterest, const QRect &minimalRect)
 
KisOpenGLUpdateInfoSP fetchFrameData (int time, KisImageSP image, const KisRegion &requestedRegion) const
 
bool framesHaveValidRoi (const KisTimeSpan &range, const QRect &regionOfInterest)
 
CacheStatus frameStatus (int time) const
 
QImage getFrame (int time)
 
KisImageWSP image ()
 
 KisAnimationFrameCache (KisOpenGLImageTexturesSP textures)
 
bool shouldUploadNewFrame (int newTime, int oldTime) const
 
bool tryGlueSameFrames (const KisTimeSpan &range)
 
bool uploadFrame (int time)
 
 ~KisAnimationFrameCache () override
 
- Public Member Functions inherited from KisShared
bool deref ()
 
bool ref ()
 
int refCount ()
 
QAtomicInt * sharedWeakReference ()
 

Static Public Member Functions

static const KisAnimationFrameCacheSP cacheForImage (KisImageWSP image)
 
static const QList< KisAnimationFrameCache * > caches ()
 
static KisAnimationFrameCacheSP getFrameCache (KisOpenGLImageTexturesSP textures)
 

Private Slots

void framesChanged (const KisTimeSpan &range, const QRect &rect)
 
void slotConfigChanged ()
 

Private Attributes

QScopedPointer< Privatem_d
 

Additional Inherited Members

- Protected Member Functions inherited from KisShared
 KisShared ()
 
 ~KisShared ()
 

Detailed Description

Definition at line 28 of file kis_animation_frame_cache.h.

Member Enumeration Documentation

◆ CacheStatus

Constructor & Destructor Documentation

◆ KisAnimationFrameCache()

KisAnimationFrameCache::KisAnimationFrameCache ( KisOpenGLImageTexturesSP textures)

Definition at line 212 of file kis_animation_frame_cache.cpp.

213 : m_d(new Private(textures))
214{
215 // create swapping backend
217
218 connect(m_d->image->animationInterface(), SIGNAL(sigFramesChanged(KisTimeSpan,QRect)), this, SLOT(framesChanged(KisTimeSpan,QRect)));
219 connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotConfigChanged()));
220}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
QScopedPointer< Private > m_d
void framesChanged(const KisTimeSpan &range, const QRect &rect)
static KisConfigNotifier * instance()

References connect(), framesChanged(), KisConfigNotifier::instance(), m_d, and slotConfigChanged().

◆ ~KisAnimationFrameCache()

KisAnimationFrameCache::~KisAnimationFrameCache ( )
override

Definition at line 222 of file kis_animation_frame_cache.cpp.

223{
224 Private::caches.remove(m_d->textures);
225}

References KisAnimationFrameCache::Private::caches, and m_d.

Member Function Documentation

◆ addConvertedFrameData()

void KisAnimationFrameCache::addConvertedFrameData ( KisOpenGLUpdateInfoSP info,
int time )

Definition at line 432 of file kis_animation_frame_cache.cpp.

433{
434 const KisTimeSpan identicalRange =
436
437 m_d->addFrame(info, identicalRange);
438
439 Q_EMIT changed();
440}
static KisTimeSpan calculateIdenticalFramesRecursive(const KisNode *node, int time)

References KisTimeSpan::calculateIdenticalFramesRecursive(), changed(), and m_d.

◆ cacheForImage()

const KisAnimationFrameCacheSP KisAnimationFrameCache::cacheForImage ( KisImageWSP image)
static

Definition at line 204 of file kis_animation_frame_cache.cpp.

205{
206 auto it = std::find_if(Private::caches.begin(), Private::caches.end(),
207 [image] (KisAnimationFrameCache *cache) { return cache->image() == image; });
208
209 return it != Private::caches.end() ? *it : nullptr;
210}

References KisAnimationFrameCache::Private::caches, and image().

◆ caches()

const QList< KisAnimationFrameCache * > KisAnimationFrameCache::caches ( )
static

Definition at line 199 of file kis_animation_frame_cache.cpp.

200{
201 return Private::caches.values();
202}

References KisAnimationFrameCache::Private::caches.

◆ changed

void KisAnimationFrameCache::changed ( )
signal

◆ dropLowQualityFrames()

void KisAnimationFrameCache::dropLowQualityFrames ( const KisTimeSpan & range,
const QRect & regionOfInterest,
const QRect & minimalRect )

Drops all the frames with worse level of detail values than the current desired level of detail.

Definition at line 442 of file kis_animation_frame_cache.cpp.

443{
445 if (m_d->newFrames.isEmpty()) return;
446
447 auto it = m_d->newFrames.upperBound(range.start());
448
449 // the vector is guaranteed to be non-empty,
450 // so decrementing iterator is safe
451 if (it != m_d->newFrames.begin()) it--;
452
453 while (it != m_d->newFrames.end() && it.key() <= range.end()) {
454 const int frameId = it.key();
455 const int frameLength = it.value();
456
457 if (frameId + frameLength - 1 < range.start()) {
458 ++it;
459 continue;
460 }
461
462 const QRect frameRect = m_d->swapper->frameDirtyRect(frameId);
463 const int frameLod = m_d->swapper->frameLevelOfDetail(frameId);
464
465 if (frameLod > m_d->effectiveLevelOfDetail(regionOfInterest) || !frameRect.contains(minimalRect)) {
466 m_d->swapper->forgetFrame(frameId);
467 it = m_d->newFrames.erase(it);
468 } else {
469 ++it;
470 }
471 }
472}
int start() const
bool isInfinite() const
int end() const
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128

References KisTimeSpan::end(), KisTimeSpan::isInfinite(), KIS_SAFE_ASSERT_RECOVER_RETURN, m_d, and KisTimeSpan::start().

◆ fetchFrameData()

KisOpenGLUpdateInfoSP KisAnimationFrameCache::fetchFrameData ( int time,
KisImageSP image,
const KisRegion & requestedRegion ) const

Definition at line 405 of file kis_animation_frame_cache.cpp.

406{
407 if (time != image->animationInterface()->currentTime()) {
408 qWarning() << "WARNING: KisAnimationFrameCache::frameReady image's time doesn't coincide with the requested time!";
409 qWarning() << " " << ppVar(image->animationInterface()->currentTime()) << ppVar(time);
410 }
411
412 // the frames are always generated at full scale
414
415 const int lod = m_d->effectiveLevelOfDetail(requestedRegion.boundingRect());
416
417 KisOpenGLUpdateInfoSP totalInfo;
418
419 Q_FOREACH (const QRect &rc, requestedRegion.rects()) {
420 KisOpenGLUpdateInfoSP info = m_d->fetchFrameDataImpl(image, rc, lod);
421 if (!totalInfo) {
422 totalInfo = info;
423 } else {
424 const bool result = totalInfo->tryMergeWith(*info);
426 }
427 }
428
429 return totalInfo;
430}
KisImageAnimationInterface * animationInterface() const
int currentLevelOfDetail() const
bool tryMergeWith(const KisOpenGLUpdateInfo &rhs)
QRect boundingRect() const
QVector< QRect > rects() const
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
#define ppVar(var)
Definition kis_debug.h:155

References KisImage::animationInterface(), KisRegion::boundingRect(), KisImage::currentLevelOfDetail(), KisImageAnimationInterface::currentTime(), image(), KIS_SAFE_ASSERT_RECOVER_NOOP, m_d, ppVar, KisRegion::rects(), and KisOpenGLUpdateInfo::tryMergeWith().

◆ framesChanged

void KisAnimationFrameCache::framesChanged ( const KisTimeSpan & range,
const QRect & rect )
privateslot

Definition at line 362 of file kis_animation_frame_cache.cpp.

363{
364 Q_UNUSED(rect);
365
366 if (!range.isValid()) return;
367
368 bool cacheChanged = m_d->invalidate(range);
369
370 if (cacheChanged) {
371 Q_EMIT changed();
372 }
373}
bool isValid() const

References changed(), KisTimeSpan::isValid(), and m_d.

◆ framesHaveValidRoi()

bool KisAnimationFrameCache::framesHaveValidRoi ( const KisTimeSpan & range,
const QRect & regionOfInterest )

Definition at line 474 of file kis_animation_frame_cache.cpp.

475{
477 if (m_d->newFrames.isEmpty()) return false;
478
479 auto it = m_d->newFrames.upperBound(range.start());
480
481 if (it != m_d->newFrames.begin()) it--;
482
483 int expectedNextFrameStart = it.key();
484
485 while (it.key() <= range.end()) {
486 const int frameId = it.key();
487 const int frameLength = it.value();
488
489 if (frameId + frameLength - 1 < range.start()) {
490 expectedNextFrameStart = frameId + frameLength;
491 ++it;
492 continue;
493 }
494
495 if (expectedNextFrameStart != frameId) {
496 KIS_SAFE_ASSERT_RECOVER_NOOP(expectedNextFrameStart < frameId);
497 return false;
498 }
499
500 if (!m_d->swapper->frameDirtyRect(frameId).contains(regionOfInterest)) {
501 return false;
502 }
503
504 expectedNextFrameStart = frameId + frameLength;
505 ++it;
506 }
507
508 return true;
509}
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129

References KisTimeSpan::end(), KisTimeSpan::isInfinite(), KIS_SAFE_ASSERT_RECOVER_NOOP, KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, m_d, and KisTimeSpan::start().

◆ frameStatus()

KisAnimationFrameCache::CacheStatus KisAnimationFrameCache::frameStatus ( int time) const

Definition at line 254 of file kis_animation_frame_cache.cpp.

255{
256 return m_d->hasFrame(time) ? Cached : Uncached;
257}

References Cached, m_d, and Uncached.

◆ getFrame()

QImage KisAnimationFrameCache::getFrame ( int time)

◆ getFrameCache()

KisAnimationFrameCacheSP KisAnimationFrameCache::getFrameCache ( KisOpenGLImageTexturesSP textures)
static

Definition at line 184 of file kis_animation_frame_cache.cpp.

185{
187
188 Private::CachesMap::iterator it = Private::caches.find(textures);
189 if (it == Private::caches.end()) {
190 cache = new KisAnimationFrameCache(textures);
191 Private::caches.insert(textures, cache);
192 } else {
193 cache = it.value();
194 }
195
196 return cache;
197}
KisAnimationFrameCache(KisOpenGLImageTexturesSP textures)

References KisAnimationFrameCache::Private::caches, and KisAnimationFrameCache().

◆ image()

KisImageWSP KisAnimationFrameCache::image ( )

Definition at line 357 of file kis_animation_frame_cache.cpp.

358{
359 return m_d->image;
360}

References m_d.

◆ shouldUploadNewFrame()

bool KisAnimationFrameCache::shouldUploadNewFrame ( int newTime,
int oldTime ) const

Definition at line 243 of file kis_animation_frame_cache.cpp.

244{
245 if (oldTime < 0) return true;
246
247 const int oldKeyframeStart = m_d->getFrameIdAtTime(oldTime);
248 if (oldKeyframeStart < 0) return true;
249
250 const int oldKeyFrameLength = m_d->newFrames[oldKeyframeStart];
251 return !(newTime >= oldKeyframeStart && (newTime < oldKeyframeStart + oldKeyFrameLength || oldKeyFrameLength == -1));
252}

References m_d.

◆ slotConfigChanged

void KisAnimationFrameCache::slotConfigChanged ( )
privateslot

Definition at line 375 of file kis_animation_frame_cache.cpp.

376{
377 m_d->newFrames.clear();
378
379 KisImageConfig cfg(true);
380
381 if (cfg.useOnDiskAnimationCacheSwapping()) {
382 m_d->swapper.reset(new KisFrameCacheSwapper(m_d->textures->updateInfoBuilder(), cfg.swapDir()));
383 } else {
384 m_d->swapper.reset(new KisInMemoryFrameCacheSwapper());
385 }
386
387 m_d->frameSizeLimit = cfg.useAnimationCacheFrameSizeLimit() ? cfg.animationCacheFrameSizeLimit() : 0;
388 Q_EMIT changed();
389}

References KisImageConfig::animationCacheFrameSizeLimit(), changed(), m_d, KisImageConfig::swapDir(), KisImageConfig::useAnimationCacheFrameSizeLimit(), and KisImageConfig::useOnDiskAnimationCacheSwapping().

◆ tryGlueSameFrames()

bool KisAnimationFrameCache::tryGlueSameFrames ( const KisTimeSpan & range)

Definition at line 326 of file kis_animation_frame_cache.cpp.

327{
328 struct FramesGluer : FramesGluerBase
329 {
330 KisAbstractFrameCacheSwapper *swapper {nullptr};
331
332 FramesGluer(KisAbstractFrameCacheSwapper *_swapper, QMap<int, int> &_frames)
333 : FramesGluerBase(_frames)
334 , swapper(_swapper)
335 {}
336
337 void moveFrame(int oldStart, int newStart) override {
338 swapper->moveFrame(oldStart, newStart);
339 }
340
341 void forgetFrame(int start) override{
342 swapper->forgetFrame(start);
343 }
344 };
345
346 FramesGluer gluer(m_d->swapper.data(), m_d->newFrames);
347
348 const bool cacheChanged = gluer.glueFrames(range);
349
350 if (cacheChanged) {
351 Q_EMIT changed();
352 }
353
354 return cacheChanged;
355}
virtual void moveFrame(int oldStart, int newStart)=0

References changed(), m_d, and FramesGluerBase::moveFrame().

◆ uploadFrame()

bool KisAnimationFrameCache::uploadFrame ( int time)

Definition at line 227 of file kis_animation_frame_cache.cpp.

228{
229 KisOpenGLUpdateInfoSP info = m_d->getFrame(time);
230
231 if (!info) {
232 // Do nothing!
233 //
234 // Previously we were trying to start cache regeneration in this point,
235 // but it caused even bigger slowdowns when scrubbing
236 } else {
237 m_d->textures->recalculateCache(info, false);
238 }
239
240 return bool(info);
241}

References m_d.

Member Data Documentation

◆ m_d

QScopedPointer<Private> KisAnimationFrameCache::m_d
private

Definition at line 74 of file kis_animation_frame_cache.h.


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