1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#ifndef UI_SPICE_DISPLAY_H
19#define UI_SPICE_DISPLAY_H
20
21#include <spice.h>
22#include <spice/ipc_ring.h>
23#include <spice/enums.h>
24#include <spice/qxl_dev.h>
25
26#include "qemu/thread.h"
27#include "ui/qemu-pixman.h"
28#include "ui/console.h"
29
30#if defined(CONFIG_OPENGL) && defined(CONFIG_GBM)
31# define HAVE_SPICE_GL 1
32# include "ui/egl-helpers.h"
33# include "ui/egl-context.h"
34#endif
35
36#define NUM_MEMSLOTS 8
37#define MEMSLOT_GENERATION_BITS 8
38#define MEMSLOT_SLOT_BITS 8
39
40#define MEMSLOT_GROUP_HOST 0
41#define MEMSLOT_GROUP_GUEST 1
42#define NUM_MEMSLOTS_GROUPS 2
43
44
45
46
47
48
49
50
51
52
53typedef enum qxl_async_io {
54 QXL_SYNC,
55 QXL_ASYNC,
56} qxl_async_io;
57
58enum {
59 QXL_COOKIE_TYPE_IO,
60 QXL_COOKIE_TYPE_RENDER_UPDATE_AREA,
61 QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
62 QXL_COOKIE_TYPE_GL_DRAW_DONE,
63};
64
65typedef struct QXLCookie {
66 int type;
67 uint64_t io;
68 union {
69 uint32_t surface_id;
70 QXLRect area;
71 struct {
72 QXLRect area;
73 int redraw;
74 } render;
75 void *data;
76 } u;
77} QXLCookie;
78
79QXLCookie *qxl_cookie_new(int type, uint64_t io);
80
81typedef struct SimpleSpiceDisplay SimpleSpiceDisplay;
82typedef struct SimpleSpiceUpdate SimpleSpiceUpdate;
83typedef struct SimpleSpiceCursor SimpleSpiceCursor;
84
85struct SimpleSpiceDisplay {
86 DisplaySurface *ds;
87 DisplayGLCtx dgc;
88 DisplayChangeListener dcl;
89 void *buf;
90 int bufsize;
91 QXLInstance qxl;
92 uint32_t unique;
93 pixman_image_t *surface;
94 pixman_image_t *mirror;
95 int32_t num_surfaces;
96
97 QXLRect dirty;
98 int notify;
99
100
101
102
103
104
105 QemuMutex lock;
106 QTAILQ_HEAD(, SimpleSpiceUpdate) updates;
107
108
109 SimpleSpiceCursor *ptr_define;
110 SimpleSpiceCursor *ptr_move;
111 int16_t ptr_x, ptr_y;
112 int16_t hot_x, hot_y;
113
114
115 QEMUCursor *cursor;
116 int mouse_x, mouse_y;
117 QEMUBH *cursor_bh;
118
119#ifdef HAVE_SPICE_GL
120
121 QEMUBH *gl_unblock_bh;
122 QEMUTimer *gl_unblock_timer;
123 QemuGLShader *gls;
124 int gl_updates;
125 bool have_scanout;
126 bool have_surface;
127
128 QemuDmaBuf *guest_dmabuf;
129 bool guest_dmabuf_refresh;
130 bool render_cursor;
131
132 egl_fb guest_fb;
133 egl_fb blit_fb;
134 egl_fb cursor_fb;
135 bool have_hot;
136#endif
137};
138
139struct SimpleSpiceUpdate {
140 QXLDrawable drawable;
141 QXLImage image;
142 QXLCommandExt ext;
143 uint8_t *bitmap;
144 QTAILQ_ENTRY(SimpleSpiceUpdate) next;
145};
146
147struct SimpleSpiceCursor {
148 QXLCursorCmd cmd;
149 QXLCommandExt ext;
150 QXLCursor cursor;
151};
152
153extern bool spice_opengl;
154
155int qemu_spice_rect_is_empty(const QXLRect* r);
156void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r);
157
158void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update);
159void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
160void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
161void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd);
162void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd);
163
164void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
165 int x, int y, int w, int h);
166void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
167 DisplaySurface *surface);
168void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
169void qemu_spice_cursor_refresh_bh(void *opaque);
170
171void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
172 qxl_async_io async);
173void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid,
174 uint32_t sid);
175void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
176 QXLDevSurfaceCreate *surface,
177 qxl_async_io async);
178void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
179 uint32_t id, qxl_async_io async);
180void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
181void qemu_spice_display_start(void);
182void qemu_spice_display_stop(void);
183int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd);
184
185#endif
186