Skip to content

Commit

Permalink
drm/fb-helper: Clip damage area to written memory range
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Thomas Zimmermann committed Feb 10, 2022
1 parent 67b723f commit fe23b56
Showing 1 changed file with 21 additions and 7 deletions.
28 changes: 21 additions & 7 deletions drivers/gpu/drm/drm_fb_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit fe23b56

Please sign in to comment.