This patchset introduces kaiju to the wlr_scene API. Let me know if you want me to broke down into smaller hunks/commits. Pedro Lucas Porcellis (4): render: replace manual render logic with wlr_scene server: build wlr_scene graph during initialization view: update view to use wlr_scene API server: find view from scene node graph render.c | 130 +++---------------------------------------------------- server.c | 44 +++++++++++-------- server.h | 2 + view.c | 10 ++++- view.h | 1 + 5 files changed, 44 insertions(+), 143 deletions(-) -- 2.35.1
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~bl4ckb0ne/kaiju-dev/patches/31851/mbox | git am -3Learn more about email & git
--- render.c | 130 +++---------------------------------------------------- 1 file changed, 5 insertions(+), 125 deletions(-) diff --git a/render.c b/render.c index f868ca1..c6eaca7 100644 --- a/render.c +++ b/render.c @@ -20,137 +20,17 @@ struct render_data { struct timespec *when; }; -static void -render_surface(struct wlr_surface *surface, int x, int y, void *data) -{ - const struct render_data *rdata = data; - struct wlr_output *output = rdata->output; - - struct wlr_texture *texture = wlr_surface_get_texture(surface); - if (texture == NULL) - { - return; - } - - double ox = 0.0, oy = 0.0; - wlr_output_layout_output_coords(rdata->layout, output, &ox, &oy); - - ox += x + rdata->geometry->x; - oy += y + rdata->geometry->y; - - struct wlr_box box = { - .x = (int)(ox * (double)output->scale), - .y = (int)(oy * (double)output->scale), - .width = surface->current.width * (int)output->scale, - .height = surface->current.height * (int)output->scale, - }; - - enum wl_output_transform transform = wlr_output_transform_invert( - surface->current.transform); - - float matrix[9]; - wlr_matrix_project_box(matrix, &box, transform, 0, - output->transform_matrix); - - wlr_render_texture_with_matrix(rdata->renderer, texture, matrix, 1); - - wlr_surface_send_frame_done(surface, rdata->when); -} - -static void -render_view(struct kaiju_view *view, struct render_data *rdata) -{ - if (!view->mapped) { - return; - } - - wlr_xdg_surface_for_each_surface(view->wlr_xdg_surface, render_surface, - rdata); -} - -static void -render_views(struct wl_list *views, struct render_data *rdata) -{ - struct kaiju_view *view = NULL; - wl_list_for_each_reverse(view, views, link) { - struct wlr_box box = { - .x = view->x, - .y = view->y, - }; - kaiju_view_get_geometry(view, &box.width, &box.height); - rdata->geometry = &box; - render_view(view, rdata); - } -} - -static void -render_layer(struct kaiju_layer *layer, struct render_data *rdata) -{ - if (!layer->mapped) { - return; - } - - wlr_layer_surface_v1_for_each_surface(layer->wlr_layer_surface, - render_surface, rdata); -} - -static void -render_layers(struct wl_list *layers, struct render_data *rdata) -{ - struct kaiju_layer *layer = NULL; - wl_list_for_each(layer, layers, link) { - rdata->geometry = &layer->geometry; - render_layer(layer, rdata); - } -} - void kaiju_render_frame(struct kaiju_output *output) { - struct wlr_output *wlr_output = output->wlr_output; - - if (!wlr_output_attach_render(wlr_output, NULL)) { - return; - } + struct wlr_scene *scene = output->server->scene; - struct kaiju_server *server = output->server; - struct wlr_renderer *renderer = server->wlr_renderer; + struct wlr_scene_output *scene_output = wlr_scene_get_scene_output( + scene, output->wlr_output); - int width, height; - wlr_output_effective_resolution(wlr_output, &width, &height); + wlr_scene_output_commit(scene_output); struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); - - wlr_renderer_begin(renderer, width, height); - { - static const float color[4] = {0.22f, 0.24f, 0.33f, 1.0f}; - wlr_renderer_clear(renderer, color); - - struct render_data rdata = { - .renderer = renderer, - .output = wlr_output, - .layout = output->server->wlr_output_layout, - .when = &now, - }; - - render_layers(&server->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], - &rdata); - - render_views(&server->views, &rdata); - - render_layers(&server->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], - &rdata); - - render_layers(&server->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], - &rdata); - - render_layers(&server->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], - &rdata); - - wlr_output_render_software_cursors(wlr_output, NULL); - wlr_renderer_scissor(renderer, NULL); - } - wlr_renderer_end(renderer); - wlr_output_commit(wlr_output); + wlr_scene_output_send_frame_done(scene_output, &now); } -- 2.35.1
--- server.c | 15 ++++++++++++++- server.h | 2 ++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/server.c b/server.c index acaea16..235ff5d 100644 --- a/server.c +++ b/server.c @@ -105,10 +105,19 @@ new_xdg_surface_handler(struct wl_listener *listener, void *data) events.new_xdg_surface); struct wlr_xdg_surface *surface = data; - if (surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) { + if (surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { + struct wlr_xdg_surface *parent = + wlr_xdg_surface_from_wlr_surface(surface->popup->parent); + + struct wlr_scene_node *parent_node = parent->data; + surface->data = wlr_scene_xdg_surface_create(parent_node, + surface); + return; } + assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); + wlr_log(WLR_DEBUG, "New xdg surface %s", surface->toplevel->app_id); struct kaiju_view *view = kaiju_view_create(server, surface); @@ -160,6 +169,10 @@ kaiju_server_init(struct kaiju_server *server) server->wlr_output_layout = wlr_output_layout_create(); + server->scene = wlr_scene_create(); + wlr_scene_attach_output_layout(server->scene, + server->wlr_output_layout); + server->wlr_input_method_manager = wlr_input_method_manager_v2_create( server->wl_display); diff --git a/server.h b/server.h index 91e20ee..f8e9a4d 100644 --- a/server.h +++ b/server.h @@ -9,6 +9,7 @@ #include <wlr/types/wlr_data_device.h> #include <wlr/types/wlr_output_layout.h> #include <wlr/types/wlr_xdg_shell.h> +#include <wlr/types/wlr_scene.h> #include <wlr/types/wlr_layer_shell_v1.h> #include <wlr/types/wlr_virtual_keyboard_v1.h> #include <wlr/types/wlr_input_method_v2.h> @@ -23,6 +24,7 @@ struct kaiju_server { struct wl_display *wl_display; const char *socket; + struct wlr_scene *scene; struct wlr_backend *wlr_backend; struct wlr_renderer *wlr_renderer; struct wlr_allocator *wlr_allocator; -- 2.35.1
--- view.c | 10 +++++++++- view.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/view.c b/view.c index e12fc1f..ca4e074 100644 --- a/view.c +++ b/view.c @@ -32,6 +32,8 @@ kaiju_view_focus(struct kaiju_view *view) struct kaiju_server *server = view->server; struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat); + wlr_scene_node_raise_to_top(view->scene_node); + /* Move the view to the front */ wl_list_remove(&view->link); wl_list_insert(&server->views, &view->link); @@ -62,7 +64,6 @@ kaiju_view_position(struct kaiju_view *view) struct wlr_box *layout = wlr_output_layout_get_box( view->server->wlr_output_layout, NULL); - //if (view->wlr_xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) { if (!view->wlr_xdg_surface->toplevel->parent) { /* The parent view should occupy all the screen space */ view->x = layout->x; @@ -78,6 +79,7 @@ kaiju_view_position(struct kaiju_view *view) kaiju_view_get_geometry(view, &width, &height); view->x = (layout->width - width) / 2; view->y = (layout->height - height) / 2; + wlr_scene_node_set_position(view->scene_node, view->x, view->y); } } @@ -128,6 +130,12 @@ struct kaiju_view *kaiju_view_create(struct kaiju_server *server, view->server = server; view->wlr_xdg_surface = surface; + view->scene_node = wlr_scene_xdg_surface_create( + &view->server->scene->node, + view->wlr_xdg_surface); + + view->scene_node->data = view; + view->wlr_xdg_surface->data = view->scene_node; view->events.map.notify = view_map_handler; wl_signal_add(&surface->events.map, &view->events.map); diff --git a/view.h b/view.h index 5356b1c..b36a934 100644 --- a/view.h +++ b/view.h @@ -10,6 +10,7 @@ struct kaiju_server; struct kaiju_view { struct wlr_xdg_surface *wlr_xdg_surface; + struct wlr_scene_node *scene_node; bool mapped; int x, y; -- 2.35.1
--- server.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/server.c b/server.c index 235ff5d..f66d8b9 100644 --- a/server.c +++ b/server.c @@ -10,28 +10,25 @@ #include <wlr/util/log.h> #include <stdlib.h> +#include <assert.h> struct kaiju_view *kaiju_server_view_at(struct kaiju_server *server, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { - struct kaiju_view *view = NULL; - wl_list_for_each(view, &server->views, link) { - double view_sx = lx - view->x; - double view_sy = ly - view->y; - double tmp_sx, tmp_sy; - struct wlr_surface *tmp = wlr_xdg_surface_surface_at( - view->wlr_xdg_surface, view_sx, view_sy, - &tmp_sx, &tmp_sy); - - if (tmp != NULL) { - *surface = tmp; - *sx = tmp_sx; - *sy = tmp_sy; - return view; - } + struct wlr_scene_node *node = wlr_scene_node_at(&server->scene->node, + lx, ly, sx, sy); + + if (node == NULL || node->type != WLR_SCENE_NODE_SURFACE) { + return NULL; + } + + *surface = wlr_scene_surface_from_node(node)->surface; + + while (node != NULL && node->data == NULL) { + node = node->parent; } - return NULL; + return node->data; } bool -- 2.35.1