started memory cache server
This commit is contained in:
@@ -286,6 +286,8 @@ set(OLIVE_SOURCES
|
|||||||
rendering/exportthread.h
|
rendering/exportthread.h
|
||||||
rendering/framebufferobject.cpp
|
rendering/framebufferobject.cpp
|
||||||
rendering/framebufferobject.h
|
rendering/framebufferobject.h
|
||||||
|
rendering/memorycache.h
|
||||||
|
rendering/memorycache.cpp
|
||||||
rendering/pixelformats.cpp
|
rendering/pixelformats.cpp
|
||||||
rendering/pixelformats.h
|
rendering/pixelformats.h
|
||||||
rendering/qopenglshaderprogramptr.h
|
rendering/qopenglshaderprogramptr.h
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ void EffectField::PrepareDataForKeyframing(bool enabled, ComboAction *ca)
|
|||||||
// Create keyframe from perpetual data
|
// Create keyframe from perpetual data
|
||||||
EffectKeyframe key;
|
EffectKeyframe key;
|
||||||
|
|
||||||
key.time = GetParentRow()->ParentNode()->ParentGraph()->Time();
|
key.time = GetParentRow()->ParentNode()->Time();
|
||||||
key.data = persistent_data_;
|
key.data = persistent_data_;
|
||||||
key.type = EFFECT_KEYFRAME_LINEAR;
|
key.type = EFFECT_KEYFRAME_LINEAR;
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ void EffectField::PrepareDataForKeyframing(bool enabled, ComboAction *ca)
|
|||||||
// Convert keyframes to one "perpetual" keyframe
|
// Convert keyframes to one "perpetual" keyframe
|
||||||
|
|
||||||
// Set first keyframe to whatever the data is now
|
// Set first keyframe to whatever the data is now
|
||||||
ca->append(new SetQVariant(&persistent_data_, persistent_data_, GetValueAt(GetParentRow()->ParentNode()->ParentGraph()->Time())));
|
ca->append(new SetQVariant(&persistent_data_, persistent_data_, GetValueAt(GetParentRow()->ParentNode()->Time())));
|
||||||
|
|
||||||
// Delete all keyframes
|
// Delete all keyframes
|
||||||
for (int i=0;i<keyframes.size();i++) {
|
for (int i=0;i<keyframes.size();i++) {
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ void load_internal_effects() {
|
|||||||
olive::node_library[kVstEffect] = std::make_shared<VSTHost>(nullptr);
|
olive::node_library[kVstEffect] = std::make_shared<VSTHost>(nullptr);
|
||||||
olive::node_library[kCornerPinEffect] = std::make_shared<CornerPinEffect>(nullptr);
|
olive::node_library[kCornerPinEffect] = std::make_shared<CornerPinEffect>(nullptr);
|
||||||
olive::node_library[kRichTextInput] = std::make_shared<RichTextEffect>(nullptr);
|
olive::node_library[kRichTextInput] = std::make_shared<RichTextEffect>(nullptr);
|
||||||
olive::node_library[kMediaInput] = std::make_shared<NodeMedia>(nullptr);
|
//olive::node_library[kMediaInput] = std::make_shared<NodeMedia>(nullptr);
|
||||||
olive::node_library[kImageOutput] = std::make_shared<NodeImageOutput>(nullptr);
|
olive::node_library[kImageOutput] = std::make_shared<NodeImageOutput>(nullptr);
|
||||||
olive::node_library[kCrossDissolveTransition] = std::make_shared<CrossDissolveTransition>(nullptr);
|
olive::node_library[kCrossDissolveTransition] = std::make_shared<CrossDissolveTransition>(nullptr);
|
||||||
olive::node_library[kLinearFadeTransition] = std::make_shared<LinearFadeTransition>(nullptr);
|
olive::node_library[kLinearFadeTransition] = std::make_shared<LinearFadeTransition>(nullptr);
|
||||||
|
|||||||
+5
-5
@@ -38,16 +38,16 @@ int Node::ParameterCount()
|
|||||||
return parameters_.size();
|
return parameters_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Node::Process(rational time)
|
||||||
|
{
|
||||||
|
Q_UNUSED(time)
|
||||||
|
}
|
||||||
|
|
||||||
NodeGraph *Node::ParentGraph()
|
NodeGraph *Node::ParentGraph()
|
||||||
{
|
{
|
||||||
return static_cast<NodeGraph*>(parent());
|
return static_cast<NodeGraph*>(parent());
|
||||||
}
|
}
|
||||||
|
|
||||||
double Node::Time()
|
|
||||||
{
|
|
||||||
return ParentGraph()->Time();
|
|
||||||
}
|
|
||||||
|
|
||||||
const QPointF &Node::pos()
|
const QPointF &Node::pos()
|
||||||
{
|
{
|
||||||
return pos_;
|
return pos_;
|
||||||
|
|||||||
+6
-3
@@ -1,9 +1,8 @@
|
|||||||
#ifndef NODE_H
|
#ifndef NODE_H
|
||||||
#define NODE_H
|
#define NODE_H
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "nodes/nodeio.h"
|
#include "nodes/nodeio.h"
|
||||||
|
#include "global/rational.h"
|
||||||
|
|
||||||
class NodeGraph;
|
class NodeGraph;
|
||||||
|
|
||||||
@@ -16,16 +15,20 @@ public:
|
|||||||
virtual QString name();
|
virtual QString name();
|
||||||
virtual QString id();
|
virtual QString id();
|
||||||
|
|
||||||
|
virtual void Process(rational time);
|
||||||
|
|
||||||
void AddParameter(NodeIO* row);
|
void AddParameter(NodeIO* row);
|
||||||
int IndexOfParameter(NodeIO* row);
|
int IndexOfParameter(NodeIO* row);
|
||||||
NodeIO* Parameter(int i);
|
NodeIO* Parameter(int i);
|
||||||
int ParameterCount();
|
int ParameterCount();
|
||||||
|
|
||||||
NodeGraph* ParentGraph();
|
NodeGraph* ParentGraph();
|
||||||
double Time();
|
|
||||||
|
|
||||||
const QPointF& pos();
|
const QPointF& pos();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void GLContextChangeEvent();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void SetPos(const QPointF& pos);
|
void SetPos(const QPointF& pos);
|
||||||
|
|
||||||
|
|||||||
+44
-3
@@ -3,11 +3,20 @@
|
|||||||
#include <QChildEvent>
|
#include <QChildEvent>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
NodeGraph::NodeGraph()
|
NodeGraph::NodeGraph() :
|
||||||
|
output_node_(nullptr),
|
||||||
|
ctx_(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeGraph::Process()
|
||||||
|
{
|
||||||
|
if (output_node_ != nullptr) {
|
||||||
|
output_node_->Process(Time());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NodeGraph::childEvent(QChildEvent *event)
|
void NodeGraph::childEvent(QChildEvent *event)
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::ChildAdded || event->type() == QEvent::ChildRemoved) {
|
if (event->type() == QEvent::ChildAdded || event->type() == QEvent::ChildRemoved) {
|
||||||
@@ -25,13 +34,45 @@ Node *NodeGraph::OutputNode()
|
|||||||
return output_node_;
|
return output_node_;
|
||||||
}
|
}
|
||||||
|
|
||||||
double NodeGraph::Time()
|
const rational& NodeGraph::Time()
|
||||||
{
|
{
|
||||||
return time_;
|
return time_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeGraph::SetTime(double d)
|
void NodeGraph::SetTime(const rational &d)
|
||||||
{
|
{
|
||||||
time_ = d;
|
time_ = d;
|
||||||
emit TimeChanged();
|
emit TimeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemoryCache *NodeGraph::memory_cache()
|
||||||
|
{
|
||||||
|
return &memory_cache_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int &NodeGraph::width()
|
||||||
|
{
|
||||||
|
return width_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int &NodeGraph::height()
|
||||||
|
{
|
||||||
|
return height_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeGraph::set_width(const int& w)
|
||||||
|
{
|
||||||
|
width_ = w;
|
||||||
|
emit ParametersChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeGraph::set_height(const int& h)
|
||||||
|
{
|
||||||
|
height_ = h;
|
||||||
|
emit ParametersChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeGraph::SetGLContext(QOpenGLContext *ctx)
|
||||||
|
{
|
||||||
|
memory_cache_.SetParameters(ctx, width_, height_);
|
||||||
|
}
|
||||||
|
|||||||
+22
-3
@@ -5,6 +5,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "nodes/node.h"
|
#include "nodes/node.h"
|
||||||
|
#include "rendering/memorycache.h"
|
||||||
|
|
||||||
class NodeGraph : public QObject
|
class NodeGraph : public QObject
|
||||||
{
|
{
|
||||||
@@ -12,6 +13,12 @@ class NodeGraph : public QObject
|
|||||||
public:
|
public:
|
||||||
NodeGraph();
|
NodeGraph();
|
||||||
|
|
||||||
|
const int& width();
|
||||||
|
void set_width(const int& w);
|
||||||
|
|
||||||
|
const int& height();
|
||||||
|
void set_height(const int& h);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Process the graph
|
* @brief Process the graph
|
||||||
*
|
*
|
||||||
@@ -41,12 +48,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
Node* OutputNode();
|
Node* OutputNode();
|
||||||
|
|
||||||
double Time();
|
const rational &Time();
|
||||||
void SetTime(double d);
|
void SetTime(const rational& d);
|
||||||
|
|
||||||
|
MemoryCache* memory_cache();
|
||||||
|
|
||||||
|
QOpenGLContext* GLContext();
|
||||||
|
void SetGLContext(QOpenGLContext* ctx);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void NodeGraphChanged();
|
void NodeGraphChanged();
|
||||||
void TimeChanged();
|
void TimeChanged();
|
||||||
|
void ParametersChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void childEvent(QChildEvent *event) override;
|
virtual void childEvent(QChildEvent *event) override;
|
||||||
@@ -54,7 +67,13 @@ protected:
|
|||||||
private:
|
private:
|
||||||
Node* output_node_;
|
Node* output_node_;
|
||||||
|
|
||||||
double time_;
|
MemoryCache memory_cache_;
|
||||||
|
QOpenGLContext* ctx_;
|
||||||
|
|
||||||
|
int width_;
|
||||||
|
int height_;
|
||||||
|
|
||||||
|
rational time_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NODEGRAPH_H
|
#endif // NODEGRAPH_H
|
||||||
|
|||||||
+27
-21
@@ -1,13 +1,16 @@
|
|||||||
#include "nodemedia.h"
|
#include "nodemedia.h"
|
||||||
|
|
||||||
NodeMedia::NodeMedia(Clip* c) :
|
#include "nodes/nodegraph.h"
|
||||||
OldEffectNode(c)
|
|
||||||
{
|
|
||||||
NodeIO* matrix_input = new NodeIO(this, "matrix", tr("Matrix"), true, false);
|
|
||||||
matrix_input->AddAcceptedNodeInput(olive::nodes::kMatrix);
|
|
||||||
|
|
||||||
NodeIO* texture_output = new NodeIO(this, "texture", tr("Texture"), true, false);
|
NodeMedia::NodeMedia(NodeGraph* c) :
|
||||||
texture_output->SetOutputDataType(olive::nodes::kTexture);
|
Node(c),
|
||||||
|
buffer_(c->memory_cache())
|
||||||
|
{
|
||||||
|
matrix_input_ = new NodeIO(this, "matrix", tr("Matrix"), true, false);
|
||||||
|
matrix_input_->AddAcceptedNodeInput(olive::nodes::kMatrix);
|
||||||
|
|
||||||
|
texture_output_ = new NodeIO(this, "texture", tr("Texture"), true, false);
|
||||||
|
texture_output_->SetOutputDataType(olive::nodes::kTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString NodeMedia::name()
|
QString NodeMedia::name()
|
||||||
@@ -20,27 +23,30 @@ QString NodeMedia::id()
|
|||||||
return "org.olivevideoeditor.Olive.media";
|
return "org.olivevideoeditor.Olive.media";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString NodeMedia::category()
|
void NodeMedia::Process(rational time)
|
||||||
{
|
{
|
||||||
return tr("Inputs");
|
Q_UNUSED(time)
|
||||||
|
|
||||||
|
buffer_.buffer()->BindBuffer();
|
||||||
|
|
||||||
|
// DEBUG CODE - we should see a solid red color return from this function
|
||||||
|
glClearColor(1.0, 0.0, 0.0, 1.0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
// END DEBUG CODE
|
||||||
|
|
||||||
|
buffer_.buffer()->ReleaseBuffer();
|
||||||
|
|
||||||
|
texture_output_->SetValue(buffer_.buffer()->texture());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString NodeMedia::description()
|
NodeIO *NodeMedia::matrix_input()
|
||||||
{
|
{
|
||||||
return tr("Retrieve frames from a media source.");
|
return matrix_input_;
|
||||||
}
|
}
|
||||||
|
|
||||||
EffectType NodeMedia::type()
|
NodeIO *NodeMedia::texture_output()
|
||||||
{
|
{
|
||||||
return EFFECT_TYPE_EFFECT;
|
return texture_output_;
|
||||||
}
|
}
|
||||||
|
|
||||||
olive::TrackType NodeMedia::subtype()
|
|
||||||
{
|
|
||||||
return olive::kTypeVideo;
|
|
||||||
}
|
|
||||||
|
|
||||||
OldEffectNodePtr NodeMedia::Create(Clip *c)
|
|
||||||
{
|
|
||||||
return std::make_shared<NodeMedia>(c);
|
|
||||||
}
|
|
||||||
|
|||||||
+16
-8
@@ -1,20 +1,28 @@
|
|||||||
#ifndef MEDIANODE_H
|
#ifndef MEDIANODE_H
|
||||||
#define MEDIANODE_H
|
#define MEDIANODE_H
|
||||||
|
|
||||||
#include "nodes/oldeffectnode.h"
|
#include "nodes/node.h"
|
||||||
|
#include "rendering/memorycache.h"
|
||||||
|
|
||||||
class NodeMedia : public OldEffectNode
|
class NodeMedia : public Node
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
NodeMedia(Clip *c);
|
NodeMedia(NodeGraph *c);
|
||||||
|
|
||||||
virtual QString name() override;
|
virtual QString name() override;
|
||||||
virtual QString id() override;
|
virtual QString id() override;
|
||||||
virtual QString category() override;
|
|
||||||
virtual QString description() override;
|
virtual void Process(rational time) override;
|
||||||
virtual EffectType type() override;
|
|
||||||
virtual olive::TrackType subtype() override;
|
NodeIO* matrix_input();
|
||||||
virtual OldEffectNodePtr Create(Clip *c) override;
|
NodeIO* texture_output();
|
||||||
|
|
||||||
|
private:
|
||||||
|
NodeIO* matrix_input_;
|
||||||
|
NodeIO* texture_output_;
|
||||||
|
|
||||||
|
MemoryCache::Reference buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MEDIANODE_H
|
#endif // MEDIANODE_H
|
||||||
|
|||||||
@@ -0,0 +1,181 @@
|
|||||||
|
#include "memorycache.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
MemoryCache::MemoryCache() :
|
||||||
|
ctx_(nullptr),
|
||||||
|
width_(0),
|
||||||
|
height_(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryCache::~MemoryCache()
|
||||||
|
{
|
||||||
|
buffer_array_mutex_.lock();
|
||||||
|
|
||||||
|
Clear();
|
||||||
|
|
||||||
|
buffer_array_mutex_.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryCache::SetParameters(QOpenGLContext *ctx, int width, int height)
|
||||||
|
{
|
||||||
|
buffer_array_mutex_.lock();
|
||||||
|
|
||||||
|
ctx_ = ctx;
|
||||||
|
|
||||||
|
if (ctx_ != nullptr) {
|
||||||
|
Q_ASSERT(width > 0 && height > 0);
|
||||||
|
|
||||||
|
width_ = width;
|
||||||
|
height_ = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
Clear();
|
||||||
|
|
||||||
|
buffer_array_mutex_.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
int MemoryCache::RequestBuffer(Reference* r)
|
||||||
|
{
|
||||||
|
if (ctx_ == nullptr) {
|
||||||
|
qWarning() << "A memcache request was made with an invalid context";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width_ == 0 || height_ == 0) {
|
||||||
|
qWarning() << "A memcache request was made with an invalid size [" << width_ << "," << height_ << "]";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_array_mutex_.lock();
|
||||||
|
|
||||||
|
int buffer = RequestBufferInternal(r);
|
||||||
|
|
||||||
|
buffer_array_mutex_.unlock();
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MemoryCache::RequestBufferInternal(MemoryCache::Reference *r)
|
||||||
|
{
|
||||||
|
// Try to return a relinquished buffer
|
||||||
|
if (!relinquished_buffers_.isEmpty()) {
|
||||||
|
|
||||||
|
int buf_index = relinquished_buffers_.takeFirst();
|
||||||
|
|
||||||
|
refs_.replace(buf_index, r);
|
||||||
|
|
||||||
|
return buf_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no buffer was available, we may have to create a new one
|
||||||
|
|
||||||
|
// Check if we have enough memory (according to user-defined limits in the Config), if we don't, try to relinquish an
|
||||||
|
// old buffer and return that.
|
||||||
|
if (OutOfMemory()) {
|
||||||
|
|
||||||
|
int least_recent_access = 0;
|
||||||
|
|
||||||
|
// Loop through buffers for the oldest accessed buffer
|
||||||
|
for (int i=1;i<access_times_.size();i++) {
|
||||||
|
if (access_times_.at(i) < access_times_.at(least_recent_access)
|
||||||
|
&& refs_.at(i) != nullptr) { // ensure this buffer has not been relinquished
|
||||||
|
least_recent_access = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Relinquish this buffer
|
||||||
|
refs_.at(least_recent_access)->Relinquish();
|
||||||
|
refs_.replace(least_recent_access, r);
|
||||||
|
return least_recent_access;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, just generate a new buffer
|
||||||
|
buffers_.append(FramebufferObject());
|
||||||
|
refs_.append(r);
|
||||||
|
access_times_.append(time(nullptr));
|
||||||
|
|
||||||
|
return buffers_.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryCache::RelinquishBuffer(int index)
|
||||||
|
{
|
||||||
|
buffer_array_mutex_.lock();
|
||||||
|
|
||||||
|
refs_.replace(index, nullptr);
|
||||||
|
relinquished_buffers_.append(index);
|
||||||
|
|
||||||
|
buffer_array_mutex_.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
FramebufferObject* MemoryCache::Buffer(int index)
|
||||||
|
{
|
||||||
|
access_times_.replace(index, time(nullptr));
|
||||||
|
return &buffers_[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemoryCache::OutOfMemory()
|
||||||
|
{
|
||||||
|
// TODO actually check if we have any memory or not
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryCache::Clear()
|
||||||
|
{
|
||||||
|
for (int i=0;i<refs_.size();i++) {
|
||||||
|
refs_.at(i)->Relinquish();
|
||||||
|
}
|
||||||
|
|
||||||
|
buffers_.clear();
|
||||||
|
refs_.clear();
|
||||||
|
relinquished_buffers_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryCache::Reference::Reference(MemoryCache *cache) :
|
||||||
|
cache_(cache),
|
||||||
|
buffer_(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryCache::Reference::~Reference()
|
||||||
|
{
|
||||||
|
Relinquish();
|
||||||
|
}
|
||||||
|
|
||||||
|
FramebufferObject *MemoryCache::Reference::buffer()
|
||||||
|
{
|
||||||
|
// If we don't have a buffer yet, request one
|
||||||
|
if (buffer_ == -1) {
|
||||||
|
Request();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we didn't receive one, return null
|
||||||
|
if (buffer_ == -1) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, return the buffer we received
|
||||||
|
return &cache_->buffers_[buffer_];
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryCache::Reference::Relinquish()
|
||||||
|
{
|
||||||
|
if (buffer_ == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_->RelinquishBuffer(buffer_);
|
||||||
|
buffer_ = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryCache::Reference::Request()
|
||||||
|
{
|
||||||
|
// Check if we already have a buffer, in which case we don't need to request a new one
|
||||||
|
if (buffer_ != -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_ = cache_->RequestBuffer(this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#ifndef MEMORYCACHE_H
|
||||||
|
#define MEMORYCACHE_H
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
#include "framebufferobject.h"
|
||||||
|
|
||||||
|
class MemoryCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class Reference {
|
||||||
|
public:
|
||||||
|
Reference(MemoryCache* cache);
|
||||||
|
~Reference();
|
||||||
|
|
||||||
|
FramebufferObject* buffer();
|
||||||
|
|
||||||
|
void Relinquish();
|
||||||
|
private:
|
||||||
|
void Request();
|
||||||
|
|
||||||
|
MemoryCache* cache_;
|
||||||
|
int buffer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
MemoryCache();
|
||||||
|
~MemoryCache();
|
||||||
|
|
||||||
|
void SetParameters(QOpenGLContext* ctx, int width, int height);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int RequestBuffer(Reference *r);
|
||||||
|
int RequestBufferInternal(Reference *r);
|
||||||
|
|
||||||
|
void RelinquishBuffer(int index);
|
||||||
|
|
||||||
|
FramebufferObject *Buffer(int index);
|
||||||
|
|
||||||
|
bool OutOfMemory();
|
||||||
|
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
QList<FramebufferObject> buffers_;
|
||||||
|
QList<Reference*> refs_;
|
||||||
|
QList<time_t> access_times_;
|
||||||
|
|
||||||
|
QOpenGLContext* ctx_;
|
||||||
|
|
||||||
|
QList<int> relinquished_buffers_;
|
||||||
|
|
||||||
|
int width_;
|
||||||
|
int height_;
|
||||||
|
|
||||||
|
QMutex buffer_array_mutex_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MEMORYCACHE_H
|
||||||
Reference in New Issue
Block a user