some render cache adjustments

This commit is contained in:
itsmattkc
2019-09-04 10:58:50 +10:00
parent 12bc5839a6
commit 371d0e2b37
22 changed files with 150 additions and 48 deletions
+9
View File
@@ -91,3 +91,12 @@ bool NodeGraph::ContainsNode(Node *n)
{
return (n->parent() == this);
}
void NodeGraph::Release()
{
QList<Node*> all_nodes = nodes();
foreach (Node* n, all_nodes) {
n->Release();
}
}
+5
View File
@@ -80,6 +80,11 @@ public:
*/
bool ContainsNode(Node* n);
/**
* @brief Releases all Nodes in this NodeGraph
*/
void Release();
signals:
/**
* @brief Signal emitted when a Node is added to the graph
-1
View File
@@ -315,7 +315,6 @@ void Node::Hash(QCryptographicHash *hash, NodeOutput* from, const rational &time
{
// Add this Node's ID
hash->addData(id().toUtf8());
qDebug() << "Hashing" << id();
// Add each value
QList<NodeParam*> params = parameters();
+5 -2
View File
@@ -80,8 +80,10 @@ void ViewerOutput::AttachViewer(ViewerPanel *viewer)
void ViewerOutput::InvalidateCache(const rational &start_range, const rational &end_range, NodeInput *from)
{
// Update any attached viewer
UpdateViewer();
if (start_range == current_time_ || end_range == current_time_) {
// Update any attached viewer
UpdateViewer();
}
Node::InvalidateCache(start_range, end_range, from);
}
@@ -89,6 +91,7 @@ void ViewerOutput::InvalidateCache(const rational &start_range, const rational &
void ViewerOutput::UpdateViewer()
{
texture_input_->ClearCachedValue();
ViewerTimeChanged(current_time_);
}
+5
View File
@@ -238,3 +238,8 @@ void NodeParam::ClearCachedValue()
// currently cached
time_ = -1;
}
const rational &NodeParam::LastRequestedTime()
{
return time_;
}
+5
View File
@@ -208,6 +208,11 @@ public:
*/
void ClearCachedValue();
/**
* @brief Retrieve the last time this parameter had a value requested from
*/
const rational& LastRequestedTime();
signals:
/**
* @brief Signal emitted when an edge is added to this parameter
+11 -10
View File
@@ -36,8 +36,7 @@ RendererProcessor::RendererProcessor() :
width_(0),
height_(0),
divider_(1),
caching_(false),
last_requested_time_(-1)
caching_(false)
{
texture_input_ = new NodeInput("tex_in");
texture_input_->add_data_input(NodeInput::kTexture);
@@ -79,8 +78,6 @@ void RendererProcessor::SetCacheName(const QString &s)
QVariant RendererProcessor::Value(NodeOutput* output, const rational& time)
{
if (output == texture_output_) {
last_requested_time_ = time;
if (!texture_input_->IsConnected()) {
// Nothing is connected - nothing to show or render
return 0;
@@ -98,7 +95,6 @@ QVariant RendererProcessor::Value(NodeOutput* output, const rational& time)
// Find frame in map
if (time_hash_map_.contains(time)) {
qDebug() << "Showed:" << time_hash_map_[time].toHex();
QString fn = CachePathName(time_hash_map_[time]);
@@ -340,6 +336,11 @@ void RendererProcessor::ThreadCallback()
time_hash_map_.insert(cache_frame_, master_thread_->hash());
// We didn't receive a texture to download, but the viewer may still need updating
if (texture == nullptr) {
DownloadThreadFinished(cache_frame_);
}
CacheNext();
}
}
@@ -357,15 +358,15 @@ void RendererProcessor::ThreadRequestSibling(NodeDependency dep)
void RendererProcessor::DownloadThreadFinished(const rational& time)
{
// Check if we just downloaded (akak finished caching) the frame we're currently on
if (texture_output_->IsConnected() && time == last_requested_time_) {
if (texture_output_->IsConnected()) {
if (texture_output_->LastRequestedTime() == time) {
texture_output_->ClearCachedValue();
}
// Send invalidate cache signal to all nodes connected to the texture output
QVector<NodeEdgePtr> edges = texture_output()->edges();
texture_output_->ClearCachedValue();
foreach (NodeEdgePtr edge, edges) {
edge->input()->ClearCachedValue();
edge->input()->parent()->InvalidateCache(time,
time,
edge->input());
-2
View File
@@ -176,8 +176,6 @@ private:
QVector<RendererDownloadThreadPtr> download_threads_;
int last_download_thread_;
rational last_requested_time_;
RenderTexturePtr master_texture_;
QMap<rational, QByteArray> time_hash_map_;
@@ -12,7 +12,8 @@ RendererDownloadThread::RendererDownloadThread(QOpenGLContext *share_ctx,
const int &height,
const olive::PixelFormat &format,
const olive::RenderMode &mode) :
RendererThreadBase(share_ctx, width, height, format, mode)
RendererThreadBase(share_ctx, width, height, format, mode),
cancelled_(false)
{
}
@@ -29,6 +30,17 @@ void RendererDownloadThread::Queue(RenderTexturePtr texture, const QString& fn,
texture_queue_lock_.unlock();
}
void RendererDownloadThread::Cancel()
{
cancelled_ = true;
texture_queue_lock_.lock();
wait_cond_.wakeAll();
texture_queue_lock_.unlock();
wait();
}
void RendererDownloadThread::ProcessLoop()
{
QOpenGLFunctions* f = render_instance()->context()->functions();
@@ -53,13 +65,21 @@ void RendererDownloadThread::ProcessLoop()
OIIO::ImageSpec spec(render_instance()->width(), render_instance()->height(), kRGBAChannels, format_info.oiio_desc);
spec.attribute("compression", "dwaa:200");
while (!Cancelled()) {
while (!cancelled_) {
// Check queue for textures to download (use mutex to prevent collisions)
texture_queue_lock_.lock();
while (texture_queue_.isEmpty()) {
// Main waiting condition
wait_cond_.wait(&texture_queue_lock_);
if (cancelled_) {
break;
}
}
if (cancelled_) {
texture_queue_lock_.unlock();
break;
}
working_texture = texture_queue_.takeFirst();
@@ -15,6 +15,9 @@ public:
void Queue(RenderTexturePtr texture, const QString &fn, const rational &time);
public slots:
virtual void Cancel() override;
signals:
void Downloaded(const rational& time);
@@ -32,6 +35,8 @@ private:
QMutex texture_queue_lock_;
QAtomicInt cancelled_;
};
using RendererDownloadThreadPtr = std::shared_ptr<RendererDownloadThread>;
@@ -29,7 +29,8 @@ RendererProcessThread::RendererProcessThread(RendererProcessor* parent,
const olive::PixelFormat &format,
const olive::RenderMode &mode) :
RendererThreadBase(share_ctx, width, height, format, mode),
parent_(parent)
parent_(parent),
cancelled_(false)
{
}
@@ -70,12 +71,27 @@ RenderTexturePtr RendererProcessThread::texture()
return texture_;
}
void RendererProcessThread::Cancel()
{
cancelled_ = true;
mutex_.lock();
wait_cond_.wakeAll();
mutex_.unlock();
wait();
}
void RendererProcessThread::ProcessLoop()
{
while (!Cancelled()) {
while (!cancelled_) {
// Main waiting condition
wait_cond_.wait(&mutex_);
if (cancelled_) {
break;
}
// Wake up main thread
caller_mutex_.lock();
wait_cond_.wakeAll();
@@ -42,6 +42,9 @@ public:
RenderTexturePtr texture();
public slots:
virtual void Cancel() override;
protected:
virtual void ProcessLoop() override;
@@ -61,6 +64,8 @@ private:
RenderTexturePtr texture_;
QAtomicInt cancelled_;
};
using RendererProcessThreadPtr = std::shared_ptr<RendererProcessThread>;
@@ -24,7 +24,6 @@
RendererThreadBase::RendererThreadBase(QOpenGLContext *share_ctx, const int &width, const int &height, const olive::PixelFormat &format, const olive::RenderMode &mode) :
share_ctx_(share_ctx),
cancelled_(false),
width_(width),
height_(height),
format_(format),
@@ -34,15 +33,6 @@ RendererThreadBase::RendererThreadBase(QOpenGLContext *share_ctx, const int &wid
connect(share_ctx_, SIGNAL(aboutToBeDestroyed()), this, SLOT(Cancel()));
}
void RendererThreadBase::Cancel()
{
// Escape main loop
cancelled_ = true;
// Wait until thread is finished before returning
wait();
}
RenderInstance *RendererThreadBase::render_instance()
{
return render_instance_;
@@ -79,11 +69,6 @@ void RendererThreadBase::run()
mutex_.unlock();
}
bool RendererThreadBase::Cancelled()
{
return cancelled_;
}
void RendererThreadBase::StartThread(QThread::Priority priority)
{
caller_mutex_.lock();
@@ -46,13 +46,11 @@ public:
virtual void run() override;
public slots:
void Cancel();
virtual void Cancel() = 0;
protected:
virtual void ProcessLoop() = 0;
bool Cancelled();
QWaitCondition wait_cond_;
QMutex mutex_;
@@ -62,8 +60,6 @@ protected:
private:
QOpenGLContext* share_ctx_;
bool cancelled_;
const int& width_;
const int& height_;
+7
View File
@@ -25,7 +25,14 @@ PanelManager* olive::panel_focus_manager = nullptr;
PanelManager::PanelManager(QObject *parent) :
QObject(parent)
{
}
void PanelManager::DeleteAllPanels()
{
foreach (PanelWidget* panel, focus_history_) {
delete panel;
}
focus_history_.clear();
}
PanelWidget *PanelManager::CurrentlyFocused() const
+2
View File
@@ -47,6 +47,8 @@ class PanelManager : public QObject
public:
PanelManager(QObject* parent);
void DeleteAllPanels();
/**
* @brief Return the currently focused widget, or nullptr if nothing is focused
*/
+15 -8
View File
@@ -49,13 +49,16 @@ bool RenderInstance::Start()
return true;
}
// Create context object
ctx_ = new QOpenGLContext();
// If we're sharing resources, set this up now
if (share_ctx_ != nullptr) {
ctx_.setShareContext(share_ctx_);
ctx_->setShareContext(share_ctx_);
}
// Create OpenGL context (automatically destroys any existing if there is one)
if (!ctx_.create()) {
if (!ctx_->create()) {
qWarning() << tr("Failed to create OpenGL context in thread %1").arg(reinterpret_cast<quintptr>(this));
return false;
}
@@ -64,16 +67,16 @@ bool RenderInstance::Start()
surface_.create();
// Make context current on that surface
if (!ctx_.makeCurrent(&surface_)) {
if (!ctx_->makeCurrent(&surface_)) {
qWarning() << tr("Failed to makeCurrent() on offscreen surface in thread %1").arg(reinterpret_cast<quintptr>(this));
surface_.destroy();
return false;
}
buffer_.Create(&ctx_);
buffer_.Create(ctx_);
// Set viewport to the compositing dimensions
ctx_.functions()->glViewport(0, 0, width_, height_);
ctx_->functions()->glViewport(0, 0, width_, height_);
// Set up default pipeline
default_pipeline_ = olive::ShaderGenerator::DefaultPipeline();
@@ -83,14 +86,18 @@ bool RenderInstance::Start()
void RenderInstance::Stop()
{
if (IsStarted()) {
return;
}
// Destroy pipeline
default_pipeline_ = nullptr;
// Destroy buffer
buffer_.Destroy();
// Release OpenGL context
ctx_.doneCurrent();
// Destroy context
delete ctx_;
// Destroy offscreen surface
surface_.destroy();
@@ -108,7 +115,7 @@ RenderFramebuffer *RenderInstance::buffer()
QOpenGLContext *RenderInstance::context()
{
return &ctx_;
return ctx_;
}
const int &RenderInstance::width() const
+1 -1
View File
@@ -67,7 +67,7 @@ public:
ShaderPtr default_pipeline() const;
private:
QOpenGLContext ctx_;
QOpenGLContext* ctx_;
QOpenGLContext* share_ctx_;
+12
View File
@@ -32,13 +32,25 @@ NodeView::NodeView(QWidget *parent) :
connect(&scene_, SIGNAL(selectionChanged()), this, SLOT(SceneSelectionChangedSlot()));
}
NodeView::~NodeView()
{
// Unset the current graph
SetGraph(nullptr);
}
void NodeView::SetGraph(NodeGraph *graph)
{
if (graph_ == graph) {
return;
}
if (graph_ != nullptr) {
disconnect(graph_, SIGNAL(NodeAdded(Node*)), this, SLOT(AddNode(Node*)));
disconnect(graph_, SIGNAL(NodeRemoved(Node*)), this, SLOT(RemoveNode(Node*)));
disconnect(graph_, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(AddEdge(NodeEdgePtr)));
disconnect(graph_, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(RemoveEdge(NodeEdgePtr)));
graph_->Release();
}
// Clear the scene of all UI objects
+2
View File
@@ -39,6 +39,8 @@ class NodeView : public QGraphicsView
public:
NodeView(QWidget* parent);
virtual ~NodeView() override;
/**
* @brief Sets the graph to view
*/
+17
View File
@@ -79,3 +79,20 @@ void olive::MainWindow::ProjectOpen(Project* p)
connect(node_panel, SIGNAL(SelectionChanged(QList<Node*>)), param_panel, SLOT(SetNodes(QList<Node*>)));
}
// FIXME: Test code
#include <QDir>
#include "common/filefunctions.h"
// End test code
void olive::MainWindow::closeEvent(QCloseEvent *e)
{
olive::panel_focus_manager->DeleteAllPanels();
// FIXME: Test code - We have no cache management and the cache is very much testing only, so we delete it on close
// as to not clog up HDD space
QDir(GetMediaCacheLocation()).removeRecursively();
// End test code
QMainWindow::closeEvent(e);
}
+3
View File
@@ -38,6 +38,9 @@ public:
public slots:
void ProjectOpen(Project *p);
protected:
virtual void closeEvent(QCloseEvent* e) override;
private: