mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 08:26:59 +00:00
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
This commit is contained in:
parent
67b723f5b7
commit
fe23b56f56
1 changed files with 21 additions and 7 deletions
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue