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

The KisFrameDisplayProxy class sits between the KisCanvas (within its KisCanvasAnimationState) and its associated KisImage. Its mainly responsible for choosing whether to reproject the image (always accurate) OR reuse the canvas' KisAnimationFrameCache (usually fast). :) More...

#include <KisFrameDisplayProxy.h>

+ Inheritance diagram for KisFrameDisplayProxy:

Signals

void sigFrameChange ()
 
void sigFrameDisplayRefreshed ()
 
void sigFrameRefreshSkipped ()
 sigFrameRefreshSkipped tracks whether asynchronous "slow" refreshes are skipped due to the frame being the same. In the case of waiting for next frame to render, it is necessary to let any binding classes know that the there was no need to refresh the display at all.
 

Public Member Functions

int activeFrame () const
 Gets the active frame, the frame that is intended to be shown. This should always reflect the actual time position of the canvas at any given point. In certain circumstances this value can be different from what is currently being shown. (For example, when showing the activeKeyframe instead.)
 
bool displayFrame (int frame, bool forceReproject)
 Tell the DisplayProxy to show a new frame.
 
 KisFrameDisplayProxy (class KisCanvas2 *canvas, QObject *parent=nullptr)
 
 ~KisFrameDisplayProxy ()
 

Private Member Functions

int activeKeyframe () const
 Get the active keyframe. This is the latest unique frame that is actually visible. It is not always the same as the position of playback, since it only changes when there's new content to be shown. (Consider "held" frames.)
 
bool needsReprojection (KisAnimationFrameCacheSP cache, int from, int to)
 
bool shouldUploadFrame (KisAnimationFrameCacheSP cache, int from, int to)
 

Private Attributes

QScopedPointer< struct Privatem_d
 

Detailed Description

The KisFrameDisplayProxy class sits between the KisCanvas (within its KisCanvasAnimationState) and its associated KisImage. Its mainly responsible for choosing whether to reproject the image (always accurate) OR reuse the canvas' KisAnimationFrameCache (usually fast). :)

Definition at line 21 of file KisFrameDisplayProxy.h.

Constructor & Destructor Documentation

◆ KisFrameDisplayProxy()

KisFrameDisplayProxy::KisFrameDisplayProxy ( class KisCanvas2 * canvas,
QObject * parent = nullptr )

Definition at line 25 of file KisFrameDisplayProxy.cpp.

26 : QObject(parent)
27 , m_d(new Private(canvas))
28{
29 KIS_ASSERT(canvas);
30
31 connect(m_d->canvas->image()->animationInterface(), &KisImageAnimationInterface::sigFrameRegenerated, this, [this](int frame){
32 if (m_d->intendedFrame != frame ) {
33 // We only want to correct our intended frame when the image regenerates
34 // and we're not currently in playback. (In other words, when the state of the image
35 // is determined by external time controls.)
36 KisCanvasAnimationState* state = m_d->canvas->animationState();
37 if (state->playbackState() != PLAYING) {
38 m_d->intendedFrame = frame;
39 Q_EMIT sigFrameChange();
40 }
41 }
42
43 if (m_d->displayedFrame != frame) {
44 m_d->displayedFrame = frame;
45 Q_EMIT sigFrameDisplayRefreshed();
46 }
47 });
48
49
50 connect(m_d->canvas->image()->animationInterface(), &KisImageAnimationInterface::sigFrameRegenerationSkipped, this, [this](int frame){
51 if (m_d->intendedFrame != frame) {
52 //TODO make below a method?
53 KisCanvasAnimationState* state = m_d->canvas->animationState();
54 if (state->playbackState() != PLAYING) {
55 m_d->intendedFrame = frame;
56 Q_EMIT sigFrameChange();
57 }
58 }
59
61 });
62
63 m_d->displayedFrame = m_d->canvas->image()->animationInterface()->currentUITime();
64 m_d->intendedFrame = m_d->displayedFrame;
65}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void sigFrameRefreshSkipped()
sigFrameRefreshSkipped tracks whether asynchronous "slow" refreshes are skipped due to the frame bein...
QScopedPointer< struct Private > m_d
void sigFrameRegenerationSkipped(int time)
sigFrameRegenerationSkipped notified when async frame changes are skipped.
void sigFrameRegenerated(int time)
sigFrameRegenerated notifies when internal frame has been fully regenerated.
#define KIS_ASSERT(cond)
Definition kis_assert.h:33

References connect(), KIS_ASSERT, m_d, and KisImageAnimationInterface::sigFrameRegenerated().

◆ ~KisFrameDisplayProxy()

KisFrameDisplayProxy::~KisFrameDisplayProxy ( )

Definition at line 67 of file KisFrameDisplayProxy.cpp.

68{
69}

Member Function Documentation

◆ activeFrame()

int KisFrameDisplayProxy::activeFrame ( ) const

Gets the active frame, the frame that is intended to be shown. This should always reflect the actual time position of the canvas at any given point. In certain circumstances this value can be different from what is currently being shown. (For example, when showing the activeKeyframe instead.)

Definition at line 108 of file KisFrameDisplayProxy.cpp.

109{
110 return m_d->intendedFrame;
111}

References m_d.

◆ activeKeyframe()

int KisFrameDisplayProxy::activeKeyframe ( ) const
private

Get the active keyframe. This is the latest unique frame that is actually visible. It is not always the same as the position of playback, since it only changes when there's new content to be shown. (Consider "held" frames.)

Definition at line 113 of file KisFrameDisplayProxy.cpp.

114{
115 return m_d->displayedFrame;
116}

References m_d.

◆ displayFrame()

bool KisFrameDisplayProxy::displayFrame ( int frame,
bool forceReproject )

Tell the DisplayProxy to show a new frame.

Parameters
forceReprojectdemands that the image used instead of the canvas' animation cache.

Definition at line 71 of file KisFrameDisplayProxy.cpp.

72{
73 KisAnimationFrameCacheSP cache = m_d->canvas->frameCache();
75
76 if (frame != m_d->intendedFrame) {
77 m_d->intendedFrame = frame;
78 Q_EMIT sigFrameChange();
79 }
80
81 if (forceReproject || needsReprojection(cache, m_d->displayedFrame, frame)) {
82 // BUG:445265
83 // Edgecase occurs where if we move from a cached frame to a non-cached frame,
84 // we never technically "switch" to the cached one during scrubbing, which
85 // will prevent the uncached frame from ever determining it needs to be
86 // regenerated. We will force a frame switch when going from uncached to cached
87 // to work around this issue.
89 return true;
90
91 } else if ( shouldUploadFrame(cache, m_d->displayedFrame, frame) && cache->uploadFrame(frame) ) {
92 m_d->canvas->updateCanvas();
93 m_d->displayedFrame = frame;
95 return true;
96
97 } else if (!cache && ai->hasAnimation() && ai->currentUITime() != frame){
98 if (m_d->canvas->image()->tryBarrierLock(true)) {
99 m_d->canvas->image()->unlock();
100 ai->switchCurrentTimeAsync(frame);
101 return true;
102 }
103 }
104
105 return false;
106}
bool shouldUploadFrame(KisAnimationFrameCacheSP cache, int from, int to)
bool needsReprojection(KisAnimationFrameCacheSP cache, int from, int to)
void sigFrameDisplayRefreshed()
void switchCurrentTimeAsync(int frameId, SwitchTimeAsyncFlags options=STAO_NONE)
KisImageAnimationInterface * animationInterface() const

References KisImage::animationInterface(), KisImageAnimationInterface::currentUITime(), KisImageAnimationInterface::hasAnimation(), KisImageAnimationInterface::image(), m_d, needsReprojection(), shouldUploadFrame(), sigFrameChange(), sigFrameDisplayRefreshed(), KisImageAnimationInterface::STAO_FORCE_REGENERATION, KisImageAnimationInterface::switchCurrentTimeAsync(), and KisAnimationFrameCache::uploadFrame().

◆ needsReprojection()

bool KisFrameDisplayProxy::needsReprojection ( KisAnimationFrameCacheSP cache,
int from,
int to )
private

Definition at line 123 of file KisFrameDisplayProxy.cpp.

124{
125 return cache && cache->frameStatus(from) != cache->frameStatus(to);
126}
CacheStatus frameStatus(int time) const

References KisAnimationFrameCache::frameStatus().

◆ shouldUploadFrame()

bool KisFrameDisplayProxy::shouldUploadFrame ( KisAnimationFrameCacheSP cache,
int from,
int to )
private

Definition at line 118 of file KisFrameDisplayProxy.cpp.

119{
120 return cache && cache->shouldUploadNewFrame(to, from);
121}
bool shouldUploadNewFrame(int newTime, int oldTime) const

References KisAnimationFrameCache::shouldUploadNewFrame().

◆ sigFrameChange

void KisFrameDisplayProxy::sigFrameChange ( )
signal

◆ sigFrameDisplayRefreshed

void KisFrameDisplayProxy::sigFrameDisplayRefreshed ( )
signal

◆ sigFrameRefreshSkipped

void KisFrameDisplayProxy::sigFrameRefreshSkipped ( )
signal

sigFrameRefreshSkipped tracks whether asynchronous "slow" refreshes are skipped due to the frame being the same. In the case of waiting for next frame to render, it is necessary to let any binding classes know that the there was no need to refresh the display at all.

Member Data Documentation

◆ m_d

QScopedPointer<struct Private> KisFrameDisplayProxy::m_d
private

Definition at line 63 of file KisFrameDisplayProxy.h.


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