diff options
author | Richard Grenville <[email protected]> | 2014-03-17 23:25:34 +0800 |
---|---|---|
committer | Richard Grenville <[email protected]> | 2014-03-17 23:25:34 +0800 |
commit | 224dcd29cc383a61c85140897424b07f905f2c95 (patch) | |
tree | b3c8ec6c9c6fc3c9ca685c5f467af467a18165b4 /opengl.c | |
parent | f01576deb4f747f72e85795dcca8c43b43d22e5e (diff) | |
download | tdebase-224dcd29cc383a61c85140897424b07f905f2c95.tar.gz tdebase-224dcd29cc383a61c85140897424b07f905f2c95.zip |
Bug fix #181: Add --xrender-sync{,-fence}
- Add --xrender-sync{,-fence} to deal with redraw lag issue on GLX
backend. --xrender-sync-fence requires a sufficiently new xorg-server
and libXext. NO_XSYNC=1 may be used to disable it at compile time.
Thanks to tchebb for reporting and everybody else for testing. (#181)
- A bit code clean-up. Replace a few XSync() with XFlush() to minimize
the latency.
Diffstat (limited to 'opengl.c')
-rw-r--r-- | opengl.c | 127 |
1 files changed, 105 insertions, 22 deletions
@@ -10,6 +10,50 @@ #include "opengl.h" +#ifdef CONFIG_GLX_SYNC +void +xr_glx_sync(session_t *ps, Drawable d, XSyncFence *pfence) { + if (*pfence) { + // GLsync sync = ps->glFenceSyncProc(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + GLsync sync = ps->glImportSyncEXT(GL_SYNC_X11_FENCE_EXT, *pfence, 0); + XSync(ps->dpy, False); + glx_check_err(ps); + /* GLenum ret = ps->glClientWaitSyncProc(sync, GL_SYNC_FLUSH_COMMANDS_BIT, + 1000); + assert(GL_CONDITION_SATISFIED == ret); */ + ps->glWaitSyncProc(sync, 0, GL_TIMEOUT_IGNORED); + // ps->glDeleteSyncProc(sync); + // XSyncResetFence(ps->dpy, *pfence); + } + glx_check_err(ps); +} +#endif + +static inline GLXFBConfig +get_fbconfig_from_visualinfo(session_t *ps, const XVisualInfo *visualinfo) { + int nelements = 0; + GLXFBConfig *fbconfigs = glXGetFBConfigs(ps->dpy, visualinfo->screen, + &nelements); + for (int i = 0; i < nelements; ++i) { + int visual_id = 0; + if (Success == glXGetFBConfigAttrib(ps->dpy, fbconfigs[i], GLX_VISUAL_ID, &visual_id) + && visual_id == visualinfo->visualid) + return fbconfigs[i]; + } + + return NULL; +} + +#ifdef DEBUG_GLX_DEBUG_CONTEXT +static void +glx_debug_msg_callback(GLenum source, GLenum type, + GLuint id, GLenum severity, GLsizei length, const GLchar *message, + GLvoid *userParam) { + printf_dbgf("(): source 0x%04X, type 0x%04X, id %u, severity 0x%0X, \"%s\"\n", + source, type, id, severity, message); +} +#endif + /** * Initialize OpenGL. */ @@ -56,7 +100,33 @@ glx_init(session_t *ps, bool need_render) { if (!ps->glx_context) { // Get GLX context +#ifndef DEBUG_GLX_DEBUG_CONTEXT ps->glx_context = glXCreateContext(ps->dpy, pvis, None, GL_TRUE); +#else + { + GLXFBConfig fbconfig = get_fbconfig_from_visualinfo(ps, pvis); + if (!fbconfig) { + printf_errf("(): Failed to get GLXFBConfig for root visual %#lx.", + pvis->visualid); + goto glx_init_end; + } + + f_glXCreateContextAttribsARB p_glXCreateContextAttribsARB = + (f_glXCreateContextAttribsARB) + glXGetProcAddress((const GLubyte *) "glXCreateContextAttribsARB"); + if (!p_glXCreateContextAttribsARB) { + printf_errf("(): Failed to get glXCreateContextAttribsARB()."); + goto glx_init_end; + } + + static const int attrib_list[] = { + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, + None + }; + ps->glx_context = p_glXCreateContextAttribsARB(ps->dpy, fbconfig, NULL, + GL_TRUE, attrib_list); + } +#endif if (!ps->glx_context) { printf_errf("(): Failed to get GLX context."); @@ -68,6 +138,20 @@ glx_init(session_t *ps, bool need_render) { printf_errf("(): Failed to attach GLX context."); goto glx_init_end; } + +#ifdef DEBUG_GLX_DEBUG_CONTEXT + { + f_DebugMessageCallback p_DebugMessageCallback = + (f_DebugMessageCallback) + glXGetProcAddress((const GLubyte *) "glDebugMessageCallback"); + if (!p_DebugMessageCallback) { + printf_errf("(): Failed to get glDebugMessageCallback(0."); + goto glx_init_end; + } + p_DebugMessageCallback(glx_debug_msg_callback, ps); + } +#endif + } // Ensure we have a stencil buffer. X Fixes does not guarantee rectangles @@ -114,6 +198,27 @@ glx_init(session_t *ps, bool need_render) { goto glx_init_end; } } + +#ifdef CONFIG_GLX_SYNC + ps->glFenceSyncProc = (f_FenceSync) + glXGetProcAddress((const GLubyte *) "glFenceSync"); + ps->glIsSyncProc = (f_IsSync) + glXGetProcAddress((const GLubyte *) "glIsSync"); + ps->glDeleteSyncProc = (f_DeleteSync) + glXGetProcAddress((const GLubyte *) "glDeleteSync"); + ps->glClientWaitSyncProc = (f_ClientWaitSync) + glXGetProcAddress((const GLubyte *) "glClientWaitSync"); + ps->glWaitSyncProc = (f_WaitSync) + glXGetProcAddress((const GLubyte *) "glWaitSync"); + ps->glImportSyncEXT = (f_ImportSyncEXT) + glXGetProcAddress((const GLubyte *) "glImportSyncEXT"); + if (!ps->glFenceSyncProc || !ps->glIsSyncProc || !ps->glDeleteSyncProc + || !ps->glClientWaitSyncProc || !ps->glWaitSyncProc + || !ps->glImportSyncEXT) { + printf_errf("(): Failed to acquire GLX sync functions."); + goto glx_init_end; + } +#endif } // Acquire FBConfigs @@ -344,9 +449,7 @@ glx_init_blur(session_t *ps) { } -#ifdef DEBUG_GLX_ERR glx_check_err(ps); -#endif return true; #else @@ -655,9 +758,7 @@ glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, Pixmap pixmap, glBindTexture(ptex->target, 0); glDisable(ptex->target); -#ifdef DEBUG_GLX_ERR glx_check_err(ps); -#endif return true; } @@ -680,9 +781,7 @@ glx_release_pixmap(session_t *ps, glx_texture_t *ptex) { ptex->glpixmap = 0; } -#ifdef DEBUG_GLX_ERR glx_check_err(ps); -#endif } /** @@ -803,9 +902,7 @@ glx_paint_pre(session_t *ps, XserverRegion *preg) { glx_render_color(ps, 0, 0, ps->root_width, ps->root_height, 0, *preg, NULL); #endif -#ifdef DEBUG_GLX_ERR glx_check_err(ps); -#endif } /** @@ -886,9 +983,7 @@ glx_set_clip(session_t *ps, XserverRegion reg, const reg_data_t *pcache_reg) { cxfree(rects_free); -#ifdef DEBUG_GLX_ERR glx_check_err(ps); -#endif } #define P_PAINTREG_START() \ @@ -1174,9 +1269,7 @@ glx_blur_dst_end: free_glx_bc(ps, pbc); } -#ifdef DEBUG_GLX_ERR glx_check_err(ps); -#endif return ret; } @@ -1212,9 +1305,7 @@ glx_dim_dst(session_t *ps, int dx, int dy, int width, int height, float z, glColor4f(0.0f, 0.0f, 0.0f, 0.0f); glDisable(GL_BLEND); -#ifdef DEBUG_GLX_ERR glx_check_err(ps); -#endif return true; } @@ -1412,9 +1503,7 @@ glx_render(session_t *ps, const glx_texture_t *ptex, glActiveTexture(GL_TEXTURE0); } -#ifdef DEBUG_GLX_ERR glx_check_err(ps); -#endif return true; } @@ -1452,9 +1541,7 @@ glx_render_color(session_t *ps, int dx, int dy, int width, int height, int z, } glColor4f(0.0f, 0.0f, 0.0f, 0.0f); -#ifdef DEBUG_GLX_ERR glx_check_err(ps); -#endif } /** @@ -1492,9 +1579,7 @@ glx_render_dots(session_t *ps, int dx, int dy, int width, int height, int z, } glColor4f(0.0f, 0.0f, 0.0f, 0.0f); -#ifdef DEBUG_GLX_ERR glx_check_err(ps); -#endif } /** @@ -1524,9 +1609,7 @@ glx_swap_copysubbuffermesa(session_t *ps, XserverRegion reg) { } } -#ifdef DEBUG_GLX_ERR glx_check_err(ps); -#endif cxfree(rects); } |