drm/qxl: reapply cursor after resetting primary
QXL associates mouse state with its primary plane. Destroying a primary plane and putting a new one in place has the side effect of destroying the cursor as well. This commit changes the driver to reapply the cursor any time a new primary is created. It achieves this by keeping a reference to the cursor bo on the qxl_crtc struct. This fix is very similar to commit4532b241a4
("drm/qxl: reapply cursor after SetCrtc calls") which got implicitly reverted as part of implementing the atomic modeset feature. Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Dave Airlie <airlied@redhat.com> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1512097 Fixes:1277eed5fe
("drm: qxl: Atomic phase 1: convert cursor to universal plane") Cc: stable@vger.kernel.org Signed-off-by: Ray Strode <rstrode@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Родитель
16c6db3688
Коммит
9428088c90
|
@ -289,6 +289,7 @@ static void qxl_crtc_destroy(struct drm_crtc *crtc)
|
|||
{
|
||||
struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc);
|
||||
|
||||
qxl_bo_unref(&qxl_crtc->cursor_bo);
|
||||
drm_crtc_cleanup(crtc);
|
||||
kfree(qxl_crtc);
|
||||
}
|
||||
|
@ -495,6 +496,53 @@ static int qxl_primary_atomic_check(struct drm_plane *plane,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int qxl_primary_apply_cursor(struct drm_plane *plane)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct qxl_device *qdev = dev->dev_private;
|
||||
struct drm_framebuffer *fb = plane->state->fb;
|
||||
struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc);
|
||||
struct qxl_cursor_cmd *cmd;
|
||||
struct qxl_release *release;
|
||||
int ret = 0;
|
||||
|
||||
if (!qcrtc->cursor_bo)
|
||||
return 0;
|
||||
|
||||
ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd),
|
||||
QXL_RELEASE_CURSOR_CMD,
|
||||
&release, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = qxl_release_list_add(release, qcrtc->cursor_bo);
|
||||
if (ret)
|
||||
goto out_free_release;
|
||||
|
||||
ret = qxl_release_reserve_list(release, false);
|
||||
if (ret)
|
||||
goto out_free_release;
|
||||
|
||||
cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
|
||||
cmd->type = QXL_CURSOR_SET;
|
||||
cmd->u.set.position.x = plane->state->crtc_x + fb->hot_x;
|
||||
cmd->u.set.position.y = plane->state->crtc_y + fb->hot_y;
|
||||
|
||||
cmd->u.set.shape = qxl_bo_physical_address(qdev, qcrtc->cursor_bo, 0);
|
||||
|
||||
cmd->u.set.visible = 1;
|
||||
qxl_release_unmap(qdev, release, &cmd->release_info);
|
||||
|
||||
qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
|
||||
qxl_release_fence_buffer_objects(release);
|
||||
|
||||
return ret;
|
||||
|
||||
out_free_release:
|
||||
qxl_release_free(qdev, release);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void qxl_primary_atomic_update(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_state)
|
||||
{
|
||||
|
@ -510,6 +558,7 @@ static void qxl_primary_atomic_update(struct drm_plane *plane,
|
|||
.x2 = qfb->base.width,
|
||||
.y2 = qfb->base.height
|
||||
};
|
||||
int ret;
|
||||
bool same_shadow = false;
|
||||
|
||||
if (old_state->fb) {
|
||||
|
@ -531,6 +580,11 @@ static void qxl_primary_atomic_update(struct drm_plane *plane,
|
|||
if (!same_shadow)
|
||||
qxl_io_destroy_primary(qdev);
|
||||
bo_old->is_primary = false;
|
||||
|
||||
ret = qxl_primary_apply_cursor(plane);
|
||||
if (ret)
|
||||
DRM_ERROR(
|
||||
"could not set cursor after creating primary");
|
||||
}
|
||||
|
||||
if (!bo->is_primary) {
|
||||
|
@ -571,6 +625,7 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane,
|
|||
struct drm_device *dev = plane->dev;
|
||||
struct qxl_device *qdev = dev->dev_private;
|
||||
struct drm_framebuffer *fb = plane->state->fb;
|
||||
struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc);
|
||||
struct qxl_release *release;
|
||||
struct qxl_cursor_cmd *cmd;
|
||||
struct qxl_cursor *cursor;
|
||||
|
@ -628,6 +683,10 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane,
|
|||
cmd->u.set.shape = qxl_bo_physical_address(qdev,
|
||||
cursor_bo, 0);
|
||||
cmd->type = QXL_CURSOR_SET;
|
||||
|
||||
qxl_bo_unref(&qcrtc->cursor_bo);
|
||||
qcrtc->cursor_bo = cursor_bo;
|
||||
cursor_bo = NULL;
|
||||
} else {
|
||||
|
||||
ret = qxl_release_reserve_list(release, true);
|
||||
|
|
|
@ -111,6 +111,8 @@ struct qxl_bo_list {
|
|||
struct qxl_crtc {
|
||||
struct drm_crtc base;
|
||||
int index;
|
||||
|
||||
struct qxl_bo *cursor_bo;
|
||||
};
|
||||
|
||||
struct qxl_output {
|
||||
|
|
Загрузка…
Ссылка в новой задаче