render: implemented frame pool

Optimization
This commit is contained in:
itsmattkc
2021-04-28 17:31:25 +10:00
parent 2e96b57319
commit 51ccaedc78
8 changed files with 270 additions and 15 deletions
+2
View File
@@ -33,6 +33,8 @@ set(OLIVE_SOURCES
render/diskmanager.h
render/framehashcache.cpp
render/framehashcache.h
render/framemanager.cpp
render/framemanager.h
render/managedcolor.cpp
render/managedcolor.h
render/playbackcache.cpp
+129
View File
@@ -0,0 +1,129 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2021 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#include "framemanager.h"
#include <QDateTime>
#include <QDebug>
namespace olive {
FrameManager* FrameManager::instance_ = nullptr;
const int FrameManager::kFrameLifetime = 5000;
void FrameManager::CreateInstance()
{
instance_ = new FrameManager();
}
void FrameManager::DestroyInstance()
{
delete instance_;
instance_ = nullptr;
}
FrameManager *FrameManager::instance()
{
return instance_;
}
char *FrameManager::Allocate(int size)
{
if (instance()) {
return instance()->AllocateFromPool(size);
} else {
return new char[size];
}
}
void FrameManager::Deallocate(int size, char *buffer)
{
if (instance()) {
instance()->DeallocateToPool(size, buffer);
} else {
delete [] buffer;
}
}
FrameManager::FrameManager()
{
clear_timer_.setInterval(kFrameLifetime);
connect(&clear_timer_, &QTimer::timeout, this, &FrameManager::GarbageCollection);
clear_timer_.start();
}
char *FrameManager::AllocateFromPool(int size)
{
QMutexLocker locker(&mutex_);
std::list<Buffer>& buffer_list = pool_[size];
char* buf = nullptr;
if (buffer_list.empty()) {
buf = new char[size];
} else {
// Take this buffer from the list
buf = buffer_list.front().data;
buffer_list.pop_front();
}
return buf;
}
void FrameManager::DeallocateToPool(int size, char *buffer)
{
QMutexLocker locker(&mutex_);
std::list<Buffer>& buffer_list = pool_[size];
buffer_list.push_back({QDateTime::currentMSecsSinceEpoch(), buffer});
}
void FrameManager::GarbageCollection()
{
QMutexLocker locker(&mutex_);
qint64 min_life = QDateTime::currentMSecsSinceEpoch() - kFrameLifetime;
for (auto it=pool_.begin(); it!=pool_.end(); it++) {
std::list<Buffer>& list = it->second;
while (list.size() > 0 && list.front().time < min_life) {
delete [] list.front().data;
list.pop_front();
}
}
}
FrameManager::~FrameManager()
{
QMutexLocker locker(&mutex_);
for (auto it=pool_.begin(); it!=pool_.end(); it++) {
std::list<Buffer>& list = it->second;
for (auto jt=list.begin(); jt!=list.end(); jt++) {
delete [] (*jt).data;
}
}
pool_.clear();
}
}
+91
View File
@@ -0,0 +1,91 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2021 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef FRAMEMANAGER_H
#define FRAMEMANAGER_H
#include <QObject>
#include <QTimer>
namespace olive {
class FrameManager : public QObject
{
Q_OBJECT
public:
static void CreateInstance();
static void DestroyInstance();
static FrameManager* instance();
static char* Allocate(int size);
static void Deallocate(int size, char* buffer);
private:
FrameManager();
virtual ~FrameManager() override;
/**
* @brief Allocate buffer
*
* Caller takes ownership of buffer and can delete it if they want. It can also be returned to
* the manager with Deallocate and potentially be re-used later.
*
* Thread-safe.
*/
char* AllocateFromPool(int size);
/**
* @brief Deallocate buffer
*
* Manager will take ownership and buffer will stay allocated for some time in case it can be
* re-used.
*
* Thread-safe.
*/
void DeallocateToPool(int size, char* buffer);
static FrameManager* instance_;
static const int kFrameLifetime;
struct Buffer
{
qint64 time;
char* data;
};
std::map< int, std::list<Buffer> > pool_;
QMutex mutex_;
QTimer clear_timer_;
private slots:
void GarbageCollection();
};
}
#endif // FRAMEMANAGER_H