From 3f00b3622c1fcc8fa115bb7a8a5d1bbc2ba9c62f Mon Sep 17 00:00:00 2001 From: Richard Grenville Date: Sat, 27 Apr 2013 17:34:42 +0800 Subject: [PATCH] Bug fix: Fix --resize-damage - Fix --resize-damage. I forgot to shrink the painting region back when actually copying to destination. - Include extra pixels around the blur texture to avoid some possible small issues, if --resize-damage is positive. - Known issue: Line artifacts may still appear with --dbe (X Render backend) or --glx-swap-method (GLX backend). I doubt if there's way to fix this without very inefficient mechanisms. --- src/common.h | 3 +++ src/compton.c | 18 +++++++++++++----- src/compton.h | 2 +- src/opengl.c | 30 +++++++++++++++++++++--------- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/common.h b/src/common.h index 2a98253d..9a693c65 100644 --- a/src/common.h +++ b/src/common.h @@ -1599,6 +1599,9 @@ find_focused(session_t *ps) { */ static inline XserverRegion copy_region(const session_t *ps, XserverRegion oldregion) { + if (!oldregion) + return None; + XserverRegion region = XFixesCreateRegion(ps->dpy, NULL, 0); XFixesCopyRegion(ps->dpy, region, oldregion); diff --git a/src/compton.c b/src/compton.c index cfd773c6..d5989d66 100644 --- a/src/compton.c +++ b/src/compton.c @@ -1597,7 +1597,10 @@ rebuild_screen_reg(session_t *ps) { } static void -paint_all(session_t *ps, XserverRegion region, win *t) { +paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t) { + if (!region_real) + region_real = region; + #ifdef DEBUG_REPAINT static struct timespec last_paint = { 0 }; #endif @@ -1645,7 +1648,8 @@ paint_all(session_t *ps, XserverRegion region, win *t) { } #endif - XFixesSetPictureClipRegion(ps->dpy, ps->tgt_picture, 0, 0, region); + if (BKEND_XRENDER == ps->o.backend) + XFixesSetPictureClipRegion(ps->dpy, ps->tgt_picture, 0, 0, region_real); #ifdef MONITOR_REPAINT switch (ps->o.backend) { @@ -1820,7 +1824,7 @@ paint_all(session_t *ps, XserverRegion region, win *t) { #ifdef CONFIG_VSYNC_OPENGL case BKEND_GLX: if (ps->o.glx_use_copysubbuffermesa) - glx_swap_copysubbuffermesa(ps, region); + glx_swap_copysubbuffermesa(ps, region_real); else glXSwapBuffers(ps->dpy, get_tgt_window(ps)); break; @@ -6551,7 +6555,7 @@ session_run(session_t *ps) { t = paint_preprocess(ps, ps->list); if (ps->redirected) - paint_all(ps, None, t); + paint_all(ps, None, None, t); // Initialize idling ps->idling = false; @@ -6587,10 +6591,13 @@ session_run(session_t *ps) { if (!ps->redirected) free_region(ps, &ps->all_damage); + XserverRegion all_damage_orig = None; + if (ps->o.resize_damage > 0) + all_damage_orig = copy_region(ps, ps->all_damage); resize_region(ps, ps->all_damage, ps->o.resize_damage); if (ps->all_damage && !is_region_empty(ps, ps->all_damage, NULL)) { static int paint = 0; - paint_all(ps, ps->all_damage, t); + paint_all(ps, ps->all_damage, all_damage_orig, t); ps->reg_ignore_expire = false; paint++; if (ps->o.benchmark && paint >= ps->o.benchmark) @@ -6598,6 +6605,7 @@ session_run(session_t *ps) { XSync(ps->dpy, False); ps->all_damage = None; } + free_region(ps, &all_damage_orig); if (ps->idling) ps->fade_time = 0L; diff --git a/src/compton.h b/src/compton.h index 6b23e1d5..b069620c 100644 --- a/src/compton.h +++ b/src/compton.h @@ -571,7 +571,7 @@ set_tgt_clip(session_t *ps, XserverRegion reg, const reg_data_t *pcache_reg) { } static void -paint_all(session_t *ps, XserverRegion region, win *t); +paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t); static void add_damage(session_t *ps, XserverRegion damage); diff --git a/src/opengl.c b/src/opengl.c index 4d6d6594..71017f7b 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -797,6 +797,18 @@ glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z, return false; } + int mdx = dx, mdy = dy, mwidth = width, mheight = height; + if (ps->o.resize_damage > 0) { + int inc_x = min_i(ps->o.resize_damage, XFixedToDouble(ps->o.blur_kern[0]) / 2), + inc_y = min_i(ps->o.resize_damage, XFixedToDouble(ps->o.blur_kern[1]) / 2); + mdx = max_i(dx - inc_x, 0); + mdy = max_i(dy - inc_y, 0); + int mdx2 = min_i(dx + width + inc_x, ps->root_width), + mdy2 = min_i(dy + height + inc_y, ps->root_height); + mwidth = mdx2 - mdx; + mheight = mdy2 - mdy; + } + GLenum tex_tgt = GL_TEXTURE_RECTANGLE; if (ps->glx_has_texture_non_power_of_two) tex_tgt = GL_TEXTURE_2D; @@ -807,11 +819,11 @@ glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z, glTexParameteri(tex_tgt, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(tex_tgt, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(tex_tgt, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(tex_tgt, 0, GL_RGB, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); - glCopyTexSubImage2D(tex_tgt, 0, 0, 0, dx, ps->root_height - dy - height, width, height); + glTexImage2D(tex_tgt, 0, GL_RGB, mwidth, mheight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + glCopyTexSubImage2D(tex_tgt, 0, 0, 0, mdx, ps->root_height - mdy - mheight, mwidth, mheight); #ifdef DEBUG_GLX - printf_dbgf("(): %d, %d, %d, %d\n", dx, ps->root_height - dy - height, width, height); + printf_dbgf("(): %d, %d, %d, %d\n", mdx, ps->root_height - mdy - mheight, mwidth, mheight); #endif // Paint it back @@ -824,9 +836,9 @@ glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z, #ifdef CONFIG_VSYNC_OPENGL_GLSL glUseProgram(ps->glx_prog_blur); if (ps->glx_prog_blur_unifm_offset_x >= 0) - glUniform1f(ps->glx_prog_blur_unifm_offset_x, 1.0f / width); + glUniform1f(ps->glx_prog_blur_unifm_offset_x, 1.0f / mwidth); if (ps->glx_prog_blur_unifm_offset_y >= 0) - glUniform1f(ps->glx_prog_blur_unifm_offset_y, 1.0f / height); + glUniform1f(ps->glx_prog_blur_unifm_offset_y, 1.0f / mheight); if (ps->glx_prog_blur_unifm_factor_center >= 0) glUniform1f(ps->glx_prog_blur_unifm_factor_center, factor_center); #endif @@ -834,10 +846,10 @@ glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z, { P_PAINTREG_START(); { - const GLfloat rx = (double) (crect.x - dx) / width; - const GLfloat ry = 1.0 - (double) (crect.y - dy) / height; - const GLfloat rxe = rx + (double) crect.width / width; - const GLfloat rye = ry - (double) crect.height / height; + const GLfloat rx = (double) (crect.x - mdx) / mwidth; + const GLfloat ry = 1.0 - (double) (crect.y - mdy) / mheight; + const GLfloat rxe = rx + (double) crect.width / mwidth; + const GLfloat rye = ry - (double) crect.height / mheight; const GLfloat rdx = crect.x; const GLfloat rdy = ps->root_height - crect.y; const GLfloat rdxe = rdx + crect.width;