Merge branch 'master' into gizmos
This commit is contained in:
+8
-1
@@ -94,6 +94,7 @@ if(MSVC)
|
||||
/external:anglebrackets
|
||||
/external:W0
|
||||
"$<$<CONFIG:RELEASE>:/O2>"
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:/MP>"
|
||||
)
|
||||
else()
|
||||
target_compile_options(
|
||||
@@ -110,7 +111,7 @@ else()
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_compile_options(
|
||||
target_link_options(
|
||||
${OLIVE_TARGET}
|
||||
PRIVATE
|
||||
-rdynamic
|
||||
@@ -155,6 +156,12 @@ if (WIN32)
|
||||
PRIVATE
|
||||
DbgHelp
|
||||
)
|
||||
elseif (APPLE)
|
||||
target_link_libraries(
|
||||
${OLIVE_TARGET}
|
||||
PRIVATE
|
||||
"-framework ApplicationServices"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(OLIVE_TS_FILES
|
||||
|
||||
@@ -98,8 +98,8 @@ void Config::SetDefaults()
|
||||
|
||||
config_map_["DiskCachePath"] = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
|
||||
config_map_["DiskCacheSize"] = 20.0;
|
||||
config_map_["DiskCacheBehind"] = QVariant::fromValue(rational(2));
|
||||
config_map_["DiskCacheAhead"] = QVariant::fromValue(rational(10));
|
||||
config_map_["DiskCacheBehind"] = QVariant::fromValue(rational(1));
|
||||
config_map_["DiskCacheAhead"] = QVariant::fromValue(rational(5));
|
||||
config_map_["ClearDiskCacheOnClose"] = false;
|
||||
|
||||
config_map_["DefaultSequenceWidth"] = 1920;
|
||||
|
||||
@@ -109,7 +109,7 @@ FootagePropertiesDialog::FootagePropertiesDialog(QWidget *parent, Footage *foota
|
||||
|
||||
// Auto-select first item that actually has properties
|
||||
if (first_usable_stream >= 0) {
|
||||
track_list->item(first_usable_stream)->setSelected(true);
|
||||
track_list->setCurrentRow(first_usable_stream);
|
||||
}
|
||||
track_list->setFocus();
|
||||
}
|
||||
|
||||
@@ -44,10 +44,12 @@ ProjectPropertiesDialog::ProjectPropertiesDialog(Project* p, QWidget *parent) :
|
||||
|
||||
setWindowTitle(tr("Project Properties for '%1'").arg(working_project_->name()));
|
||||
|
||||
QTabWidget* tabs = new QTabWidget;
|
||||
layout->addWidget(tabs);
|
||||
|
||||
{
|
||||
// Color management group
|
||||
QGroupBox* color_group = new QGroupBox();
|
||||
color_group->setTitle(tr("Color Management"));
|
||||
QWidget* color_group = new QWidget();
|
||||
|
||||
QGridLayout* color_layout = new QGridLayout(color_group);
|
||||
|
||||
@@ -72,18 +74,19 @@ ProjectPropertiesDialog::ProjectPropertiesDialog(Project* p, QWidget *parent) :
|
||||
color_layout->addWidget(browse_btn, 0, 2);
|
||||
connect(browse_btn, &QPushButton::clicked, this, &ProjectPropertiesDialog::BrowseForOCIOConfig);
|
||||
|
||||
layout->addWidget(color_group);
|
||||
|
||||
ocio_filename_->setText(working_project_->color_manager()->GetConfigFilename());
|
||||
|
||||
connect(ocio_filename_, &QLineEdit::textChanged, this, &ProjectPropertiesDialog::OCIOFilenameUpdated);
|
||||
OCIOFilenameUpdated();
|
||||
|
||||
tabs->addTab(color_group, tr("Color Management"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
// Paths group
|
||||
QGroupBox* paths_group = new QGroupBox();
|
||||
paths_group->setTitle(tr("Paths"));
|
||||
QWidget* paths_group = new QWidget();
|
||||
|
||||
QGridLayout* paths_layout = new QGridLayout(paths_group);
|
||||
|
||||
@@ -104,7 +107,7 @@ ProjectPropertiesDialog::ProjectPropertiesDialog(Project* p, QWidget *parent) :
|
||||
paths_layout->addWidget(proxy_path_->browse_btn(), row, 2);
|
||||
paths_layout->addWidget(proxy_path_->default_box(), row, 3);
|
||||
|
||||
layout->addWidget(paths_group);
|
||||
tabs->addTab(paths_group, tr("Paths"));
|
||||
}
|
||||
|
||||
QDialogButtonBox* dialog_btns = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
|
||||
|
||||
@@ -124,7 +124,7 @@ TimeRange AudioRenderBackend::PopNextFrameFromQueue()
|
||||
return range;
|
||||
}
|
||||
|
||||
void AudioRenderBackend::InvalidateCacheInternal(const rational &start_range, const rational &end_range)
|
||||
void AudioRenderBackend::InvalidateCacheInternal(const rational &start_range, const rational &end_range, bool only_visible)
|
||||
{
|
||||
if (!ic_from_conform_) {
|
||||
// Cancel any ranges waiting on a conform here since obviously the contents have changed
|
||||
@@ -153,7 +153,7 @@ void AudioRenderBackend::InvalidateCacheInternal(const rational &start_range, co
|
||||
}
|
||||
}
|
||||
|
||||
RenderBackend::InvalidateCacheInternal(start_range, end_range);
|
||||
RenderBackend::InvalidateCacheInternal(start_range, end_range, only_visible);
|
||||
}
|
||||
|
||||
void AudioRenderBackend::ListenForConformSignal(AudioStreamPtr s)
|
||||
|
||||
@@ -67,7 +67,7 @@ protected:
|
||||
|
||||
virtual TimeRange PopNextFrameFromQueue() override;
|
||||
|
||||
virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range) override;
|
||||
virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range, bool only_visible) override;
|
||||
|
||||
private:
|
||||
struct ConformWaitInfo {
|
||||
|
||||
@@ -259,6 +259,8 @@ void RenderBackend::CacheNext()
|
||||
SetWorkerBusyState(worker, true);
|
||||
cancel_dialog_->WorkerStarted();
|
||||
|
||||
WorkerAboutToStartEvent(worker);
|
||||
|
||||
QMetaObject::invokeMethod(worker,
|
||||
"Render",
|
||||
Qt::QueuedConnection,
|
||||
@@ -290,24 +292,14 @@ void RenderBackend::CancelQueue()
|
||||
cancel_dialog_->RunIfWorkersAreBusy();
|
||||
}
|
||||
|
||||
void RenderBackend::InvalidateVisible(const TimeRange &range, NodeInput *from)
|
||||
{
|
||||
InvalidateCacheVeryInternal(range, from, true);
|
||||
}
|
||||
|
||||
void RenderBackend::InvalidateCache(const TimeRange &range, NodeInput *from)
|
||||
{
|
||||
// Adjust range to min/max values
|
||||
rational start_range_adj = qMax(rational(0), range.in());
|
||||
rational end_range_adj = qMin(GetSequenceLength(), range.out());
|
||||
|
||||
qDebug() << "Cache invalidated between"
|
||||
<< start_range_adj.toDouble()
|
||||
<< "and"
|
||||
<< end_range_adj.toDouble();
|
||||
|
||||
if (from) {
|
||||
// Queue value update
|
||||
qDebug() << " from" << from->parentNode()->id() << "::" << from->id();
|
||||
QueueValueUpdate(from);
|
||||
}
|
||||
|
||||
InvalidateCacheInternal(start_range_adj, end_range_adj);
|
||||
InvalidateCacheVeryInternal(range, from, false);
|
||||
}
|
||||
|
||||
bool RenderBackend::ViewerIsConnected() const
|
||||
@@ -349,6 +341,26 @@ void RenderBackend::SetWorkerBusyState(RenderWorker *worker, bool busy)
|
||||
processor_busy_state_.replace(processors_.indexOf(worker), busy);
|
||||
}
|
||||
|
||||
void RenderBackend::InvalidateCacheVeryInternal(const TimeRange &range, NodeInput *from, bool only_visible)
|
||||
{
|
||||
// Adjust range to min/max values
|
||||
rational start_range_adj = qMax(rational(0), range.in());
|
||||
rational end_range_adj = qMin(GetSequenceLength(), range.out());
|
||||
|
||||
qDebug() << "Cache invalidated between"
|
||||
<< start_range_adj.toDouble()
|
||||
<< "and"
|
||||
<< end_range_adj.toDouble();
|
||||
|
||||
if (from) {
|
||||
// Queue value update
|
||||
qDebug() << " from" << from->parentNode()->id() << "::" << from->id();
|
||||
QueueValueUpdate(from);
|
||||
}
|
||||
|
||||
InvalidateCacheInternal(start_range_adj, end_range_adj, only_visible);
|
||||
}
|
||||
|
||||
void RenderBackend::CopyNodeInputValue(NodeInput *input)
|
||||
{
|
||||
// Find our copy of this parameter
|
||||
@@ -446,8 +458,10 @@ const QVector<QThread *> &RenderBackend::threads()
|
||||
return threads_;
|
||||
}
|
||||
|
||||
void RenderBackend::InvalidateCacheInternal(const rational &start_range, const rational &end_range)
|
||||
void RenderBackend::InvalidateCacheInternal(const rational &start_range, const rational &end_range, bool only_visible)
|
||||
{
|
||||
Q_UNUSED(only_visible)
|
||||
|
||||
// Add the range to the list
|
||||
cache_queue_.InsertTimeRange(TimeRange(start_range, end_range));
|
||||
|
||||
@@ -459,6 +473,11 @@ void RenderBackend::CacheIDChangedEvent(const QString &id)
|
||||
Q_UNUSED(id)
|
||||
}
|
||||
|
||||
void RenderBackend::WorkerAboutToStartEvent(RenderWorker *worker)
|
||||
{
|
||||
Q_UNUSED(worker)
|
||||
}
|
||||
|
||||
void RenderBackend::InitWorkers()
|
||||
{
|
||||
for (int i=0;i<processors_.size();i++) {
|
||||
|
||||
@@ -51,6 +51,8 @@ public:
|
||||
|
||||
void CancelQueue();
|
||||
|
||||
void InvalidateVisible(const TimeRange &range, NodeInput *from);
|
||||
|
||||
public slots:
|
||||
void InvalidateCache(const TimeRange &range, NodeInput *from);
|
||||
|
||||
@@ -77,10 +79,12 @@ protected:
|
||||
*/
|
||||
virtual bool GenerateCacheIDInternal(QCryptographicHash& hash) = 0;
|
||||
|
||||
virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range);
|
||||
virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range, bool only_visible);
|
||||
|
||||
virtual void CacheIDChangedEvent(const QString& id);
|
||||
|
||||
virtual void WorkerAboutToStartEvent(RenderWorker* worker);
|
||||
|
||||
void SetError(const QString& error);
|
||||
|
||||
virtual void ConnectViewer(ViewerOutput* node);
|
||||
@@ -120,6 +124,8 @@ protected:
|
||||
NodeGraph copied_graph_;
|
||||
|
||||
private:
|
||||
void InvalidateCacheVeryInternal(const TimeRange &range, NodeInput *from, bool only_visible);
|
||||
|
||||
void CopyNodeInputValue(NodeInput* input);
|
||||
Node *CopyNodeConnections(Node *src_node);
|
||||
void CopyNodeMakeConnection(NodeInput *src_input, NodeInput *dst_input);
|
||||
|
||||
@@ -41,7 +41,8 @@ VideoRenderBackend::VideoRenderBackend(QObject *parent) :
|
||||
operating_mode_(VideoRenderWorker::kHashRenderCache),
|
||||
only_signal_last_frame_requested_(true),
|
||||
limit_caching_(true),
|
||||
pop_toggle_(false)
|
||||
pop_toggle_(false),
|
||||
queue_is_visible_only_(false)
|
||||
{
|
||||
connect(DiskManager::instance(), &DiskManager::DeletedFrame, this, &VideoRenderBackend::FrameRemovedFromDiskCache);
|
||||
}
|
||||
@@ -152,7 +153,7 @@ void VideoRenderBackend::ConnectWorkerToThis(RenderWorker *processor)
|
||||
connect(video_processor, &VideoRenderWorker::GeneratedFrame, this, &VideoRenderBackend::ThreadGeneratedFrame, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void VideoRenderBackend::InvalidateCacheInternal(const rational &start_range, const rational &end_range)
|
||||
void VideoRenderBackend::InvalidateCacheInternal(const rational &start_range, const rational &end_range, bool only_visible)
|
||||
{
|
||||
TimeRange invalidated(start_range, end_range);
|
||||
|
||||
@@ -160,7 +161,39 @@ void VideoRenderBackend::InvalidateCacheInternal(const rational &start_range, co
|
||||
|
||||
emit RangeInvalidated(invalidated);
|
||||
|
||||
Requeue();
|
||||
queue_is_visible_only_ = only_visible;
|
||||
|
||||
if (only_visible) {
|
||||
|
||||
// We're only caching this frame, and for maximum responsiveness, should cancel the rest of the
|
||||
// queue
|
||||
cache_queue_.clear();
|
||||
cache_queue_.InsertTimeRange(TimeRange(start_range, end_range));
|
||||
|
||||
CacheNext();
|
||||
|
||||
} else {
|
||||
|
||||
// Rework the queue
|
||||
Requeue();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void VideoRenderBackend::WorkerAboutToStartEvent(RenderWorker *worker)
|
||||
{
|
||||
if (operating_mode_ & VideoRenderWorker::kDownloadOnly) {
|
||||
int mode = operating_mode_;
|
||||
|
||||
if (queue_is_visible_only_) {
|
||||
mode &= ~VideoRenderWorker::kDownloadOnly;
|
||||
} else {
|
||||
mode |= VideoRenderWorker::kDownloadOnly;
|
||||
}
|
||||
|
||||
static_cast<VideoRenderWorker*>(worker)->
|
||||
SetOperatingMode(static_cast<VideoRenderWorker::OperatingMode>(mode));
|
||||
}
|
||||
}
|
||||
|
||||
VideoRenderFrameCache *VideoRenderBackend::frame_cache()
|
||||
@@ -201,9 +234,11 @@ QString VideoRenderBackend::GetCachedFrame(const rational &time)
|
||||
|
||||
void VideoRenderBackend::UpdateLastRequestedTime(const rational &time)
|
||||
{
|
||||
last_time_requested_ = time;
|
||||
if (last_time_requested_ != time) {
|
||||
last_time_requested_ = time;
|
||||
|
||||
Requeue();
|
||||
Requeue();
|
||||
}
|
||||
}
|
||||
|
||||
NodeInput *VideoRenderBackend::GetDependentInput()
|
||||
|
||||
@@ -99,10 +99,12 @@ protected:
|
||||
|
||||
virtual void ConnectWorkerToThis(RenderWorker* processor) override;
|
||||
|
||||
virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range) override;
|
||||
virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range, bool only_visible) override;
|
||||
|
||||
virtual void ParamsChangedEvent(){}
|
||||
|
||||
virtual void WorkerAboutToStartEvent(RenderWorker* worker) override;
|
||||
|
||||
VideoRenderWorker::OperatingMode operating_mode_;
|
||||
|
||||
signals:
|
||||
@@ -135,6 +137,8 @@ private:
|
||||
|
||||
bool pop_toggle_;
|
||||
|
||||
bool queue_is_visible_only_;
|
||||
|
||||
private slots:
|
||||
void ThreadCompletedDownload(NodeDependency dep, qint64 job_time, QByteArray hash);
|
||||
void ThreadSkippedFrame(NodeDependency dep, qint64 job_time, QByteArray hash);
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
@@ -48,40 +53,51 @@ SliderLabel::SliderLabel(QWidget *parent) :
|
||||
setFocusPolicy(Qt::TabFocus);
|
||||
}
|
||||
|
||||
void SliderLabel::mousePressEvent(QMouseEvent *ev)
|
||||
void SliderLabel::mousePressEvent(QMouseEvent *)
|
||||
{
|
||||
QLabel::mousePressEvent(ev);
|
||||
emit drag_start();
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
CGAssociateMouseAndMouseCursorPosition(false);
|
||||
CGDisplayHideCursor(kCGDirectMainDisplay);
|
||||
CGGetLastMouseDelta(nullptr, nullptr);
|
||||
#else
|
||||
drag_start_ = QCursor::pos();
|
||||
|
||||
static_cast<QGuiApplication*>(QApplication::instance())->setOverrideCursor(Qt::BlankCursor);
|
||||
|
||||
emit drag_start();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SliderLabel::mouseMoveEvent(QMouseEvent *ev)
|
||||
void SliderLabel::mouseMoveEvent(QMouseEvent *)
|
||||
{
|
||||
QLabel::mouseMoveEvent(ev);
|
||||
|
||||
QPoint current_pos = QCursor::pos();
|
||||
|
||||
int x_mvmt = current_pos.x() - drag_start_.x();
|
||||
int y_mvmt = drag_start_.y() - current_pos.y();
|
||||
|
||||
emit dragged(x_mvmt + y_mvmt);
|
||||
int32_t x_mvmt, y_mvmt;
|
||||
|
||||
// Keep cursor in the same position
|
||||
#if defined(Q_OS_MAC)
|
||||
CGGetLastMouseDelta(&x_mvmt, &y_mvmt);
|
||||
#else
|
||||
QPoint current_pos = QCursor::pos();
|
||||
|
||||
x_mvmt = current_pos.x() - drag_start_.x();
|
||||
y_mvmt = drag_start_.y() - current_pos.y();
|
||||
|
||||
QCursor::setPos(drag_start_);
|
||||
#endif
|
||||
|
||||
emit dragged(x_mvmt + y_mvmt);
|
||||
}
|
||||
|
||||
void SliderLabel::mouseReleaseEvent(QMouseEvent *ev)
|
||||
void SliderLabel::mouseReleaseEvent(QMouseEvent *)
|
||||
{
|
||||
QWidget::mouseReleaseEvent(ev);
|
||||
#if defined(Q_OS_MAC)
|
||||
CGAssociateMouseAndMouseCursorPosition(true);
|
||||
CGDisplayShowCursor(kCGDirectMainDisplay);
|
||||
#else
|
||||
static_cast<QGuiApplication*>(QApplication::instance())->restoreOverrideCursor();
|
||||
#endif
|
||||
|
||||
// Emit a clicked signal
|
||||
emit drag_stop();
|
||||
|
||||
static_cast<QGuiApplication*>(QApplication::instance())->restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void SliderLabel::focusInEvent(QFocusEvent *event)
|
||||
|
||||
@@ -54,6 +54,8 @@ signals:
|
||||
private:
|
||||
QPoint drag_start_;
|
||||
|
||||
bool cancel_mm_event_;
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -105,6 +105,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
connect(video_renderer_, &VideoRenderBackend::CachedTimeReady, this, &ViewerWidget::RendererCachedTime);
|
||||
connect(video_renderer_, &VideoRenderBackend::CachedTimeReady, ruler(), &TimeRuler::CacheTimeReady);
|
||||
connect(video_renderer_, &VideoRenderBackend::RangeInvalidated, ruler(), &TimeRuler::CacheInvalidatedRange);
|
||||
connect(video_renderer_, &VideoRenderBackend::GeneratedFrame, this, &ViewerWidget::RendererGeneratedFrame);
|
||||
audio_renderer_ = new AudioBackend(this);
|
||||
|
||||
waveform_view_->SetBackend(audio_renderer_);
|
||||
@@ -522,6 +523,13 @@ void ViewerWidget::ContextMenuScopeTriggered(QAction *action)
|
||||
emit RequestScopePanel(static_cast<ScopePanel::Type>(action->data().toInt()));
|
||||
}
|
||||
|
||||
void ViewerWidget::RendererGeneratedFrame(FramePtr f)
|
||||
{
|
||||
foreach (ViewerDisplayWidget* glw, gl_widgets_) {
|
||||
glw->SetImageFromLoadBuffer(f.get());
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::UpdateRendererParameters()
|
||||
{
|
||||
if (!GetConnectedNode()) {
|
||||
@@ -878,7 +886,7 @@ void ViewerWidget::SetZoomFromMenu(QAction *action)
|
||||
|
||||
void ViewerWidget::InvalidateVisible(NodeInput* source)
|
||||
{
|
||||
video_renderer_->InvalidateCache(TimeRange(GetTime(), GetTime()), source);
|
||||
video_renderer_->InvalidateVisible(TimeRange(GetTime(), GetTime()), source);
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -236,6 +236,8 @@ private slots:
|
||||
|
||||
void ContextMenuScopeTriggered(QAction* action);
|
||||
|
||||
void RendererGeneratedFrame(FramePtr f);
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
Reference in New Issue
Block a user