fix multithreading issues with X

This commit is contained in:
David Rose 2006-05-23 14:16:38 +00:00
parent 70dda7cff5
commit 91b341dafb
8 changed files with 72 additions and 10 deletions

View File

@ -73,7 +73,7 @@ report_errors(int line, const char *source_file) {
INLINE void CLP(GraphicsStateGuardian):: INLINE void CLP(GraphicsStateGuardian)::
report_my_errors(int line, const char *source_file) { report_my_errors(int line, const char *source_file) {
#ifndef NDEBUG #ifndef NDEBUG
GLenum error_code = GLP(GetError)(); GLenum error_code = gl_get_error();
if (error_code != GL_NO_ERROR) { if (error_code != GL_NO_ERROR) {
if (!report_errors_loop(line, source_file, error_code, _error_count)) { if (!report_errors_loop(line, source_file, error_code, _error_count)) {
panic_deactivate(); panic_deactivate();

View File

@ -1524,14 +1524,11 @@ end_frame(Thread *current_thread) {
} }
} }
{
PStatTimer timer(_flush_pcollector);
// Calling glFlush() at the end of the frame is particularly // Calling glFlush() at the end of the frame is particularly
// necessary if this is a single-buffered visual, so that the frame // necessary if this is a single-buffered visual, so that the frame
// will be finished drawing before we return to the application. // will be finished drawing before we return to the application.
// It's not clear what effect this has on our total frame time. // It's not clear what effect this has on our total frame time.
GLP(Flush)(); gl_flush();
}
report_my_gl_errors(); report_my_gl_errors();
} }
@ -4188,6 +4185,27 @@ draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, G
} }
#endif // SUPPORT_IMMEDIATE_MODE #endif // SUPPORT_IMMEDIATE_MODE
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::gl_flush
// Access: Protected, Virtual
// Description: Calls glFlush().
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
gl_flush() const {
PStatTimer timer(_flush_pcollector);
GLP(Flush)();
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::gl_get_error
// Access: Protected, Virtual
// Description: Returns the result of glGetError().
////////////////////////////////////////////////////////////////////
GLenum CLP(GraphicsStateGuardian)::
gl_get_error() const {
return GLP(GetError)();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::report_errors_loop // Function: GLGraphicsStateGuardian::report_errors_loop
// Access: Protected, Static // Access: Protected, Static

View File

@ -208,6 +208,9 @@ protected:
void do_issue_tex_gen(); void do_issue_tex_gen();
void do_issue_tex_matrix(); void do_issue_tex_matrix();
virtual void gl_flush() const;
virtual GLenum gl_get_error() const;
static bool report_errors_loop(int line, const char *source_file, static bool report_errors_loop(int line, const char *source_file,
GLenum error_code, int &error_count); GLenum error_code, int &error_count);
static string get_error_string(GLenum error_code); static string get_error_string(GLenum error_code);

View File

@ -30,6 +30,8 @@ bool glxGraphicsPipe::_error_handlers_installed = false;
glxGraphicsPipe::ErrorHandlerFunc *glxGraphicsPipe::_prev_error_handler; glxGraphicsPipe::ErrorHandlerFunc *glxGraphicsPipe::_prev_error_handler;
glxGraphicsPipe::IOErrorHandlerFunc *glxGraphicsPipe::_prev_io_error_handler; glxGraphicsPipe::IOErrorHandlerFunc *glxGraphicsPipe::_prev_io_error_handler;
Mutex glxGraphicsPipe::_x_mutex;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: glxGraphicsPipe::Constructor // Function: glxGraphicsPipe::Constructor
// Access: Public // Access: Public

View File

@ -23,6 +23,7 @@
#include "graphicsWindow.h" #include "graphicsWindow.h"
#include "graphicsPipe.h" #include "graphicsPipe.h"
#include "glgsg.h" #include "glgsg.h"
#include "pmutex.h"
class FrameBufferProperties; class FrameBufferProperties;
@ -160,6 +161,11 @@ private:
static ErrorHandlerFunc *_prev_error_handler; static ErrorHandlerFunc *_prev_error_handler;
static IOErrorHandlerFunc *_prev_io_error_handler; static IOErrorHandlerFunc *_prev_io_error_handler;
public:
// This Mutex protects any X library calls, which all have to be
// single-threaded. In particular, it protects glXMakeCurrent().
static Mutex _x_mutex;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;

View File

@ -183,6 +183,30 @@ glx_is_at_least_version(int major_version, int minor_version) const {
return true; return true;
} }
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsStateGuardian::gl_flush
// Access: Protected, Virtual
// Description: Calls glFlush().
////////////////////////////////////////////////////////////////////
void glxGraphicsStateGuardian::
gl_flush() const {
// This call requires synchronization with X.
MutexHolder holder(glxGraphicsPipe::_x_mutex);
GLGraphicsStateGuardian::gl_flush();
}
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsStateGuardian::gl_get_error
// Access: Protected, Virtual
// Description: Returns the result of glGetError().
////////////////////////////////////////////////////////////////////
GLenum glxGraphicsStateGuardian::
gl_get_error() const {
// This call requires synchronization with X.
MutexHolder holder(glxGraphicsPipe::_x_mutex);
return GLGraphicsStateGuardian::gl_get_error();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: glxGraphicsStateGuardian::query_gl_version // Function: glxGraphicsStateGuardian::query_gl_version
// Access: Protected, Virtual // Access: Protected, Virtual

View File

@ -104,6 +104,9 @@ public:
PFNGLXSWAPINTERVALSGIPROC _glXSwapIntervalSGI; PFNGLXSWAPINTERVALSGIPROC _glXSwapIntervalSGI;
protected: protected:
virtual void gl_flush() const;
virtual GLenum gl_get_error() const;
virtual void query_gl_version(); virtual void query_gl_version();
virtual void get_extra_extensions(); virtual void get_extra_extensions();
virtual void *get_extension_func(const char *prefix, const char *name); virtual void *get_extension_func(const char *prefix, const char *name);

View File

@ -131,7 +131,10 @@ begin_frame(FrameMode mode, Thread *current_thread) {
glxGraphicsStateGuardian *glxgsg; glxGraphicsStateGuardian *glxgsg;
DCAST_INTO_R(glxgsg, _gsg, false); DCAST_INTO_R(glxgsg, _gsg, false);
{
MutexHolder holder(glxGraphicsPipe::_x_mutex);
glXMakeCurrent(_display, _xwindow, glxgsg->_context); glXMakeCurrent(_display, _xwindow, glxgsg->_context);
}
// Now that we have made the context current to a window, we can // Now that we have made the context current to a window, we can
// reset the GSG state if this is the first time it has been used. // reset the GSG state if this is the first time it has been used.
@ -200,6 +203,7 @@ begin_flip() {
//make_current(); //make_current();
MutexHolder holder(glxGraphicsPipe::_x_mutex);
glXSwapBuffers(_display, _xwindow); glXSwapBuffers(_display, _xwindow);
} }
} }
@ -216,6 +220,8 @@ begin_flip() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void glxGraphicsWindow:: void glxGraphicsWindow::
process_events() { process_events() {
MutexHolder holder(glxGraphicsPipe::_x_mutex);
GraphicsWindow::process_events(); GraphicsWindow::process_events();
if (_xwindow == (Window)0) { if (_xwindow == (Window)0) {