diff options
author | Pekka Paalanen <pekka.paalanen@collabora.co.uk> | 2018-04-23 11:44:56 +0200 |
---|---|---|
committer | Pekka Paalanen <pekka.paalanen@collabora.co.uk> | 2018-05-24 17:20:04 +0300 |
commit | acf50c3d96a5ab7b393a064e10b6e4affbd7236f (patch) | |
tree | 283d21801ee2c391d3e406e6a20813ea4718a817 | |
parent | 944fae8887642982473e1a541b8b37aef5c61d51 (diff) | |
download | weston-acf50c3d96a5ab7b393a064e10b6e4affbd7236f.tar.gz weston-acf50c3d96a5ab7b393a064e10b6e4affbd7236f.tar.bz2 weston-acf50c3d96a5ab7b393a064e10b6e4affbd7236f.zip |
pixman,drm: do not composite previous damage
Pixman-renderer uses a single internal shadow buffer. It is enough to
composite the current damage into shadow, but the copy to hw buffer
needs to include the previous damage because of double-buffering in
DRM-backend.
This patch lets pixman-renderer do exactly that without compositing also
the previous damage on DRM-renderer.
Arguably weston_output should not have field previous_damage to begin
with, because it implies double-buffering, which e.g. EGL does not
guarantee. It would be better for each backend explicitly always provide
any extra damage that should be copied to hw.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Signed-off-by: Fabien Lahoudere <fabien.lahoudere@collabora.com>
Reviewed-by: Ian Ray <ian.ray@ge.com>
-rw-r--r-- | libweston/compositor-drm.c | 16 | ||||
-rw-r--r-- | libweston/pixman-renderer.c | 35 | ||||
-rw-r--r-- | libweston/pixman-renderer.h | 7 |
3 files changed, 40 insertions, 18 deletions
diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c index 287431eb..52b5dd70 100644 --- a/libweston/compositor-drm.c +++ b/libweston/compositor-drm.c @@ -1673,25 +1673,17 @@ drm_output_render_pixman(struct drm_output_state *state, { struct drm_output *output = state->output; struct weston_compositor *ec = output->base.compositor; - pixman_region32_t total_damage, previous_damage; - - pixman_region32_init(&total_damage); - pixman_region32_init(&previous_damage); - - pixman_region32_copy(&previous_damage, damage); - - pixman_region32_union(&total_damage, damage, &output->previous_damage); - pixman_region32_copy(&output->previous_damage, &previous_damage); output->current_image ^= 1; pixman_renderer_output_set_buffer(&output->base, output->image[output->current_image]); + pixman_renderer_output_set_hw_extra_damage(&output->base, + &output->previous_damage); - ec->renderer->repaint_output(&output->base, &total_damage); + ec->renderer->repaint_output(&output->base, damage); - pixman_region32_fini(&total_damage); - pixman_region32_fini(&previous_damage); + pixman_region32_copy(&output->previous_damage, damage); return drm_fb_ref(output->dumb[output->current_image]); } diff --git a/libweston/pixman-renderer.c b/libweston/pixman-renderer.c index f7366cf6..cf43b15d 100644 --- a/libweston/pixman-renderer.c +++ b/libweston/pixman-renderer.c @@ -41,6 +41,7 @@ struct pixman_output_state { void *shadow_buffer; pixman_image_t *shadow_image; pixman_image_t *hw_buffer; + pixman_region32_t *hw_extra_damage; }; struct pixman_surface_state { @@ -555,15 +556,29 @@ copy_to_hw_buffer(struct weston_output *output, pixman_region32_t *region) static void pixman_renderer_repaint_output(struct weston_output *output, - pixman_region32_t *output_damage) + pixman_region32_t *output_damage) { struct pixman_output_state *po = get_output_state(output); + pixman_region32_t hw_damage; - if (!po->hw_buffer) - return; + if (!po->hw_buffer) { + po->hw_extra_damage = NULL; + return; + } + + pixman_region32_init(&hw_damage); + if (po->hw_extra_damage) { + pixman_region32_union(&hw_damage, + po->hw_extra_damage, output_damage); + po->hw_extra_damage = NULL; + } else { + pixman_region32_copy(&hw_damage, output_damage); + } repaint_surfaces(output, output_damage); - copy_to_hw_buffer(output, output_damage); + + copy_to_hw_buffer(output, &hw_damage); + pixman_region32_fini(&hw_damage); pixman_region32_copy(&output->previous_damage, output_damage); wl_signal_emit(&output->frame_signal, output); @@ -862,7 +877,8 @@ pixman_renderer_init(struct weston_compositor *ec) } WL_EXPORT void -pixman_renderer_output_set_buffer(struct weston_output *output, pixman_image_t *buffer) +pixman_renderer_output_set_buffer(struct weston_output *output, + pixman_image_t *buffer) { struct pixman_output_state *po = get_output_state(output); @@ -876,6 +892,15 @@ pixman_renderer_output_set_buffer(struct weston_output *output, pixman_image_t * } } +WL_EXPORT void +pixman_renderer_output_set_hw_extra_damage(struct weston_output *output, + pixman_region32_t *extra_damage) +{ + struct pixman_output_state *po = get_output_state(output); + + po->hw_extra_damage = extra_damage; +} + WL_EXPORT int pixman_renderer_output_create(struct weston_output *output) { diff --git a/libweston/pixman-renderer.h b/libweston/pixman-renderer.h index 1b42f14f..f19e1477 100644 --- a/libweston/pixman-renderer.h +++ b/libweston/pixman-renderer.h @@ -34,7 +34,12 @@ int pixman_renderer_output_create(struct weston_output *output); void -pixman_renderer_output_set_buffer(struct weston_output *output, pixman_image_t *buffer); +pixman_renderer_output_set_buffer(struct weston_output *output, + pixman_image_t *buffer); + +void +pixman_renderer_output_set_hw_extra_damage(struct weston_output *output, + pixman_region32_t *extra_damage); void pixman_renderer_output_destroy(struct weston_output *output); |