static int virtio_gpu_crtc_cursor_set(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 virtio_gpu_device *vgdev = crtc->dev->dev_private; struct virtio_gpu_output *output = container_of(crtc, struct virtio_gpu_output, crtc); struct drm_gem_object *gobj = NULL; struct virtio_gpu_object *qobj = NULL; struct virtio_gpu_fence *fence = NULL; int ret = 0; if (handle == 0) { virtio_gpu_hide_cursor(vgdev, output); return 0; } /* lookup the cursor */ gobj = drm_gem_object_lookup(crtc->dev, file_priv, handle); if (gobj == NULL) return -ENOENT; qobj = gem_to_virtio_gpu_obj(gobj); if (!qobj->hw_res_handle) { ret = -EINVAL; goto out; } virtio_gpu_cmd_transfer_to_host_2d(vgdev, qobj->hw_res_handle, 0, cpu_to_le32(64), cpu_to_le32(64), 0, 0, &fence); ret = virtio_gpu_object_reserve(qobj, false); if (!ret) { reservation_object_add_excl_fence(qobj->tbo.resv, &fence->f); fence_put(&fence->f); virtio_gpu_object_unreserve(qobj); virtio_gpu_object_wait(qobj, false); } output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_UPDATE_CURSOR); output->cursor.resource_id = cpu_to_le32(qobj->hw_res_handle); output->cursor.hot_x = cpu_to_le32(hot_x); output->cursor.hot_y = cpu_to_le32(hot_y); virtio_gpu_cursor_ping(vgdev, output); ret = 0; out: drm_gem_object_unreference_unlocked(gobj); return ret; }
void virtio_gpu_gem_object_close(struct drm_gem_object *obj, struct drm_file *file) { struct virtio_gpu_device *vgdev = obj->dev->dev_private; struct virtio_gpu_fpriv *vfpriv = file->driver_priv; struct virtio_gpu_object *qobj = gem_to_virtio_gpu_obj(obj); int r; if (!vgdev->has_virgl_3d) return; r = virtio_gpu_object_reserve(qobj, false); if (r) return; virtio_gpu_cmd_context_detach_resource(vgdev, vfpriv->ctx_id, qobj->hw_res_handle); virtio_gpu_object_unreserve(qobj); }