From 69c3579a24635e9504bceabc1c76dfe96342c3b0 Mon Sep 17 00:00:00 2001 From: Richard Grenville Date: Mon, 18 Mar 2013 19:01:18 +0800 Subject: Improvement: GLX: Use SCISSOR_TEST instead of STENCIL_TEST when possible - GLX backend: Use GL_SCISSOR_TEST instead of STENCIL_TEST if there's only one rectangle in glx_set_clip(). Profiling with gDebugger shows a 10% performance improvement. - Add .desktop installation rules. (#97) --- compton.c | 2 +- opengl.c | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/compton.c b/compton.c index 539f8d201..a2fbee265 100644 --- a/compton.c +++ b/compton.c @@ -4136,7 +4136,7 @@ usage(void) { "--glx-no-stencil\n" " Avoid using stencil buffer under GLX backend. Might cause issues\n" " when rendering transparent content, may have a positive or\n" - " negative effect on performance.\n" + " negative effect on performance. (My test shows a 10% slowdown.)\n" #undef WARNING #ifndef CONFIG_DBUS #define WARNING WARNING_DISABLED diff --git a/opengl.c b/opengl.c index 21b3c181f..92b0292b0 100644 --- a/opengl.c +++ b/opengl.c @@ -487,7 +487,31 @@ glx_set_clip(session_t *ps, XserverRegion reg) { if (ps->o.glx_no_stencil) return; - if (reg) { + static XRectangle rect_blank = { + .x = 0, .y = 0, .width = 0, .height = 0 + }; + + glDisable(GL_STENCIL_TEST); + glDisable(GL_SCISSOR_TEST); + + if (!reg) + return; + + int nrects = 0; + XRectangle *rects = XFixesFetchRegion(ps->dpy, reg, &nrects); + if (!nrects) { + if (rects) XFree(rects); + nrects = 1; + rects = &rect_blank; + } + + assert(nrects); + if (1 == nrects) { + glEnable(GL_SCISSOR_TEST); + glScissor(rects[0].x, ps->root_height - rects[0].y - rects[0].height, + rects[0].width, rects[0].height); + } + else { glEnable(GL_STENCIL_TEST); glClear(GL_STENCIL_BUFFER_BIT); @@ -495,8 +519,6 @@ glx_set_clip(session_t *ps, XserverRegion reg) { glDepthMask(GL_FALSE); glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); - int nrects = 0; - XRectangle *rects = XFixesFetchRegion(ps->dpy, reg, &nrects); glBegin(GL_QUADS); @@ -519,16 +541,13 @@ glx_set_clip(session_t *ps, XserverRegion reg) { glEnd(); - if (rects) - XFree(rects); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_TRUE); } - else { - glDisable(GL_STENCIL_TEST); - } + + if (rects && &rect_blank != rects) + XFree(rects); } /** -- cgit v1.2.1