diff options
author | Richard Grenville <pyxlcy@gmail.com> | 2013-03-20 17:29:45 +0800 |
---|---|---|
committer | Richard Grenville <pyxlcy@gmail.com> | 2013-03-20 17:29:45 +0800 |
commit | da85de48a9d078eeb5a437482c41c85884496318 (patch) | |
tree | e9617a3e23a497c7ad23f42b90e966d0e26634a0 /compton.c | |
parent | cdd6a73836cc2c1943cdbceab4328dec96949d51 (diff) | |
download | tdebase-da85de48a9d078eeb5a437482c41c85884496318.tar.gz tdebase-da85de48a9d078eeb5a437482c41c85884496318.zip |
Feature #69: GLX: Blur background
- GLX backend: Add blur background support using a GLSL shader. Only
tested with nvidia-drivers-313.26. Known to cause quite some decrease
in performance (~10%?).
- Detach shaders in glx_create_program(). Misc changes.
Diffstat (limited to 'compton.c')
-rw-r--r-- | compton.c | 98 |
1 files changed, 57 insertions, 41 deletions
@@ -1329,60 +1329,76 @@ win_build_picture(session_t *ps, win *w, XRenderPictFormat *pictfmt) { static inline void win_blur_background(session_t *ps, win *w, Picture tgt_buffer, XserverRegion reg_paint) { - const static int convolution_blur_size = 3; - // Convolution filter parameter (box blur) - // gaussian or binomial filters are definitely superior, yet looks - // like they aren't supported as of xorg-server-1.13.0 - XFixed convolution_blur[] = { - // Must convert to XFixed with XDoubleToFixed() - // Matrix size - XDoubleToFixed(convolution_blur_size), - XDoubleToFixed(convolution_blur_size), - // Matrix - XDoubleToFixed(1), XDoubleToFixed(1), XDoubleToFixed(1), - XDoubleToFixed(1), XDoubleToFixed(1), XDoubleToFixed(1), - XDoubleToFixed(1), XDoubleToFixed(1), XDoubleToFixed(1), - }; - const int x = w->a.x; const int y = w->a.y; const int wid = w->widthb; const int hei = w->heightb; - // Directly copying from tgt_buffer does not work, so we create a - // Picture in the middle. - Picture tmp_picture = win_build_picture(ps, w, NULL); - - if (!tmp_picture) - return; - + double factor_center = 1.0; // Adjust blur strength according to window opacity, to make it appear // better during fading if (!ps->o.blur_background_fixed) { double pct = 1.0 - get_opacity_percent(w) * (1.0 - 1.0 / 9.0); - convolution_blur[2 + convolution_blur_size + ((convolution_blur_size - 1) / 2)] = XDoubleToFixed(pct * 8.0 / (1.1 - pct)); + factor_center = pct * 8.0 / (1.1 - pct); } - // Minimize the region we try to blur, if the window itself is not - // opaque, only the frame is. - if (WMODE_SOLID == w->mode && w->frame_opacity) { - XserverRegion reg_all = border_size(ps, w, false); - XserverRegion reg_noframe = win_get_region_noframe(ps, w, false); - XFixesSubtractRegion(ps->dpy, reg_noframe, reg_all, reg_noframe); - XFixesSetPictureClipRegion(ps->dpy, tmp_picture, reg_noframe, 0, 0); - free_region(ps, ®_all); - free_region(ps, ®_noframe); - } + switch (ps->o.backend) { + case BKEND_XRENDER: + { + const static int convolution_blur_size = 3; + // Convolution filter parameter (box blur) + // gaussian or binomial filters are definitely superior, yet looks + // like they aren't supported as of xorg-server-1.13.0 + XFixed convolution_blur[] = { + // Must convert to XFixed with XDoubleToFixed() + // Matrix size + XDoubleToFixed(convolution_blur_size), + XDoubleToFixed(convolution_blur_size), + // Matrix + XDoubleToFixed(1), XDoubleToFixed(1), XDoubleToFixed(1), + XDoubleToFixed(1), XDoubleToFixed(1), XDoubleToFixed(1), + XDoubleToFixed(1), XDoubleToFixed(1), XDoubleToFixed(1), + }; + + // Directly copying from tgt_buffer does not work, so we create a + // Picture in the middle. + Picture tmp_picture = win_build_picture(ps, w, NULL); + + if (!tmp_picture) + return; - // Copy the content to tmp_picture, then copy back. The filter must - // be applied on tgt_buffer, to get the nearby pixels outside the - // window. - XRenderSetPictureFilter(ps->dpy, tgt_buffer, XRFILTER_CONVOLUTION, (XFixed *) convolution_blur, sizeof(convolution_blur) / sizeof(XFixed)); - XRenderComposite(ps->dpy, PictOpSrc, tgt_buffer, None, tmp_picture, x, y, 0, 0, 0, 0, wid, hei); - xrfilter_reset(ps, tgt_buffer); - XRenderComposite(ps->dpy, PictOpSrc, tmp_picture, None, tgt_buffer, 0, 0, 0, 0, x, y, wid, hei); + convolution_blur[2 + convolution_blur_size + ((convolution_blur_size - 1) / 2)] = XDoubleToFixed(factor_center); - free_picture(ps, &tmp_picture); + // Minimize the region we try to blur, if the window itself is not + // opaque, only the frame is. + if (WMODE_SOLID == w->mode && w->frame_opacity) { + XserverRegion reg_all = border_size(ps, w, false); + XserverRegion reg_noframe = win_get_region_noframe(ps, w, false); + XFixesSubtractRegion(ps->dpy, reg_noframe, reg_all, reg_noframe); + XFixesSetPictureClipRegion(ps->dpy, tmp_picture, reg_noframe, 0, 0); + free_region(ps, ®_all); + free_region(ps, ®_noframe); + } + + // Copy the content to tmp_picture, then copy back. The filter must + // be applied on tgt_buffer, to get the nearby pixels outside the + // window. + XRenderSetPictureFilter(ps->dpy, tgt_buffer, XRFILTER_CONVOLUTION, (XFixed *) convolution_blur, sizeof(convolution_blur) / sizeof(XFixed)); + XRenderComposite(ps->dpy, PictOpSrc, tgt_buffer, None, tmp_picture, x, y, 0, 0, 0, 0, wid, hei); + xrfilter_reset(ps, tgt_buffer); + XRenderComposite(ps->dpy, PictOpSrc, tmp_picture, None, tgt_buffer, 0, 0, 0, 0, x, y, wid, hei); + + free_picture(ps, &tmp_picture); + } + break; +#ifdef CONFIG_VSYNC_OPENGL + case BKEND_GLX: + glx_blur_dst(ps, x, y, wid, hei, ps->glx_z - 0.5, factor_center); + break; +#endif + default: + assert(0); + } } static void |