X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=blobdiff_plain;f=src%2Fwx%2Fgl_video_view.cc;h=969264c2710d5656a22303c07c5b38f69660b23b;hp=a87249fafdd73d637bfc4649e36ea8137e32a0c3;hb=dd9be86db6cde0afa5da0d1d1ac43b42e05dca26;hpb=2da4caba7871455c097c0ed940dd6f2332dbda5d diff --git a/src/wx/gl_video_view.cc b/src/wx/gl_video_view.cc index a87249faf..969264c27 100644 --- a/src/wx/gl_video_view.cc +++ b/src/wx/gl_video_view.cc @@ -27,7 +27,7 @@ #include "lib/cross.h" #include "lib/player_video.h" #include "lib/butler.h" -#include +#include #include #ifdef DCPOMATIC_OSX @@ -40,7 +40,6 @@ #ifdef DCPOMATIC_LINUX #include #include -#include #endif #ifdef DCPOMATIC_WINDOWS @@ -50,8 +49,22 @@ #endif using std::cout; -using boost::shared_ptr; +using std::shared_ptr; using boost::optional; +#if BOOST_VERSION >= 106100 +using namespace boost::placeholders; +#endif + + +static void +check_gl_error (char const * last) +{ + GLenum const e = glGetError (); + if (e != GL_NO_ERROR) { + throw GLError (last, e); + } +} + GLVideoView::GLVideoView (FilmViewer* viewer, wxWindow *parent) : VideoView (viewer) @@ -63,53 +76,20 @@ GLVideoView::GLVideoView (FilmViewer* viewer, wxWindow *parent) _canvas = new wxGLCanvas (parent, wxID_ANY, 0, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE); _canvas->Bind (wxEVT_PAINT, boost::bind(&GLVideoView::update, this)); _canvas->Bind (wxEVT_SIZE, boost::bind(boost::ref(Sized))); - _canvas->Bind (wxEVT_CREATE, boost::bind(&GLVideoView::create, this)); _canvas->Bind (wxEVT_TIMER, boost::bind(&GLVideoView::check_for_butler_errors, this)); _timer.reset (new wxTimer(_canvas)); _timer->Start (2000); - -#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 - - glGenTextures (1, &_id); - glBindTexture (GL_TEXTURE_2D, _id); - glPixelStorei (GL_UNPACK_ALIGNMENT, 1); } GLVideoView::~GLVideoView () { + boost::this_thread::disable_interruption dis; + try { _thread.interrupt (); _thread.join (); - } catch (...) { - - } + } catch (...) {} glDeleteTextures (1, &_id); } @@ -128,14 +108,6 @@ GLVideoView::check_for_butler_errors () } } -static void -check_gl_error (char const * last) -{ - GLenum const e = glGetError (); - if (e != GL_NO_ERROR) { - throw GLError (last, e); - } -} void GLVideoView::update () @@ -146,6 +118,11 @@ GLVideoView::update () return; } } + + if (!_thread.joinable()) { + _thread = boost::thread (boost::bind(&GLVideoView::thread, this)); + } + request_one_shot (); } @@ -257,6 +234,7 @@ DCPOMATIC_ENABLE_WARNINGS } glFlush(); + check_gl_error ("glFlush"); boost::mutex::scoped_lock lm (_canvas_mutex); _canvas->SwapBuffers(); @@ -347,8 +325,9 @@ GLVideoView::set_image_and_draw () { shared_ptr pv = player_video().first; if (pv) { - set_image (pv->image(bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), false, true)); + set_image (pv->image(bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), VIDEO_RANGE_FULL, false, true)); draw (pv->inter_position(), pv->inter_size()); + _viewer->image_changed (pv); } } @@ -359,10 +338,46 @@ try { { boost::mutex::scoped_lock lm (_canvas_mutex); - _context = new wxGLContext (_canvas); //local + _context = new wxGLContext (_canvas); _canvas->SetCurrent (*_context); } + +#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 + + glGenTextures (1, &_id); + check_gl_error ("glGenTextures"); + glBindTexture (GL_TEXTURE_2D, _id); + check_gl_error ("glBindTexture"); + glPixelStorei (GL_UNPACK_ALIGNMENT, 1); + check_gl_error ("glPixelStorei"); + while (true) { boost::mutex::scoped_lock lm (_playing_mutex); while (!_playing && !_one_shot) { @@ -390,14 +405,16 @@ catch (boost::thread_interrupted& e) store_current (); } -bool + +VideoView::NextFrameResult GLVideoView::display_next_frame (bool non_blocking) { - bool const r = get_next_frame (non_blocking); + NextFrameResult const r = get_next_frame (non_blocking); request_one_shot (); return r; } + void GLVideoView::request_one_shot () { @@ -406,10 +423,3 @@ GLVideoView::request_one_shot () _thread_work_condition.notify_all (); } -void -GLVideoView::create () -{ - if (!_thread.joinable()) { - _thread = boost::thread (boost::bind(&GLVideoView::thread, this)); - } -}