summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Paalanen <pekka.paalanen@collabora.co.uk>2018-04-23 11:44:56 +0200
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>2018-05-24 17:20:04 +0300
commitacf50c3d96a5ab7b393a064e10b6e4affbd7236f (patch)
tree283d21801ee2c391d3e406e6a20813ea4718a817
parent944fae8887642982473e1a541b8b37aef5c61d51 (diff)
downloadweston-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.c16
-rw-r--r--libweston/pixman-renderer.c35
-rw-r--r--libweston/pixman-renderer.h7
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);