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");