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)::
report_my_errors(int line, const char *source_file) {
#ifndef NDEBUG
GLenum error_code = GLP(GetError)();
GLenum error_code = gl_get_error();
if (error_code != GL_NO_ERROR) {
if (!report_errors_loop(line, source_file, error_code, _error_count)) {
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
// necessary if this is a single-buffered visual, so that the frame
// will be finished drawing before we return to the application.
// It's not clear what effect this has on our total frame time.
GLP(Flush)();
}
gl_flush();
report_my_gl_errors();
}
@ -4188,6 +4185,27 @@ draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, G
}
#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
// Access: Protected, Static

View File

@ -208,6 +208,9 @@ protected:
void do_issue_tex_gen();
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,
GLenum error_code, int &error_count);
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::IOErrorHandlerFunc *glxGraphicsPipe::_prev_io_error_handler;
Mutex glxGraphicsPipe::_x_mutex;
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsPipe::Constructor
// Access: Public

View File

@ -23,6 +23,7 @@
#include "graphicsWindow.h"
#include "graphicsPipe.h"
#include "glgsg.h"
#include "pmutex.h"
class FrameBufferProperties;
@ -160,6 +161,11 @@ private:
static ErrorHandlerFunc *_prev_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:
static TypeHandle get_class_type() {
return _type_handle;

View File

@ -183,6 +183,30 @@ glx_is_at_least_version(int major_version, int minor_version) const {
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
// Access: Protected, Virtual

View File

@ -104,6 +104,9 @@ public:
PFNGLXSWAPINTERVALSGIPROC _glXSwapIntervalSGI;
protected:
virtual void gl_flush() const;
virtual GLenum gl_get_error() const;
virtual void query_gl_version();
virtual void get_extra_extensions();
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;
DCAST_INTO_R(glxgsg, _gsg, false);
{
MutexHolder holder(glxGraphicsPipe::_x_mutex);
glXMakeCurrent(_display, _xwindow, glxgsg->_context);
}
// 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.
@ -200,6 +203,7 @@ begin_flip() {
//make_current();
MutexHolder holder(glxGraphicsPipe::_x_mutex);
glXSwapBuffers(_display, _xwindow);
}
}
@ -216,6 +220,8 @@ begin_flip() {
////////////////////////////////////////////////////////////////////
void glxGraphicsWindow::
process_events() {
MutexHolder holder(glxGraphicsPipe::_x_mutex);
GraphicsWindow::process_events();
if (_xwindow == (Window)0) {