diff options
author | Thomas Zimmermann <tzimmermann@suse.de> | 2023-02-15 17:15:09 +0100 |
---|---|---|
committer | Thomas Zimmermann <tzimmermann@suse.de> | 2023-03-13 10:36:24 +0100 |
commit | 03e7ac67e743195633455d7ecb4f7327e3797986 (patch) | |
tree | e2215d1fdeb18fe90b7a179355a8165580c59f6f /drivers/gpu/drm/tiny/cirrus.c | |
parent | drm/cirrus: Convert to regular atomic helpers (diff) | |
download | linux-03e7ac67e743195633455d7ecb4f7327e3797986.tar.xz linux-03e7ac67e743195633455d7ecb4f7327e3797986.zip |
drm/cirrus: Enable damage clipping on primary plane
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@suse.de>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230215161517.5113-10-tzimmermann@suse.de
Diffstat (limited to 'drivers/gpu/drm/tiny/cirrus.c')
-rw-r--r-- | drivers/gpu/drm/tiny/cirrus.c | 10 |
1 files 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, |