Merge pull request #581 from AttorneyOnline/aolayer-preload

Massively improve AOLayer performance by preloading next frame from disk before the current frame is done ticking
This commit is contained in:
oldmud0 2021-08-12 21:37:52 -05:00 committed by GitHub
commit 1bf12a919c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 13 deletions

View File

@ -19,6 +19,9 @@ QMAKE_LFLAGS += -Wl,-rpath,"'\$$ORIGIN/lib'"
# Uncomment for verbose network logging # Uncomment for verbose network logging
# DEFINES += DEBUG_NETWORK # DEFINES += DEBUG_NETWORK
# Uncomment for verbose animation logging
# DEFINES += DEBUG_MOVIE
# Uncomment for building with debug symbols # Uncomment for building with debug symbols
# CONFIG += debug # CONFIG += debug

View File

@ -7,6 +7,7 @@
#include <QLabel> #include <QLabel>
#include <QTimer> #include <QTimer>
#include <QBitmap> #include <QBitmap>
#include <QtConcurrent/QtConcurrentRun>
class AOApplication; class AOApplication;
class VPath; class VPath;
@ -139,6 +140,12 @@ protected:
// Center the QLabel in the viewport based on the dimensions of f_pixmap // Center the QLabel in the viewport based on the dimensions of f_pixmap
void center_pixmap(QPixmap f_pixmap); void center_pixmap(QPixmap f_pixmap);
// Populates the frame and delay vectors with the next frame's data.
void load_next_frame();
// used in load_next_frame
QFuture<void> future;
signals: signals:
void done(); void done();

View File

@ -320,10 +320,7 @@ void AOLayer::start_playback(QString p_image)
for (int i = frame; i--;) { for (int i = frame; i--;) {
if (i <= -1) if (i <= -1)
break; break;
QPixmap l_pixmap = this->get_pixmap(m_reader.read()); load_next_frame();
int l_delay = m_reader.nextImageDelay();
movie_frames.append(l_pixmap);
movie_delays.append(l_delay);
} }
} }
last_path = p_image; last_path = p_image;
@ -344,7 +341,7 @@ void AOLayer::start_playback(QString p_image)
if (duration > 0 && cull_image == true) if (duration > 0 && cull_image == true)
shfx_timer->start(duration); shfx_timer->start(duration);
#ifdef DEBUG_MOVIE #ifdef DEBUG_MOVIE
qDebug() << max_frames << "Setting image to " << image_path qDebug() << max_frames << "Setting image to " << p_image
<< "Time taken to process image:" << actual_time.elapsed(); << "Time taken to process image:" << actual_time.elapsed();
actual_time.restart(); actual_time.restart();
@ -532,7 +529,11 @@ void CharLayer::movie_ticker()
void AOLayer::movie_ticker() void AOLayer::movie_ticker()
{ {
++frame; ++frame;
if (frame >= max_frames) { if (frame >= movie_frames.size() && frame < max_frames) { // need to load the image
future.waitForFinished(); // Do Not want this to be running twice
future = QtConcurrent::run(this, &AOLayer::load_next_frame);
}
else if (frame >= max_frames) {
if (play_once) { if (play_once) {
if (cull_image) if (cull_image)
this->stop(); this->stop();
@ -544,19 +545,21 @@ void AOLayer::movie_ticker()
else else
frame = 0; frame = 0;
} }
// qint64 difference = elapsed - movie_delays[frame]; future.waitForFinished(); // don't set the frame before we definitely have it in memory
if (frame >= movie_frames.size()) {
movie_frames.append(this->get_pixmap(m_reader.read()));
movie_delays.append(m_reader.nextImageDelay());
}
#ifdef DEBUG_MOVIE #ifdef DEBUG_MOVIE
qDebug() << frame << movie_delays[frame] qDebug() << frame << movie_delays[frame]
<< "actual time taken from last frame:" << actual_time.restart(); << "actual time taken from last frame:" << actual_time.restart();
#endif #endif
this->set_frame(movie_frames[frame]); this->set_frame(movie_frames[frame]);
ticker->setInterval(this->get_frame_delay(movie_delays[frame])); ticker->setInterval(this->get_frame_delay(movie_delays[frame]));
if (frame + 1 >= movie_frames.size() && frame + 1 < max_frames) { // load the next frame before we tick again
future = QtConcurrent::run(this, &AOLayer::load_next_frame);
}
}
void AOLayer::load_next_frame() {
movie_frames.append(this->get_pixmap(m_reader.read()));
movie_delays.append(m_reader.nextImageDelay());
} }
void CharLayer::preanim_done() void CharLayer::preanim_done()