1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2025-03-10 17:16:30 -04:00

backend: gl: fix crash when shadow radius is 0

Fixes #927

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2022-11-17 22:07:59 +00:00
parent 7233601be3
commit e61b3ea7a3
No known key found for this signature in database
GPG key ID: D3A4405BE6CC17F4

View file

@ -1174,18 +1174,23 @@ struct gl_shadow_context {
struct backend_shadow_context *gl_create_shadow_context(backend_t *base, double radius) { struct backend_shadow_context *gl_create_shadow_context(backend_t *base, double radius) {
auto ctx = ccalloc(1, struct gl_shadow_context); auto ctx = ccalloc(1, struct gl_shadow_context);
ctx->radius = radius; ctx->radius = radius;
ctx->blur_context = NULL;
struct gaussian_blur_args args = { if (radius > 0) {
.size = (int)radius, struct gaussian_blur_args args = {
.deviation = gaussian_kernel_std_for_size(radius, 0.5 / 256.0), .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 = gl_create_blur_context(base, BLUR_METHOD_GAUSSIAN, &args);
}
return (struct backend_shadow_context *)ctx; return (struct backend_shadow_context *)ctx;
} }
void gl_destroy_shadow_context(backend_t *base attr_unused, 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; 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_); free(ctx_);
} }
@ -1246,27 +1251,32 @@ void *gl_shadow_from_mask(backend_t *base, void *mask,
gl_check_err(); gl_check_err();
glActiveTexture(GL_TEXTURE0); auto tmp_texture = source_texture;
auto tmp_texture = gl_new_texture(GL_TEXTURE_2D); if (gsctx->blur_context != NULL) {
glBindTexture(GL_TEXTURE_2D, tmp_texture); glActiveTexture(GL_TEXTURE0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, new_inner->width, new_inner->height, 0, tmp_texture = gl_new_texture(GL_TEXTURE_2D);
GL_RED, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, tmp_texture);
glBindTexture(GL_TEXTURE_2D, 0); 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); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
tmp_texture, 0); GL_TEXTURE_2D, tmp_texture, 0);
region_t reg_blur; region_t reg_blur;
pixman_region32_init_rect(&reg_blur, 0, 0, (unsigned int)new_inner->width, pixman_region32_init_rect(&reg_blur, 0, 0, (unsigned int)new_inner->width,
(unsigned int)new_inner->height); (unsigned int)new_inner->height);
// gl_blur expects reg_blur to be in X coordinate system (i.e. y flipped), but we // gl_blur expects reg_blur to be in X coordinate system (i.e. y flipped),
// are covering the whole texture so we don't need to worry about that. // but we are covering the whole texture so we don't need to worry about
gl_blur_impl(1.0, gsctx->blur_context, NULL, (coord_t){0}, &reg_blur, NULL, // that.
source_texture, gl_blur_impl(
(geometry_t){.width = new_inner->width, .height = new_inner->height}, 1.0, gsctx->blur_context, NULL, (coord_t){0}, &reg_blur, NULL,
fbo, gd->default_mask_texture); source_texture,
pixman_region32_fini(&reg_blur); (geometry_t){.width = new_inner->width, .height = new_inner->height},
fbo, gd->default_mask_texture);
pixman_region32_fini(&reg_blur);
}
// Colorize the shadow with color. // Colorize the shadow with color.
log_debug("Colorize shadow"); log_debug("Colorize shadow");
@ -1318,7 +1328,10 @@ void *gl_shadow_from_mask(backend_t *base, void *mask,
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(2, bo); 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); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbo); glDeleteFramebuffers(1, &fbo);
gl_check_err(); gl_check_err();