Files
oak-editor/app/render/backend/renderbackend.h
T
itsmattkc 7f796bd99f revised video renderer's invalidate cache to use ranges rather than discrete
frames

Previously, when the video renderer received a dirty cache signal, it would
proceed to extract all frames from the range and queue them. However, this could
be extremely slow for long ranges since it had to iterate through the entire
range and calculate the individual frames it contained. Now, we use the same
range combining system as audio and automatically calculate the next frame
within the range only when necessary. Essentially the same work, but split up
over time and done only when needed leading to no discernible UI pause when
invalidating cache.
2020-01-03 15:50:43 +11:00

147 lines
2.9 KiB
C++

#ifndef RENDERBACKEND_H
#define RENDERBACKEND_H
#include <QLinkedList>
#include "common/constructors.h"
#include "decodercache.h"
#include "node/graph.h"
#include "node/output/viewer/viewer.h"
#include "renderworker.h"
class RenderBackend : public QObject
{
Q_OBJECT
public:
RenderBackend(QObject* parent = nullptr);
DISABLE_COPY_MOVE(RenderBackend)
bool Init();
void Close();
const QString& GetError() const;
void SetViewerNode(ViewerOutput* viewer_node);
bool IsInitiated();
ViewerOutput* viewer_node() const;
public slots:
void InvalidateCache(const rational &start_range, const rational &end_range);
bool Compile();
void Decompile();
signals:
void QueueComplete();
protected:
void RegenerateCacheID();
virtual bool InitInternal() = 0;
virtual void CloseInternal() = 0;
virtual bool CompileInternal() = 0;
virtual void DecompileInternal() = 0;
virtual bool CanRender();
virtual TimeRange PopNextFrameFromQueue();
rational GetSequenceLength();
const QVector<QThread*>& threads();
/**
* @brief Internal function for generating the cache ID
*/
virtual bool GenerateCacheIDInternal(QCryptographicHash& hash) = 0;
virtual void CacheIDChangedEvent(const QString& id);
void SetError(const QString& error);
virtual void ConnectViewer(ViewerOutput* node);
virtual void DisconnectViewer(ViewerOutput* node);
/**
* @brief Function called when there are frames in the queue to cache
*
* This function is NOT thread-safe and should only be called in the main thread.
*/
void CacheNext();
void InitWorkers();
virtual NodeInput* GetDependentInput() = 0;
virtual void ConnectWorkerToThis(RenderWorker* worker) = 0;
bool ViewerIsConnected() const;
const QString& cache_id() const;
void QueueValueUpdate();
bool WorkerIsBusy(RenderWorker* worker) const;
void SetWorkerBusyState(RenderWorker* worker, bool busy);
TimeRangeList cache_queue_;
QVector<RenderWorker*> processors_;
bool compiled_;
QHash<TimeRange, qint64> render_job_info_;
protected slots:
void QueueRecompile();
private:
bool AllProcessorsAreAvailable() const;
/**
* @brief Internal list of RenderProcessThreads
*/
QVector<QThread*> threads_;
/**
* @brief Internal variable that contains whether the Renderer has started or not
*/
bool started_;
/**
* @brief Internal reference to attached viewer node
*/
ViewerOutput* viewer_node_;
/**
* @brief Internal reference to the copied viewer node we made in the compilation process
*/
ViewerOutput* copied_viewer_node_;
/**
* @brief Error string that can be set in SetError() to handle failures
*/
QString error_;
QString cache_id_;
QList<Node*> source_node_list_;
NodeGraph copied_graph_;
bool recompile_queued_;
bool input_update_queued_;
QVector<bool> processor_busy_state_;
};
#endif // RENDERBACKEND_H