If you run into new OpenGL issues, this is likely the commit that caused it. I've tested this on as many systems as I have access to (including AMD, Apple, Intel, and NVIDIA GPUs with a mixture of Windows, Linux, and macOS) and it appears to work fine, however we all know how unpredictable GPUs can be. This should help increase GPU performance and compatibility. Squashed commit of the following: commit fa3c0ac7c469aebe2941a803736bdc06cdd5a2d8 Author: itsmattkc <itsmattkc@gmail.com> Date: Thu May 27 13:17:44 2021 +1000 viewer: updated pixel sampling for shared contexts commit 9334261da235f09cb67b193c5bb6169abd7a95f7 Author: itsmattkc <itsmattkc@gmail.com> Date: Thu May 27 13:12:39 2021 +1000 pixelsampler: show color preview box commit dacd9be6971c5c0312ae45c8db349d47910a80dd Author: itsmattkc <itsmattkc@gmail.com> Date: Thu May 27 12:43:32 2021 +1000 renderer: interlace on GPU commit 074cea06cb87e9fdc4e8ea6b09587be6df296057 Author: itsmattkc <itsmattkc@gmail.com> Date: Thu May 27 12:43:14 2021 +1000 renderer: added texture clear option commit 5d4f86b4cf1b1dcd3fb8e8c854ffa7f6fb8ca346 Author: itsmattkc <itsmattkc@gmail.com> Date: Thu May 27 12:42:12 2021 +1000 renderer: updated scopes for shared textures commit 6fad96358d189874cf45f7887b7e13cc2b1603c4 Author: itsmattkc <itsmattkc@gmail.com> Date: Thu May 27 11:42:05 2021 +1000 opengl: fixed edge case commit 1a19ffb53703ac6f30ed210f6d8eb5fc4b7b0f2d Author: itsmattkc <itsmattkc@gmail.com> Date: Thu May 27 10:56:13 2021 +1000 opengl: fix deinterlace shader commit 085961aa39cca90ebf51b919a78ef07a4882f0e1 Author: itsmattkc <itsmattkc@gmail.com> Date: Thu May 27 10:08:40 2021 +1000 opengl: downgrade to ES 2.0 With half-float/float/3D extensions, this should be doable commit ea1ab45cbcf5e017dfd0d8f28b231ff3255dfe92 Author: itsmattkc <itsmattkc@gmail.com> Date: Thu May 27 10:06:59 2021 +1000 renderer: fixed mutex deadlock commit ecc2f08b16f03421870c5b61625ecd26f2f96582 Author: itsmattkc <itsmattkc@gmail.com> Date: Wed May 26 21:28:13 2021 +1000 opengl: fixed shared contexts commit 261c689ea8089463155cf11b9ab15aa3f879f439 Merge: bfd4338a91c88b1cAuthor: itsmattkc <itsmattkc@gmail.com> Date: Wed May 26 19:52:00 2021 +1000 Merge branch 'master' into shared-contexts commit bfd4338aaa3b09b6fbb7717c637face8d5490721 Author: itsmattkc <itsmattkc@gmail.com> Date: Wed May 26 18:52:38 2021 +1000 viewer: remove debug line commit 45868d8a396181bf81c24b92a1ac5ce9ffed3426 Merge: 642f8e9dd0bd5e21Author: itsmattkc <itsmattkc@gmail.com> Date: Wed May 26 17:21:48 2021 +1000 Merge branch 'master' into shared-contexts commit 642f8e9df7d7d1a9ed4202d428f4d968ff668552 Merge: 861e5b894de0a727Author: itsmattkc <itsmattkc@gmail.com> Date: Wed May 26 17:01:38 2021 +1000 Merge branch 'master' of https://github.com/olive-editor/olive into shared-contexts commit 861e5b89a38c281897dc44b20e3587d39c4f808c Merge: 472598a7ef31c3fbAuthor: itsmattkc <itsmattkc@gmail.com> Date: Wed May 26 14:28:21 2021 +1000 Merge branch 'master' into shared-contexts commit 472598a740a095aa43a4aad5680dd5abcf453a4c Author: itsmattkc <itsmattkc@gmail.com> Date: Fri May 14 16:29:35 2021 +1000 attempt at sharing contexts
227 lines
6.0 KiB
C++
227 lines
6.0 KiB
C++
#ifndef AUTOCACHER_H
|
|
#define AUTOCACHER_H
|
|
|
|
#include <QtConcurrent/QtConcurrent>
|
|
|
|
#include "config/config.h"
|
|
#include "node/graph.h"
|
|
#include "node/color/colormanager/colormanager.h"
|
|
#include "node/node.h"
|
|
#include "node/output/viewer/viewer.h"
|
|
#include "node/project/project.h"
|
|
#include "threading/threadticketwatcher.h"
|
|
|
|
namespace olive {
|
|
|
|
/**
|
|
* @brief Manager for dynamically caching a sequence in the background
|
|
*
|
|
* Intended to be used with a Viewer to dynamically cache parts of a sequence based on the playhead.
|
|
*/
|
|
class PreviewAutoCacher : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
PreviewAutoCacher();
|
|
|
|
virtual ~PreviewAutoCacher() override;
|
|
|
|
RenderTicketPtr GetSingleFrame(const rational& t, bool prioritize);
|
|
|
|
/**
|
|
* @brief Set the viewer node to auto-cache
|
|
*/
|
|
void SetViewerNode(ViewerOutput *viewer_node);
|
|
|
|
/**
|
|
* @brief If the mouse is held during the next cache invalidation, cache anyway
|
|
*
|
|
* By default, PreviewAutoCacher ignores invalidations that occur while the mouse is held down,
|
|
* assuming that if the mouse is held, the user is dragging something. If you know the mouse will
|
|
* be held during a certain action and want PreviewAutoCacher to cache anyway, call this before
|
|
* the cache invalidates.
|
|
*/
|
|
void IgnoreNextMouseButton();
|
|
|
|
/**
|
|
* @brief Returns whether the auto-cache is currently paused or not
|
|
*/
|
|
bool IsPaused() const
|
|
{
|
|
return paused_;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets whether the auto-cache is currently paused or not
|
|
* @param paused
|
|
*
|
|
* If TRUE, the cache queue is cleared (any frames currently being rendered will be processed as
|
|
* normal however). If FALSE, any uncached frames in the range will automatically be queued.
|
|
*/
|
|
void SetPaused(bool paused);
|
|
|
|
/**
|
|
* @brief Force a certain range to be cached
|
|
*
|
|
* Usually, PreviewAutoCacher caches a user-defined range around the playhead, however there are
|
|
* times they may want certain non-playhead-related time ranges to be cached (i.e. entire sequence
|
|
* or in/out range), so that can be set here.
|
|
*/
|
|
void ForceCacheRange(const TimeRange& range);
|
|
|
|
/**
|
|
* @brief Updates the range of frames to auto-cache
|
|
*/
|
|
void SetPlayhead(const rational& playhead);
|
|
|
|
void ClearHashQueue(bool wait = false);
|
|
void ClearVideoQueue(bool wait = false);
|
|
void ClearAudioQueue(bool wait = false);
|
|
void ClearVideoDownloadQueue(bool wait = false);
|
|
|
|
private:
|
|
static void GenerateHashes(ViewerOutput *viewer, FrameHashCache *cache, const QVector<rational>& times, qint64 job_time);
|
|
|
|
void TryRender();
|
|
|
|
RenderTicketWatcher *RenderFrame(const QByteArray& hash, const rational &time, bool prioritize, bool texture_only);
|
|
|
|
/**
|
|
* @brief Process all changes to internal NodeGraph copy
|
|
*
|
|
* PreviewAutoCacher staggers updates to its internal NodeGraph copy, only applying them when the
|
|
* RenderManager is not reading from it. This function is called when such an opportunity arises.
|
|
*/
|
|
void ProcessUpdateQueue();
|
|
|
|
bool HasActiveJobs() const;
|
|
|
|
void AddNode(Node* node);
|
|
void RemoveNode(Node* node);
|
|
void AddEdge(const NodeOutput& output, const NodeInput& input);
|
|
void RemoveEdge(const NodeOutput& output, const NodeInput& input);
|
|
void CopyValue(const NodeInput& input);
|
|
|
|
void InsertIntoCopyMap(Node* node, Node* copy);
|
|
|
|
void UpdateLastSyncedValue();
|
|
|
|
void CancelQueuedSingleFrameRender();
|
|
|
|
template <typename T, typename Func>
|
|
void ClearQueueInternal(T& list, bool hard, Func member);
|
|
|
|
void ClearQueueRemoveEventInternal(QMap<RenderTicketWatcher*, QByteArray>::iterator it);
|
|
void ClearQueueRemoveEventInternal(QMap<RenderTicketWatcher*, TimeRange>::iterator it);
|
|
void ClearQueueRemoveEventInternal(QVector<RenderTicketWatcher*>::iterator it);
|
|
|
|
class QueuedJob {
|
|
public:
|
|
enum Type {
|
|
kNodeAdded,
|
|
kNodeRemoved,
|
|
kEdgeAdded,
|
|
kEdgeRemoved,
|
|
kValueChanged
|
|
};
|
|
|
|
Type type;
|
|
Node* node;
|
|
NodeInput input;
|
|
NodeOutput output;
|
|
};
|
|
|
|
ViewerOutput* viewer_node_;
|
|
|
|
Project copied_project_;
|
|
|
|
QVector<QueuedJob> graph_update_queue_;
|
|
QHash<Node*, Node*> copy_map_;
|
|
ViewerOutput* copied_viewer_node_;
|
|
ColorManager* copied_color_manager_;
|
|
QVector<Node*> created_nodes_;
|
|
|
|
bool paused_;
|
|
|
|
TimeRange cache_range_;
|
|
|
|
bool has_changed_;
|
|
|
|
bool use_custom_range_;
|
|
TimeRange custom_autocache_range_;
|
|
|
|
TimeRangeList invalidated_video_;
|
|
TimeRangeList invalidated_audio_;
|
|
|
|
RenderTicketPtr single_frame_render_;
|
|
|
|
QList<QFutureWatcher<void>*> hash_tasks_;
|
|
QMap<RenderTicketWatcher*, TimeRange> audio_tasks_;
|
|
QMap<RenderTicketWatcher*, QByteArray> video_tasks_;
|
|
QMap<RenderTicketWatcher*, QByteArray> video_download_tasks_;
|
|
QMap<RenderTicketWatcher*, QVector<RenderTicketPtr> > video_immediate_passthroughs_;
|
|
|
|
qint64 last_update_time_;
|
|
|
|
bool ignore_next_mouse_button_;
|
|
|
|
QTimer delayed_requeue_timer_;
|
|
|
|
TimeRangeList audio_needing_conform_;
|
|
|
|
qint64 last_conform_task_;
|
|
|
|
private slots:
|
|
/**
|
|
* @brief Handler for when the NodeGraph reports a video change over a certain time range
|
|
*/
|
|
void VideoInvalidated(const olive::TimeRange &range);
|
|
|
|
/**
|
|
* @brief Handler for when the NodeGraph reports a audio change over a certain time range
|
|
*/
|
|
void AudioInvalidated(const olive::TimeRange &range);
|
|
|
|
/**
|
|
* @brief Handler for when we have applied all the hashes to the FrameHashCache
|
|
*/
|
|
void HashesProcessed();
|
|
|
|
/**
|
|
* @brief Handler for when the RenderManager has returned rendered audio
|
|
*/
|
|
void AudioRendered();
|
|
|
|
/**
|
|
* @brief Handler for when the RenderManager has returned rendered video frames
|
|
*/
|
|
void VideoRendered();
|
|
|
|
/**
|
|
* @brief Handler for when we've saved a video frame to the cache
|
|
*/
|
|
void VideoDownloaded();
|
|
|
|
void NodeAdded(Node* node);
|
|
|
|
void NodeRemoved(Node* node);
|
|
|
|
void EdgeAdded(const NodeOutput& output, const NodeInput& input);
|
|
|
|
void EdgeRemoved(const NodeOutput& output, const NodeInput& input);
|
|
|
|
void ValueChanged(const NodeInput& input);
|
|
|
|
/**
|
|
* @brief Generic function called whenever the frames to render need to be (re)queued
|
|
*/
|
|
void RequeueFrames();
|
|
|
|
void ConformFinished();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif // AUTOCACHER_H
|