diff options
author | Thomas Zimmermann <tzimmermann@suse.de> | 2022-02-09 17:16:16 +0100 |
---|---|---|
committer | Thomas Zimmermann <tzimmermann@suse.de> | 2022-02-10 14:49:21 +0100 |
commit | fe23b56f56532dcc5e49e83e20333b97919dec53 (patch) | |
tree | afc9c439ce658a1b71f3e3d8b8fb5d9585fbcc8f /drivers/gpu/drm/drm_fb_helper.c | |
parent | 67b723f5b74254d27962b1b59bddfee1584575ff (diff) | |
download | linux-fe23b56f56532dcc5e49e83e20333b97919dec53.tar.gz linux-fe23b56f56532dcc5e49e83e20333b97919dec53.tar.bz2 linux-fe23b56f56532dcc5e49e83e20333b97919dec53.zip |
drm/fb-helper: Clip damage area to written memory range
Write helpers used to mark the complete screen as dirty. This is
wasteful for writes that only change a small portion of the screen.
Fix the problem by computing the damaged area from the written
memory range and perform damage handling accordingly.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220209161617.3553-5-tzimmermann@suse.de
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 3d6d0b1464e7..4d5410dd96c5 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -754,11 +754,18 @@ EXPORT_SYMBOL(drm_fb_helper_sys_read); ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos) { + loff_t pos = *ppos; ssize_t ret; + struct drm_rect damage_area; ret = fb_sys_write(info, buf, count, ppos); - if (ret > 0) - drm_fb_helper_damage(info, 0, 0, info->var.xres, info->var.yres); + if (ret <= 0) + return ret; + + drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area); + drm_fb_helper_damage(info, damage_area.x1, damage_area.y1, + drm_rect_width(&damage_area), + drm_rect_height(&damage_area)); return ret; } @@ -2237,6 +2244,7 @@ static ssize_t drm_fbdev_fb_write(struct fb_info *info, const char __user *buf, loff_t pos = *ppos; size_t total_size; ssize_t ret; + struct drm_rect damage_area; int err = 0; if (info->screen_size) @@ -2265,13 +2273,19 @@ static ssize_t drm_fbdev_fb_write(struct fb_info *info, const char __user *buf, else ret = fb_write_screen_buffer(info, buf, count, pos); - if (ret > 0) - *ppos += ret; + if (ret < 0) + return ret; /* return last error, if any */ + else if (!ret) + return err; /* return previous error, if any */ - if (ret > 0) - drm_fb_helper_damage(info, 0, 0, info->var.xres_virtual, info->var.yres_virtual); + *ppos += ret; - return ret ? ret : err; + drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area); + drm_fb_helper_damage(info, damage_area.x1, damage_area.y1, + drm_rect_width(&damage_area), + drm_rect_height(&damage_area)); + + return ret; } static void drm_fbdev_fb_fillrect(struct fb_info *info, |