Commit b0e07da3 authored by Gerd Hoffmann's avatar Gerd Hoffmann

qxl: fix primary surface handling

The atomic conversion of the qxl driver didn't got the primary surface
handling completely right.  It works in the common simple cases, but
fails for example when changing the display resolution using xrandr or
in multihead setups.

The rules are simple:  There is one primary surface.  Before defining a
new one you have to destroy the old one.

This patch makes qxl_primary_atomic_update() destroy the primary surface
before defining a new one.  It fixes is_primary flag updates.  It adds
is_primary checks so we don't try to update the primary surface in case
it already has the state we want it being in.

Fixes: 3538e80a ("drm: qxl: Atomic phase 1: Implement mode_set_nofb")
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102338
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=196777Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Reviewed-by: default avatarGabriel Krisman Bertazi <krisman@collabora.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20170911093950.22401-1-kraxel@redhat.com
parent 79964dba
......@@ -512,23 +512,25 @@ static void qxl_primary_atomic_update(struct drm_plane *plane,
.y2 = qfb->base.height
};
if (!old_state->fb) {
qxl_io_log(qdev,
"create primary fb: %dx%d,%d,%d\n",
bo->surf.width, bo->surf.height,
bo->surf.stride, bo->surf.format);
if (old_state->fb) {
qfb_old = to_qxl_framebuffer(old_state->fb);
bo_old = gem_to_qxl_bo(qfb_old->obj);
} else {
bo_old = NULL;
}
qxl_io_create_primary(qdev, 0, bo);
bo->is_primary = true;
if (bo == bo_old)
return;
} else {
qfb_old = to_qxl_framebuffer(old_state->fb);
bo_old = gem_to_qxl_bo(qfb_old->obj);
if (bo_old && bo_old->is_primary) {
qxl_io_destroy_primary(qdev);
bo_old->is_primary = false;
}
bo->is_primary = true;
if (!bo->is_primary) {
qxl_io_create_primary(qdev, 0, bo);
bo->is_primary = true;
}
qxl_draw_dirty_fb(qdev, qfb, bo, 0, 0, &norect, 1, 1);
}
......@@ -537,13 +539,15 @@ static void qxl_primary_atomic_disable(struct drm_plane *plane,
{
struct qxl_device *qdev = plane->dev->dev_private;
if (old_state->fb)
{ struct qxl_framebuffer *qfb =
if (old_state->fb) {
struct qxl_framebuffer *qfb =
to_qxl_framebuffer(old_state->fb);
struct qxl_bo *bo = gem_to_qxl_bo(qfb->obj);
qxl_io_destroy_primary(qdev);
bo->is_primary = false;
if (bo->is_primary) {
qxl_io_destroy_primary(qdev);
bo->is_primary = false;
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment