[PATCH 09/17] drm/cirrus: Enable damage clipping on primary plane

Thomas Zimmermann tzimmermann at suse.de
Wed Feb 15 16:15:09 UTC 2023


Enable damage clipping on the primary plane and iterate over small
areas of reported framebuffer damage. Avoid the overhead of permanent
full-screen updates that cirrus currently implements.

This problem is indicated by the warning

  drm_plane_enable_fb_damage_clips() not called

in the kernel's log. Without damage clipping, drivers do full updates
of the screen area. This is costly as many screen updates, such as
cursor movement or command-line input, only change a small portion
of the output. Damage clipping allows renderers to inform drivers about
the changed areas.

With the damage information known, cirrus now iterates over a list of
change areas and only flushes those to the hardware's scanout buffer.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/tiny/cirrus.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c
index af26de9ef329..46c6aa34ba79 100644
--- a/drivers/gpu/drm/tiny/cirrus.c
+++ b/drivers/gpu/drm/tiny/cirrus.c
@@ -393,7 +393,8 @@ static void cirrus_primary_plane_helper_atomic_update(struct drm_plane *plane,
 	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
 	struct drm_framebuffer *fb = plane_state->fb;
 	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
-	struct drm_rect rect;
+	struct drm_atomic_helper_damage_iter iter;
+	struct drm_rect damage;
 	int idx;
 
 	if (!fb)
@@ -407,8 +408,10 @@ static void cirrus_primary_plane_helper_atomic_update(struct drm_plane *plane,
 	if (cirrus->pitch != cirrus_pitch(fb))
 		cirrus_pitch_set(cirrus, fb);
 
-	if (drm_atomic_helper_damage_merged(old_plane_state, plane_state, &rect))
-		cirrus_fb_blit_rect(fb, &shadow_plane_state->data[0], &rect);
+	drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
+	drm_atomic_for_each_plane_damage(&iter, &damage) {
+		cirrus_fb_blit_rect(fb, &shadow_plane_state->data[0], &damage);
+	}
 
 	drm_dev_exit(idx);
 }
@@ -529,6 +532,7 @@ static int cirrus_pipe_init(struct cirrus_device *cirrus)
 	if (ret)
 		return ret;
 	drm_plane_helper_add(primary_plane, &cirrus_primary_plane_helper_funcs);
+	drm_plane_enable_fb_damage_clips(primary_plane);
 
 	crtc = &cirrus->crtc;
 	ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL,
-- 
2.39.1



More information about the dri-devel mailing list