Fix errors when reattaching video with some video cards

With ATI cards, deleting a wxGLContext seems to invalidate ALL
wxGlContexts, rather than just things associated with the deleted one.
This resulted in video breaking after closing the detached video dialog,
as the embedded video display was trying to use an invalidated context.
To work around this, delete and recreate the context when reattaching
video.

Also recreate the visual typesetting tool as OpenGLText holds references
to textures created on construction.

Originally committed to SVN as r6646.
This commit is contained in:
Thomas Goyne 2012-04-03 17:38:38 +00:00
parent 9f9ada8f8d
commit 582e947c75
5 changed files with 42 additions and 25 deletions

View file

@ -100,11 +100,18 @@ DialogDetachedVideo::DialogDetachedVideo(agi::Context *context)
DialogDetachedVideo::~DialogDetachedVideo() { } DialogDetachedVideo::~DialogDetachedVideo() { }
void DialogDetachedVideo::OnClose(wxCloseEvent &evt) { void DialogDetachedVideo::OnClose(wxCloseEvent &evt) {
evt.Skip(); // Deleting a GL context seems to invalidate ALL contexts, so we need to
// delete both the detached and undetached contexts here, then recreate
// the undetached one later
context->videoDisplay->Destroy();
old_display->Reload();
context->videoDisplay = old_display; context->videoDisplay = old_display;
context->videoSlider = old_slider; context->videoSlider = old_slider;
OPT_SET("Video/Detached/Enabled")->SetBool(false); OPT_SET("Video/Detached/Enabled")->SetBool(false);
context->videoController->Reload();
evt.Skip();
} }
void DialogDetachedVideo::OnMinimize(wxIconizeEvent &event) { void DialogDetachedVideo::OnMinimize(wxIconizeEvent &event) {

View file

@ -439,6 +439,7 @@ void FrameMain::OnVideoOpen() {
try { try {
context->audioController->OpenAudio(context->videoController->GetVideoName()); context->audioController->OpenAudio(context->videoController->GetVideoName());
} }
catch (agi::UserCancelException const&) { }
// Opening a video with no audio data isn't an error, so just log // Opening a video with no audio data isn't an error, so just log
// and move on // and move on
catch (agi::FileNotAccessibleError const&) { catch (agi::FileNotAccessibleError const&) {

View file

@ -202,12 +202,9 @@ void VideoContext::SetVideo(const wxString &filename) {
config::mru->Add("Video", STD_STR(filename)); config::mru->Add("Video", STD_STR(filename));
StandardPaths::SetPathValue("?video", wxFileName(filename).GetPath()); StandardPaths::SetPathValue("?video", wxFileName(filename).GetPath());
// Get frame
frame_n = 0;
// Show warning // Show warning
wxString warning = videoProvider->GetWarning(); wxString warning = videoProvider->GetWarning();
if (!warning.empty()) wxMessageBox(warning,"Warning",wxICON_WARNING | wxOK); if (!warning.empty()) wxMessageBox(warning, "Warning", wxICON_WARNING | wxOK);
hasSubtitles = false; hasSubtitles = false;
if (filename.Right(4).Lower() == ".mkv") { if (filename.Right(4).Lower() == ".mkv") {
@ -230,6 +227,8 @@ void VideoContext::SetVideo(const wxString &filename) {
if (commit_subs) if (commit_subs)
context->ass->Commit(_("change script resolution"), AssFile::COMMIT_SCRIPTINFO); context->ass->Commit(_("change script resolution"), AssFile::COMMIT_SCRIPTINFO);
else
JumpToFrame(0);
} }
void VideoContext::Reload() { void VideoContext::Reload() {

View file

@ -114,7 +114,7 @@ VideoDisplay::VideoDisplay(
zoomBox->Bind(wxEVT_COMMAND_TEXT_ENTER, &VideoDisplay::SetZoomFromBoxText, this); zoomBox->Bind(wxEVT_COMMAND_TEXT_ENTER, &VideoDisplay::SetZoomFromBoxText, this);
con->videoController->Bind(EVT_FRAME_READY, &VideoDisplay::UploadFrameData, this); con->videoController->Bind(EVT_FRAME_READY, &VideoDisplay::UploadFrameData, this);
slots.push_back(con->videoController->AddVideoOpenListener(&VideoDisplay::OnVideoOpen, this)); slots.push_back(con->videoController->AddVideoOpenListener(&VideoDisplay::UpdateSize, this, false));
slots.push_back(con->videoController->AddARChangeListener(&VideoDisplay::UpdateSize, this, true)); slots.push_back(con->videoController->AddARChangeListener(&VideoDisplay::UpdateSize, this, true));
Bind(wxEVT_PAINT, std::tr1::bind(&VideoDisplay::Render, this)); Bind(wxEVT_PAINT, std::tr1::bind(&VideoDisplay::Render, this));
@ -133,8 +133,9 @@ VideoDisplay::VideoDisplay(
c->videoDisplay = this; c->videoDisplay = this;
UpdateSize();
if (con->videoController->IsLoaded()) if (con->videoController->IsLoaded())
OnVideoOpen(); con->videoController->JumpToFrame(con->videoController->GetFrameN());
} }
VideoDisplay::~VideoDisplay () { VideoDisplay::~VideoDisplay () {
@ -158,11 +159,17 @@ bool VideoDisplay::InitContext() {
} }
void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) { void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) {
if (!InitContext()) return; if (!InitContext()) {
evt.Skip();
return;
}
if (!videoOut) if (!videoOut)
videoOut.reset(new VideoOutGL); videoOut.reset(new VideoOutGL);
if (!tool)
cmd::call("video/tool/cross", con);
try { try {
videoOut->UploadFrameData(*evt.frame); videoOut->UploadFrameData(*evt.frame);
} }
@ -183,14 +190,6 @@ void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) {
Render(); Render();
} }
void VideoDisplay::OnVideoOpen() {
if (!con->videoController->IsLoaded()) return;
if (!tool)
cmd::call("video/tool/cross", con);
UpdateSize();
con->videoController->JumpToFrame(0);
}
void VideoDisplay::Render() try { void VideoDisplay::Render() try {
if (!con->videoController->IsLoaded() || !videoOut || !InitContext() ) if (!con->videoController->IsLoaded() || !videoOut || !InitContext() )
return; return;
@ -221,7 +220,7 @@ void VideoDisplay::Render() try {
} }
} }
if (mouse_pos || alwaysShowTools->GetBool()) if ((mouse_pos || alwaysShowTools->GetBool()) && tool)
tool->Draw(); tool->Draw();
SwapBuffers(); SwapBuffers();
@ -273,8 +272,7 @@ void VideoDisplay::DrawOverscanMask(float horizontal_percent, float vertical_per
} }
void VideoDisplay::UpdateSize(bool force) { void VideoDisplay::UpdateSize(bool force) {
if (!con->videoController->IsLoaded()) return; if (!con->videoController->IsLoaded() || !IsShownOnScreen()) return;
if (!IsShownOnScreen()) return;
int vidW = con->videoController->GetWidth(); int vidW = con->videoController->GetWidth();
int vidH = con->videoController->GetHeight(); int vidH = con->videoController->GetHeight();
@ -359,7 +357,7 @@ void VideoDisplay::UpdateSize(bool force) {
} }
} }
if (tool.get()) if (tool)
tool->SetDisplayArea(viewport_left, viewport_top, viewport_width, viewport_height); tool->SetDisplayArea(viewport_left, viewport_top, viewport_width, viewport_height);
Refresh(false); Refresh(false);
@ -378,12 +376,14 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
mouse_pos = event.GetPosition(); mouse_pos = event.GetPosition();
tool->OnMouseEvent(event); if (tool)
tool->OnMouseEvent(event);
} }
void VideoDisplay::OnMouseLeave(wxMouseEvent& event) { void VideoDisplay::OnMouseLeave(wxMouseEvent& event) {
mouse_pos = Vector2D(); mouse_pos = Vector2D();
tool->OnMouseEvent(event); if (tool)
tool->OnMouseEvent(event);
} }
void VideoDisplay::OnMouseWheel(wxMouseEvent& event) { void VideoDisplay::OnMouseWheel(wxMouseEvent& event) {
@ -449,3 +449,12 @@ bool VideoDisplay::ToolIsType(std::type_info const& type) const {
Vector2D VideoDisplay::GetMousePosition() const { Vector2D VideoDisplay::GetMousePosition() const {
return mouse_pos ? tool->ToScriptCoords(mouse_pos) : mouse_pos; return mouse_pos ? tool->ToScriptCoords(mouse_pos) : mouse_pos;
} }
void VideoDisplay::Reload() {
glContext.reset();
videoOut.reset();
tool.reset();
if (con->videoController->IsLoaded())
con->videoController->JumpToFrame(con->videoController->GetFrameN());
}

View file

@ -127,8 +127,6 @@ class VideoDisplay : public wxGLCanvas {
/// @return Could the context be set? /// @return Could the context be set?
bool InitContext(); bool InitContext();
void OnVideoOpen();
/// @brief Set the size of the display based on the current zoom and video resolution /// @brief Set the size of the display based on the current zoom and video resolution
/// @param force Force the size to be set based on zoom even in detached mode /// @param force Force the size to be set based on zoom even in detached mode
void UpdateSize(bool force = false); void UpdateSize(bool force = false);
@ -172,4 +170,7 @@ public:
void SetTool(VisualToolBase *new_tool); void SetTool(VisualToolBase *new_tool);
bool ToolIsType(std::type_info const& type) const; bool ToolIsType(std::type_info const& type) const;
/// Discard all OpenGL state
void Reload();
}; };