From 51b952fb460c0d5501eebce0af7f636661978ff2 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 9 Apr 2020 18:38:06 +0200 Subject: [PATCH] Switch to wlr_output_layer See [1]. [1]: https://github.com/swaywm/wlroots/pull/1985 --- backend/connector.c | 75 +++++++++++++++++++++++++++++++++++++++ include/backend/backend.h | 6 ++++ include/server.h | 2 +- include/surface.h | 2 +- output.c | 16 ++++----- xdg_shell.c | 18 +++++----- 6 files changed, 98 insertions(+), 21 deletions(-) diff --git a/backend/connector.c b/backend/connector.c index 5f97769..ab50640 100644 --- a/backend/connector.c +++ b/backend/connector.c @@ -56,6 +56,8 @@ static void connector_set_crtc(struct glider_drm_connector *conn, conn->crtc = crtc; conn->props[GLIDER_DRM_CONNECTOR_CRTC_ID].pending = crtc ? crtc->id : 0; + + // TODO: teardown and re-create all liftoff_layers } static bool connector_apply_props(struct glider_drm_connector *conn, @@ -81,6 +83,45 @@ static bool connector_commit(struct glider_drm_connector *conn, bool test_only) { struct wlr_output_state *pending = &conn->output.pending; + struct glider_drm_layer *layer; + uint32_t zpos = 1; + wl_list_for_each(layer, &pending->layers, base.pending.link) { + layer->base.accepted = false; + + liftoff_layer_set_property(layer->liftoff, "zpos", zpos); + + if (layer->base.pending.committed & WLR_OUTPUT_LAYER_STATE_BUFFER) { + struct wlr_buffer *wlr_buffer = layer->base.pending.buffer; + if (wlr_buffer == NULL) { + // TODO + } else { + if (!glider_drm_connector_attach(&conn->output, wlr_buffer, + layer->liftoff)) { + liftoff_layer_set_fb_composited(layer->liftoff); + } + liftoff_layer_set_property(layer->liftoff, + "CRTC_W", wlr_buffer->width); + liftoff_layer_set_property(layer->liftoff, + "CRTC_H", wlr_buffer->height); + liftoff_layer_set_property(layer->liftoff, "SRC_X", 0); + liftoff_layer_set_property(layer->liftoff, "SRC_Y", 0); + liftoff_layer_set_property(layer->liftoff, + "SRC_W", wlr_buffer->width << 16); + liftoff_layer_set_property(layer->liftoff, + "SRC_H", wlr_buffer->height << 16); + } + } + + if (layer->base.pending.committed & WLR_OUTPUT_LAYER_STATE_POSITION) { + liftoff_layer_set_property(layer->liftoff, + "CRTC_X", layer->base.pending.x); + liftoff_layer_set_property(layer->liftoff, + "CRTC_Y", layer->base.pending.y); + } + + zpos++; + } + uint32_t flags = 0; if (test_only) { flags |= DRM_MODE_ATOMIC_TEST_ONLY; @@ -147,6 +188,14 @@ static bool connector_commit(struct glider_drm_connector *conn, wlr_log(WLR_DEBUG, "Atomic commit failed: %s", strerror(-ret)); } + if (ret == 0) { + struct glider_drm_layer *layer; + wl_list_for_each(layer, &pending->layers, base.pending.link) { + layer->base.accepted = + liftoff_layer_get_plane_id(layer->liftoff) != 0; + } + } + if (flags & DRM_MODE_ATOMIC_TEST_ONLY) { return ret == 0; } @@ -208,11 +257,37 @@ static void output_destroy(struct wlr_output *output) { memset(&conn->output, 0, sizeof(struct wlr_output)); } +static struct wlr_output_layer *output_create_layer(struct wlr_output *output) { + struct glider_drm_connector *conn = get_drm_connector_from_output(output); + + struct glider_drm_layer *layer = calloc(1, sizeof(*layer)); + if (layer == NULL) { + return NULL; + } + wlr_output_layer_init(&layer->base, output); + + layer->liftoff = liftoff_layer_create(conn->crtc->liftoff_output); + if (layer->liftoff == NULL) { + free(layer); + return NULL; + } + + return &layer->base; +} + +static void output_destroy_layer(struct wlr_output_layer *wlr_layer) { + struct glider_drm_layer *layer = (struct glider_drm_layer *)wlr_layer; + liftoff_layer_destroy(layer->liftoff); + free(layer); +} + static const struct wlr_output_impl output_impl = { .attach_render = output_attach_render, .test = output_test, .commit = output_commit, .destroy = output_destroy, + .create_layer = output_create_layer, + .destroy_layer = output_destroy_layer, }; static uint32_t get_possible_crtcs(int drm_fd, drmModeConnector *conn) { diff --git a/include/backend/backend.h b/include/backend/backend.h index 899634b..7727678 100644 --- a/include/backend/backend.h +++ b/include/backend/backend.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "allocator.h" @@ -116,6 +117,11 @@ struct glider_drm_connector { size_t modes_len; }; +struct glider_drm_layer { + struct wlr_output_layer base; + struct liftoff_layer *liftoff; +}; + struct glider_drm_device { struct glider_drm_backend *backend; int fd; diff --git a/include/server.h b/include/server.h index 99d62f5..a8f9cfb 100644 --- a/include/server.h +++ b/include/server.h @@ -11,7 +11,7 @@ struct glider_output { struct liftoff_output *liftoff_output; struct wlr_buffer *bg_buffer; - struct liftoff_layer *bg_layer; + struct wlr_output_layer *bg_layer; struct glider_swapchain *swapchain; struct liftoff_layer *composition_layer; diff --git a/include/surface.h b/include/surface.h index 9dad189..5bbcd0e 100644 --- a/include/surface.h +++ b/include/surface.h @@ -6,7 +6,7 @@ struct glider_surface_output { struct glider_output *output; struct glider_surface *surface; - struct liftoff_layer *layer; + struct wlr_output_layer *layer; struct wl_list link; // glider_surface.outputs struct wl_listener destroy; diff --git a/output.c b/output.c index 08797a0..3f86943 100644 --- a/output.c +++ b/output.c @@ -27,7 +27,7 @@ static bool output_render_bg(struct glider_output *output, } static bool output_needs_render(struct glider_output *output) { - if (liftoff_layer_get_plane_id(output->bg_layer) == 0) { + if (!output->bg_layer->accepted) { return true; } @@ -35,7 +35,7 @@ static bool output_needs_render(struct glider_output *output) { wl_list_for_each(surface, &output->server->surfaces, link) { struct glider_surface_output *so = glider_surface_get_output(surface, output); - if (so != NULL && liftoff_layer_get_plane_id(so->layer) == 0) { + if (so != NULL && !so->layer->accepted) { return true; } } @@ -61,7 +61,7 @@ static bool output_render(struct glider_output *output, wl_list_for_each(surface, &output->server->surfaces, link) { struct glider_surface_output *so = glider_surface_get_output(surface, output); - if (so == NULL || liftoff_layer_get_plane_id(so->layer) != 0) { + if (so == NULL || so->layer->accepted) { continue; } @@ -152,7 +152,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { struct glider_output *output = wl_container_of(listener, output, destroy); wl_signal_emit(&output->events.destroy, NULL); wlr_buffer_drop(output->bg_buffer); - liftoff_layer_destroy(output->bg_layer); + wlr_output_layer_remove(output->bg_layer); glider_swapchain_destroy(output->swapchain); liftoff_layer_destroy(output->composition_layer); wl_list_remove(&output->destroy.link); @@ -248,8 +248,7 @@ void handle_new_output(struct wl_listener *listener, void *data) { liftoff_output_set_composition_layer(output->liftoff_output, output->composition_layer); - output->bg_layer = liftoff_layer_create(output->liftoff_output); - liftoff_layer_set_property(output->bg_layer, "zpos", 1); + output->bg_layer = wlr_output_layer_create(output->output); output->bg_buffer = glider_allocator_create_buffer(server->allocator, output->output->width, output->output->height, format); @@ -260,8 +259,5 @@ void handle_new_output(struct wl_listener *listener, void *data) { if (!output_render_bg(output, output->bg_buffer)) { return; } - if (!glider_output_attach_buffer(output, output->bg_buffer, - output->bg_layer)) { - return; - } + wlr_output_layer_attach_buffer(output->bg_layer, output->bg_buffer); } diff --git a/xdg_shell.c b/xdg_shell.c index 55e908c..490702b 100644 --- a/xdg_shell.c +++ b/xdg_shell.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "allocator.h" #include "server.h" #include "surface.h" @@ -11,7 +12,7 @@ static void surface_output_destroy(struct glider_surface_output *so) { } wl_list_remove(&so->link); wl_list_remove(&so->destroy.link); - liftoff_layer_destroy(so->layer); + wlr_output_layer_remove(so->layer); free(so); } @@ -36,18 +37,17 @@ static void handle_surface_destroy(struct wl_listener *listener, void *data) { static void handle_surface_commit(struct wl_listener *listener, void *data) { struct glider_surface *surface = wl_container_of(listener, surface, commit); - struct wlr_client_buffer *buffer = surface->wlr_surface->buffer; + struct wlr_client_buffer *client_buffer = surface->wlr_surface->buffer; - if (buffer == NULL) { - return; + struct wlr_buffer *buffer = NULL; + if (client_buffer != NULL) { + buffer = &client_buffer->base; } struct glider_surface_output *so; wl_list_for_each(so, &surface->outputs, link) { - liftoff_layer_set_fb_composited(so->layer); - liftoff_layer_set_property(so->layer, "zpos", 2); - - glider_output_attach_buffer(so->output, &buffer->base, so->layer); + wlr_output_layer_attach_buffer(so->layer, buffer); + // TODO: set zpos } } @@ -78,7 +78,7 @@ void handle_new_xdg_surface(struct wl_listener *listener, void *data) { struct glider_surface_output *so = calloc(1, sizeof(*so)); so->output = output; so->surface = surface; - so->layer = liftoff_layer_create(output->liftoff_output); + so->layer = wlr_output_layer_create(output->output); wl_list_insert(&surface->outputs, &so->link); so->destroy.notify = handle_output_destroy;