blob: 6b5c73b21ca10e7673db993be83febc70b864ed0 [file] [log] [blame]
Gerd Hoffmanna3e22262010-08-25 15:32:06 +02001/*
2 * Copyright (C) 2010 Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 or
7 * (at your option) version 3 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <spice/ipc_ring.h>
19#include <spice/enums.h>
20#include <spice/qxl_dev.h>
21
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010022#include "qemu/thread.h"
Paolo Bonzini28ecbae2012-11-28 12:06:30 +010023#include "ui/qemu-pixman.h"
Peter Maydell0b087862013-01-21 12:03:47 +000024#include "ui/console.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010025#include "sysemu/sysemu.h"
Gerd Hoffmanna3e22262010-08-25 15:32:06 +020026
Gerd Hoffmann474114b2015-10-13 15:39:34 +020027#if defined(CONFIG_OPENGL_DMABUF)
Michal Privoznik9f5c6d02016-02-24 13:42:18 +010028# if SPICE_SERVER_VERSION >= 0x000d01 /* release 0.13.1 */
Gerd Hoffmann474114b2015-10-13 15:39:34 +020029# define HAVE_SPICE_GL 1
30# include "ui/egl-helpers.h"
31# include "ui/egl-context.h"
32# endif
33#endif
34
Gerd Hoffmanna3e22262010-08-25 15:32:06 +020035#define NUM_MEMSLOTS 8
36#define MEMSLOT_GENERATION_BITS 8
37#define MEMSLOT_SLOT_BITS 8
38
39#define MEMSLOT_GROUP_HOST 0
40#define MEMSLOT_GROUP_GUEST 1
41#define NUM_MEMSLOTS_GROUPS 2
42
Alon Levy5ff4e362011-07-20 12:20:58 +030043/*
44 * Internal enum to differenciate between options for
45 * io calls that have a sync (old) version and an _async (new)
46 * version:
47 * QXL_SYNC: use the old version
48 * QXL_ASYNC: use the new version and make sure there are no two
49 * happening at the same time. This is used for guest initiated
50 * calls
51 */
52typedef enum qxl_async_io {
53 QXL_SYNC,
54 QXL_ASYNC,
55} qxl_async_io;
56
Alon Levy2e1a98c2012-02-24 23:19:30 +020057enum {
58 QXL_COOKIE_TYPE_IO,
Alon Levy81fb6f12012-02-24 23:19:31 +020059 QXL_COOKIE_TYPE_RENDER_UPDATE_AREA,
Alon Levy020af1c2012-08-22 11:16:25 +030060 QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
Gerd Hoffmann474114b2015-10-13 15:39:34 +020061 QXL_COOKIE_TYPE_GL_DRAW_DONE,
Alon Levy2e1a98c2012-02-24 23:19:30 +020062};
63
64typedef struct QXLCookie {
65 int type;
66 uint64_t io;
67 union {
68 uint32_t surface_id;
Alon Levy81fb6f12012-02-24 23:19:31 +020069 QXLRect area;
70 struct {
71 QXLRect area;
72 int redraw;
73 } render;
Gerd Hoffmann39414ef2016-02-03 13:55:00 +010074 void *data;
Alon Levy2e1a98c2012-02-24 23:19:30 +020075 } u;
76} QXLCookie;
77
78QXLCookie *qxl_cookie_new(int type, uint64_t io);
79
Gerd Hoffmanne0c64d02011-04-27 15:21:51 +020080typedef struct SimpleSpiceDisplay SimpleSpiceDisplay;
81typedef struct SimpleSpiceUpdate SimpleSpiceUpdate;
Gerd Hoffmann5643fc02014-06-07 13:03:10 +020082typedef struct SimpleSpiceCursor SimpleSpiceCursor;
Gerd Hoffmanne0c64d02011-04-27 15:21:51 +020083
84struct SimpleSpiceDisplay {
Gerd Hoffmann71874c12013-02-28 16:42:28 +010085 DisplaySurface *ds;
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +010086 DisplayChangeListener dcl;
Gerd Hoffmanna3e22262010-08-25 15:32:06 +020087 void *buf;
88 int bufsize;
Gerd Hoffmanna3e22262010-08-25 15:32:06 +020089 QXLInstance qxl;
90 uint32_t unique;
Gerd Hoffmannd9a86562012-11-02 09:12:49 +010091 pixman_image_t *surface;
92 pixman_image_t *mirror;
Gerd Hoffmannddd8fdc2012-09-04 11:39:41 +020093 int32_t num_surfaces;
Gerd Hoffmanna3e22262010-08-25 15:32:06 +020094
Gerd Hoffmanna3e22262010-08-25 15:32:06 +020095 QXLRect dirty;
96 int notify;
Gerd Hoffmanna3e22262010-08-25 15:32:06 +020097
Gerd Hoffmanne0c64d02011-04-27 15:21:51 +020098 /*
99 * All struct members below this comment can be accessed from
100 * both spice server and qemu (iothread) context and any access
101 * to them must be protected by the lock.
102 */
103 QemuMutex lock;
Gerd Hoffmannb1af98b2012-09-05 08:25:08 +0200104 QTAILQ_HEAD(, SimpleSpiceUpdate) updates;
Gerd Hoffmann5643fc02014-06-07 13:03:10 +0200105
106 /* cursor (without qxl): displaychangelistener -> spice server */
107 SimpleSpiceCursor *ptr_define;
108 SimpleSpiceCursor *ptr_move;
Marc-André Lureaudc8dcee2015-03-24 17:50:12 +0100109 int16_t ptr_x, ptr_y;
110 int16_t hot_x, hot_y;
Gerd Hoffmann5643fc02014-06-07 13:03:10 +0200111
112 /* cursor (with qxl): qxl local renderer -> displaychangelistener */
Gerd Hoffmann07536092011-04-27 15:50:32 +0200113 QEMUCursor *cursor;
114 int mouse_x, mouse_y;
Gerd Hoffmann0b2824e2014-11-04 13:59:59 +0100115 QEMUBH *cursor_bh;
Gerd Hoffmann474114b2015-10-13 15:39:34 +0200116
117#ifdef HAVE_SPICE_GL
118 /* opengl rendering */
119 QEMUBH *gl_unblock_bh;
Gerd Hoffmann8e388e92016-02-19 07:46:47 +0100120 QEMUTimer *gl_unblock_timer;
Gerd Hoffmann46e19e12017-10-10 15:54:49 +0200121 QemuGLShader *gls;
Gerd Hoffmann44231842016-09-23 09:50:28 +0200122 int gl_updates;
123 bool have_scanout;
124 bool have_surface;
Gerd Hoffmann474114b2015-10-13 15:39:34 +0200125#endif
Gerd Hoffmanne0c64d02011-04-27 15:21:51 +0200126};
127
128struct SimpleSpiceUpdate {
Gerd Hoffmanna3e22262010-08-25 15:32:06 +0200129 QXLDrawable drawable;
130 QXLImage image;
131 QXLCommandExt ext;
132 uint8_t *bitmap;
Gerd Hoffmannb1af98b2012-09-05 08:25:08 +0200133 QTAILQ_ENTRY(SimpleSpiceUpdate) next;
Gerd Hoffmanne0c64d02011-04-27 15:21:51 +0200134};
Gerd Hoffmanna3e22262010-08-25 15:32:06 +0200135
Gerd Hoffmann5643fc02014-06-07 13:03:10 +0200136struct SimpleSpiceCursor {
137 QXLCursorCmd cmd;
138 QXLCommandExt ext;
139 QXLCursor cursor;
140};
141
Gerd Hoffmannfe5c44f2017-06-06 13:06:18 +0200142extern bool spice_opengl;
143
Gerd Hoffmanna3e22262010-08-25 15:32:06 +0200144int qemu_spice_rect_is_empty(const QXLRect* r);
145void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r);
146
Gerd Hoffmanna3e22262010-08-25 15:32:06 +0200147void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update);
148void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
149void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
150void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd);
Gerd Hoffmannc78f7132013-03-05 15:24:14 +0100151void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd);
Gerd Hoffmanna3e22262010-08-25 15:32:06 +0200152
153void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
154 int x, int y, int w, int h);
Gerd Hoffmannc12aeb82013-02-28 15:03:04 +0100155void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
156 DisplaySurface *surface);
Gerd Hoffmanna3e22262010-08-25 15:32:06 +0200157void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
Gerd Hoffmann0b2824e2014-11-04 13:59:59 +0100158void qemu_spice_cursor_refresh_bh(void *opaque);
Gerd Hoffmann5c59d112011-07-20 12:20:50 +0300159
Alon Levy5ff4e362011-07-20 12:20:58 +0300160void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
161 qxl_async_io async);
Gerd Hoffmann5c59d112011-07-20 12:20:50 +0300162void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid,
163 uint32_t sid);
164void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
Alon Levy5ff4e362011-07-20 12:20:58 +0300165 QXLDevSurfaceCreate *surface,
166 qxl_async_io async);
167void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
168 uint32_t id, qxl_async_io async);
Gerd Hoffmann5c59d112011-07-20 12:20:50 +0300169void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
Yonit Halperin71d388d2012-08-21 11:51:56 +0300170void qemu_spice_display_start(void);
171void qemu_spice_display_stop(void);
Yonit Halperin71d388d2012-08-21 11:51:56 +0300172int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd);