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() { }
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->videoSlider = old_slider;
OPT_SET("Video/Detached/Enabled")->SetBool(false);
context->videoController->Reload();
evt.Skip();
}
void DialogDetachedVideo::OnMinimize(wxIconizeEvent &event) {

View File

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

View File

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

View File

@ -114,7 +114,7 @@ VideoDisplay::VideoDisplay(
zoomBox->Bind(wxEVT_COMMAND_TEXT_ENTER, &VideoDisplay::SetZoomFromBoxText, 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));
Bind(wxEVT_PAINT, std::tr1::bind(&VideoDisplay::Render, this));
@ -133,8 +133,9 @@ VideoDisplay::VideoDisplay(
c->videoDisplay = this;
UpdateSize();
if (con->videoController->IsLoaded())
OnVideoOpen();
con->videoController->JumpToFrame(con->videoController->GetFrameN());
}
VideoDisplay::~VideoDisplay () {
@ -158,11 +159,17 @@ bool VideoDisplay::InitContext() {
}
void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) {
if (!InitContext()) return;
if (!InitContext()) {
evt.Skip();
return;
}
if (!videoOut)
videoOut.reset(new VideoOutGL);
if (!tool)
cmd::call("video/tool/cross", con);
try {
videoOut->UploadFrameData(*evt.frame);
}
@ -183,14 +190,6 @@ void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) {
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 {
if (!con->videoController->IsLoaded() || !videoOut || !InitContext() )
return;
@ -221,7 +220,7 @@ void VideoDisplay::Render() try {
}
}
if (mouse_pos || alwaysShowTools->GetBool())
if ((mouse_pos || alwaysShowTools->GetBool()) && tool)
tool->Draw();
SwapBuffers();
@ -273,8 +272,7 @@ void VideoDisplay::DrawOverscanMask(float horizontal_percent, float vertical_per
}
void VideoDisplay::UpdateSize(bool force) {
if (!con->videoController->IsLoaded()) return;
if (!IsShownOnScreen()) return;
if (!con->videoController->IsLoaded() || !IsShownOnScreen()) return;
int vidW = con->videoController->GetWidth();
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);
Refresh(false);
@ -378,12 +376,14 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
mouse_pos = event.GetPosition();
tool->OnMouseEvent(event);
if (tool)
tool->OnMouseEvent(event);
}
void VideoDisplay::OnMouseLeave(wxMouseEvent& event) {
mouse_pos = Vector2D();
tool->OnMouseEvent(event);
if (tool)
tool->OnMouseEvent(event);
}
void VideoDisplay::OnMouseWheel(wxMouseEvent& event) {
@ -449,3 +449,12 @@ bool VideoDisplay::ToolIsType(std::type_info const& type) const {
Vector2D VideoDisplay::GetMousePosition() const {
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?
bool InitContext();
void OnVideoOpen();
/// @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
void UpdateSize(bool force = false);
@ -172,4 +170,7 @@ public:
void SetTool(VisualToolBase *new_tool);
bool ToolIsType(std::type_info const& type) const;
/// Discard all OpenGL state
void Reload();
};