summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H2
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx18
-rw-r--r--src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx87
3 files changed, 88 insertions, 19 deletions
diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H
index 83b13e155..df321fc10 100644
--- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H
+++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H
@@ -46,6 +46,8 @@ private:
void swap_buffers() FL_OVERRIDE;
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() 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/Wayland/Fl_Wayland_Gl_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx
index 4553c1a0e..ac625fe6f 100644
--- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx
@@ -63,6 +63,9 @@ struct gl_start_support { // to support use of gl_start / gl_finish
static EGLConfig wld_egl_conf = NULL;
+static EGLint swap_interval_ = 1;
+static EGLint max_swap_interval = 1000;
+static EGLint min_swap_interval = 0;
EGLDisplay Fl_Wayland_Gl_Window_Driver::egl_display = EGL_NO_DISPLAY;
@@ -170,6 +173,9 @@ Fl_Gl_Choice *Fl_Wayland_Gl_Window_Driver::find(int m, const int *alistp)
Fl::fatal("failed to choose an EGL config\n");
}
+ eglGetConfigAttrib(egl_display, g->egl_conf, EGL_MAX_SWAP_INTERVAL, &max_swap_interval);
+ eglGetConfigAttrib(egl_display, g->egl_conf, EGL_MIN_SWAP_INTERVAL, &min_swap_interval);
+
first = g;
return g;
}
@@ -431,6 +437,18 @@ void Fl_Wayland_Gl_Window_Driver::gl_start() {
glClear(GL_COLOR_BUFFER_BIT);
}
+void Fl_Wayland_Gl_Window_Driver::swap_interval(int interval) {
+ if (interval < min_swap_interval) interval = min_swap_interval;
+ if (interval > max_swap_interval) interval = max_swap_interval;
+ if (egl_display && eglSwapInterval(egl_display, interval))
+ swap_interval_ = interval;
+ // printf("swap_interval_=%d\n",swap_interval_);
+}
+
+
+int Fl_Wayland_Gl_Window_Driver::swap_interval() const {
+ return swap_interval_;
+}
FL_EXPORT EGLContext fl_wl_glcontext(GLContext rc) { return (EGLContext)rc; }
diff --git a/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx
index fd07308fa..c2611e739 100644
--- a/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx
+++ b/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx
@@ -397,41 +397,90 @@ 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");
+
+// Start of swap_interval implementation in the three possibel ways for X11
+
+// -1 = not yet initialized, 0 = none found, 1 = GLX, 2 = MESA, 3 = SGI
+static signed char swap_interval_type = -1;
+
+typedef void (*GLX_Set_Swap_Iterval_Proc) (Display *dpy, GLXDrawable drawable, int interval);
+typedef int (*MESA_Set_Swap_Iterval_Proc) (unsigned int interval);
+typedef int (*MESA_Get_Swap_Iterval_Proc) ();
+typedef int (*SGI_Set_Swap_Iterval_Proc) (int interval);
+
+static union {
+ GLX_Set_Swap_Iterval_Proc glXSwapIntervalEXT = NULL;
+ MESA_Set_Swap_Iterval_Proc glXSwapIntervalMESA;
+ SGI_Set_Swap_Iterval_Proc glXSwapIntervalSGI;
+};
+
+static MESA_Get_Swap_Iterval_Proc glXGetSwapIntervalMESA = NULL;
+
+static void init_swap_interval() {
+ if (swap_interval_type != -1) return;
+ int major = 1, minor = 0;
+ glXQueryVersion(fl_display, &major, &minor);
+ swap_interval_type = 0;
+ const char *extensions = glXQueryExtensionsString(fl_display, fl_screen);
+ if (strstr(extensions, "GLX_EXT_swap_control") && ((major > 1) || (minor >= 3))) {
+ glXSwapIntervalEXT = (GLX_Set_Swap_Iterval_Proc)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalEXT");
+ swap_interval_type = 1;
+ } else if (strstr(extensions, "GLX_MESA_swap_control")) {
+ glXSwapIntervalMESA = (MESA_Set_Swap_Iterval_Proc)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalMESA");
+ glXGetSwapIntervalMESA = (MESA_Get_Swap_Iterval_Proc)glXGetProcAddressARB((const GLubyte*)"glXGetSwapIntervalMESA");
+ swap_interval_type = 2;
+ } else if (strstr(extensions, "GLX_SGI_swap_control")) {
+ glXSwapIntervalSGI = (SGI_Set_Swap_Iterval_Proc)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalSGI");
+ swap_interval_type = 3;
}
}
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);
+ if (swap_interval_type == -1)
+ init_swap_interval();
+ switch (swap_interval_type) {
+ case 1:
+ if (glXSwapIntervalEXT)
+ glXSwapIntervalEXT(fl_display, fl_xid(pWindow), interval);
+ break;
+ case 2:
+ if (glXSwapIntervalMESA)
+ glXSwapIntervalMESA((unsigned int)interval);
+ break;
+ case 3:
+ if (glXSwapIntervalSGI)
+ glXSwapIntervalSGI(interval);
+ break;
}
}
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 (swap_interval_type == -1)
+ init_swap_interval();
+ int interval = -1;
+ switch (swap_interval_type) {
+ case 1: {
+ unsigned int val = 0;
+ glXQueryDrawable(fl_display, fl_xid(pWindow), 0x20F1 /*GLX_SWAP_INTERVAL_EXT*/, &val);
+ interval = (int)val;
+ break; }
+ case 2:
+ if (glXGetSwapIntervalMESA)
+ interval = glXGetSwapIntervalMESA();
+ break;
+ case 3:
+ // not available
+ break;
}
- if (!ext_exists) return -1;
- unsigned int interval = -1;
- glXQueryDrawable(fl_display, fl_xid(pWindow), 0x20F1 /*GLX_SWAP_INTERVAL_EXT*/, &interval);
return interval;
}
+// end of swap_interval implementation
+
void Fl_X11_Gl_Window_Driver::waitGL() {
glXWaitGL();
}