diff --git a/gtk/src/gtk_display.cpp b/gtk/src/gtk_display.cpp index d702ef35..36ea7779 100644 --- a/gtk/src/gtk_display.cpp +++ b/gtk/src/gtk_display.cpp @@ -1897,3 +1897,10 @@ S9xInitDisplay (int argc, char **argv) S9xCustomDisplayString = S9xGTKDisplayString; } +bool +S9xDisplayDriverIsReady () +{ + if (!driver) + return false; + return driver->is_ready (); +} diff --git a/gtk/src/gtk_display.h b/gtk/src/gtk_display.h index 6e9f25c0..07178946 100644 --- a/gtk/src/gtk_display.h +++ b/gtk/src/gtk_display.h @@ -132,5 +132,6 @@ void S9xDisplayReconfigure (); void S9xQueryDrivers (); S9xDisplayDriver *S9xDisplayGetDriver (); +bool S9xDisplayDriverIsReady (); #endif /* __GTK_DISPLAY_H */ diff --git a/gtk/src/gtk_display_driver.h b/gtk/src/gtk_display_driver.h index 28434d98..40ef760b 100644 --- a/gtk/src/gtk_display_driver.h +++ b/gtk/src/gtk_display_driver.h @@ -23,6 +23,7 @@ class S9xDisplayDriver virtual void push_buffer (uint16 *src) = 0; virtual void *get_parameters () = 0; virtual void save (const char *filename) = 0; + virtual bool is_ready () = 0; /* Namespaced sizing constants */ static const int image_width = 1024; diff --git a/gtk/src/gtk_display_driver_gtk.h b/gtk/src/gtk_display_driver_gtk.h index d2c7ca5a..bf32f57b 100644 --- a/gtk/src/gtk_display_driver_gtk.h +++ b/gtk/src/gtk_display_driver_gtk.h @@ -24,6 +24,7 @@ class S9xGTKDisplayDriver : public S9xDisplayDriver void push_buffer (uint16 *src); void *get_parameters () { return NULL; } void save (const char *filename) { } + bool is_ready () { return true; } private: void clear (); diff --git a/gtk/src/gtk_display_driver_opengl.cpp b/gtk/src/gtk_display_driver_opengl.cpp index eeb20a22..d069735e 100644 --- a/gtk/src/gtk_display_driver_opengl.cpp +++ b/gtk/src/gtk_display_driver_opengl.cpp @@ -88,6 +88,7 @@ S9xOpenGLDisplayDriver::S9xOpenGLDisplayDriver (Snes9xWindow *window, this->window = window; this->config = config; this->drawing_area = GTK_WIDGET (window->drawing_area); + fence = NULL; } void S9xOpenGLDisplayDriver::update (int width, int height, int yoffset) @@ -645,10 +646,9 @@ void S9xOpenGLDisplayDriver::swap_buffers () { if (fences) { - GLsync fence = glFenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - usleep (0); - glClientWaitSync (fence, GL_SYNC_FLUSH_COMMANDS_BIT, 100000000); - glDeleteSync (fence); + if (fence) + glDeleteSync (fence); + fence = glFenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0); } else { @@ -716,3 +716,16 @@ int S9xOpenGLDisplayDriver::query_availability () return 0; } + +bool S9xOpenGLDisplayDriver::is_ready () +{ + if (!fence) + return true; + + if (glClientWaitSync (fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0) == GL_TIMEOUT_EXPIRED) + return false; + + glDeleteSync (fence); + fence = NULL; + return true; +} diff --git a/gtk/src/gtk_display_driver_opengl.h b/gtk/src/gtk_display_driver_opengl.h index d6696efb..4beb66e5 100644 --- a/gtk/src/gtk_display_driver_opengl.h +++ b/gtk/src/gtk_display_driver_opengl.h @@ -41,6 +41,7 @@ class S9xOpenGLDisplayDriver : public S9xDisplayDriver void *get_parameters (); void save (const char *filename); static int query_availability (); + bool is_ready (); private: int opengl_defaults (); @@ -74,6 +75,8 @@ class S9xOpenGLDisplayDriver : public S9xDisplayDriver OpenGLContext *context; + GLsync fence; + #ifdef GDK_WINDOWING_X11 GTKGLXContext glx; #endif diff --git a/gtk/src/gtk_display_driver_xv.h b/gtk/src/gtk_display_driver_xv.h index b1ea0c27..5660ee82 100644 --- a/gtk/src/gtk_display_driver_xv.h +++ b/gtk/src/gtk_display_driver_xv.h @@ -32,6 +32,7 @@ class S9xXVDisplayDriver : public S9xDisplayDriver void *get_parameters () { return NULL; } void save (const char *filename) { } static int query_availability (); + bool is_ready () { return true; } private: void clear (); diff --git a/gtk/src/gtk_s9x.cpp b/gtk/src/gtk_s9x.cpp index 0a9cf660..a287566e 100644 --- a/gtk/src/gtk_s9x.cpp +++ b/gtk/src/gtk_s9x.cpp @@ -308,9 +308,13 @@ gboolean S9xIdleFunc (gpointer data) } S9xCheckPointerTimer (); - S9xThrottle (); S9xProcessEvents (TRUE); + if (!S9xDisplayDriverIsReady ()) + return TRUE; + + S9xThrottle (); + if (!S9xNetplayPush ()) { if(Settings.Rewinding)