summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/qxl/qxl_draw.c
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2019-01-18 13:20:11 +0100
committerGerd Hoffmann <kraxel@redhat.com>2019-01-28 14:24:53 +0100
commit90adda2ce898c7a76d1a55d4650ade8cc957e54f (patch)
tree8ff81fbab03a1c28b2f93e1c88b4382036384e43 /drivers/gpu/drm/qxl/qxl_draw.c
parent4979904c62b9c0af492e679fb04f675ad5f238f2 (diff)
drm/qxl: cover all crtcs in shadow bo.
The qxl device supports only a single active framebuffer ("primary surface" in spice terminology). In multihead configurations are handled by defining rectangles within the primary surface for each head/crtc. Userspace which uses the qxl ioctl interface (xorg qxl driver) is aware of this limitation and will setup framebuffers and crtcs accordingly. Userspace which uses dumb framebuffers (xorg modesetting driver, wayland) is not aware of this limitation and tries to use two framebuffers (one for each crtc) instead. The qxl kms driver already has the dumb bo separated from the primary surface, by using a (shared) shadow bo as primary surface. This is needed to support pageflips without having to re-create the primary surface. The qxl driver will blit from the dumb bo to the shadow bo instead. So we can extend the shadow logic: Maintain a global shadow bo (aka primary surface), make it big enough that dumb bo's for all crtcs fit in side-by-side. Adjust the pageflip blits to place the heads next to each other in the shadow. With this patch in place multihead qxl works with wayland. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Noralf Trønnes <noralf@tronnes.org> Link: http://patchwork.freedesktop.org/patch/msgid/20190118122020.27596-15-kraxel@redhat.com
Diffstat (limited to 'drivers/gpu/drm/qxl/qxl_draw.c')
-rw-r--r--drivers/gpu/drm/qxl/qxl_draw.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_draw.c b/drivers/gpu/drm/qxl/qxl_draw.c
index c408bb83c7a9..5313ad21c1bb 100644
--- a/drivers/gpu/drm/qxl/qxl_draw.c
+++ b/drivers/gpu/drm/qxl/qxl_draw.c
@@ -267,7 +267,8 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev,
struct qxl_bo *bo,
unsigned int flags, unsigned int color,
struct drm_clip_rect *clips,
- unsigned int num_clips, int inc)
+ unsigned int num_clips, int inc,
+ uint32_t dumb_shadow_offset)
{
/*
* TODO: if flags & DRM_MODE_FB_DIRTY_ANNOTATE_FILL then we should
@@ -295,6 +296,9 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev,
if (ret)
return;
+ clips->x1 += dumb_shadow_offset;
+ clips->x2 += dumb_shadow_offset;
+
left = clips->x1;
right = clips->x2;
top = clips->y1;
@@ -342,7 +346,8 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev,
goto out_release_backoff;
ret = qxl_image_init(qdev, release, dimage, surface_base,
- left, top, width, height, depth, stride);
+ left - dumb_shadow_offset,
+ top, width, height, depth, stride);
qxl_bo_kunmap(bo);
if (ret)
goto out_release_backoff;