diff options
author | Richard Grenville <[email protected]> | 2013-03-21 13:05:56 +0800 |
---|---|---|
committer | Richard Grenville <[email protected]> | 2013-03-21 13:05:56 +0800 |
commit | 2dfe9d52ed6d83fd0f2cc6cc0d921701dcb8b017 (patch) | |
tree | 734b354c4c6c1ed99343bd958d53d072c4d776cb /opengl.c | |
parent | da85de48a9d078eeb5a437482c41c85884496318 (diff) | |
download | tdebase-2dfe9d52ed6d83fd0f2cc6cc0d921701dcb8b017.tar.gz tdebase-2dfe9d52ed6d83fd0f2cc6cc0d921701dcb8b017.zip |
Improvement: --glx-use-copysubbuffermesa
- GLX backend: Add --glx-use-copysubbuffermesa, to use
MESA_copy_sub_buffer to do partial screen update. Huge performance
boost on mesa drivers for partial screen updates, but does not work
for nvidia-drivers and may break VSync. Automagically overrides
--glx-copy-from-front.
- Add rect_is_fullscreen() to reuse code. Misc changes.
Diffstat (limited to 'opengl.c')
-rw-r--r-- | opengl.c | 48 |
1 files changed, 45 insertions, 3 deletions
@@ -96,6 +96,15 @@ glx_init(session_t *ps, bool need_render) { printf_errf("(): Failed to acquire glXBindTexImageEXT() / glXReleaseTexImageEXT()."); goto glx_init_end; } + + if (ps->o.glx_use_copysubbuffermesa) { + ps->glXCopySubBufferProc = (f_CopySubBuffer) + glXGetProcAddress((const GLubyte *) "glXCopySubBufferMESA"); + if (!ps->glXCopySubBufferProc) { + printf_errf("(): Failed to acquire glXCopySubBufferMESA()."); + goto glx_init_end; + } + } } // Acquire FBConfigs @@ -543,10 +552,13 @@ void glx_paint_pre(session_t *ps, XserverRegion *preg) { ps->glx_z = 0.0; // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // OpenGL doesn't support partial repaint without GLX_MESA_copy_sub_buffer, - // we currently redraw the whole screen or copy unmodified pixels from + // we could redraw the whole screen or copy unmodified pixels from // front buffer with --glx-copy-from-front. - if (!ps->o.glx_copy_from_front || !*preg) { + if (ps->o.glx_use_copysubbuffermesa || !*preg) { + } + else if (!ps->o.glx_copy_from_front) { free_region(ps, preg); } else { @@ -612,7 +624,6 @@ glx_set_clip(session_t *ps, XserverRegion reg) { glDepthMask(GL_FALSE); glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); - glBegin(GL_QUADS); for (int i = 0; i < nrects; ++i) { @@ -853,6 +864,37 @@ glx_render(session_t *ps, const glx_texture_t *ptex, return true; } +/** + * Swap buffer with glXCopySubBufferMESA(). + */ +void +glx_swap_copysubbuffermesa(session_t *ps, XserverRegion reg) { + int nrects = 0; + XRectangle *rects = XFixesFetchRegion(ps->dpy, reg, &nrects); + + if (1 == nrects && rect_is_fullscreen(ps, rects[0].x, rects[0].y, + rects[0].width, rects[0].height)) { + glXSwapBuffers(ps->dpy, get_tgt_window(ps)); + } + else { + glx_set_clip(ps, None); + for (int i = 0; i < nrects; ++i) { + const int x = rects[i].x; + const int y = ps->root_height - rects[i].y - rects[i].height; + const int wid = rects[i].width; + const int hei = rects[i].height; + +#ifdef DEBUG_GLX + printf_dbgf("(): %d, %d, %d, %d\n", x, y, wid, hei); +#endif + ps->glXCopySubBufferProc(ps->dpy, get_tgt_window(ps), x, y, wid, hei); + } + } + + if (rects) + XFree(rects); +} + #ifdef CONFIG_VSYNC_OPENGL_GLSL GLuint glx_create_shader(GLenum shader_type, const char *shader_str) { |