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

View file

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

View file

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

View file

@ -62,7 +62,7 @@ struct VideoState {
/// @class VideoDisplay /// @class VideoDisplay
/// @brief DOCME /// @brief DOCME
class VideoDisplay: public wxGLCanvas { class VideoDisplay : public wxGLCanvas {
agi::OptionValue* alwaysShowTools; agi::OptionValue* alwaysShowTools;
/// The unscaled size of the displayed video /// The unscaled size of the displayed video
wxSize origSize; wxSize origSize;
@ -147,6 +147,13 @@ class VideoDisplay: public wxGLCanvas {
/// The toolbar used by individual typesetting tools /// The toolbar used by individual typesetting tools
wxToolBar* toolBar; 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 OnMode(const wxCommandEvent &event);
void SetMode(int mode); void SetMode(int mode);