From 9d7cbe49f16cf33db378c73627a080c78182d5eb Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Tue, 15 Nov 2022 18:03:31 +0000 Subject: [PATCH 1/4] win: assert we won't clobber existing mask Signed-off-by: Yuxuan Shui --- src/win.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/win.c b/src/win.c index 370fbfd3d7..2525d89718 100644 --- a/src/win.c +++ b/src/win.c @@ -346,6 +346,7 @@ static inline bool win_bind_pixmap(struct backend_base *b, struct managed_win *w } bool win_bind_mask(struct backend_base *b, struct managed_win *w) { + assert(!w->mask_image); auto reg_bound_local = win_get_bounding_shape_global_by_val(w); pixman_region32_translate(®_bound_local, -w->g.x, -w->g.y); w->mask_image = b->ops->make_mask( From 7233601be3f1ba291d5fe2be3347c6f1003a6d0e Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Wed, 16 Nov 2022 15:39:17 +0000 Subject: [PATCH 2/4] Fix typo Fixes #922 Signed-off-by: Yuxuan Shui --- man/picom.1.asciidoc | 2 +- picom.sample.conf | 4 ++-- src/common.h | 4 ++-- src/options.c | 2 +- tests/configs/parsing_test.conf | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/man/picom.1.asciidoc b/man/picom.1.asciidoc index 7dc070f1d4..61af5a2c35 100644 --- a/man/picom.1.asciidoc +++ b/man/picom.1.asciidoc @@ -230,7 +230,7 @@ May also be one of the predefined kernels: `3x3box` (default), `5x5box`, `7x7box GLX backend: Avoid rebinding pixmap on window damage. Probably could improve performance on rapid window content changes, but is known to break things on some drivers (LLVMpipe, xf86-video-intel, etc.). Recommended if it works. *--no-use-damage*:: - Disable the use of damage information. This cause the whole screen to be redrawn everytime, instead of the part of the screen has actually changed. Potentially degrades the performance, but might fix some artifacts. + Disable the use of damage information. This cause the whole screen to be redrawn every time, instead of the part of the screen has actually changed. Potentially degrades the performance, but might fix some artifacts. *--xrender-sync-fence*:: Use X Sync fence to sync clients' draw calls, to make sure all draw calls are finished before picom starts drawing. Needed on nvidia-drivers with GLX backend for some users. diff --git a/picom.sample.conf b/picom.sample.conf index 071a9945df..a8ba5c7ede 100644 --- a/picom.sample.conf +++ b/picom.sample.conf @@ -308,7 +308,7 @@ detect-transient = true; # glx-no-rebind-pixmap = false # Disable the use of damage information. -# This cause the whole screen to be redrawn everytime, instead of the part of the screen +# This cause the whole screen to be redrawn every time, instead of the part of the screen # has actually changed. Potentially degrades the performance, but might fix some artifacts. # The opposing option is use-damage # @@ -409,7 +409,7 @@ log-level = "warn"; # transparent, and you want shadows in those areas. # # clip-shadow-above::: -# Controls wether shadows that would have been drawn above the window should +# Controls whether shadows that would have been drawn above the window should # be clipped. Useful for dock windows that should have no shadow painted on top. # # redir-ignore::: diff --git a/src/common.h b/src/common.h index c06a30c242..c77318765b 100644 --- a/src/common.h +++ b/src/common.h @@ -150,7 +150,7 @@ typedef struct session { /// Use an ev_idle callback for drawing /// So we only start drawing when events are processed ev_idle draw_idle; - /// Called everytime we have timeouts or new data on socket, + /// Called every time we have timeouts or new data on socket, /// so we can be sure if xcb read from X socket at anytime during event /// handling, we will not left any event unhandled in the queue ev_prepare event_check; @@ -240,7 +240,7 @@ typedef struct session { /// Whether we need to redraw the screen bool redraw_needed; - /// Cache a xfixes region so we don't need to allocate it everytime. + /// Cache a xfixes region so we don't need to allocate it every time. /// A workaround for yshui/picom#301 xcb_xfixes_region_t damaged_region; /// The region needs to painted on next paint. diff --git a/src/options.c b/src/options.c index ba7485dd59..0226714953 100644 --- a/src/options.c +++ b/src/options.c @@ -139,7 +139,7 @@ static const struct picom_option picom_options[] = { {"log-file" , required_argument, 322, NULL , "Path to the log file."}, {"use-damage" , no_argument , 323, NULL , "Render only the damaged (changed) part of the screen"}, {"no-use-damage" , no_argument , 324, NULL , "Disable the use of damage information. This cause the whole screen to be" - "redrawn everytime, instead of the part of the screen that has actually " + "redrawn every time, instead of the part of the screen that has actually " "changed. Potentially degrades the performance, but might fix some artifacts."}, {"no-vsync" , no_argument , 325, NULL , "Disable VSync"}, {"max-brightness" , required_argument, 326, NULL , "Dims windows which average brightness is above this threshold. Requires " diff --git a/tests/configs/parsing_test.conf b/tests/configs/parsing_test.conf index 5269e6e842..72360173a8 100644 --- a/tests/configs/parsing_test.conf +++ b/tests/configs/parsing_test.conf @@ -311,7 +311,7 @@ detect-transient = true; # glx-no-rebind-pixmap = false # Disable the use of damage information. -# This cause the whole screen to be redrawn everytime, instead of the part of the screen +# This cause the whole screen to be redrawn every time, instead of the part of the screen # has actually changed. Potentially degrades the performance, but might fix some artifacts. # The opposing option is use-damage # @@ -400,7 +400,7 @@ log-level = "warn"; # transparent, and you want shadows in those areas. # # clip-shadow-above::: -# Controls wether shadows that would have been drawn above the window should +# Controls whether shadows that would have been drawn above the window should # be clipped. Useful for dock windows that should have no shadow painted on top. # # redir-ignore::: From e61b3ea7a303f090c00b6bc88a6945ff76f89255 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Thu, 17 Nov 2022 22:07:59 +0000 Subject: [PATCH 3/4] backend: gl: fix crash when shadow radius is 0 Fixes #927 Signed-off-by: Yuxuan Shui --- src/backend/gl/gl_common.c | 71 ++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/src/backend/gl/gl_common.c b/src/backend/gl/gl_common.c index 88078e67ab..f4f277d265 100644 --- a/src/backend/gl/gl_common.c +++ b/src/backend/gl/gl_common.c @@ -1174,18 +1174,23 @@ struct gl_shadow_context { struct backend_shadow_context *gl_create_shadow_context(backend_t *base, double radius) { auto ctx = ccalloc(1, struct gl_shadow_context); ctx->radius = radius; - - struct gaussian_blur_args args = { - .size = (int)radius, - .deviation = gaussian_kernel_std_for_size(radius, 0.5 / 256.0), - }; - ctx->blur_context = gl_create_blur_context(base, BLUR_METHOD_GAUSSIAN, &args); + ctx->blur_context = NULL; + + if (radius > 0) { + struct gaussian_blur_args args = { + .size = (int)radius, + .deviation = gaussian_kernel_std_for_size(radius, 0.5 / 256.0), + }; + ctx->blur_context = gl_create_blur_context(base, BLUR_METHOD_GAUSSIAN, &args); + } return (struct backend_shadow_context *)ctx; } void gl_destroy_shadow_context(backend_t *base attr_unused, struct backend_shadow_context *ctx) { auto ctx_ = (struct gl_shadow_context *)ctx; - gl_destroy_blur_context(base, (struct backend_blur_context *)ctx_->blur_context); + if (ctx_->blur_context) { + gl_destroy_blur_context(base, (struct backend_blur_context *)ctx_->blur_context); + } free(ctx_); } @@ -1246,27 +1251,32 @@ void *gl_shadow_from_mask(backend_t *base, void *mask, gl_check_err(); - glActiveTexture(GL_TEXTURE0); - auto tmp_texture = gl_new_texture(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, tmp_texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, new_inner->width, new_inner->height, 0, - GL_RED, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, 0); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - tmp_texture, 0); - - region_t reg_blur; - pixman_region32_init_rect(®_blur, 0, 0, (unsigned int)new_inner->width, - (unsigned int)new_inner->height); - // gl_blur expects reg_blur to be in X coordinate system (i.e. y flipped), but we - // are covering the whole texture so we don't need to worry about that. - gl_blur_impl(1.0, gsctx->blur_context, NULL, (coord_t){0}, ®_blur, NULL, - source_texture, - (geometry_t){.width = new_inner->width, .height = new_inner->height}, - fbo, gd->default_mask_texture); - pixman_region32_fini(®_blur); + auto tmp_texture = source_texture; + if (gsctx->blur_context != NULL) { + glActiveTexture(GL_TEXTURE0); + tmp_texture = gl_new_texture(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, tmp_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, new_inner->width, + new_inner->height, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, 0); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, tmp_texture, 0); + + region_t reg_blur; + pixman_region32_init_rect(®_blur, 0, 0, (unsigned int)new_inner->width, + (unsigned int)new_inner->height); + // gl_blur expects reg_blur to be in X coordinate system (i.e. y flipped), + // but we are covering the whole texture so we don't need to worry about + // that. + gl_blur_impl( + 1.0, gsctx->blur_context, NULL, (coord_t){0}, ®_blur, NULL, + source_texture, + (geometry_t){.width = new_inner->width, .height = new_inner->height}, + fbo, gd->default_mask_texture); + pixman_region32_fini(®_blur); + } // Colorize the shadow with color. log_debug("Colorize shadow"); @@ -1318,7 +1328,10 @@ void *gl_shadow_from_mask(backend_t *base, void *mask, glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDeleteBuffers(2, bo); - glDeleteTextures(1, (GLuint[]){source_texture, tmp_texture}); + glDeleteTextures(1, (GLuint[]){source_texture}); + if (tmp_texture != source_texture) { + glDeleteTextures(1, (GLuint[]){tmp_texture}); + } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &fbo); gl_check_err(); From 706acb78b7c5a1236fa727292e83baf3d7803d1b Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Thu, 17 Nov 2022 22:16:27 +0000 Subject: [PATCH 4/4] backend: gl: handle blur context creation failure Signed-off-by: Yuxuan Shui --- src/backend/gl/gl_common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/backend/gl/gl_common.c b/src/backend/gl/gl_common.c index f4f277d265..a7d2aabce2 100644 --- a/src/backend/gl/gl_common.c +++ b/src/backend/gl/gl_common.c @@ -1182,6 +1182,11 @@ struct backend_shadow_context *gl_create_shadow_context(backend_t *base, double .deviation = gaussian_kernel_std_for_size(radius, 0.5 / 256.0), }; ctx->blur_context = gl_create_blur_context(base, BLUR_METHOD_GAUSSIAN, &args); + if (!ctx->blur_context) { + log_error("Failed to create shadow context"); + free(ctx); + return NULL; + } } return (struct backend_shadow_context *)ctx; }