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
315 lines
7.2 KiB
C++
315 lines
7.2 KiB
C++
/***
|
|
|
|
Olive - Non-Linear Video Editor
|
|
Copyright (C) 2021 Olive Team
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
***/
|
|
|
|
#ifndef VIEWER_WIDGET_H
|
|
#define VIEWER_WIDGET_H
|
|
|
|
#include <QFile>
|
|
#include <QLabel>
|
|
#include <QPushButton>
|
|
#include <QScrollBar>
|
|
#include <QTimer>
|
|
#include <QWidget>
|
|
|
|
#include "audiowaveformview.h"
|
|
#include "common/rational.h"
|
|
#include "node/output/viewer/viewer.h"
|
|
#include "panel/scope/scope.h"
|
|
#include "render/previewautocacher.h"
|
|
#include "threading/threadticketwatcher.h"
|
|
#include "viewerdisplay.h"
|
|
#include "viewerplaybacktimer.h"
|
|
#include "viewerqueue.h"
|
|
#include "viewersizer.h"
|
|
#include "viewerwindow.h"
|
|
#include "widget/playbackcontrols/playbackcontrols.h"
|
|
#include "widget/timebased/timebasedwidget.h"
|
|
|
|
namespace olive {
|
|
|
|
/**
|
|
* @brief An OpenGL-based viewer widget with playback controls (a PlaybackControls widget).
|
|
*/
|
|
class ViewerWidget : public TimeBasedWidget
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
ViewerWidget(QWidget* parent = nullptr);
|
|
|
|
virtual ~ViewerWidget() override;
|
|
|
|
void SetPlaybackControlsEnabled(bool enabled);
|
|
|
|
void SetTimeRulerEnabled(bool enabled);
|
|
|
|
void TogglePlayPause();
|
|
|
|
bool IsPlaying() const;
|
|
|
|
/**
|
|
* @brief Enable or disable the color management menu
|
|
*
|
|
* While the Viewer is _always_ color managed, In some contexts, the color management may be controlled from an
|
|
* external UI making the menu unnecessary.
|
|
*/
|
|
void SetColorMenuEnabled(bool enabled);
|
|
|
|
void SetMatrix(const QMatrix4x4& mat);
|
|
|
|
/**
|
|
* @brief Creates a ViewerWindow widget and places it full screen on another screen
|
|
*
|
|
* If `screen` is nullptr, the screen will be automatically selected as whichever one contains the mouse cursor.
|
|
*/
|
|
void SetFullScreen(QScreen* screen = nullptr);
|
|
|
|
ColorManager* color_manager() const
|
|
{
|
|
return display_widget_->color_manager();
|
|
}
|
|
|
|
void SetGizmos(Node* node);
|
|
|
|
public slots:
|
|
void Play(bool in_to_out_only);
|
|
|
|
void Play();
|
|
|
|
void Pause();
|
|
|
|
void ShuttleLeft();
|
|
|
|
void ShuttleStop();
|
|
|
|
void ShuttleRight();
|
|
|
|
void SetColorTransform(const ColorTransform& transform);
|
|
|
|
/**
|
|
* @brief Wrapper for ViewerGLWidget::SetSignalCursorColorEnabled()
|
|
*/
|
|
void SetSignalCursorColorEnabled(bool e);
|
|
|
|
void SetAutoCacheEnabled(bool e);
|
|
|
|
void CacheEntireSequence();
|
|
|
|
void CacheSequenceInOut();
|
|
|
|
void SetViewerResolution(int width, int height);
|
|
|
|
void SetViewerPixelAspect(const rational& ratio);
|
|
|
|
void UpdateTextureFromNode();
|
|
|
|
signals:
|
|
/**
|
|
* @brief Wrapper for ViewerGLWidget::CursorColor()
|
|
*/
|
|
void CursorColor(const Color& reference, const Color& display);
|
|
|
|
/**
|
|
* @brief Signal emitted when a new frame is loaded
|
|
*/
|
|
void TextureChanged(TexturePtr t);
|
|
|
|
/**
|
|
* @brief Request a scope panel
|
|
*
|
|
* As a widget, we don't handle panels, but a parent panel may pick this signal up.
|
|
*/
|
|
void RequestScopePanel(ScopePanel::Type type);
|
|
|
|
/**
|
|
* @brief Wrapper for ViewerGLWidget::ColorProcessorChanged()
|
|
*/
|
|
void ColorProcessorChanged(ColorProcessorPtr processor);
|
|
|
|
/**
|
|
* @brief Wrapper for ViewerGLWidget::ColorManagerChanged()
|
|
*/
|
|
void ColorManagerChanged(ColorManager* color_manager);
|
|
|
|
protected:
|
|
virtual void TimebaseChangedEvent(const rational &) override;
|
|
virtual void TimeChangedEvent(const int64_t &) override;
|
|
|
|
virtual void ConnectNodeEvent(ViewerOutput *) override;
|
|
virtual void DisconnectNodeEvent(ViewerOutput *) override;
|
|
virtual void ConnectedNodeChangeEvent(ViewerOutput *) override;
|
|
|
|
virtual void ScaleChangedEvent(const double& s) override;
|
|
|
|
virtual void resizeEvent(QResizeEvent *event) override;
|
|
|
|
PlaybackControls* controls_;
|
|
|
|
ViewerDisplayWidget* display_widget() const
|
|
{
|
|
return display_widget_;
|
|
}
|
|
|
|
private:
|
|
void UpdateTimeInternal(int64_t i);
|
|
|
|
void PlayInternal(int speed, bool in_to_out_only);
|
|
|
|
void PauseInternal();
|
|
|
|
void PushScrubbedAudio();
|
|
|
|
void UpdateMinimumScale();
|
|
|
|
void SetColorTransform(const ColorTransform& transform, ViewerDisplayWidget* sender);
|
|
|
|
QString GetCachedFilenameFromTime(const rational& time);
|
|
|
|
bool FrameExistsAtTime(const rational& time);
|
|
|
|
bool ViewerMightBeAStill();
|
|
|
|
void SetDisplayImage(QVariant frame, bool main_only = false);
|
|
|
|
void RequestNextFrameForQueue(bool prioritize = false, bool increment = true);
|
|
|
|
RenderTicketPtr GetFrame(const rational& t, bool prioritize);
|
|
|
|
void FinishPlayPreprocess();
|
|
|
|
int DeterminePlaybackQueueSize();
|
|
|
|
void PopOldestFrameFromPlaybackQueue();
|
|
|
|
static FramePtr DecodeCachedImage(const QString &cache_path, const QByteArray &hash, const rational& time);
|
|
|
|
static void DecodeCachedImage(RenderTicketPtr ticket, const QString &cache_path, const QByteArray &hash, const rational& time);
|
|
|
|
bool ShouldForceWaveform() const;
|
|
|
|
void SetEmptyImage();
|
|
|
|
void UpdateAutoCacher();
|
|
|
|
void ClearAutoCacherQueue();
|
|
|
|
QStackedWidget* stack_;
|
|
|
|
ViewerSizer* sizer_;
|
|
|
|
QAtomicInt playback_speed_;
|
|
|
|
qint64 frame_cache_job_time_;
|
|
|
|
int64_t last_time_;
|
|
|
|
bool color_menu_enabled_;
|
|
|
|
bool time_changed_from_timer_;
|
|
|
|
bool play_in_to_out_only_;
|
|
|
|
AudioWaveformView* waveform_view_;
|
|
|
|
QHash<QScreen*, ViewerWindow*> windows_;
|
|
|
|
ViewerDisplayWidget* display_widget_;
|
|
|
|
ViewerDisplayWidget* context_menu_widget_;
|
|
|
|
ViewerPlaybackTimer playback_timer_;
|
|
QTimer playback_backup_timer_;
|
|
|
|
ViewerQueue playback_queue_;
|
|
int64_t playback_queue_next_frame_;
|
|
|
|
bool prequeuing_;
|
|
|
|
QList<RenderTicketWatcher*> nonqueue_watchers_;
|
|
|
|
rational last_length_;
|
|
|
|
int prequeue_length_;
|
|
|
|
PreviewAutoCacher auto_cacher_;
|
|
|
|
QTimer audio_restart_timer_;
|
|
|
|
int active_queue_jobs_;
|
|
|
|
rational cache_time_;
|
|
|
|
static QVector<ViewerWidget*> instances_;
|
|
|
|
private slots:
|
|
void PlaybackTimerUpdate();
|
|
|
|
void LengthChangedSlot(const rational& length);
|
|
|
|
void InterlacingChangedSlot(VideoParams::Interlacing interlacing);
|
|
|
|
void UpdateRendererVideoParameters();
|
|
|
|
void UpdateRendererAudioParameters();
|
|
|
|
void ShowContextMenu(const QPoint& pos);
|
|
|
|
void SetZoomFromMenu(QAction* action);
|
|
|
|
void ViewerShiftedRange(const olive::rational& from, const olive::rational& to);
|
|
|
|
void UpdateStack();
|
|
|
|
void ContextMenuSetFullScreen(QAction* action);
|
|
|
|
void ContextMenuDisableSafeMargins();
|
|
|
|
void ContextMenuSetSafeMargins();
|
|
|
|
void ContextMenuSetCustomSafeMargins();
|
|
|
|
void WindowAboutToClose();
|
|
|
|
void ContextMenuScopeTriggered(QAction* action);
|
|
|
|
void RendererGeneratedFrame();
|
|
|
|
void RendererGeneratedFrameForQueue();
|
|
|
|
void ViewerInvalidatedVideoRange(const olive::TimeRange &range);
|
|
|
|
void ManualSwitchToWaveform(bool e);
|
|
|
|
void TimeChangedFromWaveform(qint64 t);
|
|
|
|
void DragEntered(QDragEnterEvent* event);
|
|
|
|
void Dropped(QDropEvent* event);
|
|
|
|
void AudioCacheInvalidated();
|
|
void AudioCacheValidated();
|
|
|
|
void StartAudioOutput();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif // VIEWER_WIDGET_H
|