summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-04-19 22:29:04 +0200
committerCarl Hetherington <cth@carlh.net>2025-04-20 21:18:19 +0200
commitbcf2eed456ace5abfd28f97d36eb0ef86ec8aaf3 (patch)
tree9e8dcf2fd6270d61e24be98e021722c2f305bddd
parent7274fa9a628508c451713b724c54dbef9f1d199d (diff)
Move GLVideoView thread into GLView.
-rw-r--r--src/wx/film_viewer.cc10
-rw-r--r--src/wx/film_viewer.h2
-rw-r--r--src/wx/gl_video_view.cc68
-rw-r--r--src/wx/gl_video_view.h11
-rw-r--r--src/wx/gl_view.cc67
-rw-r--r--src/wx/gl_view.h20
-rw-r--r--src/wx/video_view.h3
7 files changed, 118 insertions, 63 deletions
diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc
index 5e1caa1bf..1cbdb00bd 100644
--- a/src/wx/film_viewer.cc
+++ b/src/wx/film_viewer.cc
@@ -435,7 +435,7 @@ FilmViewer::stop()
_video_view->stop();
Stopped();
- _video_view->rethrow();
+ rethrow();
return true;
}
@@ -929,3 +929,11 @@ FilmViewer::dcp() const
return {};
}
+
+
+void
+FilmViewer::rethrow()
+{
+ _video_view->rethrow();
+}
+
diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h
index 31fdbe0c7..8325930a0 100644
--- a/src/wx/film_viewer.h
+++ b/src/wx/film_viewer.h
@@ -157,6 +157,8 @@ public:
Frame average_latency() const;
+ void rethrow();
+
/** The image we are viewing changed: call last_image() to get the image */
boost::signals2::signal<void ()> ImageChanged;
std::shared_ptr<const PlayerVideo> last_image() const;
diff --git a/src/wx/gl_video_view.cc b/src/wx/gl_video_view.cc
index f515b4f53..d2a1d8c36 100644
--- a/src/wx/gl_video_view.cc
+++ b/src/wx/gl_video_view.cc
@@ -80,7 +80,6 @@ GLVideoView::GLVideoView(FilmViewer* viewer, wxWindow *parent)
: VideoView(viewer)
, GLView(parent)
, _rec2020(false)
- , _vsync_enabled(false)
, _playing(false)
, _one_shot(false)
{
@@ -99,16 +98,6 @@ GLVideoView::size_changed(wxSizeEvent const& ev)
}
-GLVideoView::~GLVideoView()
-{
- boost::this_thread::disable_interruption dis;
-
- try {
- _thread.interrupt();
- _thread.join();
- } catch (...) {}
-}
-
void
GLVideoView::check_for_butler_errors()
{
@@ -150,9 +139,7 @@ GLVideoView::update()
}
#endif
- if (!_thread.joinable()) {
- _thread = boost::thread(boost::bind(&GLVideoView::thread, this));
- }
+ start_thread_if_required();
request_one_shot();
@@ -865,8 +852,7 @@ GLVideoView::set_image_and_draw()
void
-GLVideoView::thread()
-try
+GLVideoView::thread_setup()
{
start_of_thread("GLVideoView");
@@ -882,40 +868,17 @@ try
}
#endif
-#if defined(DCPOMATIC_LINUX) && defined(DCPOMATIC_HAVE_GLX_SWAP_INTERVAL_EXT)
- if (_canvas->IsExtensionSupported("GLX_EXT_swap_control")) {
- /* Enable vsync */
- Display* dpy = wxGetX11Display();
- glXSwapIntervalEXT(dpy, DefaultScreen(dpy), 1);
- _vsync_enabled = true;
- }
-#endif
-
-#ifdef DCPOMATIC_WINDOWS
- if (_canvas->IsExtensionSupported("WGL_EXT_swap_control")) {
- /* Enable vsync */
- PFNWGLSWAPINTERVALEXTPROC swap = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT");
- if (swap) {
- swap(1);
- _vsync_enabled = true;
- }
- }
-
-#endif
-
-#ifdef DCPOMATIC_OSX
- /* Enable vsync */
- GLint swapInterval = 1;
- CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &swapInterval);
- _vsync_enabled = true;
-#endif
-
for (int i = 0; i < 3; ++i) {
std::unique_ptr<Texture> texture(new Texture(_optimisation == Optimisation::JPEG2000 ? 2 : 1, i));
_video_textures.push_back(std::move(texture));
}
_subtitle_texture.reset(new Texture(1, 3));
+}
+
+void
+GLVideoView::thread_body()
+{
while (true) {
boost::mutex::scoped_lock lm(_playing_mutex);
while (!_playing && !_one_shot) {
@@ -938,14 +901,6 @@ try
* without also deleting the wxGLCanvas.
*/
}
-catch (boost::thread_interrupted&)
-{
-
-}
-catch (...)
-{
- store_current();
-}
VideoView::NextFrameResult
@@ -1049,4 +1004,13 @@ Texture::set(shared_ptr<const Image> image, int component)
}
}
+
+void
+GLVideoView::rethrow()
+{
+ GLView::rethrow();
+}
+
+
#endif
+
diff --git a/src/wx/gl_video_view.h b/src/wx/gl_video_view.h
index 87a074d23..8d3509df3 100644
--- a/src/wx/gl_video_view.h
+++ b/src/wx/gl_video_view.h
@@ -68,7 +68,6 @@ class GLVideoView : public VideoView, public GLView
{
public:
GLVideoView(FilmViewer* viewer, wxWindow* parent);
- ~GLVideoView();
wxWindow* get() const override {
return _canvas;
@@ -76,24 +75,22 @@ public:
void update() override;
void start() override;
void stop() override;
+ void rethrow() override;
NextFrameResult display_next_frame(bool) override;
- bool vsync_enabled() const {
- return _vsync_enabled;
- }
-
std::map<GLenum, std::string> information() const {
return _information;
}
private:
void size_changed(wxSizeEvent const &) override;
+ void thread_setup() override;
+ void thread_body() override;
void set_image(std::shared_ptr<const PlayerVideo> pv);
void set_image_and_draw();
void draw();
- void thread();
void thread_playing();
void request_one_shot();
void check_for_butler_errors();
@@ -134,8 +131,6 @@ private:
std::vector<std::unique_ptr<Texture>> _video_textures;
std::unique_ptr<Texture> _subtitle_texture;
bool _have_subtitle_to_render = false;
- bool _vsync_enabled;
- boost::thread _thread;
boost::mutex _playing_mutex;
boost::condition _thread_work_condition;
diff --git a/src/wx/gl_view.cc b/src/wx/gl_view.cc
index 567057e96..6b691fcd7 100644
--- a/src/wx/gl_view.cc
+++ b/src/wx/gl_view.cc
@@ -34,6 +34,7 @@ using namespace boost::placeholders;
GLView::GLView(wxWindow* parent)
: _context(nullptr)
+ , _vsync_enabled(false)
{
wxGLAttributes attributes;
/* We don't need a depth buffer, and indeed there is apparently a bug with Windows/Intel HD 630
@@ -48,6 +49,17 @@ GLView::GLView(wxWindow* parent)
}
+GLView::~GLView()
+{
+ boost::this_thread::disable_interruption dis;
+
+ try {
+ _thread.interrupt();
+ _thread.join();
+ } catch (...) {}
+}
+
+
void
GLView::size_changed(wxSizeEvent const& ev)
{
@@ -59,5 +71,60 @@ GLView::size_changed(wxSizeEvent const& ev)
}
+void
+GLView::start_thread_if_required()
+{
+ if (!_thread.joinable()) {
+ _thread = boost::thread(boost::bind(&GLView::thread, this));
+ }
+}
+
+
+void
+GLView::thread()
+try
+{
+ thread_setup();
+
+#if defined(DCPOMATIC_LINUX) && defined(DCPOMATIC_HAVE_GLX_SWAP_INTERVAL_EXT)
+ if (_canvas->IsExtensionSupported("GLX_EXT_swap_control")) {
+ /* Enable vsync */
+ Display* dpy = wxGetX11Display();
+ glXSwapIntervalEXT(dpy, DefaultScreen(dpy), 1);
+ _vsync_enabled = true;
+ }
+#endif
+
+#ifdef DCPOMATIC_WINDOWS
+ if (_canvas->IsExtensionSupported("WGL_EXT_swap_control")) {
+ /* Enable vsync */
+ PFNWGLSWAPINTERVALEXTPROC swap = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT");
+ if (swap) {
+ swap(1);
+ _vsync_enabled = true;
+ }
+ }
+
+#endif
+
+#ifdef DCPOMATIC_OSX
+ /* Enable vsync */
+ GLint swapInterval = 1;
+ CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &swapInterval);
+ _vsync_enabled = true;
+#endif
+
+ thread_body();
+}
+catch (boost::thread_interrupted&)
+{
+
+}
+catch (...)
+{
+ store_current();
+}
+
+
#endif
diff --git a/src/wx/gl_view.h b/src/wx/gl_view.h
index e7a30021d..cdcf2af88 100644
--- a/src/wx/gl_view.h
+++ b/src/wx/gl_view.h
@@ -18,12 +18,15 @@
*/
+
+#include "lib/exception_store.h"
#include <dcp/warnings.h>
LIBDCP_DISABLE_WARNINGS
#include <wx/glcanvas.h>
#include <wx/wx.h>
LIBDCP_ENABLE_WARNINGS
#include <boost/atomic.hpp>
+#include <boost/thread.hpp>
/* The OpenGL API in wxWidgets 3.0.x is sufficiently different to make it awkward to support,
@@ -35,21 +38,36 @@ LIBDCP_ENABLE_WARNINGS
#if wxCHECK_VERSION(3,1,0)
-class GLView
+class GLView : public ExceptionStore
{
public:
GLView(wxWindow* parent);
+ virtual ~GLView();
wxWindow* canvas() const {
return _canvas;
}
+ bool vsync_enabled() const {
+ return _vsync_enabled;
+ }
+
protected:
virtual void size_changed(wxSizeEvent const& ev);
+ virtual void thread_setup() = 0;
+ virtual void thread_body() = 0;
+
+ void start_thread_if_required();
wxGLCanvas* _canvas;
boost::atomic<wxSize> _canvas_size;
wxGLContext* _context;
+
+private:
+ void thread();
+
+ boost::thread _thread;
+ bool _vsync_enabled;
};
diff --git a/src/wx/video_view.h b/src/wx/video_view.h
index 3ea03a5fd..707f43f7d 100644
--- a/src/wx/video_view.h
+++ b/src/wx/video_view.h
@@ -45,7 +45,7 @@ class PlayerVideo;
class wxWindow;
-class VideoView : public ExceptionStore, public Signaller
+class VideoView : public Signaller
{
public:
VideoView (FilmViewer* viewer);
@@ -62,6 +62,7 @@ public:
virtual void start ();
/** Called when playback stops */
virtual void stop () {}
+ virtual void rethrow() {}
enum NextFrameResult {
FAIL,