From bde255933eb4cd2bab2d310725ab5de39467b900 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 18 Jan 2018 19:47:21 +0100 Subject: [PATCH] output: add wlr_output::damage, fixes #572 --- backend/meson.build | 13 +++++++++++- include/wlr/types/wlr_output.h | 3 ++- render/meson.build | 2 +- rootston/output.c | 11 ++++------ types/wlr_output.c | 39 +++++++++++++++++++++++++++------- xcursor/wlr_xcursor.c | 1 - 6 files changed, 50 insertions(+), 19 deletions(-) diff --git a/backend/meson.build b/backend/meson.build index b8084448..9931f546 100644 --- a/backend/meson.build +++ b/backend/meson.build @@ -45,5 +45,16 @@ lib_wlr_backend = static_library( 'wlr_backend', backend_files, include_directories: wlr_inc, - dependencies: [wayland_server, egl, gbm, libinput, systemd, elogind, wlr_render, wlr_protos, drm], + dependencies: [ + wayland_server, + egl, + gbm, + libinput, + systemd, + elogind, + wlr_render, + wlr_protos, + drm, + pixman, + ], ) diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 71463cb5..f6a5ac84 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -2,6 +2,7 @@ #define WLR_TYPES_WLR_OUTPUT_H #include +#include #include #include @@ -51,8 +52,8 @@ struct wlr_output { float scale; enum wl_output_subpixel subpixel; enum wl_output_transform transform; - bool needs_swap; + pixman_region32_t damage; float transform_matrix[16]; // Note: some backends may have zero modes diff --git a/render/meson.build b/render/meson.build index 1eea9a83..309e83cd 100644 --- a/render/meson.build +++ b/render/meson.build @@ -22,7 +22,7 @@ lib_wlr_render = static_library( glapi[0], glapi[1], include_directories: wlr_inc, - dependencies: [glesv2, egl], + dependencies: [glesv2, egl, pixman], ) wlr_render = declare_dependency( diff --git a/rootston/output.c b/rootston/output.c index 6e3403fc..38ca7241 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -62,7 +62,6 @@ static void render_surface(struct wlr_surface *surface, goto render_subsurfaces; } - // TODO: do not render regions of the surface that aren't damaged // TODO: output scale, output transform support pixman_region32_t surface_damage; pixman_region32_init(&surface_damage); @@ -71,7 +70,7 @@ static void render_surface(struct wlr_surface *surface, pixman_region32_intersect(&surface_damage, &surface_damage, damage); bool damaged = pixman_region32_not_empty(&surface_damage); if (!damaged) { - goto finish_surface_damage; + goto surface_damage_finish; } float transform[16]; @@ -130,7 +129,7 @@ static void render_surface(struct wlr_surface *surface, wlr_surface_send_frame_done(surface, when); -finish_surface_damage: +surface_damage_finish: pixman_region32_fini(&surface_damage); render_subsurfaces:; @@ -272,14 +271,12 @@ static void render_output(struct roots_output *output) { struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); + pixman_region32_union(&output->damage, &output->damage, &wlr_output->damage); + pixman_region32_t damage; pixman_region32_init(&damage); pixman_region32_union(&damage, &output->damage, &output->previous_damage); - // TODO: use real wlr_output damage - if (wlr_output->needs_swap) { - output_damage_whole(output); - } // TODO: fullscreen if (!pixman_region32_not_empty(&output->damage)) { float hz = wlr_output->refresh / 1000.0f; diff --git a/types/wlr_output.c b/types/wlr_output.c index b47fb3a0..e55243ef 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -279,6 +279,7 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, wl_signal_init(&output->events.scale); wl_signal_init(&output->events.transform); wl_signal_init(&output->events.destroy); + pixman_region32_init(&output->damage); output->display_destroy.notify = handle_display_destroy; wl_display_add_destroy_listener(display, &output->display_destroy); @@ -292,6 +293,7 @@ void wlr_output_destroy(struct wlr_output *output) { wl_list_remove(&output->display_destroy.link); wlr_output_destroy_global(output); wlr_output_set_fullscreen_surface(output, NULL); + pixman_region32_fini(&output->damage); wl_signal_emit(&output->events.destroy, output); @@ -440,7 +442,7 @@ void wlr_output_swap_buffers(struct wlr_output *output) { } output->impl->swap_buffers(output); - output->needs_swap = false; + pixman_region32_clear(&output->damage); } void wlr_output_set_gamma(struct wlr_output *output, @@ -457,12 +459,17 @@ uint32_t wlr_output_get_gamma_size(struct wlr_output *output) { return output->impl->get_gamma_size(output); } +static void output_damage_whole(struct wlr_output *output) { + pixman_region32_union_rect(&output->damage, &output->damage, 0, 0, + output->width, output->height); +} + static void output_fullscreen_surface_reset(struct wlr_output *output) { if (output->fullscreen_surface != NULL) { wl_list_remove(&output->fullscreen_surface_commit.link); wl_list_remove(&output->fullscreen_surface_destroy.link); output->fullscreen_surface = NULL; - output->needs_swap = true; + output_damage_whole(output); } } @@ -470,7 +477,8 @@ static void output_fullscreen_surface_handle_commit( struct wl_listener *listener, void *data) { struct wlr_output *output = wl_container_of(listener, output, fullscreen_surface_commit); - output->needs_swap = true; + // TODO: use surface damage + output_damage_whole(output); } static void output_fullscreen_surface_handle_destroy( @@ -491,7 +499,7 @@ void wlr_output_set_fullscreen_surface(struct wlr_output *output, output_fullscreen_surface_reset(output); output->fullscreen_surface = surface; - output->needs_swap = true; + output_damage_whole(output); if (surface == NULL) { return; @@ -507,9 +515,16 @@ void wlr_output_set_fullscreen_surface(struct wlr_output *output, } +static void output_cursor_damage_whole(struct wlr_output_cursor *cursor) { + struct wlr_box box; + output_cursor_get_box(cursor, &box); + pixman_region32_union_rect(&cursor->output->damage, &cursor->output->damage, + box.x, box.y, box.width, box.height); +} + static void output_cursor_reset(struct wlr_output_cursor *cursor) { if (cursor->output->hardware_cursor != cursor) { - cursor->output->needs_swap = true; + output_cursor_damage_whole(cursor); } if (cursor->surface != NULL) { wl_list_remove(&cursor->surface_commit.link); @@ -543,7 +558,7 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, } wlr_log(L_DEBUG, "Falling back to software cursor"); - cursor->output->needs_swap = true; + output_cursor_damage_whole(cursor); cursor->enabled = pixels != NULL; if (!cursor->enabled) { @@ -602,7 +617,7 @@ static void output_cursor_commit(struct wlr_output_cursor *cursor) { cursor->height = cursor->surface->current->height * cursor->output->scale; if (cursor->output->hardware_cursor != cursor) { - cursor->output->needs_swap = true; + output_cursor_damage_whole(cursor); } else { // TODO: upload pixels @@ -677,6 +692,14 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, double x, double y) { + if (cursor->x == x && cursor->y == y) { + return true; + } + + if (cursor->output->hardware_cursor != cursor) { + output_cursor_damage_whole(cursor); + } + x *= cursor->output->scale; y *= cursor->output->scale; cursor->x = x; @@ -684,7 +707,7 @@ bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, output_cursor_update_visible(cursor); if (cursor->output->hardware_cursor != cursor) { - cursor->output->needs_swap = true; + output_cursor_damage_whole(cursor); return true; } diff --git a/xcursor/wlr_xcursor.c b/xcursor/wlr_xcursor.c index b1678223..2d1a38b5 100644 --- a/xcursor/wlr_xcursor.c +++ b/xcursor/wlr_xcursor.c @@ -24,7 +24,6 @@ */ #define _XOPEN_SOURCE 500 -#include #include #include #include