diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-04-19 23:08:25 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-04-20 21:18:19 +0200 |
| commit | d618ea99fcf29a1d7384819eb92e865ea69fd3a2 (patch) | |
| tree | 42e69d875c6791ae4f8fe7cf902bfa41bc458291 | |
| parent | 7c2677811b0b3da7b3eb6ed1918cf55068688f96 (diff) | |
Move thread logic from GLVideoView to GLView.
| -rw-r--r-- | src/wx/gl_video_view.cc | 55 | ||||
| -rw-r--r-- | src/wx/gl_video_view.h | 12 | ||||
| -rw-r--r-- | src/wx/gl_view.cc | 47 | ||||
| -rw-r--r-- | src/wx/gl_view.h | 13 |
4 files changed, 71 insertions, 56 deletions
diff --git a/src/wx/gl_video_view.cc b/src/wx/gl_video_view.cc index 5d5818901..dc3846e80 100644 --- a/src/wx/gl_video_view.cc +++ b/src/wx/gl_video_view.cc @@ -80,8 +80,6 @@ GLVideoView::GLVideoView(FilmViewer* viewer, wxWindow *parent) : VideoView(viewer) , GLView(parent) , _rec2020(false) - , _playing(false) - , _one_shot(false) { _canvas->Bind(wxEVT_PAINT, boost::bind(&GLVideoView::update, this)); _canvas->Bind(wxEVT_TIMER, boost::bind(&GLVideoView::check_for_butler_errors, this)); @@ -804,17 +802,13 @@ void GLVideoView::start() { VideoView::start(); - - boost::mutex::scoped_lock lm(_playing_mutex); - _playing = true; - _thread_work_condition.notify_all(); + GLView::start(); } void GLVideoView::stop() { - boost::mutex::scoped_lock lm(_playing_mutex); - _playing = false; + GLView::stop(); } @@ -834,7 +828,7 @@ GLVideoView::thread_playing() } while (true) { - optional<int> n = time_until_next_frame(); + auto n = time_until_next_frame(); if (!n || *n > 5) { break; } @@ -869,33 +863,6 @@ GLVideoView::thread_setup() } -void -GLVideoView::thread_body() -{ - while (true) { - boost::mutex::scoped_lock lm(_playing_mutex); - while (!_playing && !_one_shot) { - _thread_work_condition.wait(lm); - } - lm.unlock(); - - if (_playing) { - thread_playing(); - } else if (_one_shot) { - _one_shot = false; - draw(); - } - - boost::this_thread::interruption_point(); - dcpomatic_sleep_milliseconds(time_until_next_frame().get_value_or(0)); - } - - /* XXX: leaks _context, but that seems preferable to deleting it here - * without also deleting the wxGLCanvas. - */ -} - - VideoView::NextFrameResult GLVideoView::display_next_frame(bool non_blocking) { @@ -905,15 +872,6 @@ GLVideoView::display_next_frame(bool non_blocking) } -void -GLVideoView::request_one_shot() -{ - boost::mutex::scoped_lock lm(_playing_mutex); - _one_shot = true; - _thread_work_condition.notify_all(); -} - - Texture::Texture(GLint unpack_alignment, int unit) : _unpack_alignment(unpack_alignment) , _unit(unit) @@ -1005,5 +963,12 @@ GLVideoView::rethrow() } +optional<int> +GLVideoView::time_until_next_frame () const +{ + return VideoView::time_until_next_frame(); +} + + #endif diff --git a/src/wx/gl_video_view.h b/src/wx/gl_video_view.h index 9bf02a835..a3bbe716f 100644 --- a/src/wx/gl_video_view.h +++ b/src/wx/gl_video_view.h @@ -86,12 +86,11 @@ public: private: void size_changed(wxSizeEvent const &) override; void thread_setup() override; - void thread_body() override; + void thread_playing() override; + void draw() override; + boost::optional<int> time_until_next_frame () const override; void set_image(std::shared_ptr<const PlayerVideo> pv); - void draw(); - void thread_playing(); - void request_one_shot(); void check_for_butler_errors(); void ensure_context(); void setup_shaders(); @@ -131,11 +130,6 @@ private: std::unique_ptr<Texture> _subtitle_texture; bool _have_subtitle_to_render = false; - boost::mutex _playing_mutex; - boost::condition _thread_work_condition; - boost::atomic<bool> _playing; - boost::atomic<bool> _one_shot; - GLuint _vao; GLint _fragment_type; bool _setup_shaders_done = false; diff --git a/src/wx/gl_view.cc b/src/wx/gl_view.cc index 6b691fcd7..f97797c40 100644 --- a/src/wx/gl_view.cc +++ b/src/wx/gl_view.cc @@ -19,6 +19,7 @@ */ +#include "lib/cross.h" #include "lib/dcpomatic_log.h" #include "gl_view.h" #include <wx/wx.h> @@ -35,6 +36,8 @@ using namespace boost::placeholders; GLView::GLView(wxWindow* parent) : _context(nullptr) , _vsync_enabled(false) + , _playing(false) + , _one_shot(false) { wxGLAttributes attributes; /* We don't need a depth buffer, and indeed there is apparently a bug with Windows/Intel HD 630 @@ -114,7 +117,23 @@ try _vsync_enabled = true; #endif - thread_body(); + while (true) { + boost::mutex::scoped_lock lm(_playing_mutex); + while (!_playing && !_one_shot) { + _thread_work_condition.wait(lm); + } + lm.unlock(); + + if (_playing) { + thread_playing(); + } else if (_one_shot) { + _one_shot = false; + draw(); + } + + boost::this_thread::interruption_point(); + dcpomatic_sleep_milliseconds(time_until_next_frame().get_value_or(0)); + } } catch (boost::thread_interrupted&) { @@ -126,5 +145,31 @@ catch (...) } +void +GLView::start() +{ + boost::mutex::scoped_lock lm(_playing_mutex); + _playing = true; + _thread_work_condition.notify_all(); +} + + +void +GLView::stop() +{ + boost::mutex::scoped_lock lm(_playing_mutex); + _playing = false; +} + + +void +GLView::request_one_shot() +{ + boost::mutex::scoped_lock lm(_playing_mutex); + _one_shot = true; + _thread_work_condition.notify_all(); +} + + #endif diff --git a/src/wx/gl_view.h b/src/wx/gl_view.h index cdcf2af88..c5f056cb5 100644 --- a/src/wx/gl_view.h +++ b/src/wx/gl_view.h @@ -27,6 +27,7 @@ LIBDCP_DISABLE_WARNINGS LIBDCP_ENABLE_WARNINGS #include <boost/atomic.hpp> #include <boost/thread.hpp> +#include <boost/thread/condition.hpp> /* The OpenGL API in wxWidgets 3.0.x is sufficiently different to make it awkward to support, @@ -55,9 +56,14 @@ public: protected: virtual void size_changed(wxSizeEvent const& ev); virtual void thread_setup() = 0; - virtual void thread_body() = 0; + virtual void draw() = 0; + virtual void thread_playing() = 0; + virtual boost::optional<int> time_until_next_frame() const = 0; void start_thread_if_required(); + void start(); + void stop(); + void request_one_shot(); wxGLCanvas* _canvas; boost::atomic<wxSize> _canvas_size; @@ -68,6 +74,11 @@ private: boost::thread _thread; bool _vsync_enabled; + + boost::mutex _playing_mutex; + boost::condition _thread_work_condition; + boost::atomic<bool> _playing; + boost::atomic<bool> _one_shot; }; |
