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