diff options
Diffstat (limited to 'qxl-reapply-cursor-after-SetCrtc-calls.patch')
-rw-r--r-- | qxl-reapply-cursor-after-SetCrtc-calls.patch | 439 |
1 files changed, 0 insertions, 439 deletions
diff --git a/qxl-reapply-cursor-after-SetCrtc-calls.patch b/qxl-reapply-cursor-after-SetCrtc-calls.patch deleted file mode 100644 index d70acc4eb..000000000 --- a/qxl-reapply-cursor-after-SetCrtc-calls.patch +++ /dev/null @@ -1,439 +0,0 @@ -From 92777b4dfc3920edb449d0be6ead65d8460653cc Mon Sep 17 00:00:00 2001 -From: Ray Strode <rstrode@redhat.com> -Date: Tue, 12 May 2015 12:51:18 -0400 -Subject: [PATCH] drm/qxl: reapply cursor after SetCrtc calls - -The qxl driver currently destroys and recreates the -qxl "primary" any time the first crtc is set. - -A side-effect of destroying the primary is mouse state -associated with the crtc is lost, which leads to -disappearing mouse cursors on wayland sessions. - -This commit changes the driver to reapply the cursor -any time SetCrtc is called. It achieves this by keeping -a copy of the cursor data on the qxl_crtc struct. - -Signed-off-by: Ray Strode <rstrode@redhat.com> - -https://bugzilla.redhat.com/show_bug.cgi?id=1200901 ---- - drivers/gpu/drm/qxl/qxl_display.c | 98 +++++++++++++++++++++++++++++++++++++++ - drivers/gpu/drm/qxl/qxl_drv.h | 1 + - 2 files changed, 99 insertions(+) - -diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c -index 3aef127..34ab444 100644 ---- a/drivers/gpu/drm/qxl/qxl_display.c -+++ b/drivers/gpu/drm/qxl/qxl_display.c -@@ -184,60 +184,61 @@ static struct mode_size { - {1440, 900}, - {1400, 1050}, - {1680, 1050}, - {1600, 1200}, - {1920, 1080}, - {1920, 1200} - }; - - static int qxl_add_common_modes(struct drm_connector *connector, - unsigned pwidth, - unsigned pheight) - { - struct drm_device *dev = connector->dev; - struct drm_display_mode *mode = NULL; - int i; - for (i = 0; i < ARRAY_SIZE(common_modes); i++) { - mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, - 60, false, false, false); - if (common_modes[i].w == pwidth && common_modes[i].h == pheight) - mode->type |= DRM_MODE_TYPE_PREFERRED; - drm_mode_probed_add(connector, mode); - } - return i - 1; - } - - static void qxl_crtc_destroy(struct drm_crtc *crtc) - { - struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc); - - drm_crtc_cleanup(crtc); -+ kfree(qxl_crtc->cursor); - kfree(qxl_crtc); - } - - static int qxl_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event, - uint32_t page_flip_flags) - { - struct drm_device *dev = crtc->dev; - struct qxl_device *qdev = dev->dev_private; - struct qxl_framebuffer *qfb_src = to_qxl_framebuffer(fb); - struct qxl_framebuffer *qfb_old = to_qxl_framebuffer(crtc->primary->fb); - struct qxl_bo *bo_old = gem_to_qxl_bo(qfb_old->obj); - struct qxl_bo *bo = gem_to_qxl_bo(qfb_src->obj); - unsigned long flags; - struct drm_clip_rect norect = { - .x1 = 0, - .y1 = 0, - .x2 = fb->width, - .y2 = fb->height - }; - int inc = 1; - int one_clip_rect = 1; - int ret = 0; - - crtc->primary->fb = fb; - bo_old->is_primary = false; - bo->is_primary = true; - - ret = qxl_bo_reserve(bo, false); -@@ -269,60 +270,145 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc, - return 0; - } - - static int - qxl_hide_cursor(struct qxl_device *qdev) - { - struct qxl_release *release; - struct qxl_cursor_cmd *cmd; - int ret; - - ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd), QXL_RELEASE_CURSOR_CMD, - &release, NULL); - if (ret) - return ret; - - ret = qxl_release_reserve_list(release, true); - if (ret) { - qxl_release_free(qdev, release); - return ret; - } - - cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); - cmd->type = QXL_CURSOR_HIDE; - 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 0; - } - -+static int qxl_crtc_stash_cursor(struct drm_crtc *crtc, -+ struct qxl_cursor *cursor) -+{ -+ struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); -+ size_t cursor_size; -+ -+ cursor_size = sizeof(struct qxl_cursor) + cursor->data_size; -+ -+ if (!qcrtc->cursor || qcrtc->cursor->data_size != cursor->data_size) { -+ kfree(qcrtc->cursor); -+ qcrtc->cursor = kmalloc(cursor_size, GFP_KERNEL); -+ -+ if (!qcrtc->cursor) -+ return -ENOMEM; -+ } -+ -+ memcpy(qcrtc->cursor, cursor, cursor_size); -+ -+ return 0; -+} -+ -+static int qxl_crtc_apply_cursor(struct drm_crtc *crtc) -+{ -+ struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); -+ struct drm_device *dev = crtc->dev; -+ struct qxl_device *qdev = dev->dev_private; -+ struct qxl_cursor *cursor; -+ struct qxl_cursor_cmd *cmd; -+ struct qxl_bo *cursor_bo; -+ struct qxl_release *release; -+ size_t cursor_size; -+ int ret = 0; -+ -+ if (!qcrtc->cursor) -+ return 0; -+ -+ cursor_size = sizeof(*qcrtc->cursor) + qcrtc->cursor->data_size; -+ -+ ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd), -+ QXL_RELEASE_CURSOR_CMD, -+ &release, NULL); -+ if (ret) -+ return ret; -+ -+ ret = qxl_alloc_bo_reserved(qdev, release, cursor_size, &cursor_bo); -+ if (ret) -+ goto out_free_release; -+ -+ ret = qxl_release_reserve_list(release, false); -+ if (ret) -+ goto out_free_bo; -+ -+ ret = qxl_bo_kmap(cursor_bo, (void **)&cursor); -+ if (ret) -+ goto out_backoff; -+ -+ memcpy(cursor, qcrtc->cursor, cursor_size); -+ -+ qxl_bo_kunmap(cursor_bo); -+ -+ cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); -+ cmd->type = QXL_CURSOR_SET; -+ cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x; -+ cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y; -+ -+ cmd->u.set.shape = qxl_bo_physical_address(qdev, 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); -+ qxl_bo_unref(&cursor_bo); -+ -+ return ret; -+ -+out_backoff: -+ qxl_release_backoff_reserve_list(release); -+out_free_bo: -+ qxl_bo_unref(&cursor_bo); -+out_free_release: -+ qxl_release_free(qdev, release); -+ return ret; -+} -+ - static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, - uint32_t height, int32_t hot_x, int32_t hot_y) - { - struct drm_device *dev = crtc->dev; - struct qxl_device *qdev = dev->dev_private; - struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); - struct drm_gem_object *obj; - struct qxl_cursor *cursor; - struct qxl_cursor_cmd *cmd; - struct qxl_bo *cursor_bo, *user_bo; - struct qxl_release *release; - void *user_ptr; - - int size = 64*64*4; - int ret = 0; - if (!handle) - return qxl_hide_cursor(qdev); - - obj = drm_gem_object_lookup(file_priv, handle); - if (!obj) { - DRM_ERROR("cannot find cursor object\n"); - return -ENOENT; - } - - user_bo = gem_to_qxl_bo(obj); - - ret = qxl_bo_reserve(user_bo, false); -@@ -343,60 +429,66 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, - &release, NULL); - if (ret) - goto out_kunmap; - - ret = qxl_alloc_bo_reserved(qdev, release, sizeof(struct qxl_cursor) + size, - &cursor_bo); - if (ret) - goto out_free_release; - - ret = qxl_release_reserve_list(release, false); - if (ret) - goto out_free_bo; - - ret = qxl_bo_kmap(cursor_bo, (void **)&cursor); - if (ret) - goto out_backoff; - - cursor->header.unique = 0; - cursor->header.type = SPICE_CURSOR_TYPE_ALPHA; - cursor->header.width = 64; - cursor->header.height = 64; - cursor->header.hot_spot_x = hot_x; - cursor->header.hot_spot_y = hot_y; - cursor->data_size = size; - cursor->chunk.next_chunk = 0; - cursor->chunk.prev_chunk = 0; - cursor->chunk.data_size = size; - - memcpy(cursor->chunk.data, user_ptr, size); - -+ ret = qxl_crtc_stash_cursor(crtc, cursor); -+ if (ret) { -+ DRM_ERROR("cannot save cursor, may be lost on next mode set\n"); -+ ret = 0; -+ } -+ - qxl_bo_kunmap(cursor_bo); - - qxl_bo_kunmap(user_bo); - - qcrtc->cur_x += qcrtc->hot_spot_x - hot_x; - qcrtc->cur_y += qcrtc->hot_spot_y - hot_y; - qcrtc->hot_spot_x = hot_x; - qcrtc->hot_spot_y = hot_y; - - cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); - cmd->type = QXL_CURSOR_SET; - cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x; - cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y; - - cmd->u.set.shape = qxl_bo_physical_address(qdev, 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); - - /* finish with the userspace bo */ - ret = qxl_bo_reserve(user_bo, false); - if (!ret) { - qxl_bo_unpin(user_bo); - qxl_bo_unreserve(user_bo); - } - drm_gem_object_unreference_unlocked(obj); - -@@ -628,60 +720,66 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, - x, y, - mode->hdisplay, mode->vdisplay, - adjusted_mode->hdisplay, - adjusted_mode->vdisplay); - - if (bo->is_primary == false) - recreate_primary = true; - - if (bo->surf.stride * bo->surf.height > qdev->vram_size) { - DRM_ERROR("Mode doesn't fit in vram size (vgamem)"); - return -EINVAL; - } - - ret = qxl_bo_reserve(bo, false); - if (ret != 0) - return ret; - ret = qxl_bo_pin(bo, bo->type, NULL); - if (ret != 0) { - qxl_bo_unreserve(bo); - return -EINVAL; - } - qxl_bo_unreserve(bo); - if (recreate_primary) { - qxl_io_destroy_primary(qdev); - qxl_io_log(qdev, - "recreate primary: %dx%d,%d,%d\n", - bo->surf.width, bo->surf.height, - bo->surf.stride, bo->surf.format); - qxl_io_create_primary(qdev, 0, bo); - bo->is_primary = true; -+ -+ ret = qxl_crtc_apply_cursor(crtc); -+ if (ret) { -+ DRM_ERROR("could not set cursor after modeset"); -+ ret = 0; -+ } - } - - if (bo->is_primary) { - DRM_DEBUG_KMS("setting surface_id to 0 for primary surface %d on crtc %d\n", bo->surface_id, qcrtc->index); - surf_id = 0; - } else { - surf_id = bo->surface_id; - } - - if (old_bo && old_bo != bo) { - old_bo->is_primary = false; - ret = qxl_bo_reserve(old_bo, false); - qxl_bo_unpin(old_bo); - qxl_bo_unreserve(old_bo); - } - - qxl_monitors_config_set(qdev, qcrtc->index, x, y, - mode->hdisplay, - mode->vdisplay, surf_id); - return 0; - } - - static void qxl_crtc_prepare(struct drm_crtc *crtc) - { - DRM_DEBUG("current: %dx%d+%d+%d (%d).\n", - crtc->mode.hdisplay, crtc->mode.vdisplay, - crtc->x, crtc->y, crtc->enabled); - } - - static void qxl_crtc_commit(struct drm_crtc *crtc) -diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h -index 8e633ca..6b63c54 100644 ---- a/drivers/gpu/drm/qxl/qxl_drv.h -+++ b/drivers/gpu/drm/qxl/qxl_drv.h -@@ -110,60 +110,61 @@ struct qxl_bo { - void *kptr; - int type; - - /* Constant after initialization */ - struct drm_gem_object gem_base; - bool is_primary; /* is this now a primary surface */ - bool hw_surf_alloc; - struct qxl_surface surf; - uint32_t surface_id; - struct qxl_release *surf_create; - }; - #define gem_to_qxl_bo(gobj) container_of((gobj), struct qxl_bo, gem_base) - #define to_qxl_bo(tobj) container_of((tobj), struct qxl_bo, tbo) - - struct qxl_gem { - struct mutex mutex; - struct list_head objects; - }; - - struct qxl_bo_list { - struct ttm_validate_buffer tv; - }; - - struct qxl_crtc { - struct drm_crtc base; - int index; - int cur_x; - int cur_y; - int hot_spot_x; - int hot_spot_y; -+ struct qxl_cursor *cursor; - }; - - struct qxl_output { - int index; - struct drm_connector base; - struct drm_encoder enc; - }; - - struct qxl_framebuffer { - struct drm_framebuffer base; - struct drm_gem_object *obj; - }; - - #define to_qxl_crtc(x) container_of(x, struct qxl_crtc, base) - #define drm_connector_to_qxl_output(x) container_of(x, struct qxl_output, base) - #define drm_encoder_to_qxl_output(x) container_of(x, struct qxl_output, enc) - #define to_qxl_framebuffer(x) container_of(x, struct qxl_framebuffer, base) - - struct qxl_mman { - struct ttm_bo_global_ref bo_global_ref; - struct drm_global_reference mem_global_ref; - bool mem_global_referenced; - struct ttm_bo_device bdev; - }; - - struct qxl_mode_info { - int num_modes; - struct qxl_mode *modes; - bool mode_config_initialized; - --- -2.7.4 - |