This adds support for using a shadow buffer for fbdev that is copied to the real buffer during dirty flushing. shmem buffers doesn't work with the fbdev deferred io functions, because it touches page->mapping and page->lru. Signed-off-by: Noralf Trønnes <noralf@xxxxxxxxxxx> --- drivers/gpu/drm/drm_fb_helper.c | 21 +++++++++++++++++++-- include/drm/drm_fb_helper.h | 8 ++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 721511d..d8b2690 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -739,8 +739,25 @@ static void drm_fb_helper_dirty_work(struct work_struct *work) spin_unlock_irqrestore(&helper->dirty_lock, flags); /* call dirty callback only when it has been really touched */ - if (clip_copy.x1 < clip_copy.x2 && clip_copy.y1 < clip_copy.y2) - helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1); + if (clip_copy.x1 > clip_copy.x2 || clip_copy.y1 > clip_copy.y2) + return; + + /* using shadow buffer? */ + if (helper->defio_vaddr) { + unsigned int pitch = helper->fb->pitches[0]; + u8 cpp = helper->fb->format->cpp[0]; + unsigned int y; + + for (y = clip_copy.y1; y < clip_copy.y2; y++) { + size_t offset = (y * pitch) + (clip_copy.x1 * cpp); + + memcpy(helper->defio_vaddr + offset, + helper->fbdev->screen_buffer + offset, + (clip_copy.x2 - clip_copy.x1) * cpp); + } + } + + helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1); } /** diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index ea170b9..159d5dd 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -203,6 +203,14 @@ struct drm_fb_helper { struct drm_clip_rect dirty_clip; spinlock_t dirty_lock; struct work_struct dirty_work; + /** + * @defio_vaddr: + * + * Destination address for shadowed and deferred framebuffer. If this + * is set, the dirty area is copied from &fb_info->screen_buffer to + * this address before calling &drm_framebuffer_funcs->dirty. + */ + void *defio_vaddr; struct work_struct resume_work; /** -- 2.7.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel