#include "qemu/osdep.h"
#include "ui/qemu-spice.h"
+#include "qemu/error-report.h"
#include "qemu/timer.h"
#include "qemu/lockable.h"
#include "qemu/main-loop.h"
{
static const int blksize = 32;
int blocks = DIV_ROUND_UP(surface_width(ssd->ds), blksize);
- int dirty_top[blocks];
+ g_autofree int *dirty_top = NULL;
int y, yoff1, yoff2, x, xoff, blk, bw;
int bpp = surface_bytes_per_pixel(ssd->ds);
uint8_t *guest, *mirror;
return;
};
+ dirty_top = g_new(int, blocks);
for (blk = 0; blk < blocks; blk++) {
dirty_top[blk] = -1;
}
}
if (ssd->ds) {
ssd->surface = pixman_image_ref(ssd->ds->image);
- ssd->mirror = qemu_pixman_mirror_create(ssd->ds->format,
+ ssd->mirror = qemu_pixman_mirror_create(surface_format(ssd->ds),
ssd->ds->image);
qemu_spice_create_host_primary(ssd);
}
if (ssd->cursor) {
QEMUCursor *c = ssd->cursor;
assert(ssd->dcl.con);
- cursor_get(c);
+ cursor_ref(c);
qemu_mutex_unlock(&ssd->lock);
dpy_cursor_define(ssd->dcl.con, c);
qemu_mutex_lock(&ssd->lock);
- cursor_put(c);
+ cursor_unref(c);
}
if (ssd->mouse_x != -1 && ssd->mouse_y != -1) {
/* spice display interface callbacks */
-static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
+#if SPICE_HAS_ATTACHED_WORKER
+static void interface_attached_worker(QXLInstance *sin)
{
/* nothing to do */
}
-
-static void interface_set_compression_level(QXLInstance *sin, int level)
+#else
+static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
{
/* nothing to do */
}
+#endif
-#if SPICE_NEEDS_SET_MM_TIME
-static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
+static void interface_set_compression_level(QXLInstance *sin, int level)
{
/* nothing to do */
}
-#endif
static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
{
.base.major_version = SPICE_INTERFACE_QXL_MAJOR,
.base.minor_version = SPICE_INTERFACE_QXL_MINOR,
+#if SPICE_HAS_ATTACHED_WORKER
+ .attached_worker = interface_attached_worker,
+#else
.attache_worker = interface_attach_worker,
- .set_compression_level = interface_set_compression_level,
-#if SPICE_NEEDS_SET_MM_TIME
- .set_mm_time = interface_set_mm_time,
#endif
+ .set_compression_level = interface_set_compression_level,
.get_init_info = interface_get_init_info,
/* the callbacks below are called from spice server thread context */
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
qemu_mutex_lock(&ssd->lock);
- cursor_get(c);
- cursor_put(ssd->cursor);
+ cursor_ref(c);
+ cursor_unref(ssd->cursor);
ssd->cursor = c;
ssd->hot_x = c->hot_x;
ssd->hot_y = c->hot_y;
}
}
-static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl,
+static QEMUGLContext qemu_spice_gl_create_context(DisplayGLCtx *dgc,
QEMUGLParams *params)
{
eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
qemu_egl_rn_ctx);
- return qemu_egl_create_context(dcl, params);
+ return qemu_egl_create_context(dgc, params);
}
static void qemu_spice_gl_scanout_disable(DisplayChangeListener *dcl)
uint32_t backing_width,
uint32_t backing_height,
uint32_t x, uint32_t y,
- uint32_t w, uint32_t h)
+ uint32_t w, uint32_t h,
+ void *d3d_tex2d)
{
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
EGLint stride = 0, fourcc = 0;
uint32_t hot_x, uint32_t hot_y)
{
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+ uint32_t width, height, texture;
ssd->have_hot = have_hot;
ssd->hot_x = hot_x;
trace_qemu_spice_gl_cursor(ssd->qxl.id, dmabuf != NULL, have_hot);
if (dmabuf) {
egl_dmabuf_import_texture(dmabuf);
- if (!dmabuf->texture) {
+ texture = qemu_dmabuf_get_texture(dmabuf);
+ if (!texture) {
return;
}
- egl_fb_setup_for_tex(&ssd->cursor_fb, dmabuf->width, dmabuf->height,
- dmabuf->texture, false);
+ width = qemu_dmabuf_get_width(dmabuf);
+ height = qemu_dmabuf_get_height(dmabuf);
+ egl_fb_setup_for_tex(&ssd->cursor_fb, width, height, texture, false);
} else {
egl_fb_destroy(&ssd->cursor_fb);
}
bool y_0_top = false; /* FIXME */
uint64_t cookie;
int fd;
+ uint32_t width, height, texture;
if (!ssd->have_scanout) {
return;
if (ssd->guest_dmabuf_refresh) {
QemuDmaBuf *dmabuf = ssd->guest_dmabuf;
+ width = qemu_dmabuf_get_width(dmabuf);
+ height = qemu_dmabuf_get_height(dmabuf);
+
if (render_cursor) {
egl_dmabuf_import_texture(dmabuf);
- if (!dmabuf->texture) {
+ texture = qemu_dmabuf_get_texture(dmabuf);
+ if (!texture) {
return;
}
/* source framebuffer */
- egl_fb_setup_for_tex(&ssd->guest_fb,
- dmabuf->width, dmabuf->height,
- dmabuf->texture, false);
+ egl_fb_setup_for_tex(&ssd->guest_fb, width, height,
+ texture, false);
/* dest framebuffer */
- if (ssd->blit_fb.width != dmabuf->width ||
- ssd->blit_fb.height != dmabuf->height) {
- trace_qemu_spice_gl_render_dmabuf(ssd->qxl.id, dmabuf->width,
- dmabuf->height);
+ if (ssd->blit_fb.width != width ||
+ ssd->blit_fb.height != height) {
+ trace_qemu_spice_gl_render_dmabuf(ssd->qxl.id, width,
+ height);
egl_fb_destroy(&ssd->blit_fb);
egl_fb_setup_new_tex(&ssd->blit_fb,
- dmabuf->width, dmabuf->height);
+ width, height);
fd = egl_get_fd_for_texture(ssd->blit_fb.texture,
&stride, &fourcc, NULL);
- spice_qxl_gl_scanout(&ssd->qxl, fd,
- dmabuf->width, dmabuf->height,
+ spice_qxl_gl_scanout(&ssd->qxl, fd, width, height,
stride, fourcc, false);
}
} else {
- trace_qemu_spice_gl_forward_dmabuf(ssd->qxl.id,
- dmabuf->width, dmabuf->height);
+ stride = qemu_dmabuf_get_stride(dmabuf);
+ fourcc = qemu_dmabuf_get_fourcc(dmabuf);
+ y_0_top = qemu_dmabuf_get_y0_top(dmabuf);
+ fd = qemu_dmabuf_dup_fd(dmabuf);
+
+ trace_qemu_spice_gl_forward_dmabuf(ssd->qxl.id, width, height);
/* note: spice server will close the fd, so hand over a dup */
- spice_qxl_gl_scanout(&ssd->qxl, dup(dmabuf->fd),
- dmabuf->width, dmabuf->height,
- dmabuf->stride, dmabuf->fourcc,
- dmabuf->y0_top);
+ spice_qxl_gl_scanout(&ssd->qxl, fd, width, height,
+ stride, fourcc, y_0_top);
}
- qemu_spice_gl_monitor_config(ssd, 0, 0, dmabuf->width, dmabuf->height);
+ qemu_spice_gl_monitor_config(ssd, 0, 0, width, height);
ssd->guest_dmabuf_refresh = false;
}
if (render_cursor) {
- int x, y;
+ int ptr_x, ptr_y;
+
qemu_mutex_lock(&ssd->lock);
- x = ssd->ptr_x;
- y = ssd->ptr_y;
+ ptr_x = ssd->ptr_x;
+ ptr_y = ssd->ptr_y;
qemu_mutex_unlock(&ssd->lock);
egl_texture_blit(ssd->gls, &ssd->blit_fb, &ssd->guest_fb,
!y_0_top);
egl_texture_blend(ssd->gls, &ssd->blit_fb, &ssd->cursor_fb,
- !y_0_top, x, y, 1.0, 1.0);
+ !y_0_top, ptr_x, ptr_y, 1.0, 1.0);
glFlush();
}
.dpy_mouse_set = display_mouse_set,
.dpy_cursor_define = display_mouse_define,
- .dpy_gl_ctx_create = qemu_spice_gl_create_context,
- .dpy_gl_ctx_destroy = qemu_egl_destroy_context,
- .dpy_gl_ctx_make_current = qemu_egl_make_context_current,
-
.dpy_gl_scanout_disable = qemu_spice_gl_scanout_disable,
.dpy_gl_scanout_texture = qemu_spice_gl_scanout_texture,
.dpy_gl_scanout_dmabuf = qemu_spice_gl_scanout_dmabuf,
.dpy_gl_update = qemu_spice_gl_update,
};
+static bool
+qemu_spice_is_compatible_dcl(DisplayGLCtx *dgc,
+ DisplayChangeListener *dcl)
+{
+ return dcl->ops == &display_listener_gl_ops;
+}
+
+static const DisplayGLCtxOps gl_ctx_ops = {
+ .dpy_gl_ctx_is_compatible_dcl = qemu_spice_is_compatible_dcl,
+ .dpy_gl_ctx_create = qemu_spice_gl_create_context,
+ .dpy_gl_ctx_destroy = qemu_egl_destroy_context,
+ .dpy_gl_ctx_make_current = qemu_egl_make_context_current,
+};
+
#endif /* HAVE_SPICE_GL */
static void qemu_spice_display_init_one(QemuConsole *con)
#ifdef HAVE_SPICE_GL
if (spice_opengl) {
ssd->dcl.ops = &display_listener_gl_ops;
+ ssd->dgc.ops = &gl_ctx_ops;
ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
qemu_spice_gl_block_timer, ssd);
qemu_spice_add_display_interface(&ssd->qxl, con);
#if SPICE_SERVER_VERSION >= 0x000e02 /* release 0.14.2 */
+ Error *err = NULL;
char device_address[256] = "";
- if (qemu_spice_fill_device_address(con, device_address, 256)) {
+ if (qemu_console_fill_device_address(con, device_address, 256, &err)) {
spice_qxl_set_device_info(&ssd->qxl,
device_address,
qemu_console_get_head(con),
1);
+ } else {
+ error_report_err(err);
}
#endif
qemu_spice_create_host_memslot(ssd);
if (spice_opengl) {
- qemu_console_set_display_gl_ctx(con, &ssd->dcl);
+ qemu_console_set_display_gl_ctx(con, &ssd->dgc);
}
register_displaychangelistener(&ssd->dcl);
}