tUse wlroots rendering API to paint output - spkp - Stacking wayland compositor
(HTM) git clone git://git.z3bra.org/spkp.git
(DIR) Log
(DIR) Files
(DIR) Refs
---
(DIR) commit e92e912c7ee178d472aecde1434b0069cf4a3254
(DIR) parent 44185c5c8a0c3d205c90a8ca42a5ab899b71a7a8
(HTM) Author: Willy Goiffon <dev@z3bra.org>
Date: Sun, 8 Nov 2020 00:03:22 +0100
Use wlroots rendering API to paint output
Diffstat:
M compositor.c | 64 +++++++++++++------------------
1 file changed, 26 insertions(+), 38 deletions(-)
---
(DIR) diff --git a/compositor.c b/compositor.c
t@@ -2,12 +2,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <wayland-server.h>
+
#include <wlr/backend.h>
-#include <wlr/render/egl.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_output.h>
-#include <wlr/types/wlr_output_damage.h>
-
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_data_control_v1.h>
#include <wlr/types/wlr_gamma_control_v1.h>
t@@ -22,19 +20,20 @@ struct state {
struct wl_display *dpy;
struct wl_event_loop *evloop;
struct wlr_backend *backend;
+ struct wlr_renderer *renderer;
+
struct wl_listener new_output;
+
struct wl_list outputs;
};
/* compositor output */
struct output {
- struct state *server; /* pointer to the containing struct */
-
+ struct state *server;
struct wlr_output *wlr_output;
- struct wlr_output_damage *damage;
struct wl_listener destroy;
- struct wl_listener damage_frame;
+ struct wl_listener frame;
/* pointer to the next output */
struct wl_list link;
t@@ -45,7 +44,7 @@ static void usage(char *);
/* callback functions triggered when a new event occur */
static void cb_new_output(struct wl_listener *, void *);
static void cb_destroy_output(struct wl_listener *, void *);
-static void cb_damage_frame(struct wl_listener *, void *);
+static void cb_frame_output(struct wl_listener *, void *);
void
usage(char *pgm)
t@@ -85,17 +84,16 @@ cb_new_output(struct wl_listener *listener, void *data)
output = calloc(1, sizeof(*output));
output->server = server;
output->wlr_output = wlr_output;
- output->damage = wlr_output_damage_create(wlr_output);
wl_list_insert(&server->outputs, &output->link);
/* setup callbacks for our output */
output->destroy.notify = cb_destroy_output;
- output->damage_frame.notify = cb_damage_frame;
+ output->frame.notify = cb_frame_output;
/* setup signals for above notifies */
wl_signal_add(&wlr_output->events.destroy, &output->destroy);
- wl_signal_add(&output->damage->events.frame, &output->damage_frame);
+ wl_signal_add(&wlr_output->events.frame, &output->frame);
wlr_output_create_global(wlr_output);
}
t@@ -112,52 +110,44 @@ cb_destroy_output(struct wl_listener *listener, void *data)
wl_list_remove(&output->link);
wl_list_remove(&output->destroy.link);
- wl_list_remove(&output->damage_frame.link);
+ wl_list_remove(&output->frame.link);
free(output);
}
/*
- * Output frame buffer was modified (damaged) since last render. Compute
- * the new buffer for rendering.
+ * Output is displaying a frame. This would be called 60 times per
+ * seconds on a 60Hz monitor.
*/
void
-cb_damage_frame(struct wl_listener *listener, void *data)
+cb_frame_output(struct wl_listener *listener, void *data)
{
- bool needs_frame;
struct output *output;
struct wlr_output *wlr_output;
struct wlr_renderer *renderer;
- pixman_region32_t damage;
- output = wl_container_of(listener, output, damage_frame);
+ output = wl_container_of(listener, output, frame);
wlr_output = output->wlr_output;
+ renderer = output->server->renderer;
if (!wlr_output->enabled)
return;
- renderer = wlr_backend_get_renderer(wlr_output->backend);
-
- /* create a damage buffer to render our frame */
- pixman_region32_init(&damage);
- wlr_output_damage_attach_render(output->damage, &needs_frame, &damage);
-
- if (!needs_frame) {
- wlr_output_rollback(wlr_output);
- pixman_region32_fini(&damage);
+ if (!wlr_output_attach_render(wlr_output, NULL))
return;
- }
- /* paint surface with the background color */
+ /* Update output resolution with current values */
+ wlr_output_effective_resolution(wlr_output, &wlr_output->width, &wlr_output->height);
+
+ /* Paint whole output surface with the background color */
wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
wlr_renderer_clear(renderer, background);
- wlr_renderer_end(renderer);
- /* apply damaged region on-screen */
- wlr_output_set_damage(wlr_output, &damage);
- pixman_region32_fini(&damage);
+ /* render cursor by software in case the GPU doesn't handle it */
+ wlr_output_render_software_cursors(wlr_output, NULL);
- /* commit output, if needed */
+ /* commit changes made to output */
+ wlr_renderer_end(renderer);
wlr_output_commit(wlr_output);
}
t@@ -177,12 +167,10 @@ main(int argc, char *argv[])
} ARGEND;
server.dpy = wl_display_create();
- assert(server.dpy);
server.evloop = wl_display_get_event_loop(server.dpy);
- assert(server.evloop);
server.backend = wlr_backend_autocreate(server.dpy, NULL);
- assert(server.backend);
+ server.renderer = wlr_backend_get_renderer(server.backend);
wl_list_init(&server.outputs);
t@@ -190,7 +178,7 @@ main(int argc, char *argv[])
wl_signal_add(&server.backend->events.new_output, &server.new_output);
socket = wl_display_add_socket_auto(server.dpy);
- assert(socket);
+ setenv("WAYLAND_DISPLAY", socket, 1);
if (!wlr_backend_start(server.backend)) {
fprintf(stderr, "Failed to start backend\n");