summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-04-19 23:08:25 +0200
committerCarl Hetherington <cth@carlh.net>2025-04-20 21:18:19 +0200
commitd618ea99fcf29a1d7384819eb92e865ea69fd3a2 (patch)
tree42e69d875c6791ae4f8fe7cf902bfa41bc458291
parent7c2677811b0b3da7b3eb6ed1918cf55068688f96 (diff)
Move thread logic from GLVideoView to GLView.
-rw-r--r--src/wx/gl_video_view.cc55
-rw-r--r--src/wx/gl_video_view.h12
-rw-r--r--src/wx/gl_view.cc47
-rw-r--r--src/wx/gl_view.h13
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;
};