[weston,1/4] pixman,drm: do not composite previous damage

Submitted by Fabien Lahoudere on April 23, 2018, 8:29 a.m.

Details

Message ID 1524472161-3385-2-git-send-email-fabien.lahoudere@collabora.com
State Accepted
Commit acf50c3d96a5ab7b393a064e10b6e4affbd7236f
Headers show
Series "Optimize pixman renderer" ( rev: 1 ) in Wayland

Not browsing as part of any series.

Commit Message

Fabien Lahoudere April 23, 2018, 8:29 a.m.
From: Pekka Paalanen <pekka.paalanen@collabora.co.uk>

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>
---
 libweston/compositor-drm.c  | 16 ++++------------
 libweston/pixman-renderer.c | 35 ++++++++++++++++++++++++++++++-----
 libweston/pixman-renderer.h |  7 ++++++-
 3 files changed, 40 insertions(+), 18 deletions(-)

Patch hide | download patch | download mbox

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 23fd887..fa650c3 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1670,25 +1670,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 f7366cf..cf43b15 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 1b42f14..f19e147 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);