nodes: implemented infrastructure for caching any node

Not accessible through UI yet, but ported Footage node to it
(previously we used a hack to ensure Footage textures were
cached, now it's a formal infrastructure).
This commit is contained in:
itsmattkc
2021-04-11 18:56:39 +10:00
parent 210eb86cd2
commit 6c30f8cf46
10 changed files with 129 additions and 39 deletions
+2 -1
View File
@@ -48,7 +48,8 @@ Node::Node(bool create_default_output) :
override_color_(-1),
last_change_time_(0),
folder_(nullptr),
operation_stack_(0)
operation_stack_(0),
cache_result_(false)
{
if (create_default_output) {
AddOutput();
+12
View File
@@ -756,6 +756,16 @@ public:
folder_ = folder;
}
bool GetCacheTextures() const
{
return cache_result_;
}
void SetCacheTextures(bool e)
{
cache_result_ = e;
}
static const QString kDefaultOutput;
protected:
@@ -1191,6 +1201,8 @@ private:
int operation_stack_;
bool cache_result_;
private slots:
/**
* @brief Slot when a keyframe's time changes to keep the keyframes correctly sorted by time
+2
View File
@@ -48,6 +48,8 @@ Footage::Footage(const QString &filename) :
Clear();
set_filename(filename);
SetCacheTextures(true);
}
void Footage::Retranslate()
+27 -10
View File
@@ -22,6 +22,7 @@
#include "node.h"
#include "render/job/footagejob.h"
#include "render/rendermanager.h"
namespace olive {
@@ -110,7 +111,7 @@ NodeValueTable NodeTraverser::GenerateTable(const Node *n, const QString& output
// By this point, the node should have all the inputs it needs to render correctly
NodeValueTable table = n->Value(output, database);
PostProcessTable(n, range, table);
PostProcessTable(n, output, range, table);
return table;
}
@@ -171,10 +172,15 @@ QVariant NodeTraverser::ProcessFrameGeneration(const Node *node, const GenerateJ
return QVariant();
}
QVariant NodeTraverser::GetCachedFrame(const Node *node, const rational &time)
void NodeTraverser::SaveCachedTexture(const QByteArray &hash, const QVariant &texture)
{
Q_UNUSED(node)
Q_UNUSED(time)
Q_UNUSED(hash)
Q_UNUSED(texture)
}
QVariant NodeTraverser::GetCachedTexture(const QByteArray& hash)
{
Q_UNUSED(hash)
return QVariant();
}
@@ -190,17 +196,23 @@ void NodeTraverser::AddGlobalsToDatabase(NodeValueDatabase &db, const TimeRange&
db.Insert(QStringLiteral("global"), global);
}
void NodeTraverser::PostProcessTable(const Node *node, const TimeRange &range, NodeValueTable &output_params)
void NodeTraverser::PostProcessTable(const Node *node, const QString& output, const TimeRange &range, NodeValueTable &output_params)
{
bool got_cached_frame = false;
QByteArray cached_node_hash;
// Convert footage to image/sample buffers
QVariant cached_frame = GetCachedFrame(node, range.in());
if (!cached_frame.isNull()) {
output_params.Push(NodeValue::kTexture, cached_frame, node);
if (CanCacheFrames() && node->GetCacheTextures()) {
// This node is set to cache the result, see if we can retrieved a previously cached version
cached_node_hash = RenderManager::Hash(node, output, GetCacheVideoParams(), range.in());
// No more to do here
got_cached_frame = true;
QVariant cached_frame = GetCachedTexture(cached_node_hash);
if (!cached_frame.isNull()) {
output_params.Push(NodeValue::kTexture, cached_frame, node);
// No more to do here
got_cached_frame = true;
}
}
// Strip out any jobs or footage
@@ -285,6 +297,11 @@ void NodeTraverser::PostProcessTable(const Node *node, const TimeRange &range, N
output_params.Push(NodeValue::kSamples, value, node);
}
}
if (CanCacheFrames() && node->GetCacheTextures() && !got_cached_frame) {
// Save cached texture
SaveCachedTexture(cached_node_hash, output_params.Get(NodeValue::kTexture));
}
}
}
+14 -2
View File
@@ -59,7 +59,19 @@ protected:
virtual QVariant ProcessFrameGeneration(const Node *node, const GenerateJob& job);
virtual QVariant GetCachedFrame(const Node *node, const rational &time);
virtual QVariant GetCachedTexture(const QByteArray& hash);
virtual void SaveCachedTexture(const QByteArray& hash, const QVariant& texture);
virtual bool CanCacheFrames()
{
return false;
}
virtual VideoParams GetCacheVideoParams()
{
return VideoParams();
}
void AddGlobalsToDatabase(NodeValueDatabase& db, const TimeRange &range) const;
@@ -69,7 +81,7 @@ protected:
}
private:
void PostProcessTable(const Node *node, const TimeRange &range, NodeValueTable &output_params);
void PostProcessTable(const Node *node, const QString &output, const TimeRange &range, NodeValueTable &output_params);
};