Fix OpenGL crashes on macOS (#1899).
authorCarl Hetherington <cth@carlh.net>
Fri, 15 Jan 2021 23:55:29 +0000 (00:55 +0100)
committerCarl Hetherington <cth@carlh.net>
Sat, 16 Jan 2021 02:01:41 +0000 (03:01 +0100)
src/wx/gl_video_view.cc
src/wx/gl_video_view.h

index 969264c2710d5656a22303c07c5b38f69660b23b..5d40050de59fe9aaee717f8dda74df6482fc7724 100644 (file)
@@ -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)
@@ -117,6 +118,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 +132,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)
 {
@@ -338,10 +354,21 @@ try
 {
        {
                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")) {
index d8ee65da63e04d63fc572676d6ff7b9a2c8b24f8..1e6886f26cd4e91b032558f03d5acd3e486980c1 100644 (file)
@@ -61,6 +61,7 @@ private:
        void thread_playing ();
        void request_one_shot ();
        void check_for_butler_errors ();
+       void ensure_context ();
 
        /* Mutex for use of _canvas; it's only contended when our ::thread
           is started up so this may be overkill.