Krita Source Code Documentation
Loading...
Searching...
No Matches
KisFrameDisplayProxy.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2022 Eoin O'Neill <eoinoneill1991@gmail.com>
3 * SPDX-FileCopyrightText: 2022 Emmet O'Neill <emmetoneill.pdx@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
9
10#include "kis_canvas2.h"
13
24
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
60 Q_EMIT sigFrameRefreshSkipped();
61 });
62
63 m_d->displayedFrame = m_d->canvas->image()->animationInterface()->currentUITime();
64 m_d->intendedFrame = m_d->displayedFrame;
65}
66
70
71bool KisFrameDisplayProxy::displayFrame(int frame, bool forceReproject)
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}
107
109{
110 return m_d->intendedFrame;
111}
112
114{
115 return m_d->displayedFrame;
116}
117
119{
120 return cache && cache->shouldUploadNewFrame(to, from);
121}
122
124{
125 return cache && cache->frameStatus(from) != cache->frameStatus(to);
126}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
CacheStatus frameStatus(int time) const
bool shouldUploadNewFrame(int newTime, int oldTime) const
bool shouldUploadFrame(KisAnimationFrameCacheSP cache, int from, int to)
bool displayFrame(int frame, bool forceReproject)
Tell the DisplayProxy to show a new frame.
bool needsReprojection(KisAnimationFrameCacheSP cache, int from, int to)
int activeKeyframe() const
Get the active keyframe. This is the latest unique frame that is actually visible....
KisFrameDisplayProxy(class KisCanvas2 *canvas, QObject *parent=nullptr)
QScopedPointer< struct Private > m_d
void sigFrameDisplayRefreshed()
int activeFrame() const
Gets the active frame, the frame that is intended to be shown. This should always reflect the actual ...
void switchCurrentTimeAsync(int frameId, SwitchTimeAsyncFlags options=STAO_NONE)
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.
KisImageAnimationInterface * animationInterface() const
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
Private(KisCanvas2 *c)
KisCanvas2 * canvas