swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit 87e5e78e2a7149a13c9d519688d8d874483215d5
parent 75b42b770d9ac621d3741e42fe46a5e7f1688ff5
Author: Michael Forney <mforney@mforney.org>
Date:   Fri,  6 Dec 2013 20:28:02 -0800

compositor: Better support for multiple outputs

Now, multiple outputs displaying the same region both get painted
correctly because each output keeps track of it's damage since it's last
refresh.

Diffstat:
Mlibswc/compositor.c | 72++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Mlibswc/output.c | 1+
Mlibswc/output.h | 2+-
3 files changed, 48 insertions(+), 27 deletions(-)

diff --git a/libswc/compositor.c b/libswc/compositor.c @@ -85,43 +85,49 @@ static void calculate_damage(struct swc_compositor * compositor) } static void repaint_output(struct swc_compositor * compositor, - struct swc_output * output) + struct swc_output * output, + pixman_region32_t * damage) { - pixman_region32_t damage, previous_damage, base_damage; + pixman_region32_t base_damage; - pixman_region32_init(&damage); - pixman_region32_init(&previous_damage); pixman_region32_init(&base_damage); - - pixman_region32_intersect_rect - (&damage, &compositor->damage, output->geometry.x, output->geometry.y, - output->geometry.width, output->geometry.height); - - /* We must save the damage from the previous frame because the back buffer - * is also damaged in this region. */ - pixman_region32_copy(&previous_damage, &output->previous_damage); - pixman_region32_copy(&output->previous_damage, &damage); - - /* The total damage is composed of the damage from the new frame, and the - * damage from the last frame. */ - pixman_region32_union(&damage, &damage, &previous_damage); - - pixman_region32_subtract(&base_damage, &damage, &compositor->opaque); + pixman_region32_subtract(&base_damage, damage, &compositor->opaque); swc_renderer_set_target(&compositor->renderer, &output->framebuffer_plane); - swc_renderer_repaint(&compositor->renderer, &damage, &base_damage, + swc_renderer_repaint(&compositor->renderer, damage, &base_damage, &compositor->surfaces); - pixman_region32_subtract(&compositor->damage, &compositor->damage, &damage); - - pixman_region32_fini(&damage); - pixman_region32_fini(&previous_damage); pixman_region32_fini(&base_damage); if (!swc_plane_flip(&output->framebuffer_plane)) fprintf(stderr, "Plane flip failed\n"); } +static void update_output_damage(struct swc_output * output, + pixman_region32_t * damage) +{ + pixman_region32_union + (&output->current_damage, &output->current_damage, damage); + pixman_region32_intersect_rect + (&output->current_damage, &output->current_damage, + output->geometry.x, output->geometry.y, + output->geometry.width, output->geometry.height); +} + +static void flush_output_damage(struct swc_output * output, + pixman_region32_t * damage) +{ + /* The total damage is composed of the damage from the new frame, and the + * damage from the last frame. */ + pixman_region32_union(damage, + &output->current_damage, &output->previous_damage); + + /* We must save the damage from the previous frame because the back buffer + * is also damaged in this region. */ + pixman_region32_copy(&output->previous_damage, &output->current_damage); + pixman_region32_clear(&output->current_damage); +} + static void perform_update(void * data) { struct swc_compositor * compositor = data; @@ -131,15 +137,29 @@ static void perform_update(void * data) if (updates) { + pixman_region32_t damage; + printf("performing update\n"); calculate_damage(compositor); + pixman_region32_init(&damage); wl_list_for_each(output, &compositor->outputs, link) { - if (updates & SWC_OUTPUT_MASK(output)) - repaint_output(compositor, output); + if (compositor->scheduled_updates & SWC_OUTPUT_MASK(output)) + { + update_output_damage(output, &compositor->damage); + + if (!(compositor->pending_flips & SWC_OUTPUT_MASK(output))) + { + flush_output_damage(output, &damage); + repaint_output(compositor, output, &damage); + } + } } + pixman_region32_fini(&damage); + /* XXX: Should assert that all damage was covered by some output */ + pixman_region32_clear(&compositor->damage); compositor->pending_flips |= updates; compositor->scheduled_updates &= ~updates; } diff --git a/libswc/output.c b/libswc/output.c @@ -64,6 +64,7 @@ bool swc_output_initialize(struct swc_output * output, struct swc_drm * drm, wl_list_init(&output->resources); wl_array_init(&output->modes); + pixman_region32_init(&output->current_damage); pixman_region32_init(&output->previous_damage); output->crtc_id = crtc_id; diff --git a/libswc/output.h b/libswc/output.h @@ -29,7 +29,7 @@ struct swc_output struct swc_plane framebuffer_plane; struct swc_plane cursor_plane; - pixman_region32_t previous_damage; + pixman_region32_t current_damage, previous_damage; /* The CRTC and connector we are using to drive this output */ uint32_t crtc_id;