Add some possibly-useful markers for debugging threads from coredumps.
[dcpomatic.git] / src / wx / gl_video_view.cc
index 0d79a75627973d9f44d03515ecbb490eb0d93969..ad0ff38a741027bf57fc5de81762742a7a54f0a9 100644 (file)
@@ -49,7 +49,7 @@
 #endif
 
 using std::cout;
-using boost::shared_ptr;
+using std::shared_ptr;
 using boost::optional;
 #if BOOST_VERSION >= 106100
 using namespace boost::placeholders;
@@ -68,6 +68,7 @@ check_gl_error (char const * last)
 
 GLVideoView::GLVideoView (FilmViewer* viewer, wxWindow *parent)
        : VideoView (viewer)
+       , _context (nullptr)
        , _have_storage (false)
        , _vsync_enabled (false)
        , _playing (false)
@@ -105,6 +106,8 @@ GLVideoView::check_for_butler_errors ()
                _viewer->butler()->rethrow ();
        } catch (DecodeError& e) {
                error_dialog (get(), e.what());
+       } catch (dcp::ReadError& e) {
+               error_dialog (get(), wxString::Format(_("Could not read DCP: %s"), std_to_wx(e.what())));
        }
 }
 
@@ -117,6 +120,11 @@ GLVideoView::update ()
                if (!_canvas->IsShownOnScreen()) {
                        return;
                }
+
+#ifdef DCPOMATIC_OSX
+               /* macOS gives errors if we don't do this (and therefore [NSOpenGLContext setView:]) from the main thread */
+               ensure_context ();
+#endif
        }
 
        if (!_thread.joinable()) {
@@ -126,6 +134,16 @@ GLVideoView::update ()
        request_one_shot ();
 }
 
+
+void
+GLVideoView::ensure_context ()
+{
+       if (!_context) {
+               _context = new wxGLContext (_canvas);
+               _canvas->SetCurrent (*_context);
+       }
+}
+
 void
 GLVideoView::draw (Position<int> inter_position, dcp::Size inter_size)
 {
@@ -145,7 +163,9 @@ GLVideoView::draw (Position<int> inter_position, dcp::Size inter_size)
        wxSize canvas_size;
        {
                boost::mutex::scoped_lock lm (_canvas_mutex);
-               canvas_size = _canvas->GetSize ();
+               if (_canvas) {
+                       canvas_size = _canvas->GetSize ();
+               }
        }
 
        if (canvas_size.GetWidth() < 64 || canvas_size.GetHeight() < 0) {
@@ -325,7 +345,7 @@ GLVideoView::set_image_and_draw ()
 {
        shared_ptr<PlayerVideo> pv = player_video().first;
        if (pv) {
-               set_image (pv->image(bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), VIDEO_RANGE_FULL, false, true));
+               set_image (pv->image(bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), VideoRange::FULL, false, true));
                draw (pv->inter_position(), pv->inter_size());
                _viewer->image_changed (pv);
        }
@@ -336,12 +356,25 @@ void
 GLVideoView::thread ()
 try
 {
+       start_of_thread ("GLVideoView");
+
        {
                boost::mutex::scoped_lock lm (_canvas_mutex);
-               _context = new wxGLContext (_canvas);
-               _canvas->SetCurrent (*_context);
-       }
 
+#if defined(DCPOMATIC_OSX)
+               /* Without this we see errors like
+                * ../src/osx/cocoa/glcanvas.mm(194): assert ""context"" failed in SwapBuffers(): should have current context [in thread 700006970000]
+                */
+               WXGLSetCurrentContext (_context->GetWXGLContext());
+#else
+               /* We must call this here on Linux otherwise we get no image (for reasons
+                * that aren't clear).  However, doing ensure_context() from this thread
+                * on macOS gives
+                * "[NSOpenGLContext setView:] must be called from the main thread".
+                */
+               ensure_context ();
+#endif
+       }
 
 #if defined(DCPOMATIC_LINUX) && defined(DCPOMATIC_HAVE_GLX_SWAP_INTERVAL_EXT)
        if (_canvas->IsExtensionSupported("GLX_EXT_swap_control")) {