diff options
Diffstat (limited to 'progs/xdemos/glxgears.c')
-rw-r--r-- | progs/xdemos/glxgears.c | 126 |
1 files changed, 124 insertions, 2 deletions
diff --git a/progs/xdemos/glxgears.c b/progs/xdemos/glxgears.c index c98c3157b5..2dc157a890 100644 --- a/progs/xdemos/glxgears.c +++ b/progs/xdemos/glxgears.c @@ -39,6 +39,9 @@ #include <GL/gl.h> #include <GL/glx.h> +static int is_glx_extension_supported(Display *dpy, const char *query); + +static void query_vsync(Display *dpy); #define BENCHMARK @@ -419,6 +422,52 @@ init(void) } +/** + * Remove window border/decorations. + */ +static void +no_border( Display *dpy, Window w) +{ + static const unsigned MWM_HINTS_DECORATIONS = (1 << 1); + static const int PROP_MOTIF_WM_HINTS_ELEMENTS = 5; + + typedef struct + { + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long inputMode; + unsigned long status; + } PropMotifWmHints; + + PropMotifWmHints motif_hints; + Atom prop, proptype; + unsigned long flags = 0; + + /* setup the property */ + motif_hints.flags = MWM_HINTS_DECORATIONS; + motif_hints.decorations = flags; + + /* get the atom for the property */ + prop = XInternAtom( dpy, "_MOTIF_WM_HINTS", True ); + if (!prop) { + /* something went wrong! */ + return; + } + + /* not sure this is correct, seems to work, XA_WM_HINTS didn't work */ + proptype = prop; + + XChangeProperty( dpy, w, /* display, window */ + prop, proptype, /* property, type */ + 32, /* format: 32-bit datums */ + PropModeReplace, /* mode */ + (unsigned char *) &motif_hints, /* data */ + PROP_MOTIF_WM_HINTS_ELEMENTS /* nelements */ + ); +} + + /* * Create an RGB, double-buffered window. * Return the window and context handles. @@ -479,13 +528,15 @@ make_window( Display *dpy, const char *name, attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; /* XXX this is a bad way to get a borderless window! */ - attr.override_redirect = fullscreen; - mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow( dpy, root, x, y, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr ); + if (fullscreen) + no_border(dpy, win); + /* set hints and properties */ { XSizeHints sizehints; @@ -513,12 +564,82 @@ make_window( Display *dpy, const char *name, /** + * Determine whether or not a GLX extension is supported. + */ +int +is_glx_extension_supported(Display *dpy, const char *query) +{ + const int scrnum = DefaultScreen(dpy); + const char *glx_extensions = NULL; + const size_t len = strlen(query); + const char *ptr; + + if (glx_extensions == NULL) { + glx_extensions = glXQueryExtensionsString(dpy, scrnum); + } + + ptr = strstr(glx_extensions, query); + return ((ptr != NULL) && ((ptr[len] == ' ') || (ptr[len] == '\0'))); +} + + +/** + * Attempt to determine whether or not the display is synched to vblank. + */ +void +query_vsync(Display *dpy) +{ + int interval = 0; + + +#ifdef GLX_MESA_swap_control + if ((interval <= 0) + && is_glx_extension_supported(dpy, "GLX_MESA_swap_control")) { + PFNGLXGETSWAPINTERVALMESAPROC pglXGetSwapIntervalMESA = + (PFNGLXGETSWAPINTERVALMESAPROC) + glXGetProcAddressARB((const GLubyte *) "glXGetSwapIntervalMESA"); + + interval = (*pglXGetSwapIntervalMESA)(); + } +#endif + + +#ifdef GLX_SGI_video_sync + if ((interval <= 0) + && is_glx_extension_supported(dpy, "GLX_SGI_video_sync")) { + PFNGLXGETVIDEOSYNCSGIPROC pglXGetVideoSyncSGI = + (PFNGLXGETVIDEOSYNCSGIPROC) + glXGetProcAddressARB((const GLubyte *) "glXGetVideoSyncSGI"); + unsigned count; + + if ((*pglXGetVideoSyncSGI)(& count) == 0) { + interval = (int) count; + } + } +#endif + + + if (interval > 0) { + printf("Running synchronized to the vertical refresh. The framerate should be\n"); + if (interval == 1) { + printf("approximately the same as the monitor refresh rate.\n"); + } else if (interval > 1) { + printf("approximately 1/%d the monitor refresh rate.\n", + interval); + } + } +} + +/** * Handle one X event. * \return NOP, EXIT or DRAW */ static int handle_event(Display *dpy, Window win, XEvent *event) { + (void) dpy; + (void) win; + switch (event->type) { case Expose: return DRAW; @@ -638,6 +759,7 @@ main(int argc, char *argv[]) make_window(dpy, "glxgears", x, y, winWidth, winHeight, &win, &ctx); XMapWindow(dpy, win); glXMakeCurrent(dpy, win, ctx); + query_vsync(dpy); if (printInfo) { printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); |