diff --git a/src/Fl_Gl_Window_Driver.H b/src/Fl_Gl_Window_Driver.H index 79f696905..ee3332545 100644 --- a/src/Fl_Gl_Window_Driver.H +++ b/src/Fl_Gl_Window_Driver.H @@ -70,7 +70,7 @@ public: virtual void resize(int /*is_a_resize*/, int /*w*/, int /*h*/) {} virtual char swap_type(); virtual void swap_interval(int) { } - virtual int swap_interval() { return -1; } + virtual int swap_interval() const { return -1; } virtual int flush_begin(char&) {return 0;} virtual void gl_hide_before(void *&) {} // the default implementation may be enough static Fl_Gl_Choice *find_begin(int m, const int *alistp); diff --git a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H index 21a3a4589..d5ba9c21c 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H +++ b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H @@ -39,7 +39,7 @@ class Fl_Cocoa_Gl_Window_Driver : public Fl_Gl_Window_Driver { void resize(int is_a_resize, int w, int h) FL_OVERRIDE; char swap_type() FL_OVERRIDE; void swap_interval(int) FL_OVERRIDE; - int swap_interval() FL_OVERRIDE; + int swap_interval() const FL_OVERRIDE; Fl_Gl_Choice *find(int m, const int *alistp) FL_OVERRIDE; GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g) FL_OVERRIDE; void set_gl_context(Fl_Window* w, GLContext context) FL_OVERRIDE; diff --git a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm index 43bc2d480..0bcc77af5 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm +++ b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm @@ -362,7 +362,7 @@ void Fl_Cocoa_Gl_Window_Driver::swap_interval(int n) { [ctx setValues:&interval forParameter:NSOpenGLContextParameterSwapInterval]; } -int Fl_Cocoa_Gl_Window_Driver::swap_interval() { +int Fl_Cocoa_Gl_Window_Driver::swap_interval() const { GLint interval = (GLint)-1; NSOpenGLContext* ctx = (NSOpenGLContext*)pWindow->context(); if (ctx) diff --git a/src/drivers/X11/Fl_X11_Gl_Window_Driver.H b/src/drivers/X11/Fl_X11_Gl_Window_Driver.H index 026f3ec4a..1f4c71053 100644 --- a/src/drivers/X11/Fl_X11_Gl_Window_Driver.H +++ b/src/drivers/X11/Fl_X11_Gl_Window_Driver.H @@ -32,6 +32,8 @@ class Fl_X11_Gl_Window_Driver : public Fl_Gl_Window_Driver { int mode_(int m, const int *a) FL_OVERRIDE; void swap_buffers() FL_OVERRIDE; char swap_type() FL_OVERRIDE; + void swap_interval(int) FL_OVERRIDE; + int swap_interval() const FL_OVERRIDE; Fl_Gl_Choice *find(int m, const int *alistp) FL_OVERRIDE; GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g) FL_OVERRIDE; void set_gl_context(Fl_Window* w, GLContext context) FL_OVERRIDE; diff --git a/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx index 3f09edae2..fd07308fa 100644 --- a/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx @@ -393,14 +393,49 @@ void Fl_X11_Gl_Window_Driver::swap_buffers() { glXSwapBuffers(fl_display, fl_xid(pWindow)); } +char Fl_X11_Gl_Window_Driver::swap_type() { + return copy; +} -char Fl_X11_Gl_Window_Driver::swap_type() {return copy;} +typedef void (*SWAPINTERVALPROC) (Display *dpy, GLXDrawable drawable, int interval); +static SWAPINTERVALPROC glXSwapIntervalEXT = NULL; +static bool glXSwapIntervalChecked = false; +static void checkGlxXSwapInterval() { + if (!glXSwapIntervalChecked) { + glXSwapIntervalChecked = true; + glXSwapIntervalEXT = (SWAPINTERVALPROC)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalEXT"); + } +} + +void Fl_X11_Gl_Window_Driver::swap_interval(int interval) { + if (!fl_xid(pWindow)) + return; + if (!glXSwapIntervalChecked) checkGlxXSwapInterval(); + if (glXSwapIntervalEXT) { + glXSwapIntervalEXT(fl_display, fl_xid(pWindow), interval); + } +} + +int Fl_X11_Gl_Window_Driver::swap_interval() const { + if (!fl_xid(pWindow)) + return -1; + if (!glXSwapIntervalChecked) checkGlxXSwapInterval(); + if (!glXSwapIntervalEXT) return -1; + static bool ext_checked = false, ext_exists = false; + if (!ext_checked) { + ext_checked = true; + ext_exists = (strstr(glXQueryExtensionsString(fl_display, fl_screen), "GLX_EXT_swap_control") != NULL); + } + if (!ext_exists) return -1; + unsigned int interval = -1; + glXQueryDrawable(fl_display, fl_xid(pWindow), 0x20F1 /*GLX_SWAP_INTERVAL_EXT*/, &interval); + return interval; +} void Fl_X11_Gl_Window_Driver::waitGL() { glXWaitGL(); } - void Fl_X11_Gl_Window_Driver::gl_visual(Fl_Gl_Choice *c) { Fl_Gl_Window_Driver::gl_visual(c); fl_visual = ((Fl_X11_Gl_Choice*)c)->vis;