From 142d10e591c0f349843f718d87b44c8ba2b33476 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 5 Nov 2021 12:26:38 +0100 Subject: [PATCH] output: add wlr_output_init_render Co-authored-by: Simon Zeni --- include/wlr/types/wlr_output.h | 14 +++++++++++ types/output/cursor.c | 25 ++++++------------- types/output/render.c | 45 +++++++++++++++++++++++++--------- 3 files changed, 55 insertions(+), 29 deletions(-) diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 17f48311..9d3dc3cb 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -182,6 +182,8 @@ struct wlr_output { struct wlr_buffer *cursor_front_buffer; int software_cursor_locks; // number of locks forcing software cursors + struct wlr_allocator *allocator; + struct wlr_renderer *renderer; struct wlr_swapchain *swapchain; struct wlr_buffer *back_buffer, *front_buffer; @@ -256,6 +258,18 @@ struct wlr_surface; void wlr_output_enable(struct wlr_output *output, bool enable); void wlr_output_create_global(struct wlr_output *output); void wlr_output_destroy_global(struct wlr_output *output); +/** + * Initialize the output's rendering subsystem with the provided allocator and + * renderer. Can only be called once. + * + * Call this function prior to any call to wlr_output_attach_render, + * wlr_output_commit or wlr_output_cursor_create. + * + * The buffer capabilities of the provided must match the capabilities of the + * output's backend. Returns false otherwise. + */ +bool wlr_output_init_render(struct wlr_output *output, + struct wlr_allocator *allocator, struct wlr_renderer *renderer); /** * Returns the preferred mode for this output. If the output doesn't support * modes, returns NULL. diff --git a/types/output/cursor.c b/types/output/cursor.c index 0a6cbb75..f1e6aee5 100644 --- a/types/output/cursor.c +++ b/types/output/cursor.c @@ -6,7 +6,6 @@ #include #include #include -#include "backend/backend.h" #include "render/allocator/allocator.h" #include "render/swapchain.h" #include "types/wlr_output.h" @@ -38,7 +37,7 @@ void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock) { } static void output_scissor(struct wlr_output *output, pixman_box32_t *rect) { - struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); + struct wlr_renderer *renderer = output->renderer; assert(renderer); struct wlr_box box = { @@ -71,8 +70,7 @@ static void output_cursor_get_box(struct wlr_output_cursor *cursor, static void output_cursor_render(struct wlr_output_cursor *cursor, pixman_region32_t *damage) { - struct wlr_renderer *renderer = - wlr_backend_get_renderer(cursor->output->backend); + struct wlr_renderer *renderer = cursor->output->renderer; assert(renderer); struct wlr_texture *texture = cursor->texture; @@ -195,7 +193,7 @@ static void output_cursor_update_visible(struct wlr_output_cursor *cursor) { } static struct wlr_drm_format *output_pick_cursor_format(struct wlr_output *output) { - struct wlr_allocator *allocator = backend_get_allocator(output->backend); + struct wlr_allocator *allocator = output->allocator; assert(allocator != NULL); const struct wlr_drm_format_set *display_formats = NULL; @@ -226,17 +224,9 @@ static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor) return NULL; } - struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); - if (renderer == NULL) { - wlr_log(WLR_ERROR, "Failed to get backend renderer"); - return NULL; - } - - struct wlr_allocator *allocator = backend_get_allocator(output->backend); - if (allocator == NULL) { - wlr_log(WLR_ERROR, "Failed to get backend allocator"); - return NULL; - } + struct wlr_allocator *allocator = output->allocator; + struct wlr_renderer *renderer = output->renderer; + assert(allocator != NULL && renderer != NULL); int width = texture->width; int height = texture->height; @@ -370,8 +360,7 @@ static bool output_cursor_attempt_hardware(struct wlr_output_cursor *cursor) { bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, int32_t hotspot_y) { - struct wlr_renderer *renderer = - wlr_backend_get_renderer(cursor->output->backend); + struct wlr_renderer *renderer = cursor->output->renderer; if (!renderer) { // if the backend has no renderer, we can't draw a cursor, but this is // actually okay, for ex. with the noop backend diff --git a/types/output/render.c b/types/output/render.c index b37b8ea1..2f6fe260 100644 --- a/types/output/render.c +++ b/types/output/render.c @@ -11,6 +11,30 @@ #include "render/wlr_renderer.h" #include "types/wlr_output.h" +bool wlr_output_init_render(struct wlr_output *output, + struct wlr_allocator *allocator, struct wlr_renderer *renderer) { + assert(output->allocator == NULL && allocator != NULL); + assert(output->renderer == NULL && renderer != NULL); + + uint32_t backend_caps = backend_get_buffer_caps(output->backend); + uint32_t renderer_caps = renderer_get_render_buffer_caps(renderer); + + if (!(backend_caps & allocator->buffer_caps)) { + wlr_log(WLR_ERROR, "output backend and allocator buffer capabilities " + "don't match"); + return false; + } else if (!(backend_caps & renderer_caps)) { + wlr_log(WLR_ERROR, "output backend and renderer buffer capabilities " + "don't match"); + return false; + } + + output->allocator = allocator; + output->renderer = renderer; + + return true; +} + /** * Ensure the output has a suitable swapchain. The swapchain is re-created if * necessary. @@ -29,11 +53,8 @@ static bool output_create_swapchain(struct wlr_output *output, return true; } - struct wlr_allocator *allocator = backend_get_allocator(output->backend); - if (allocator == NULL) { - wlr_log(WLR_ERROR, "Failed to get backend allocator"); - return false; - } + struct wlr_allocator *allocator = output->allocator; + assert(allocator != NULL); const struct wlr_drm_format_set *display_formats = NULL; if (output->impl->get_primary_formats) { @@ -80,7 +101,7 @@ static bool output_attach_back_buffer(struct wlr_output *output, return false; } - struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); + struct wlr_renderer *renderer = output->renderer; assert(renderer != NULL); struct wlr_buffer *buffer = @@ -103,7 +124,7 @@ void output_clear_back_buffer(struct wlr_output *output) { return; } - struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); + struct wlr_renderer *renderer = output->renderer; assert(renderer != NULL); renderer_bind_buffer(renderer, NULL); @@ -130,7 +151,7 @@ static bool output_attach_empty_buffer(struct wlr_output *output) { int width, height; output_pending_resolution(output, &width, &height); - struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); + struct wlr_renderer *renderer = output->renderer; wlr_renderer_begin(renderer, width, height); wlr_renderer_clear(renderer, (float[]){0, 0, 0, 0}); wlr_renderer_end(renderer); @@ -211,8 +232,8 @@ void wlr_output_lock_attach_render(struct wlr_output *output, bool lock) { struct wlr_drm_format *output_pick_format(struct wlr_output *output, const struct wlr_drm_format_set *display_formats) { - struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); - struct wlr_allocator *allocator = backend_get_allocator(output->backend); + struct wlr_renderer *renderer = output->renderer; + struct wlr_allocator *allocator = output->allocator; assert(renderer != NULL && allocator != NULL); const struct wlr_drm_format_set *render_formats = @@ -264,7 +285,9 @@ struct wlr_drm_format *output_pick_format(struct wlr_output *output, } uint32_t wlr_output_preferred_read_format(struct wlr_output *output) { - struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); + struct wlr_renderer *renderer = output->renderer; + assert(renderer != NULL); + if (!renderer->impl->preferred_read_format || !renderer->impl->read_pixels) { return DRM_FORMAT_INVALID; }