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:
parent
9f9ada8f8d
commit
582e947c75
5 changed files with 42 additions and 25 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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&) {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue