diff --git a/include/picom/backend.h b/include/picom/backend.h index 38db10138b..74e6f1e4af 100644 --- a/include/picom/backend.h +++ b/include/picom/backend.h @@ -36,15 +36,7 @@ struct managed_win; struct ev_loop; struct backend_operations; -typedef struct backend_base { - struct backend_operations *ops; - struct x_connection *c; - struct ev_loop *loop; - - /// Whether the backend can accept new render request at the moment - bool busy; - // ... -} backend_t; +typedef struct backend_base backend_t; // This mimics OpenGL's ARB_robustness extension, which enables detection of GPU context // resets. @@ -475,6 +467,16 @@ struct backend_operations { enum device_status (*device_status)(backend_t *backend_data); }; +struct backend_base { + struct backend_operations ops; + struct x_connection *c; + struct ev_loop *loop; + + /// Whether the backend can accept new render request at the moment + bool busy; + // ... +}; + /// Register a new backend, `major` and `minor` should be the version of the picom backend /// interface. You should just pass `PICOM_BACKEND_MAJOR` and `PICOM_BACKEND_MINOR` here. /// `name` is the name of the backend, `init` is the function to initialize the backend, diff --git a/src/backend/backend.c b/src/backend/backend.c index f302788e4e..4204a8f0e0 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -117,22 +117,22 @@ bool backend_execute(struct backend_base *backend, image_handle target, unsigned continue; } succeeded = - backend->ops->blit(backend, cmd->origin, target, &cmd->blit); + backend->ops.blit(backend, cmd->origin, target, &cmd->blit); break; case BACKEND_COMMAND_COPY_AREA: if (!pixman_region32_not_empty(cmd->copy_area.region)) { continue; } - succeeded = backend->ops->copy_area(backend, cmd->origin, target, - cmd->copy_area.source_image, - cmd->copy_area.region); + succeeded = backend->ops.copy_area(backend, cmd->origin, target, + cmd->copy_area.source_image, + cmd->copy_area.region); break; case BACKEND_COMMAND_BLUR: if (!pixman_region32_not_empty(cmd->blur.target_mask)) { continue; } succeeded = - backend->ops->blur(backend, cmd->origin, target, &cmd->blur); + backend->ops.blur(backend, cmd->origin, target, &cmd->blur); break; case BACKEND_COMMAND_INVALID: default: assert(false); diff --git a/src/backend/backend_common.c b/src/backend/backend_common.c index 7863dde69c..4554964ae0 100644 --- a/src/backend/backend_common.c +++ b/src/backend/backend_common.c @@ -6,7 +6,6 @@ #include #include -#include "backend/backend.h" #include "backend/backend_common.h" #include "common.h" #include "config.h" @@ -413,7 +412,7 @@ void init_backend_base(struct backend_base *base, session_t *ps) { base->c = &ps->c; base->loop = ps->loop; base->busy = false; - base->ops = NULL; + base->ops = (struct backend_operations){}; } uint32_t backend_no_quirks(struct backend_base *base attr_unused) { diff --git a/src/backend/backend_common.h b/src/backend/backend_common.h index e9091cbeb5..0bab860763 100644 --- a/src/backend/backend_common.h +++ b/src/backend/backend_common.h @@ -7,15 +7,14 @@ #include -#include "backend.h" #include "config.h" -#include "region.h" struct session; struct win; struct conv; struct backend_base; struct backend_operations; +struct x_connection; struct dual_kawase_params { /// Number of downsample passes diff --git a/src/backend/driver.c b/src/backend/driver.c index 99ea4d7a3a..53ef1f5138 100644 --- a/src/backend/driver.c +++ b/src/backend/driver.c @@ -83,8 +83,8 @@ enum driver detect_driver(xcb_connection_t *c, backend_t *backend_data, xcb_wind free(randr_version); // If the backend supports driver detection, use that as well - if (backend_data && backend_data->ops->detect_driver) { - ret |= backend_data->ops->detect_driver(backend_data); + if (backend_data && backend_data->ops.detect_driver) { + ret |= backend_data->ops.detect_driver(backend_data); } return ret; } diff --git a/src/backend/dummy/dummy.c b/src/backend/dummy/dummy.c index 773dac598b..04ec3fff20 100644 --- a/src/backend/dummy/dummy.c +++ b/src/backend/dummy/dummy.c @@ -29,12 +29,12 @@ struct dummy_data { struct dummy_image back_buffer; }; -struct backend_operations dummy_ops; +const struct backend_operations dummy_ops; struct backend_base *dummy_init(session_t *ps attr_unused, xcb_window_t target attr_unused) { auto ret = ccalloc(1, struct dummy_data); init_backend_base(&ret->base, ps); - ret->base.ops = &dummy_ops; + ret->base.ops = dummy_ops; list_init_head(&ret->non_pixmap_images); return &ret->base; } @@ -216,7 +216,7 @@ static void dummy_version(struct backend_base * /*base*/, uint64_t *major, uint6 *minor = PICOM_BACKEND_DUMMY_MINOR; } -struct backend_operations dummy_ops = { +const struct backend_operations dummy_ops = { .apply_alpha = dummy_apply_alpha, .back_buffer = dummy_back_buffer, .blit = dummy_blit, diff --git a/src/backend/gl/egl.c b/src/backend/gl/egl.c index 4548eeb5c1..9b5dbbb2e5 100644 --- a/src/backend/gl/egl.c +++ b/src/backend/gl/egl.c @@ -4,8 +4,6 @@ */ #include -#include -#include #include #include #include @@ -105,7 +103,7 @@ static bool egl_set_swap_interval(int interval, EGLDisplay dpy) { return eglSwapInterval(dpy, interval); } -struct backend_operations egl_ops; +const struct backend_operations egl_ops; /** * Initialize OpenGL. */ @@ -154,7 +152,7 @@ static backend_t *egl_init(session_t *ps, xcb_window_t target) { eglext_init(gd->display); init_backend_base(&gd->gl.base, ps); - gd->gl.base.ops = &egl_ops; + gd->gl.base.ops = egl_ops; if (!eglext.has_EGL_KHR_image_pixmap) { log_error("EGL_KHR_image_pixmap not available."); goto end; @@ -355,7 +353,7 @@ static void egl_version(struct backend_base * /*base*/, uint64_t *major, uint64_ *minor = PICOM_BACKEND_EGL_MINOR; } -struct backend_operations egl_ops = { +const struct backend_operations egl_ops = { .apply_alpha = gl_apply_alpha, .back_buffer = gl_back_buffer, .blit = gl_blit, diff --git a/src/backend/gl/glx.c b/src/backend/gl/glx.c index 7fee1e2435..791f433bda 100644 --- a/src/backend/gl/glx.c +++ b/src/backend/gl/glx.c @@ -11,7 +11,6 @@ */ #include -#include #include #include #include @@ -31,7 +30,6 @@ #include "config.h" #include "log.h" #include "picom.h" -#include "region.h" #include "utils.h" #include "win.h" #include "x.h" @@ -225,7 +223,7 @@ static bool glx_set_swap_interval(int interval, Display *dpy, GLXDrawable drawab return vsync_enabled; } -struct backend_operations glx_ops; +const struct backend_operations glx_ops; /** * Initialize OpenGL. */ @@ -234,7 +232,7 @@ static backend_t *glx_init(session_t *ps, xcb_window_t target) { glxext_init(ps->c.dpy, ps->c.screen); auto gd = ccalloc(1, struct _glx_data); init_backend_base(&gd->gl.base, ps); - gd->gl.base.ops = &glx_ops; + gd->gl.base.ops = glx_ops; gd->target_win = target; @@ -529,7 +527,7 @@ static void glx_version(struct backend_base * /*base*/, uint64_t *major, uint64_ *minor = PICOM_BACKEND_GLX_MINOR; } -struct backend_operations glx_ops = { +const struct backend_operations glx_ops = { .apply_alpha = gl_apply_alpha, .back_buffer = gl_back_buffer, .bind_pixmap = glx_bind_pixmap, diff --git a/src/backend/xrender/xrender.c b/src/backend/xrender/xrender.c index 4ffb6fae77..e83c4bd146 100644 --- a/src/backend/xrender/xrender.c +++ b/src/backend/xrender/xrender.c @@ -865,7 +865,7 @@ static void xrender_get_blur_size(void *blur_context, int *width, int *height) { *width = ctx->resize_width; *height = ctx->resize_height; } -struct backend_operations xrender_ops; +const struct backend_operations xrender_ops; static backend_t *xrender_init(session_t *ps, xcb_window_t target) { if (ps->o.dithered_present) { log_warn("\"dithered-present\" is not supported by the xrender backend, " @@ -878,7 +878,7 @@ static backend_t *xrender_init(session_t *ps, xcb_window_t target) { auto xd = ccalloc(1, struct xrender_data); init_backend_base(&xd->base, ps); - xd->base.ops = &xrender_ops; + xd->base.ops = xrender_ops; for (int i = 0; i <= MAX_ALPHA; ++i) { double o = (double)i / (double)MAX_ALPHA; @@ -1032,7 +1032,7 @@ static void xrender_version(struct backend_base * /*base*/, uint64_t *major, uin *minor = PICOM_BACKEND_XRENDER_MINOR; } -struct backend_operations xrender_ops = { +const struct backend_operations xrender_ops = { .apply_alpha = xrender_apply_alpha, .back_buffer = xrender_back_buffer, .bind_pixmap = xrender_bind_pixmap, diff --git a/src/diagnostic.c b/src/diagnostic.c index aec78b0565..7cfac5cbde 100644 --- a/src/diagnostic.c +++ b/src/diagnostic.c @@ -51,11 +51,11 @@ void print_diagnostics(session_t *ps, const char *config_file, bool compositor_r printf(" Cannot initialize backend %s\n", backend_name(i)); continue; } - if (backend_data->ops->diagnostics) { + if (backend_data->ops.diagnostics) { printf("\n### Backend: %s\n\n", backend_name(i)); - backend_data->ops->diagnostics(backend_data); + backend_data->ops.diagnostics(backend_data); } - backend_data->ops->deinit(backend_data); + backend_data->ops.deinit(backend_data); } } diff --git a/src/picom.c b/src/picom.c index 10fda60345..35212e9dac 100644 --- a/src/picom.c +++ b/src/picom.c @@ -152,7 +152,7 @@ enum vblank_callback_action check_render_finish(struct vblank_event *e attr_unus struct timespec render_time; bool completed = - ps->backend_data->ops->last_render_time(ps->backend_data, &render_time); + ps->backend_data->ops.last_render_time(ps->backend_data, &render_time); if (!completed) { // Render hasn't completed yet, we can't start another render. // Check again at the next vblank. @@ -575,14 +575,14 @@ static void destroy_backend(session_t *ps) { HASH_ITER2(ps->shaders, shader) { if (shader->backend_shader != NULL) { - ps->backend_data->ops->destroy_shader(ps->backend_data, - shader->backend_shader); + ps->backend_data->ops.destroy_shader(ps->backend_data, + shader->backend_shader); shader->backend_shader = NULL; } } if (ps->backend_data && ps->root_image) { - ps->backend_data->ops->release_image(ps->backend_data, ps->root_image); + ps->backend_data->ops.release_image(ps->backend_data, ps->root_image); ps->root_image = NULL; } @@ -593,11 +593,11 @@ static void destroy_backend(session_t *ps) { } // deinit backend if (ps->backend_blur_context) { - ps->backend_data->ops->destroy_blur_context( + ps->backend_data->ops.destroy_blur_context( ps->backend_data, ps->backend_blur_context); ps->backend_blur_context = NULL; } - ps->backend_data->ops->deinit(ps->backend_data); + ps->backend_data->ops.deinit(ps->backend_data); ps->backend_data = NULL; } } @@ -635,7 +635,7 @@ static bool initialize_blur(session_t *ps) { enum backend_image_format format = ps->o.dithered_present ? BACKEND_IMAGE_FORMAT_PIXMAP_HIGH : BACKEND_IMAGE_FORMAT_PIXMAP; - ps->backend_blur_context = ps->backend_data->ops->create_blur_context( + ps->backend_blur_context = ps->backend_data->ops.create_blur_context( ps->backend_data, ps->o.blur_method, format, args); return ps->backend_blur_context != NULL; } @@ -674,14 +674,14 @@ static bool initialize_backend(session_t *ps) { } // Create shaders - if (!ps->backend_data->ops->create_shader && ps->shaders) { + if (!ps->backend_data->ops.create_shader && ps->shaders) { log_warn("Shaders are not supported by selected backend %s, " "they will be ignored", backend_name(ps->o.backend)); } else { HASH_ITER2(ps->shaders, shader) { assert(shader->backend_shader == NULL); - shader->backend_shader = ps->backend_data->ops->create_shader( + shader->backend_shader = ps->backend_data->ops.create_shader( ps->backend_data, shader->source); if (shader->backend_shader == NULL) { log_warn("Failed to create shader for shader " @@ -689,9 +689,9 @@ static bool initialize_backend(session_t *ps) { shader->key); } else { shader->attributes = 0; - if (ps->backend_data->ops->get_shader_attributes) { + if (ps->backend_data->ops.get_shader_attributes) { shader->attributes = - ps->backend_data->ops->get_shader_attributes( + ps->backend_data->ops.get_shader_attributes( ps->backend_data, shader->backend_shader); } @@ -719,7 +719,7 @@ static bool initialize_backend(session_t *ps) { // The old backends binds pixmap lazily, nothing to do here return true; err: - ps->backend_data->ops->deinit(ps->backend_data); + ps->backend_data->ops.deinit(ps->backend_data); ps->backend_data = NULL; quit(ps); return false; @@ -741,7 +741,7 @@ static void configure_root(session_t *ps) { // On root window changes if (!ps->o.use_legacy_backends) { assert(ps->backend_data); - has_root_change = ps->backend_data->ops->root_change != NULL; + has_root_change = ps->backend_data->ops.root_change != NULL; } else { // Old backend can handle root change has_root_change = true; @@ -788,7 +788,7 @@ static void configure_root(session_t *ps) { #endif if (has_root_change) { if (ps->backend_data != NULL) { - ps->backend_data->ops->root_change(ps->backend_data, ps); + ps->backend_data->ops.root_change(ps->backend_data, ps); } // Old backend's root_change is not a specific function } else { @@ -1082,7 +1082,7 @@ void root_damaged(session_t *ps) { if (ps->backend_data) { if (ps->root_image) { - ps->backend_data->ops->release_image(ps->backend_data, ps->root_image); + ps->backend_data->ops.release_image(ps->backend_data, ps->root_image); ps->root_image = NULL; } auto pixmap = x_get_root_back_pixmap(&ps->c, ps->atoms); @@ -1116,7 +1116,7 @@ void root_damaged(session_t *ps) { : x_get_visual_for_depth(ps->c.screen_info, r->depth); free(r); - ps->root_image = ps->backend_data->ops->bind_pixmap( + ps->root_image = ps->backend_data->ops.bind_pixmap( ps->backend_data, pixmap, x_get_visual_info(&ps->c, visual)); ps->root_image_generation += 1; if (!ps->root_image) { @@ -1421,7 +1421,7 @@ static bool redirect_start(session_t *ps) { if (!ps->o.use_legacy_backends) { assert(ps->backend_data); ps->damage_ring.count = - ps->backend_data->ops->max_buffer_age(ps->backend_data); + ps->backend_data->ops.max_buffer_age(ps->backend_data); ps->layout_manager = layout_manager_new((unsigned)ps->damage_ring.count); } else { ps->damage_ring.count = maximum_buffer_age(ps); @@ -1435,7 +1435,7 @@ static bool redirect_start(session_t *ps) { ps->frame_pacing = ps->o.frame_pacing && ps->o.vsync; if ((ps->o.use_legacy_backends || ps->o.benchmark || - !ps->backend_data->ops->last_render_time) && + !ps->backend_data->ops.last_render_time) && ps->frame_pacing) { // Disable frame pacing if we are using a legacy backend or if we are in // benchmark mode, or if the backend doesn't report render time diff --git a/src/renderer/renderer.c b/src/renderer/renderer.c index cb8f813f41..d8a4068046 100644 --- a/src/renderer/renderer.c +++ b/src/renderer/renderer.c @@ -69,19 +69,19 @@ static void renderer_reallocate_culled_masks(struct renderer *r, size_t capacity void renderer_free(struct backend_base *backend, struct renderer *r) { if (r->white_image) { - backend->ops->release_image(backend, r->white_image); + backend->ops.release_image(backend, r->white_image); } if (r->black_image) { - backend->ops->release_image(backend, r->black_image); + backend->ops.release_image(backend, r->black_image); } if (r->back_image) { - backend->ops->release_image(backend, r->back_image); + backend->ops.release_image(backend, r->back_image); } if (r->monitor_repaint_pixel) { - backend->ops->release_image(backend, r->monitor_repaint_pixel); + backend->ops.release_image(backend, r->monitor_repaint_pixel); } if (r->shadow_blur_context) { - backend->ops->destroy_blur_context(backend, r->shadow_blur_context); + backend->ops.destroy_blur_context(backend, r->shadow_blur_context); } if (r->shadow_kernel) { free_conv(r->shadow_kernel); @@ -97,7 +97,7 @@ void renderer_free(struct backend_base *backend, struct renderer *r) { } if (r->monitor_repaint_copy) { for (int i = 0; i < r->max_buffer_age; i++) { - backend->ops->release_image(backend, r->monitor_repaint_copy[i]); + backend->ops.release_image(backend, r->monitor_repaint_copy[i]); } free(r->monitor_repaint_copy); } @@ -109,21 +109,21 @@ static bool renderer_init(struct renderer *renderer, struct backend_base *backend, double shadow_radius, struct color shadow_color, bool dithered_present) { auto has_high_precision = - backend->ops->is_format_supported(backend, BACKEND_IMAGE_FORMAT_PIXMAP_HIGH); + backend->ops.is_format_supported(backend, BACKEND_IMAGE_FORMAT_PIXMAP_HIGH); renderer->format = has_high_precision && dithered_present ? BACKEND_IMAGE_FORMAT_PIXMAP_HIGH : BACKEND_IMAGE_FORMAT_PIXMAP; renderer->back_image = NULL; renderer->white_image = - backend->ops->new_image(backend, renderer->format, (ivec2){1, 1}); - if (!renderer->white_image || !backend->ops->clear(backend, renderer->white_image, - (struct color){1, 1, 1, 1})) { + backend->ops.new_image(backend, renderer->format, (ivec2){1, 1}); + if (!renderer->white_image || !backend->ops.clear(backend, renderer->white_image, + (struct color){1, 1, 1, 1})) { return false; } renderer->black_image = - backend->ops->new_image(backend, renderer->format, (ivec2){1, 1}); - if (!renderer->black_image || !backend->ops->clear(backend, renderer->black_image, - (struct color){0, 0, 0, 1})) { + backend->ops.new_image(backend, renderer->format, (ivec2){1, 1}); + if (!renderer->black_image || !backend->ops.clear(backend, renderer->black_image, + (struct color){0, 0, 0, 1})) { return false; } renderer->canvas_size = (ivec2){0, 0}; @@ -132,7 +132,7 @@ renderer_init(struct renderer *renderer, struct backend_base *backend, .size = (int)shadow_radius, .deviation = gaussian_kernel_std_for_size(shadow_radius, 0.5 / 256.0), }; - renderer->shadow_blur_context = backend->ops->create_blur_context( + renderer->shadow_blur_context = backend->ops.create_blur_context( backend, BLUR_METHOD_GAUSSIAN, BACKEND_IMAGE_FORMAT_MASK, &args); if (!renderer->shadow_blur_context) { log_error("Failed to create shadow blur context"); @@ -154,7 +154,7 @@ renderer_init(struct renderer *renderer, struct backend_base *backend, } sum_kernel_preprocess(renderer->shadow_kernel); } - renderer->max_buffer_age = backend->ops->max_buffer_age(backend) + 1; + renderer->max_buffer_age = backend->ops.max_buffer_age(backend) + 1; return true; } @@ -176,23 +176,23 @@ renderer_set_root_size(struct renderer *r, struct backend_base *backend, ivec2 r return true; } if (r->back_image) { - backend->ops->release_image(backend, r->back_image); + backend->ops.release_image(backend, r->back_image); } if (r->back_buffer_copy) { for (int i = 0; i < r->max_buffer_age; i++) { - backend->ops->release_image(backend, r->back_buffer_copy[i]); + backend->ops.release_image(backend, r->back_buffer_copy[i]); } free(r->back_buffer_copy); r->back_buffer_copy = NULL; } if (r->monitor_repaint_copy) { for (int i = 0; i < r->max_buffer_age; i++) { - backend->ops->release_image(backend, r->monitor_repaint_copy[i]); + backend->ops.release_image(backend, r->monitor_repaint_copy[i]); } free(r->monitor_repaint_copy); r->monitor_repaint_copy = NULL; } - r->back_image = backend->ops->new_image(backend, r->format, root_size); + r->back_image = backend->ops.new_image(backend, r->format, root_size); if (r->back_image != NULL) { r->canvas_size = root_size; return true; @@ -205,16 +205,16 @@ static bool renderer_bind_mask(struct renderer *r, struct backend_base *backend, struct managed_win *w) { ivec2 size = {.width = w->widthb, .height = w->heightb}; bool succeeded = false; - auto image = backend->ops->new_image(backend, BACKEND_IMAGE_FORMAT_MASK, size); - if (!image || !backend->ops->clear(backend, image, (struct color){0, 0, 0, 0})) { + auto image = backend->ops.new_image(backend, BACKEND_IMAGE_FORMAT_MASK, size); + if (!image || !backend->ops.clear(backend, image, (struct color){0, 0, 0, 0})) { log_error("Failed to create mask image"); goto err; } auto bound_region_local = win_get_bounding_shape_global_by_val(w); pixman_region32_translate(&bound_region_local, -w->g.x, -w->g.y); - succeeded = backend->ops->copy_area(backend, (ivec2){0, 0}, (image_handle)image, - r->white_image, &bound_region_local); + succeeded = backend->ops.copy_area(backend, (ivec2){0, 0}, (image_handle)image, + r->white_image, &bound_region_local); pixman_region32_fini(&bound_region_local); if (!succeeded) { log_error("Failed to fill the mask"); @@ -225,7 +225,7 @@ renderer_bind_mask(struct renderer *r, struct backend_base *backend, struct mana err: if (image != NULL) { - backend->ops->release_image(backend, image); + backend->ops.release_image(backend, image); } return succeeded; } @@ -243,11 +243,11 @@ image_handle renderer_shadow_from_mask(struct renderer *r, struct backend_base * // Apply the properties on the mask image and blit the result into a larger // image, each side larger by `2 * radius` so there is space for blurring. - normalized_mask_image = backend->ops->new_image( + normalized_mask_image = backend->ops.new_image( backend, BACKEND_IMAGE_FORMAT_MASK, (ivec2){mask_size.width + 2 * radius, mask_size.height + 2 * radius}); - if (!normalized_mask_image || !backend->ops->clear(backend, normalized_mask_image, - (struct color){0, 0, 0, 0})) { + if (!normalized_mask_image || !backend->ops.clear(backend, normalized_mask_image, + (struct color){0, 0, 0, 0})) { log_error("Failed to create mask image"); goto out; } @@ -276,8 +276,8 @@ image_handle renderer_shadow_from_mask(struct renderer *r, struct backend_base * pixman_region32_init_rect(&target_mask, radius, radius, (unsigned)mask_size.width, (unsigned)mask_size.height); - succeeded = backend->ops->blit(backend, (ivec2){radius, radius}, - normalized_mask_image, &args); + succeeded = backend->ops.blit(backend, (ivec2){radius, radius}, + normalized_mask_image, &args); pixman_region32_fini(&target_mask); if (!succeeded) { log_error("Failed to blit for shadow generation"); @@ -297,7 +297,7 @@ image_handle renderer_shadow_from_mask(struct renderer *r, struct backend_base * (unsigned)(mask_size.width + 2 * radius), (unsigned)(mask_size.height + 2 * radius)); succeeded = - backend->ops->blur(backend, (ivec2){0, 0}, normalized_mask_image, &args); + backend->ops.blur(backend, (ivec2){0, 0}, normalized_mask_image, &args); pixman_region32_fini(&target_mask); if (!succeeded) { log_error("Failed to blur for shadow generation"); @@ -306,19 +306,19 @@ image_handle renderer_shadow_from_mask(struct renderer *r, struct backend_base * } // Finally, we blit with this mask to colorize the shadow succeeded = false; - shadow_image = backend->ops->new_image( + shadow_image = backend->ops.new_image( backend, BACKEND_IMAGE_FORMAT_PIXMAP, (ivec2){mask_size.width + 2 * radius, mask_size.height + 2 * radius}); if (!shadow_image || - !backend->ops->clear(backend, shadow_image, (struct color){0, 0, 0, 0})) { + !backend->ops.clear(backend, shadow_image, (struct color){0, 0, 0, 0})) { log_error("Failed to allocate shadow image"); goto out; } shadow_color_pixel = - backend->ops->new_image(backend, BACKEND_IMAGE_FORMAT_PIXMAP, (ivec2){1, 1}); + backend->ops.new_image(backend, BACKEND_IMAGE_FORMAT_PIXMAP, (ivec2){1, 1}); if (!shadow_color_pixel || - !backend->ops->clear(backend, shadow_color_pixel, r->shadow_color)) { + !backend->ops.clear(backend, shadow_color_pixel, r->shadow_color)) { log_error("Failed to create shadow color image"); goto out; } @@ -348,19 +348,19 @@ image_handle renderer_shadow_from_mask(struct renderer *r, struct backend_base * }; pixman_region32_init_rect(&target_mask, 0, 0, (unsigned)shadow_size.width, (unsigned)shadow_size.height); - succeeded = backend->ops->blit(backend, (ivec2){0, 0}, shadow_image, &args); + succeeded = backend->ops.blit(backend, (ivec2){0, 0}, shadow_image, &args); pixman_region32_fini(&target_mask); out: if (normalized_mask_image) { - backend->ops->release_image(backend, normalized_mask_image); + backend->ops.release_image(backend, normalized_mask_image); } if (shadow_color_pixel) { - backend->ops->release_image(backend, shadow_color_pixel); + backend->ops.release_image(backend, shadow_color_pixel); } if (!succeeded && shadow_image) { log_error("Failed to draw shadow image"); - backend->ops->release_image(backend, shadow_image); + backend->ops.release_image(backend, shadow_image); shadow_image = NULL; } return shadow_image; @@ -368,7 +368,7 @@ image_handle renderer_shadow_from_mask(struct renderer *r, struct backend_base * static bool renderer_bind_shadow(struct renderer *r, struct backend_base *backend, struct managed_win *w) { - if (backend->ops->quirks(backend) & BACKEND_QUIRK_SLOW_BLUR) { + if (backend->ops.quirks(backend) & BACKEND_QUIRK_SLOW_BLUR) { xcb_pixmap_t shadow = XCB_NONE; xcb_render_picture_t pict = XCB_NONE; @@ -379,7 +379,7 @@ static bool renderer_bind_shadow(struct renderer *r, struct backend_base *backen auto visual = x_get_visual_for_standard(backend->c, XCB_PICT_STANDARD_ARGB_32); - w->shadow_image = backend->ops->bind_pixmap( + w->shadow_image = backend->ops.bind_pixmap( backend, shadow, x_get_visual_info(backend->c, visual)); } else { if (!w->mask_image && !renderer_bind_mask(r, backend, w)) { @@ -467,16 +467,16 @@ void renderer_ensure_images_ready(struct renderer *r, struct backend_base *backe bool monitor_repaint) { if (monitor_repaint) { if (!r->monitor_repaint_pixel) { - r->monitor_repaint_pixel = backend->ops->new_image( + r->monitor_repaint_pixel = backend->ops.new_image( backend, BACKEND_IMAGE_FORMAT_PIXMAP, (ivec2){1, 1}); BUG_ON(!r->monitor_repaint_pixel); - backend->ops->clear(backend, r->monitor_repaint_pixel, - (struct color){.alpha = 0.5, .red = 0.5}); + backend->ops.clear(backend, r->monitor_repaint_pixel, + (struct color){.alpha = 0.5, .red = 0.5}); } if (!r->monitor_repaint_copy) { r->monitor_repaint_copy = ccalloc(r->max_buffer_age, image_handle); for (int i = 0; i < r->max_buffer_age; i++) { - r->monitor_repaint_copy[i] = backend->ops->new_image( + r->monitor_repaint_copy[i] = backend->ops.new_image( backend, BACKEND_IMAGE_FORMAT_PIXMAP, (ivec2){.width = r->canvas_size.width, .height = r->canvas_size.height}); @@ -493,10 +493,10 @@ void renderer_ensure_images_ready(struct renderer *r, struct backend_base *backe if (global_debug_options.consistent_buffer_age && !r->back_buffer_copy) { r->back_buffer_copy = ccalloc(r->max_buffer_age, image_handle); for (int i = 0; i < r->max_buffer_age; i++) { - r->back_buffer_copy[i] = backend->ops->new_image( - backend, BACKEND_IMAGE_FORMAT_PIXMAP, - (ivec2){.width = r->canvas_size.width, - .height = r->canvas_size.height}); + r->back_buffer_copy[i] = + backend->ops.new_image(backend, BACKEND_IMAGE_FORMAT_PIXMAP, + (ivec2){.width = r->canvas_size.width, + .height = r->canvas_size.height}); BUG_ON(!r->back_buffer_copy[i]); } } @@ -554,19 +554,19 @@ bool renderer_render(struct renderer *r, struct backend_base *backend, pixman_region32_init(&damage_region); pixman_region32_copy(&damage_region, &screen_region); ivec2 blur_size = {}; - if (backend->ops->get_blur_size && blur_context) { - backend->ops->get_blur_size(blur_context, &blur_size.width, &blur_size.height); + if (backend->ops.get_blur_size && blur_context) { + backend->ops.get_blur_size(blur_context, &blur_size.width, &blur_size.height); } auto buffer_age = - (use_damage || monitor_repaint) ? backend->ops->buffer_age(backend) : 0; + (use_damage || monitor_repaint) ? backend->ops.buffer_age(backend) : 0; if (buffer_age > 0 && global_debug_options.consistent_buffer_age) { int past_frame = (r->frame_index + r->max_buffer_age - buffer_age) % r->max_buffer_age; region_t region; pixman_region32_init_rect(®ion, 0, 0, (unsigned)r->canvas_size.width, (unsigned)r->canvas_size.height); - backend->ops->copy_area(backend, (ivec2){}, backend->ops->back_buffer(backend), - r->back_buffer_copy[past_frame], ®ion); + backend->ops.copy_area(backend, (ivec2){}, backend->ops.back_buffer(backend), + r->back_buffer_copy[past_frame], ®ion); pixman_region32_fini(®ion); } if (buffer_age > 0 && (unsigned)buffer_age <= layout_manager_max_buffer_age(lm)) { @@ -595,17 +595,17 @@ bool renderer_render(struct renderer *r, struct backend_base *backend, xcb_sync_reset_fence(backend->c->c, xsync_fence)); } - if (backend->ops->prepare) { - backend->ops->prepare(backend, &layout->commands[0].target_mask); + if (backend->ops.prepare) { + backend->ops.prepare(backend, &layout->commands[0].target_mask); } if (monitor_repaint && buffer_age <= r->max_buffer_age) { // Restore the area of back buffer that was tainted by monitor repaint int past_frame = (r->frame_index + r->max_buffer_age - buffer_age) % r->max_buffer_age; - backend->ops->copy_area(backend, (ivec2){}, backend->ops->back_buffer(backend), - r->monitor_repaint_copy[past_frame], - &r->monitor_repaint_region[past_frame]); + backend->ops.copy_area(backend, (ivec2){}, backend->ops.back_buffer(backend), + r->monitor_repaint_copy[past_frame], + &r->monitor_repaint_region[past_frame]); } if (!backend_execute(backend, r->back_image, layout->number_of_commands, @@ -616,9 +616,9 @@ bool renderer_render(struct renderer *r, struct backend_base *backend, if (monitor_repaint) { // Keep a copy of un-tainted back image - backend->ops->copy_area(backend, (ivec2){}, - r->monitor_repaint_copy[r->frame_index], - r->back_image, &damage_region); + backend->ops.copy_area(backend, (ivec2){}, + r->monitor_repaint_copy[r->frame_index], + r->back_image, &damage_region); pixman_region32_copy(&r->monitor_repaint_region[r->frame_index], &damage_region); struct backend_blit_args blit = { @@ -631,24 +631,22 @@ bool renderer_render(struct renderer *r, struct backend_base *backend, .scale = SCALE_IDENTITY, }; log_trace("Blit for monitor repaint"); - backend->ops->blit(backend, (ivec2){}, r->back_image, &blit); + backend->ops.blit(backend, (ivec2){}, r->back_image, &blit); } - backend->ops->copy_area_quantize(backend, (ivec2){}, - backend->ops->back_buffer(backend), - r->back_image, &damage_region); + backend->ops.copy_area_quantize(backend, (ivec2){}, backend->ops.back_buffer(backend), + r->back_image, &damage_region); if (global_debug_options.consistent_buffer_age) { region_t region; pixman_region32_init_rect(®ion, 0, 0, (unsigned)r->canvas_size.width, (unsigned)r->canvas_size.height); - backend->ops->copy_area(backend, (ivec2){}, - r->back_buffer_copy[r->frame_index], - backend->ops->back_buffer(backend), ®ion); + backend->ops.copy_area(backend, (ivec2){}, r->back_buffer_copy[r->frame_index], + backend->ops.back_buffer(backend), ®ion); pixman_region32_fini(®ion); } - if (backend->ops->present && !backend->ops->present(backend)) { + if (backend->ops.present && !backend->ops.present(backend)) { log_warn("Failed to present the frame"); } diff --git a/src/win.c b/src/win.c index b935f64fe9..a44880d9be 100644 --- a/src/win.c +++ b/src/win.c @@ -331,7 +331,7 @@ static inline void win_release_pixmap(backend_t *base, struct managed_win *w) { assert(w->win_image); if (w->win_image) { xcb_pixmap_t pixmap = XCB_NONE; - pixmap = base->ops->release_image(base, w->win_image); + pixmap = base->ops.release_image(base, w->win_image); w->win_image = NULL; // Bypassing win_set_flags, because `w` might have been destroyed w->flags |= WIN_FLAGS_PIXMAP_NONE; @@ -345,7 +345,7 @@ static inline void win_release_shadow(backend_t *base, struct managed_win *w) { if (w->shadow_image) { assert(w->shadow); xcb_pixmap_t pixmap = XCB_NONE; - pixmap = base->ops->release_image(base, w->shadow_image); + pixmap = base->ops.release_image(base, w->shadow_image); w->shadow_image = NULL; if (pixmap != XCB_NONE) { xcb_free_pixmap(base->c->c, pixmap); @@ -356,7 +356,7 @@ static inline void win_release_shadow(backend_t *base, struct managed_win *w) { static inline void win_release_mask(backend_t *base, struct managed_win *w) { if (w->mask_image) { xcb_pixmap_t pixmap = XCB_NONE; - pixmap = base->ops->release_image(base, w->mask_image); + pixmap = base->ops.release_image(base, w->mask_image); w->mask_image = NULL; if (pixmap != XCB_NONE) { xcb_free_pixmap(base->c->c, pixmap); @@ -376,7 +376,7 @@ static inline bool win_bind_pixmap(struct backend_base *b, struct managed_win *w return false; } log_debug("New named pixmap for %#010x (%s) : %#010x", w->base.id, w->name, pixmap); - w->win_image = b->ops->bind_pixmap(b, pixmap, x_get_visual_info(b->c, w->a.visual)); + w->win_image = b->ops.bind_pixmap(b, pixmap, x_get_visual_info(b->c, w->a.visual)); if (!w->win_image) { log_error("Failed to bind pixmap"); xcb_free_pixmap(b->c->c, pixmap);