Merge branch 'master' into nodeviewredux
This commit is contained in:
@@ -22,7 +22,6 @@
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "audio/audiomanager.h"
|
||||
#include "config/config.h"
|
||||
@@ -80,14 +79,14 @@ PreferencesAudioTab::PreferencesAudioTab()
|
||||
|
||||
row++;
|
||||
|
||||
QPushButton* refresh_devices = new QPushButton(tr("Refresh Devices"));
|
||||
audio_tab_layout->addWidget(refresh_devices, row, 1);
|
||||
refresh_devices_btn_ = new QPushButton(tr("Refresh Devices"));
|
||||
audio_tab_layout->addWidget(refresh_devices_btn_, row, 1);
|
||||
|
||||
row++;
|
||||
|
||||
RetrieveDeviceLists();
|
||||
|
||||
connect(refresh_devices, &QPushButton::clicked, this, &PreferencesAudioTab::RefreshDevices);
|
||||
connect(refresh_devices_btn_, &QPushButton::clicked, this, &PreferencesAudioTab::RefreshDevices);
|
||||
connect(AudioManager::instance(), &AudioManager::OutputListReady, this, &PreferencesAudioTab::RetrieveOutputList);
|
||||
connect(AudioManager::instance(), &AudioManager::InputListReady, this, &PreferencesAudioTab::RetrieveInputList);
|
||||
}
|
||||
@@ -151,6 +150,8 @@ void PreferencesAudioTab::RetrieveOutputList()
|
||||
AudioManager::instance()->IsRefreshingOutputs(),
|
||||
AudioManager::instance()->ListOutputDevices(),
|
||||
Config::Current()["AudioOutput"].toString());
|
||||
|
||||
UpdateRefreshButtonEnabled();
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::RetrieveInputList()
|
||||
@@ -159,6 +160,8 @@ void PreferencesAudioTab::RetrieveInputList()
|
||||
AudioManager::instance()->IsRefreshingInputs(),
|
||||
AudioManager::instance()->ListInputDevices(),
|
||||
Config::Current()["AudioInput"].toString());
|
||||
|
||||
UpdateRefreshButtonEnabled();
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::RetrieveDeviceLists()
|
||||
@@ -167,17 +170,22 @@ void PreferencesAudioTab::RetrieveDeviceLists()
|
||||
RetrieveInputList();
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::UpdateRefreshButtonEnabled()
|
||||
{
|
||||
refresh_devices_btn_->setEnabled(audio_output_devices_->isEnabled()
|
||||
&& audio_input_devices_->isEnabled());
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::PopulateComboBox(QComboBox *cb, bool still_refreshing, const QList<QAudioDeviceInfo> &list, const QString& preferred)
|
||||
{
|
||||
cb->clear();
|
||||
|
||||
cb->setEnabled(still_refreshing);
|
||||
cb->setEnabled(!still_refreshing);
|
||||
|
||||
if (still_refreshing) {
|
||||
cb->addItem(tr("Please wait..."));
|
||||
} else {
|
||||
bool found_preferred_device = false;
|
||||
cb->setEnabled(true);
|
||||
|
||||
// Add null default item
|
||||
cb->addItem(tr("Default"), QVariant());
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <QAudioDeviceInfo>
|
||||
#include <QComboBox>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "preferencestab.h"
|
||||
|
||||
@@ -57,6 +58,11 @@ private:
|
||||
*/
|
||||
QComboBox* recording_combobox_;
|
||||
|
||||
/**
|
||||
* @brief Button that triggers a refresh of the available audio devices
|
||||
*/
|
||||
QPushButton* refresh_devices_btn_;
|
||||
|
||||
private slots:
|
||||
void RefreshDevices();
|
||||
|
||||
@@ -67,6 +73,8 @@ private slots:
|
||||
private:
|
||||
void RetrieveDeviceLists();
|
||||
|
||||
void UpdateRefreshButtonEnabled();
|
||||
|
||||
static void PopulateComboBox(QComboBox* cb, bool still_refreshing, const QList<QAudioDeviceInfo>& list, const QString &preferred);
|
||||
|
||||
};
|
||||
|
||||
+2
-2
@@ -50,8 +50,8 @@ int main(int argc, char *argv[]) {
|
||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
|
||||
// Try to share OpenGL contexts
|
||||
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
|
||||
// Create application instance
|
||||
QApplication a(argc, argv);
|
||||
|
||||
@@ -35,10 +35,10 @@ PanelManager::PanelManager(QObject *parent) :
|
||||
|
||||
void PanelManager::DeleteAllPanels()
|
||||
{
|
||||
foreach (PanelWidget* panel, focus_history_) {
|
||||
delete panel;
|
||||
}
|
||||
// Prevent any confusion regarding focus history by clearing it first
|
||||
QList<PanelWidget*> copy = focus_history_;
|
||||
focus_history_.clear();
|
||||
qDeleteAll(copy);
|
||||
}
|
||||
|
||||
const QList<PanelWidget *> &PanelManager::panels()
|
||||
|
||||
@@ -175,14 +175,26 @@ T *PanelManager::CreatePanel(QWidget *parent)
|
||||
{
|
||||
T* panel = new T(parent);
|
||||
|
||||
panel->SetMovementLocked(locked_);
|
||||
|
||||
// Connect destroy signal so we can remove it from focus history
|
||||
connect(panel, &PanelWidget::destroyed, this, &PanelManager::PanelDestroyed);
|
||||
|
||||
// Add panel to the bottom of the focus history
|
||||
focus_history_.append(panel);
|
||||
|
||||
panel->SetMovementLocked(locked_);
|
||||
|
||||
// Sane default for panel size
|
||||
panel->resize(parent->size() / 3);
|
||||
|
||||
// We're about to center the panel relative to the parent (usually the main window), but for some
|
||||
// reason this requires the panel to be shown first.
|
||||
panel->show();
|
||||
|
||||
// Center the panel relative to the parent
|
||||
QPoint parent_center = panel->mapFromGlobal(parent->mapToGlobal(parent->rect().center()));
|
||||
QPoint panel_center = panel->rect().center();
|
||||
panel->move(parent_center - panel_center);
|
||||
|
||||
// Connect destroy signal so we can remove it from focus history
|
||||
connect(panel, &PanelWidget::destroyed, this, &PanelManager::PanelDestroyed, Qt::DirectConnection);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,9 +94,11 @@ void ParamPanel::CreateCurvePanel(NodeInput *input)
|
||||
panel->SetInput(input);
|
||||
panel->SetTimebase(view->timebase());
|
||||
panel->SetTimestamp(view->GetTimestamp());
|
||||
panel->SetTimeTarget(view->GetTimeTarget());
|
||||
|
||||
connect(view, &NodeParamView::TimebaseChanged, panel, &CurvePanel::SetTimebase);
|
||||
connect(view, &NodeParamView::TimeChanged, panel, &CurvePanel::SetTimestamp);
|
||||
connect(view, &NodeParamView::TimeTargetChanged, panel, &CurvePanel::SetTimeTarget);
|
||||
connect(panel, &CurvePanel::TimeChanged, view, &NodeParamView::SetTimestamp);
|
||||
connect(panel, &CurvePanel::TimeChanged, view, &NodeParamView::TimeChanged);
|
||||
connect(panel, &CurvePanel::CloseRequested, this, &ParamPanel::ClosingCurvePanel);
|
||||
|
||||
@@ -84,19 +84,10 @@ QString ScopePanel::TypeToName(ScopePanel::Type t)
|
||||
return QString();
|
||||
}
|
||||
|
||||
void ScopePanel::SetDisplayReferredTexture(OpenGLTexture *texture)
|
||||
{
|
||||
Q_UNUSED(texture)
|
||||
}
|
||||
|
||||
void ScopePanel::SetReferenceBuffer(Frame *frame)
|
||||
{
|
||||
histogram_->SetBuffer(frame);
|
||||
}
|
||||
|
||||
void ScopePanel::SetReferenceTexture(OpenGLTexture *texture)
|
||||
{
|
||||
waveform_view_->SetTexture(texture);
|
||||
waveform_view_->SetBuffer(frame);
|
||||
}
|
||||
|
||||
void ScopePanel::SetColorManager(ColorManager *manager)
|
||||
|
||||
@@ -50,12 +50,8 @@ public:
|
||||
static QString TypeToName(Type t);
|
||||
|
||||
public slots:
|
||||
void SetDisplayReferredTexture(OpenGLTexture* texture);
|
||||
|
||||
void SetReferenceBuffer(Frame* frame);
|
||||
|
||||
void SetReferenceTexture(OpenGLTexture* texture);
|
||||
|
||||
void SetColorManager(ColorManager* manager);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -25,8 +25,7 @@
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
ViewerPanelBase::ViewerPanelBase(const QString& object_name, QWidget *parent) :
|
||||
TimeBasedPanel(object_name, parent),
|
||||
scope_panel_count_(0)
|
||||
TimeBasedPanel(object_name, parent)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -98,33 +97,13 @@ void ViewerPanelBase::CreateScopePanel(ScopePanel::Type type)
|
||||
|
||||
p->SetType(type);
|
||||
|
||||
// If the scope closes, reduce the count (we do this because if no scopes are open, we can optimize the viewer slightly)
|
||||
connect(p, &ScopePanel::CloseRequested, this, &ViewerPanelBase::ScopePanelClosed);
|
||||
|
||||
// Connect viewer widget texture drawing to scope panel
|
||||
connect(vw, &ViewerWidget::DrewManagedTexture, p, &ScopePanel::SetDisplayReferredTexture);
|
||||
connect(vw, &ViewerWidget::LoadedBuffer, p, &ScopePanel::SetReferenceBuffer);
|
||||
connect(vw, &ViewerWidget::LoadedTexture, p, &ScopePanel::SetReferenceTexture);
|
||||
connect(vw, &ViewerWidget::ColorManagerChanged, p, &ScopePanel::SetColorManager);
|
||||
|
||||
p->SetColorManager(vw->color_manager());
|
||||
|
||||
if (!scope_panel_count_) {
|
||||
vw->SetEmitDrewManagedTextureEnabled(true);
|
||||
}
|
||||
|
||||
scope_panel_count_++;
|
||||
|
||||
vw->ForceUpdate();
|
||||
}
|
||||
|
||||
void ViewerPanelBase::ScopePanelClosed()
|
||||
{
|
||||
scope_panel_count_--;
|
||||
|
||||
if (!scope_panel_count_) {
|
||||
static_cast<ViewerWidget*>(GetTimeBasedWidget())->SetEmitDrewManagedTextureEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -59,12 +59,6 @@ public:
|
||||
protected:
|
||||
void CreateScopePanel(ScopePanel::Type type);
|
||||
|
||||
private:
|
||||
int scope_panel_count_;
|
||||
|
||||
private slots:
|
||||
void ScopePanelClosed();
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -132,7 +132,7 @@ void OpenGLProxy::FrameToValue(FramePtr frame, StreamPtr stream, NodeValueTable*
|
||||
|
||||
VideoRenderingParams footage_params(frame->width(), frame->height(), frame->format());
|
||||
|
||||
footage_tex_ref = texture_cache_.Get(ctx_, footage_params, frame->data(), frame->linesize_pixels());
|
||||
footage_tex_ref = texture_cache_.Get(ctx_, footage_params, frame);
|
||||
|
||||
if (ocio_method == ColorManager::kOCIOFast) {
|
||||
if (!color_processor->IsEnabled()) {
|
||||
|
||||
@@ -74,6 +74,11 @@ void OpenGLTexture::Create(QOpenGLContext *ctx, int width, int height, const Pix
|
||||
}
|
||||
|
||||
void OpenGLTexture::Create(QOpenGLContext *ctx, FramePtr frame)
|
||||
{
|
||||
Create(ctx, frame.get());
|
||||
}
|
||||
|
||||
void OpenGLTexture::Create(QOpenGLContext *ctx, Frame *frame)
|
||||
{
|
||||
Create(ctx, frame->width(), frame->height(), frame->format(), frame->data(), frame->linesize_pixels());
|
||||
}
|
||||
@@ -120,6 +125,16 @@ const GLuint &OpenGLTexture::texture() const
|
||||
return texture_;
|
||||
}
|
||||
|
||||
void OpenGLTexture::Upload(FramePtr frame)
|
||||
{
|
||||
Upload(frame.get());
|
||||
}
|
||||
|
||||
void OpenGLTexture::Upload(Frame *frame)
|
||||
{
|
||||
Upload(frame->data(), frame->linesize_pixels());
|
||||
}
|
||||
|
||||
void OpenGLTexture::Upload(const void *data, int linesize)
|
||||
{
|
||||
if (!IsCreated()) {
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
void Create(QOpenGLContext* ctx, int width, int height, const PixelFormat::Format &format, const void *data, int linesize);
|
||||
void Create(QOpenGLContext* ctx, int width, int height, const PixelFormat::Format &format);
|
||||
void Create(QOpenGLContext* ctx, FramePtr frame);
|
||||
void Create(QOpenGLContext* ctx, Frame* frame);
|
||||
|
||||
bool IsCreated() const;
|
||||
|
||||
@@ -59,6 +60,8 @@ public:
|
||||
|
||||
const GLuint& texture() const;
|
||||
|
||||
void Upload(FramePtr frame);
|
||||
void Upload(Frame* frame);
|
||||
void Upload(const void *data, int linesize);
|
||||
|
||||
public slots:
|
||||
|
||||
@@ -29,6 +29,16 @@ OpenGLTextureCache::~OpenGLTextureCache()
|
||||
}
|
||||
}
|
||||
|
||||
OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext *ctx, const VideoRenderingParams ¶ms, FramePtr frame)
|
||||
{
|
||||
return Get(ctx, params, frame.get());
|
||||
}
|
||||
|
||||
OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext *ctx, const VideoRenderingParams ¶ms, Frame *frame)
|
||||
{
|
||||
return Get(ctx, params, frame->data(), frame->linesize_pixels());
|
||||
}
|
||||
|
||||
OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext* ctx, const VideoRenderingParams ¶ms, const void *data, int linesize)
|
||||
{
|
||||
OpenGLTexturePtr texture = nullptr;
|
||||
|
||||
@@ -57,6 +57,8 @@ public:
|
||||
|
||||
DISABLE_COPY_MOVE(OpenGLTextureCache)
|
||||
|
||||
ReferencePtr Get(QOpenGLContext *ctx, const VideoRenderingParams& params, FramePtr frame);
|
||||
ReferencePtr Get(QOpenGLContext *ctx, const VideoRenderingParams& params, Frame* frame);
|
||||
ReferencePtr Get(QOpenGLContext *ctx, const VideoRenderingParams& params, const void *data, int linesize);
|
||||
ReferencePtr Get(QOpenGLContext *ctx, const VideoRenderingParams& params);
|
||||
|
||||
|
||||
@@ -200,6 +200,8 @@ void CurveWidget::ScaleChangedEvent(const double &scale)
|
||||
|
||||
void CurveWidget::TimeTargetChangedEvent(Node *target)
|
||||
{
|
||||
ConnectViewerNode(nullptr);
|
||||
|
||||
key_control_->SetTimeTarget(target);
|
||||
|
||||
view_->SetTimeTarget(target);
|
||||
@@ -207,6 +209,12 @@ void CurveWidget::TimeTargetChangedEvent(Node *target)
|
||||
if (bridge_) {
|
||||
bridge_->SetTimeTarget(target);
|
||||
}
|
||||
|
||||
// FIXME: If a non-viewer node is ever set here, it will fail to update the length
|
||||
ViewerOutput* viewer = dynamic_cast<ViewerOutput*>(target);
|
||||
if (viewer) {
|
||||
ConnectViewerNode(viewer);
|
||||
}
|
||||
}
|
||||
|
||||
void CurveWidget::UpdateInputLabel()
|
||||
|
||||
@@ -142,9 +142,13 @@ void ManagedDisplayWidget::MenuLookSelect(QAction *action)
|
||||
|
||||
void ManagedDisplayWidget::SetColorTransform(const ColorTransform &transform)
|
||||
{
|
||||
makeCurrent();
|
||||
|
||||
color_transform_ = transform;
|
||||
SetupColorProcessor();
|
||||
ColorProcessorChangedEvent();
|
||||
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
void ManagedDisplayWidget::initializeGL()
|
||||
@@ -248,9 +252,7 @@ void ManagedDisplayWidget::SetupColorProcessor()
|
||||
color_manager_->GetReferenceColorSpace(),
|
||||
color_transform_);
|
||||
|
||||
makeCurrent();
|
||||
color_service_->Enable(context(), true);
|
||||
doneCurrent();
|
||||
|
||||
} catch (OCIO::Exception& e) {
|
||||
|
||||
|
||||
@@ -156,7 +156,9 @@ void NodeParamView::SetNodes(QList<Node *> nodes)
|
||||
|
||||
items_.append(item);
|
||||
|
||||
QTimer::singleShot(1, item, &NodeParamViewItem::SignalAllKeyframes);
|
||||
QMetaObject::invokeMethod(item,
|
||||
"SignalAllKeyframes",
|
||||
Qt::QueuedConnection);
|
||||
|
||||
emit OpenedNode(node);
|
||||
}
|
||||
@@ -218,6 +220,11 @@ const QList<Node *> &NodeParamView::nodes()
|
||||
return nodes_;
|
||||
}
|
||||
|
||||
Node *NodeParamView::GetTimeTarget() const
|
||||
{
|
||||
return keyframe_view_->GetTimeTarget();
|
||||
}
|
||||
|
||||
void NodeParamView::UpdateItemTime(const int64_t ×tamp)
|
||||
{
|
||||
rational time = Timecode::timestamp_to_time(timestamp, keyframe_view_->timebase());
|
||||
|
||||
@@ -40,6 +40,8 @@ public:
|
||||
void SetNodes(QList<Node*> nodes);
|
||||
const QList<Node*>& nodes();
|
||||
|
||||
Node* GetTimeTarget() const;
|
||||
|
||||
signals:
|
||||
void InputDoubleClicked(NodeInput* input);
|
||||
|
||||
|
||||
@@ -49,7 +49,9 @@ void HistogramScope::SetBuffer(Frame* frame)
|
||||
{
|
||||
buffer_ = frame;
|
||||
|
||||
StartUpdate();
|
||||
if (isVisible()) {
|
||||
StartUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void HistogramScope::FinishedProcessing(QVector<double> red, QVector<double> green, QVector<double> blue)
|
||||
@@ -111,6 +113,13 @@ void HistogramScope::StartUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
void HistogramScope::showEvent(QShowEvent* e)
|
||||
{
|
||||
ManagedDisplayWidget::showEvent(e);
|
||||
|
||||
StartUpdate();
|
||||
}
|
||||
|
||||
HistogramScopeWorker::HistogramScopeWorker() :
|
||||
cancelled_(false)
|
||||
{
|
||||
|
||||
@@ -78,6 +78,8 @@ protected:
|
||||
|
||||
virtual void ColorProcessorChangedEvent() override;
|
||||
|
||||
virtual void showEvent(QShowEvent* e) override;
|
||||
|
||||
private:
|
||||
void StartUpdate();
|
||||
|
||||
|
||||
@@ -28,16 +28,32 @@ OLIVE_NAMESPACE_ENTER
|
||||
|
||||
WaveformScope::WaveformScope(QWidget* parent) :
|
||||
ManagedDisplayWidget(parent),
|
||||
texture_(nullptr)
|
||||
buffer_(nullptr)
|
||||
{
|
||||
EnableDefaultContextMenu();
|
||||
}
|
||||
|
||||
void WaveformScope::SetTexture(OpenGLTexture *texture)
|
||||
WaveformScope::~WaveformScope()
|
||||
{
|
||||
texture_ = texture;
|
||||
CleanUp();
|
||||
|
||||
update();
|
||||
if (context()) {
|
||||
disconnect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &WaveformScope::CleanUp);
|
||||
}
|
||||
}
|
||||
|
||||
void WaveformScope::SetBuffer(Frame *frame)
|
||||
{
|
||||
buffer_ = frame;
|
||||
|
||||
UploadTextureFromBuffer();
|
||||
}
|
||||
|
||||
void WaveformScope::showEvent(QShowEvent* e)
|
||||
{
|
||||
ManagedDisplayWidget::showEvent(e);
|
||||
|
||||
UploadTextureFromBuffer();
|
||||
}
|
||||
|
||||
void WaveformScope::initializeGL()
|
||||
@@ -49,37 +65,99 @@ void WaveformScope::initializeGL()
|
||||
pipeline_->addShaderFromSourceCode(QOpenGLShader::Vertex, OpenGLShader::CodeDefaultVertex());
|
||||
pipeline_->addShaderFromSourceCode(QOpenGLShader::Fragment, Node::ReadFileAsString(":/shaders/rgbwaveform.frag"));
|
||||
pipeline_->link();
|
||||
|
||||
framebuffer_.Create(context());
|
||||
|
||||
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &WaveformScope::CleanUp, Qt::DirectConnection);
|
||||
|
||||
UploadTextureFromBuffer();
|
||||
}
|
||||
|
||||
void WaveformScope::paintGL()
|
||||
{
|
||||
context()->functions()->glClearColor(0, 0, 0, 0);
|
||||
context()->functions()->glClear(GL_COLOR_BUFFER_BIT);
|
||||
QOpenGLFunctions* f = context()->functions();
|
||||
|
||||
if (!pipeline_ || !texture_) {
|
||||
f->glClearColor(0, 0, 0, 0);
|
||||
f->glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if (!pipeline_ || !texture_.IsCreated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
pipeline_->bind();
|
||||
pipeline_->setUniformValue("ove_resolution", texture_->width(), texture_->height());
|
||||
pipeline_->setUniformValue("ove_viewport", width(), height());
|
||||
{
|
||||
// Convert reference frame to display space
|
||||
framebuffer_.Attach(&managed_tex_);
|
||||
framebuffer_.Bind();
|
||||
|
||||
// The general size of a pixel
|
||||
pipeline_->setUniformValue("threshold", 2.0f / static_cast<float>(height()));
|
||||
texture_.Bind();
|
||||
|
||||
pipeline_->release();
|
||||
f->glViewport(0, 0, texture_.width(), texture_.height());
|
||||
|
||||
texture_->Bind();
|
||||
color_service()->ProcessOpenGL();
|
||||
|
||||
OpenGLRenderFunctions::Blit(pipeline_);
|
||||
texture_.Release();
|
||||
|
||||
texture_->Release();
|
||||
framebuffer_.Release();
|
||||
framebuffer_.Detach();
|
||||
}
|
||||
|
||||
{
|
||||
// Draw waveform through shader
|
||||
pipeline_->bind();
|
||||
pipeline_->setUniformValue("ove_resolution", texture_.width(), texture_.height());
|
||||
pipeline_->setUniformValue("ove_viewport", width(), height());
|
||||
|
||||
// The general size of a pixel
|
||||
pipeline_->setUniformValue("threshold", 2.0f / static_cast<float>(height()));
|
||||
|
||||
pipeline_->release();
|
||||
|
||||
f->glViewport(0, 0, width(), height());
|
||||
|
||||
managed_tex_.Bind();
|
||||
|
||||
OpenGLRenderFunctions::Blit(pipeline_);
|
||||
|
||||
managed_tex_.Release();
|
||||
}
|
||||
}
|
||||
|
||||
void WaveformScope::UploadTextureFromBuffer()
|
||||
{
|
||||
if (!buffer_ || !isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
makeCurrent();
|
||||
|
||||
if (!texture_.IsCreated()
|
||||
|| texture_.width() != buffer_->width()
|
||||
|| texture_.height() != buffer_->height()
|
||||
|| texture_.format() != buffer_->format()) {
|
||||
texture_.Destroy();
|
||||
managed_tex_.Destroy();
|
||||
|
||||
texture_.Create(context(), buffer_);
|
||||
managed_tex_.Create(context(), buffer_->width(), buffer_->height(), buffer_->format());
|
||||
} else {
|
||||
texture_.Upload(buffer_);
|
||||
}
|
||||
|
||||
doneCurrent();
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void WaveformScope::CleanUp()
|
||||
{
|
||||
makeCurrent();
|
||||
|
||||
pipeline_ = nullptr;
|
||||
texture_ = nullptr;
|
||||
texture_.Destroy();
|
||||
managed_tex_.Destroy();
|
||||
framebuffer_.Destroy();
|
||||
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "codec/frame.h"
|
||||
#include "render/backend/opengl/openglcolorprocessor.h"
|
||||
#include "render/backend/opengl/openglframebuffer.h"
|
||||
#include "render/backend/opengl/openglshader.h"
|
||||
#include "render/backend/opengl/opengltexture.h"
|
||||
#include "widget/manageddisplay/manageddisplay.h"
|
||||
@@ -35,18 +36,30 @@ class WaveformScope : public ManagedDisplayWidget
|
||||
public:
|
||||
WaveformScope(QWidget* parent = nullptr);
|
||||
|
||||
virtual ~WaveformScope() override;
|
||||
|
||||
public slots:
|
||||
void SetTexture(OpenGLTexture* texture);
|
||||
void SetBuffer(Frame* frame);
|
||||
|
||||
protected:
|
||||
virtual void initializeGL() override;
|
||||
|
||||
virtual void paintGL() override;
|
||||
|
||||
virtual void showEvent(QShowEvent* e) override;
|
||||
|
||||
private:
|
||||
void UploadTextureFromBuffer();
|
||||
|
||||
OpenGLShaderPtr pipeline_;
|
||||
|
||||
OpenGLTexture* texture_;
|
||||
OpenGLTexture texture_;
|
||||
|
||||
OpenGLTexture managed_tex_;
|
||||
|
||||
OpenGLFramebuffer framebuffer_;
|
||||
|
||||
Frame* buffer_;
|
||||
|
||||
private slots:
|
||||
void CleanUp();
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#include "manageddisplayobject.h"
|
||||
|
||||
ManagedDisplayObject::ManagedDisplayObject()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef MANAGEDDISPLAYOBJECT_H
|
||||
#define MANAGEDDISPLAYOBJECT_H
|
||||
|
||||
|
||||
class ManagedDisplayObject
|
||||
{
|
||||
public:
|
||||
ManagedDisplayObject();
|
||||
};
|
||||
|
||||
#endif // MANAGEDDISPLAYOBJECT_H
|
||||
@@ -66,8 +66,6 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
connect(main_widget, &ViewerDisplayWidget::customContextMenuRequested, this, &ViewerWidget::ShowContextMenu);
|
||||
connect(main_widget, &ViewerDisplayWidget::CursorColor, this, &ViewerWidget::CursorColor);
|
||||
connect(main_widget, &ViewerDisplayWidget::LoadedBuffer, this, &ViewerWidget::LoadedBuffer);
|
||||
connect(main_widget, &ViewerDisplayWidget::LoadedTexture, this, &ViewerWidget::LoadedTexture);
|
||||
connect(main_widget, &ViewerDisplayWidget::DrewManagedTexture, this, &ViewerWidget::DrewManagedTexture);
|
||||
connect(main_widget, &ViewerDisplayWidget::ColorProcessorChanged, this, &ViewerWidget::ColorProcessorChanged);
|
||||
connect(main_widget, &ViewerDisplayWidget::ColorManagerChanged, this, &ViewerWidget::ColorManagerChanged);
|
||||
connect(sizer_, &ViewerSizer::RequestMatrix, main_widget, &ViewerDisplayWidget::SetMatrix);
|
||||
@@ -745,11 +743,6 @@ void ViewerWidget::SetSignalCursorColorEnabled(bool e)
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::SetEmitDrewManagedTextureEnabled(bool e)
|
||||
{
|
||||
main_gl_widget()->SetEmitDrewManagedTextureEnabled(e);
|
||||
}
|
||||
|
||||
void ViewerWidget::TimebaseChangedEvent(const rational &timebase)
|
||||
{
|
||||
TimeBasedWidget::TimebaseChangedEvent(timebase);
|
||||
|
||||
@@ -107,11 +107,6 @@ public slots:
|
||||
*/
|
||||
void SetSignalCursorColorEnabled(bool e);
|
||||
|
||||
/**
|
||||
* @brief Wrapper for ViewerGLWidget::SetEmitDrewManagedTextureEnabled()
|
||||
*/
|
||||
void SetEmitDrewManagedTextureEnabled(bool e);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Wrapper for ViewerGLWidget::CursorColor()
|
||||
@@ -123,16 +118,6 @@ signals:
|
||||
*/
|
||||
void LoadedBuffer(Frame* load_buffer);
|
||||
|
||||
/**
|
||||
* @brief Wrapper for ViewerGLWidget::LoadedTexture()
|
||||
*/
|
||||
void LoadedTexture(OpenGLTexture* texture);
|
||||
|
||||
/**
|
||||
* @brief Wrapper for ViewerGLWidget::DrewManagedTexture()
|
||||
*/
|
||||
void DrewManagedTexture(OpenGLTexture* texture);
|
||||
|
||||
/**
|
||||
* @brief Request a scope panel
|
||||
*
|
||||
|
||||
@@ -42,10 +42,8 @@ bool ViewerDisplayWidget::nouveau_check_done_ = false;
|
||||
|
||||
ViewerDisplayWidget::ViewerDisplayWidget(QWidget *parent) :
|
||||
ManagedDisplayWidget(parent),
|
||||
managed_copy_pipeline_(nullptr),
|
||||
has_image_(false),
|
||||
signal_cursor_color_(false),
|
||||
enable_display_referred_signal_(false)
|
||||
signal_cursor_color_(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -91,14 +89,12 @@ void ViewerDisplayWidget::SetImage(const QString &fn)
|
||||
input->read_image(input->spec().format, load_buffer_.data(), OIIO::AutoStride, load_buffer_.linesize_bytes());
|
||||
input->close();
|
||||
|
||||
emit LoadedBuffer(&load_buffer_);
|
||||
|
||||
texture_.Upload(load_buffer_.data(), load_buffer_.linesize_pixels());
|
||||
|
||||
emit LoadedTexture(&texture_);
|
||||
texture_.Upload(&load_buffer_);
|
||||
|
||||
doneCurrent();
|
||||
|
||||
emit LoadedBuffer(&load_buffer_);
|
||||
|
||||
has_image_ = true;
|
||||
|
||||
#if OIIO_VERSION < 10903
|
||||
@@ -138,7 +134,7 @@ void ViewerDisplayWidget::SetImageFromLoadBuffer(Frame *in_buffer)
|
||||
|| texture_.format() != in_buffer->format()) {
|
||||
texture_.Create(context(), in_buffer->width(), in_buffer->height(), in_buffer->format(), in_buffer->data(), load_buffer_.linesize_pixels());
|
||||
} else {
|
||||
texture_.Upload(in_buffer->data(), load_buffer_.linesize_pixels());
|
||||
texture_.Upload(in_buffer);
|
||||
}
|
||||
|
||||
doneCurrent();
|
||||
@@ -147,18 +143,6 @@ void ViewerDisplayWidget::SetImageFromLoadBuffer(Frame *in_buffer)
|
||||
update();
|
||||
}
|
||||
|
||||
void ViewerDisplayWidget::SetEmitDrewManagedTextureEnabled(bool e)
|
||||
{
|
||||
enable_display_referred_signal_ = e;
|
||||
|
||||
if (!enable_display_referred_signal_) {
|
||||
// Destroy the texture now
|
||||
managed_texture_.Destroy();
|
||||
managed_copy_pipeline_ = nullptr;
|
||||
framebuffer_.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerDisplayWidget::ConnectSibling(ViewerDisplayWidget *sibling)
|
||||
{
|
||||
connect(this, &ViewerDisplayWidget::LoadedBuffer, sibling, &ViewerDisplayWidget::SetImageFromLoadBuffer, Qt::QueuedConnection);
|
||||
@@ -243,33 +227,6 @@ void ViewerDisplayWidget::paintGL()
|
||||
// We only draw if we have a pipeline
|
||||
if (has_image_ && color_service() && texture_.IsCreated()) {
|
||||
|
||||
// If we're distributing our display-referred final buffer, we'll have to make a copy of it
|
||||
if (enable_display_referred_signal_) {
|
||||
|
||||
if (!managed_texture_.IsCreated()
|
||||
|| managed_texture_.width() != texture_.width()
|
||||
|| managed_texture_.height() != texture_.height()
|
||||
|| managed_texture_.format() != texture_.format()) {
|
||||
managed_texture_.Destroy();
|
||||
|
||||
managed_texture_.Create(context(), texture_.width(), texture_.height(), texture_.format());
|
||||
}
|
||||
|
||||
if (!managed_copy_pipeline_) {
|
||||
managed_copy_pipeline_ = OpenGLShader::CreateDefault();
|
||||
}
|
||||
|
||||
if (!framebuffer_.IsCreated()) {
|
||||
framebuffer_.Create(context());
|
||||
}
|
||||
|
||||
framebuffer_.Attach(&managed_texture_);
|
||||
framebuffer_.Bind();
|
||||
|
||||
f->glViewport(0, 0, managed_texture_.width(), managed_texture_.height());
|
||||
|
||||
}
|
||||
|
||||
// Bind retrieved texture
|
||||
f->glBindTexture(GL_TEXTURE_2D, texture_.texture());
|
||||
|
||||
@@ -279,24 +236,6 @@ void ViewerDisplayWidget::paintGL()
|
||||
// Release retrieved texture
|
||||
f->glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
if (enable_display_referred_signal_) {
|
||||
|
||||
framebuffer_.Release();
|
||||
framebuffer_.Detach();
|
||||
|
||||
emit DrewManagedTexture(&managed_texture_);
|
||||
|
||||
// Bind retrieved texture
|
||||
managed_texture_.Bind();
|
||||
|
||||
f->glViewport(0, 0, width(), height());
|
||||
|
||||
OpenGLRenderFunctions::Blit(managed_copy_pipeline_);
|
||||
|
||||
// Bind retrieved texture
|
||||
managed_texture_.Release();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Draw action/title safe areas
|
||||
@@ -348,10 +287,7 @@ void ViewerDisplayWidget::ContextCleanup()
|
||||
{
|
||||
makeCurrent();
|
||||
|
||||
managed_copy_pipeline_ = nullptr;
|
||||
texture_.Destroy();
|
||||
managed_texture_.Destroy();
|
||||
framebuffer_.Destroy();
|
||||
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
@@ -101,15 +101,6 @@ public slots:
|
||||
*/
|
||||
void SetImageFromLoadBuffer(Frame* in_buffer);
|
||||
|
||||
/**
|
||||
* @brief Enables or disables DrewManagedTexture()
|
||||
*
|
||||
* To emit a display referred texture, it needs to be copied after the color transform is complete. This naturally
|
||||
* adds extra GPU cycles that are wasted if there's nothing receiving the signal. Therefore, the signal is disabled
|
||||
* by default.
|
||||
*/
|
||||
void SetEmitDrewManagedTextureEnabled(bool e);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when the user starts dragging from the viewer
|
||||
@@ -130,18 +121,6 @@ signals:
|
||||
*/
|
||||
void LoadedBuffer(Frame* load_buffer);
|
||||
|
||||
/**
|
||||
* @brief Signal emitted when a buffer is loaded into a texture
|
||||
*
|
||||
* This texture will be the direct output of the renderer in reference space in GPU VRAM.
|
||||
*/
|
||||
void LoadedTexture(OpenGLTexture* texture);
|
||||
|
||||
/**
|
||||
* @brief Emitted when the a texture has been transformed to display
|
||||
*/
|
||||
void DrewManagedTexture(OpenGLTexture* texture);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Override the mouse press event simply to emit the DragStarted() signal
|
||||
@@ -173,23 +152,6 @@ private:
|
||||
*/
|
||||
OpenGLTexture texture_;
|
||||
|
||||
/**
|
||||
* @brief Internal framebuffer used to draw to managed_texture_
|
||||
*/
|
||||
OpenGLFramebuffer framebuffer_;
|
||||
|
||||
/**
|
||||
* @brief Internal referenceto the OpenGL texture that's been managed
|
||||
*
|
||||
* Kept so that scopes can use the display-referred buffer without having to transform again.
|
||||
*/
|
||||
OpenGLTexture managed_texture_;
|
||||
|
||||
/**
|
||||
* @brief Pipeline used to draw to managed_texture_
|
||||
*/
|
||||
OpenGLShaderPtr managed_copy_pipeline_;
|
||||
|
||||
/**
|
||||
* @brief Drawing matrix (defaults to identity)
|
||||
*/
|
||||
@@ -210,8 +172,6 @@ private:
|
||||
|
||||
ViewerSafeMarginInfo safe_margin_;
|
||||
|
||||
bool enable_display_referred_signal_;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief Slot to connect just before the OpenGL context is destroyed to clean up resources
|
||||
|
||||
@@ -76,4 +76,11 @@ void MainStatusBar::UpdateStatus()
|
||||
}
|
||||
}
|
||||
|
||||
void MainStatusBar::mouseDoubleClickEvent(QMouseEvent* e)
|
||||
{
|
||||
QStatusBar::mouseDoubleClickEvent(e);
|
||||
|
||||
emit DoubleClicked();
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -33,11 +33,18 @@ OLIVE_NAMESPACE_ENTER
|
||||
*/
|
||||
class MainStatusBar : public QStatusBar
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainStatusBar(QWidget* parent = nullptr);
|
||||
|
||||
void ConnectTaskManager(TaskManager* manager);
|
||||
|
||||
signals:
|
||||
void DoubleClicked();
|
||||
|
||||
protected:
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent* e) override;
|
||||
|
||||
private slots:
|
||||
void UpdateStatus();
|
||||
|
||||
|
||||
@@ -33,18 +33,21 @@ OLIVE_NAMESPACE_ENTER
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
// Qt on Windows has a bug that "de-maximizes" the window when widgets are added, resizing the window beforehand
|
||||
// works around that issue and we just set it to whatever size is available
|
||||
// Resizes main window to desktop geometry on startup. Fixes the following issues:
|
||||
// * Qt on Windows has a bug that "de-maximizes" the window when widgets are added, resizing the
|
||||
// window beforehand works around that issue and we just set it to whatever size is available.
|
||||
// * On Linux, it seems the window starts off at a vastly different size and then maximizes
|
||||
// which throws off the proportions and makes the resulting layout wonky.
|
||||
resize(qApp->desktop()->availableGeometry(this).size());
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
// Set up taskbar button progress bar (used for some modal tasks like exporting)
|
||||
taskbar_btn_id_ = RegisterWindowMessage("TaskbarButtonCreated");
|
||||
taskbar_interface_ = nullptr;
|
||||
#endif
|
||||
|
||||
// Create empty central widget - we don't actually want a central widget but some of Qt's docking/undocking fails
|
||||
// without it
|
||||
// Create empty central widget - we don't actually want a central widget (so we set its maximum
|
||||
// size to 0,0) but some of Qt's docking/undocking fails without it
|
||||
QWidget* centralWidget = new QWidget(this);
|
||||
centralWidget->setMaximumSize(QSize(0, 0));
|
||||
setCentralWidget(centralWidget);
|
||||
@@ -62,6 +65,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
// Create and set status bar
|
||||
MainStatusBar* status_bar = new MainStatusBar(this);
|
||||
status_bar->ConnectTaskManager(TaskManager::instance());
|
||||
connect(status_bar, &MainStatusBar::DoubleClicked, this, &MainWindow::StatusBarDoubleClicked);
|
||||
setStatusBar(status_bar);
|
||||
|
||||
// Create standard panels
|
||||
@@ -389,6 +393,12 @@ bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *r
|
||||
}
|
||||
#endif
|
||||
|
||||
void MainWindow::StatusBarDoubleClicked()
|
||||
{
|
||||
task_man_panel_->show();
|
||||
task_man_panel_->raise();
|
||||
}
|
||||
|
||||
void MainWindow::UpdateTitle()
|
||||
{
|
||||
if (Core::instance()->GetActiveProject()) {
|
||||
|
||||
@@ -150,6 +150,8 @@ private slots:
|
||||
|
||||
void LoadLayoutInternal(QXmlStreamReader* reader, XMLNodeData *xml_data);
|
||||
|
||||
void StatusBarDoubleClicked();
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Reference in New Issue
Block a user