Make gl contexts specific to VideoDisplays and only create/use them when the display is shown. Fixes a pile of X11-related assertion failures.

Originally committed to SVN as r4686.
This commit is contained in:
Thomas Goyne 2010-07-18 05:45:52 +00:00
parent f1ea264efc
commit 63cda2d755
4 changed files with 22 additions and 31 deletions

View file

@ -86,9 +86,7 @@ END_EVENT_TABLE()
/// @brief Constructor
///
VideoContext::VideoContext()
: ownGlContext(false)
, glContext(NULL)
, startFrame(-1)
: startFrame(-1)
, endFrame(-1)
, playNextFrame(-1)
, nextFrame(-1)
@ -113,8 +111,6 @@ VideoContext::~VideoContext () {
delete audio->player;
}
tempFrame.Clear();
if (ownGlContext)
delete glContext;
}
VideoContext *VideoContext::Get() {
@ -143,8 +139,6 @@ void VideoContext::Reset() {
isPlaying = false;
nextFrame = -1;
UpdateDisplays(true);
// Clean up video data
videoName.clear();
tempFrame.Clear();
@ -162,9 +156,6 @@ void VideoContext::SetVideo(const wxString &filename) {
try {
grid->CommitChanges(true);
// Set GL context
GetGLContext(displayList.front())->SetCurrent(*displayList.front());
// Choose a provider
provider.reset(VideoProviderFactoryManager::GetProvider(filename));
@ -286,14 +277,6 @@ void VideoContext::JumpToTime(int ms, agi::vfr::Time end) {
JumpToFrame(FrameAtTime(ms, end));
}
wxGLContext *VideoContext::GetGLContext(wxGLCanvas *canvas) {
if (!glContext) {
glContext = new wxGLContext(canvas);
ownGlContext = true;
}
return glContext;
}
AegiVideoFrame VideoContext::GetFrame(int n,bool raw) {
// Current frame if -1
if (n == -1) n = frame_n;

View file

@ -86,12 +86,6 @@ private:
/// DOCME
std::list<VideoDisplay*> displayList;
/// DOCME
bool ownGlContext;
/// DOCME
wxGLContext *glContext;
/// DOCME
AegiVideoFrame tempFrame;
@ -185,8 +179,6 @@ public:
/// @param raw Should the frame have subtitles?
void SaveSnapshot(bool raw);
wxGLContext *GetGLContext(wxGLCanvas *canvas);
/// @brief Is there a video loaded?
bool IsLoaded() const { return !!provider.get(); }

View file

@ -148,6 +148,15 @@ VideoDisplay::~VideoDisplay () {
VideoContext::Get()->RemoveDisplay(this);
}
bool VideoDisplay::InitContext() {
if (!IsShownOnScreen()) return false;
if (!glContext.get()) {
glContext.reset(new wxGLContext(this));
}
SetCurrent(*glContext.get());
return true;
}
void VideoDisplay::ShowCursor(bool show) {
if (show) {
SetCursor(wxNullCursor);
@ -212,6 +221,7 @@ void VideoDisplay::SetFrame(int frameNumber) {
}
void VideoDisplay::UploadFrameData() {
if (!InitContext()) return;
VideoContext *context = VideoContext::Get();
AegiVideoFrame frame;
try {
@ -247,8 +257,9 @@ void VideoDisplay::UploadFrameData() {
}
void VideoDisplay::Refresh() {
UploadFrameData();
if (!tool.get()) tool.reset(new VisualToolCross(this, video, toolBar));
if (!InitContext()) return;
UploadFrameData();
tool->Refresh();
Render();
}
@ -258,14 +269,12 @@ void VideoDisplay::SetFrameRange(int from, int to) {
}
void VideoDisplay::Render() try {
if (!IsShownOnScreen()) return;
if (!InitContext()) return;
VideoContext *context = VideoContext::Get();
if (!context->IsLoaded()) return;
assert(wxIsMainThread());
assert(w > 0);
SetCurrent(*context->GetGLContext(this));
videoOut->Render(viewport_x, viewport_bottom, viewport_width, viewport_height);
E(glViewport(0, min(viewport_bottom, 0), w, h));

View file

@ -62,7 +62,7 @@ struct VideoState {
/// @class VideoDisplay
/// @brief DOCME
class VideoDisplay: public wxGLCanvas {
class VideoDisplay : public wxGLCanvas {
agi::OptionValue* alwaysShowTools;
/// The unscaled size of the displayed video
wxSize origSize;
@ -147,6 +147,13 @@ class VideoDisplay: public wxGLCanvas {
/// The toolbar used by individual typesetting tools
wxToolBar* toolBar;
/// The OpenGL context for this display
std::auto_ptr<wxGLContext> glContext;
/// @brief Initialize the gl context and set the active context to this one
/// @return Could the context be set?
bool InitContext();
void OnMode(const wxCommandEvent &event);
void SetMode(int mode);