From c2f274ca8a880a24ce639382647cac854b64440d Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Wed, 20 Feb 2019 18:17:16 +0000 Subject: [PATCH] Fix some problems in new backend integration Fix several use of uninitialized/unallocated variables when using --experimental-backends Signed-off-by: Yuxuan Shui --- src/backend/backend_common.c | 18 +++++++++--------- src/backend/backend_common.h | 4 ++-- src/backend/xrender.c | 9 +++++++-- src/compton.c | 12 ++++++++++++ src/render.c | 8 -------- src/render.h | 2 ++ src/win.c | 14 ++++++++++++-- 7 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/backend/backend_common.c b/src/backend/backend_common.c index 632fe2a1..a46031e1 100644 --- a/src/backend/backend_common.c +++ b/src/backend/backend_common.c @@ -1,17 +1,17 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Yuxuan Shui #include -#include #include +#include #include #include "backend/backend.h" #include "backend/backend_common.h" -#include "kernel.h" #include "common.h" +#include "kernel.h" #include "log.h" -#include "x.h" #include "win.h" +#include "x.h" /** * Generate a 1x1 Picture of a particular color. @@ -54,8 +54,8 @@ solid_picture(session_t *ps, bool argb, double a, double r, double g, double b) return picture; } -xcb_image_t *make_shadow(xcb_connection_t *c, const conv *kernel, - double opacity, int width, int height) { +xcb_image_t * +make_shadow(xcb_connection_t *c, const conv *kernel, double opacity, int width, int height) { /* * We classify shadows into 4 kinds of regions * r = shadow radius @@ -71,6 +71,7 @@ xcb_image_t *make_shadow(xcb_connection_t *c, const conv *kernel, */ xcb_image_t *ximage; const double *shadow_sum = kernel->rsum; + assert(shadow_sum); // We only support square kernels for shadow assert(kernel->w == kernel->h); int d = kernel->w, r = d / 2; @@ -184,15 +185,14 @@ xcb_image_t *make_shadow(xcb_connection_t *c, const conv *kernel, * Generate shadow Picture for a window. */ bool build_shadow(session_t *ps, double opacity, const int width, const int height, - xcb_render_picture_t shadow_pixel, xcb_pixmap_t *pixmap, - xcb_render_picture_t *pict) { + const conv *kernel, xcb_render_picture_t shadow_pixel, + xcb_pixmap_t *pixmap, xcb_render_picture_t *pict) { xcb_image_t *shadow_image = NULL; xcb_pixmap_t shadow_pixmap = XCB_NONE, shadow_pixmap_argb = XCB_NONE; xcb_render_picture_t shadow_picture = XCB_NONE, shadow_picture_argb = XCB_NONE; xcb_gcontext_t gc = XCB_NONE; - shadow_image = - make_shadow(ps->c, ps->gaussian_map, opacity, width, height); + shadow_image = make_shadow(ps->c, kernel, opacity, width, height); if (!shadow_image) { log_error("Failed to make shadow"); return false; diff --git a/src/backend/backend_common.h b/src/backend/backend_common.h index b1ca6863..9f2f92a5 100644 --- a/src/backend/backend_common.h +++ b/src/backend/backend_common.h @@ -14,8 +14,8 @@ typedef struct win win; typedef struct conv conv; bool build_shadow(session_t *ps, double opacity, const int width, const int height, - xcb_render_picture_t shadow_pixel, xcb_pixmap_t *pixmap, - xcb_render_picture_t *pict); + const conv *kernel, xcb_render_picture_t shadow_pixel, + xcb_pixmap_t *pixmap, xcb_render_picture_t *pict); xcb_render_picture_t solid_picture(session_t *ps, bool argb, double a, double r, double g, double b); diff --git a/src/backend/xrender.c b/src/backend/xrender.c index 490036fe..0bd9ce66 100644 --- a/src/backend/xrender.c +++ b/src/backend/xrender.c @@ -20,6 +20,7 @@ #include "utils.h" #include "win.h" #include "x.h" +#include "kernel.h" #define auto __auto_type @@ -51,6 +52,8 @@ typedef struct _xrender_data { /// 1x1 picture of the shadow color xcb_render_picture_t shadow_pixel; + /// convolution kernel for the shadow + conv *shadow_kernel; /// Blur kernels converted to X format xcb_render_fixed_t *x_blur_kern[MAX_BLUR_PASS]; @@ -365,8 +368,8 @@ static void *prepare_win(void *backend_data, session_t *ps, win *w) { // leave this here until we have chance to re-think the backend API if (w->shadow) { xcb_pixmap_t pixmap; - build_shadow(ps, 1, w->widthb, w->heightb, xd->shadow_pixel, &pixmap, - &wd->shadow_pict); + build_shadow(ps, 1, w->widthb, w->heightb, xd->shadow_kernel, + xd->shadow_pixel, &pixmap, &wd->shadow_pict); xcb_free_pixmap(ps->c, pixmap); } return wd; @@ -396,6 +399,8 @@ static void *init(session_t *ps) { xd->white_pixel = solid_picture(ps, true, 1, 1, 1, 1); xd->shadow_pixel = solid_picture(ps, true, 1, ps->o.shadow_red, ps->o.shadow_green, ps->o.shadow_blue); + xd->shadow_kernel = gaussian_kernel(ps->o.shadow_radius); + sum_kernel_preprocess(xd->shadow_kernel); if (ps->overlay != XCB_NONE) { xd->target = x_create_picture_with_visual_and_pixmap( diff --git a/src/compton.c b/src/compton.c index d828fe07..440f2297 100644 --- a/src/compton.c +++ b/src/compton.c @@ -2645,6 +2645,18 @@ session_init(int argc, char **argv, Display *dpy, const char *config_file, exit(1); } + if (ps->o.experimental_backends) { + ps->ndamage = backend_list[ps->o.backend]->max_buffer_age; + } else { + ps->ndamage = maximum_buffer_age(ps); + } + ps->damage_ring = ccalloc(ps->ndamage, region_t); + ps->damage = ps->damage_ring + ps->ndamage - 1; + + for (int i = 0; i < ps->ndamage; i++) { + pixman_region32_init(&ps->damage_ring[i]); + } + if (ps->o.print_diagnostics) { print_diagnostics(ps, config_file); free(config_file_to_free); diff --git a/src/render.c b/src/render.c index a122eb74..8d28f264 100644 --- a/src/render.c +++ b/src/render.c @@ -1170,14 +1170,6 @@ bool init_render(session_t *ps) { return false; } } - - ps->ndamage = maximum_buffer_age(ps); - ps->damage_ring = ccalloc(ps->ndamage, region_t); - ps->damage = ps->damage_ring + ps->ndamage - 1; - - for (int i = 0; i < ps->ndamage; i++) { - pixman_region32_init(&ps->damage_ring[i]); - } return true; } diff --git a/src/render.h b/src/render.h index 85dff4a9..c05845de 100644 --- a/src/render.h +++ b/src/render.h @@ -42,3 +42,5 @@ void free_root_tile(session_t *ps); bool init_render(session_t *ps); void deinit_render(session_t *ps); + +int maximum_buffer_age(session_t *); diff --git a/src/win.c b/src/win.c index 1944032e..d75864b3 100644 --- a/src/win.c +++ b/src/win.c @@ -611,8 +611,18 @@ void calc_win_size(session_t *ps, win *w) { w->flags |= WFLAG_SIZE_CHANGE; // Invalidate the shadow we built if (ps->o.experimental_backends) { - backend_list[ps->o.backend]->release_win(ps->backend_data, ps, w, w->win_data); - w->win_data = backend_list[ps->o.backend]->prepare_win(ps->backend_data, ps, w); + if (w->state != WSTATE_UNMAPPED && w->state != WSTATE_MAPPED) { + // wrapping up fading + w->opacity = w->opacity_tgt; + win_check_fade_finished(ps, &w); + } + if (!w) { + return; + } + if (w->state == WSTATE_MAPPED) { + backend_list[ps->o.backend]->release_win(ps->backend_data, ps, w, w->win_data); + w->win_data = backend_list[ps->o.backend]->prepare_win(ps->backend_data, ps, w); + } } else { free_paint(ps, &w->shadow_paint); }