[RFC 3/7] drm/fb-helper: Support shadow buffer with deferred io
Noralf Trønnes
noralf at tronnes.org
Wed Jul 12 13:46:01 UTC 2017
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 at tronnes.org>
---
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
More information about the dri-devel
mailing list