fixes for 2.9: vga, egl, cirrus, virtio-input.

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJY2RFxAAoJEEy22O7T6HE4/0IQANa4A7NGA2S50cHpQryCsFgD
 HC3EVC0Cd6aek3f1yEj3N442q4p3G7mvuNeNCT8hsdZ28v6BdNQssl9P210jpVZH
 7/TLvQKUC6t/oNiIeTT40cmYQCMRh5pLP+r2jE9XLPZD3pYlhpp46Y7N5Ij/ma/b
 tLGsB3U7XCrePiDKzaeXjiXckov8o1U7k+QVd3h5yXlO6iwTFCuAAIdR6Hx/3veO
 97VeU6tlpyZefqoeOFY6U9tFNHN808C7y144AgXGFevHbOVZhW9PBkkMsImAFjf3
 H2ZVpoZig8WQ6xrO2PUJtG53L14QbsMGrb/zHQeyFavH6XeLb9OOsvCYEGcx+yYY
 uFW926QJRQZhQjIB7ZFP3d4Q0Hd5a7i6/ogJJLiRxbcGY9j/OkaNnvAhGtF+uNd3
 VV6yAs5y8jCHolZfbevG+7iC92+XSh/LuH/265gYZpPeAWcuCtNDeCZNfw2Q8baY
 7lviJnxOmMrpRFBqsrmVA9aIQpnksjmA7QD87AzqrRT+JU1Jzbt+ylmy+U2SoYqF
 dOF8lff/W/rRZaaNtN8VeWXL6uQ42F/pfL/PO2ExFof4KVmv9FDFX+VREj4BRwPr
 LHL8qm6dYcPOkqUDgtES05sMhd5dzfB1LtjXaAi8U3uFN5NtPw/3dYlYpMiCQsTe
 Q9rt/ayotXi9Bsx5hXQe
 =CFdr
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kraxel/tags/pull-fixes-20170327-1' into staging

fixes for 2.9: vga, egl, cirrus, virtio-input.

# gpg: Signature made Mon 27 Mar 2017 14:19:45 BST
# gpg:                using RSA key 0x4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/pull-fixes-20170327-1:
  vnc: fix reverse mode
  ui/egl-helpers: fix egl 1.5 display init
  cirrus: fix PUTPIXEL macro
  virtio-input: fix eventq batching
  virtio-input: free event queue when finalizing

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2017-03-27 16:15:29 +01:00
commit a001631cb8
5 changed files with 86 additions and 33 deletions

View File

@ -29,8 +29,8 @@
#elif DEPTH == 24
#define PUTPIXEL(s, a, c) do { \
ROP_OP(s, a, c); \
ROP_OP(s, a + 1, (col >> 8)); \
ROP_OP(s, a + 2, (col >> 16)); \
ROP_OP(s, a + 1, (c >> 8)); \
ROP_OP(s, a + 2, (c >> 16)); \
} while (0)
#elif DEPTH == 32
#define PUTPIXEL(s, a, c) ROP_OP_32(s, a, c)

View File

@ -22,7 +22,6 @@
void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
{
VirtQueueElement *elem;
unsigned have, need;
int i, len;
if (!vinput->active) {
@ -32,10 +31,10 @@ void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
/* queue up events ... */
if (vinput->qindex == vinput->qsize) {
vinput->qsize++;
vinput->queue = realloc(vinput->queue, vinput->qsize *
sizeof(virtio_input_event));
vinput->queue = g_realloc(vinput->queue, vinput->qsize *
sizeof(vinput->queue[0]));
}
vinput->queue[vinput->qindex++] = *event;
vinput->queue[vinput->qindex++].event = *event;
/* ... until we see a report sync ... */
if (event->type != cpu_to_le16(EV_SYN) ||
@ -44,24 +43,24 @@ void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
}
/* ... then check available space ... */
need = sizeof(virtio_input_event) * vinput->qindex;
virtqueue_get_avail_bytes(vinput->evt, &have, NULL, need, 0);
if (have < need) {
vinput->qindex = 0;
trace_virtio_input_queue_full();
return;
for (i = 0; i < vinput->qindex; i++) {
elem = virtqueue_pop(vinput->evt, sizeof(VirtQueueElement));
if (!elem) {
while (--i >= 0) {
virtqueue_unpop(vinput->evt, vinput->queue[i].elem, 0);
}
vinput->qindex = 0;
trace_virtio_input_queue_full();
return;
}
vinput->queue[i].elem = elem;
}
/* ... and finally pass them to the guest */
for (i = 0; i < vinput->qindex; i++) {
elem = virtqueue_pop(vinput->evt, sizeof(VirtQueueElement));
if (!elem) {
/* should not happen, we've checked for space beforehand */
fprintf(stderr, "%s: Huh? No vq elem available ...\n", __func__);
return;
}
elem = vinput->queue[i].elem;
len = iov_from_buf(elem->in_sg, elem->in_num,
0, vinput->queue+i, sizeof(virtio_input_event));
0, &vinput->queue[i].event, sizeof(virtio_input_event));
virtqueue_push(vinput->evt, elem, len);
g_free(elem);
}
@ -272,6 +271,8 @@ static void virtio_input_finalize(Object *obj)
QTAILQ_REMOVE(&vinput->cfg_list, cfg, node);
g_free(cfg);
}
g_free(vinput->queue);
}
static void virtio_input_device_unrealize(DeviceState *dev, Error **errp)
{

View File

@ -62,7 +62,10 @@ struct VirtIOInput {
VirtQueue *evt, *sts;
char *serial;
virtio_input_event *queue;
struct {
virtio_input_event event;
VirtQueueElement *elem;
} *queue;
uint32_t qindex, qsize;
bool active;

View File

@ -192,6 +192,56 @@ EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win)
/* ---------------------------------------------------------------------- */
/*
* Taken from glamor_egl.h from the Xorg xserver, which is MIT licensed
*
* Create an EGLDisplay from a native display type. This is a little quirky
* for a few reasons.
*
* 1: GetPlatformDisplayEXT and GetPlatformDisplay are the API you want to
* use, but have different function signatures in the third argument; this
* happens not to matter for us, at the moment, but it means epoxy won't alias
* them together.
*
* 2: epoxy 1.3 and earlier don't understand EGL client extensions, which
* means you can't call "eglGetPlatformDisplayEXT" directly, as the resolver
* will crash.
*
* 3: You can't tell whether you have EGL 1.5 at this point, because
* eglQueryString(EGL_VERSION) is a property of the display, which we don't
* have yet. So you have to query for extensions no matter what. Fortunately
* epoxy_has_egl_extension _does_ let you query for client extensions, so
* we don't have to write our own extension string parsing.
*
* 4. There is no EGL_KHR_platform_base to complement the EXT one, thus one
* needs to know EGL 1.5 is supported in order to use the eglGetPlatformDisplay
* function pointer.
* We can workaround this (circular dependency) by probing for the EGL 1.5
* platform extensions (EGL_KHR_platform_gbm and friends) yet it doesn't seem
* like mesa will be able to advertise these (even though it can do EGL 1.5).
*/
static EGLDisplay qemu_egl_get_display(void *native)
{
EGLDisplay dpy = EGL_NO_DISPLAY;
#ifdef EGL_MESA_platform_gbm
/* In practise any EGL 1.5 implementation would support the EXT extension */
if (epoxy_has_egl_extension(NULL, "EGL_EXT_platform_base")) {
PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplayEXT =
(void *) eglGetProcAddress("eglGetPlatformDisplayEXT");
if (getPlatformDisplayEXT) {
dpy = getPlatformDisplayEXT(EGL_PLATFORM_GBM_MESA, native, NULL);
}
}
#endif
if (dpy == EGL_NO_DISPLAY) {
/* fallback */
dpy = eglGetDisplay(native);
}
return dpy;
}
int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug)
{
static const EGLint conf_att_gl[] = {
@ -222,12 +272,8 @@ int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug)
setenv("LIBGL_DEBUG", "verbose", true);
}
egl_dbg("eglGetDisplay (dpy %p) ...\n", dpy);
#ifdef EGL_MESA_platform_gbm
qemu_egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_MESA, dpy, NULL);
#else
qemu_egl_display = eglGetDisplay(dpy);
#endif
egl_dbg("qemu_egl_get_display (dpy %p) ...\n", dpy);
qemu_egl_display = qemu_egl_get_display(dpy);
if (qemu_egl_display == EGL_NO_DISPLAY) {
error_report("egl: eglGetDisplay failed");
return -1;

View File

@ -3401,6 +3401,7 @@ vnc_display_create_creds(bool x509,
static int vnc_display_get_address(const char *addrstr,
bool websocket,
bool reverse,
int displaynum,
int to,
bool has_ipv4,
@ -3480,21 +3481,22 @@ static int vnc_display_get_address(const char *addrstr,
inet->port = g_strdup(port);
}
} else {
int offset = reverse ? 0 : 5900;
if (parse_uint_full(port, &baseport, 10) < 0) {
error_setg(errp, "can't convert to a number: %s", port);
goto cleanup;
}
if (baseport > 65535 ||
baseport + 5900 > 65535) {
baseport + offset > 65535) {
error_setg(errp, "port %s out of range", port);
goto cleanup;
}
inet->port = g_strdup_printf(
"%d", (int)baseport + 5900);
"%d", (int)baseport + offset);
if (to) {
inet->has_to = true;
inet->to = to + 5900;
inet->to = to + offset;
}
}
@ -3516,6 +3518,7 @@ static int vnc_display_get_address(const char *addrstr,
}
static int vnc_display_get_addresses(QemuOpts *opts,
bool reverse,
SocketAddress ***retsaddr,
size_t *retnsaddr,
SocketAddress ***retwsaddr,
@ -3555,7 +3558,7 @@ static int vnc_display_get_addresses(QemuOpts *opts,
qemu_opt_iter_init(&addriter, opts, "vnc");
while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
int rv;
rv = vnc_display_get_address(addr, false, 0, to,
rv = vnc_display_get_address(addr, false, reverse, 0, to,
has_ipv4, has_ipv6,
ipv4, ipv6,
&saddr, errp);
@ -3580,7 +3583,7 @@ static int vnc_display_get_addresses(QemuOpts *opts,
qemu_opt_iter_init(&addriter, opts, "websocket");
while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
if (vnc_display_get_address(addr, true, displaynum, to,
if (vnc_display_get_address(addr, true, reverse, displaynum, to,
has_ipv4, has_ipv6,
ipv4, ipv6,
&wsaddr, errp) < 0) {
@ -3777,7 +3780,8 @@ void vnc_display_open(const char *id, Error **errp)
return;
}
if (vnc_display_get_addresses(opts, &saddr, &nsaddr,
reverse = qemu_opt_get_bool(opts, "reverse", false);
if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
&wsaddr, &nwsaddr, errp) < 0) {
goto fail;
}
@ -3803,7 +3807,6 @@ void vnc_display_open(const char *id, Error **errp)
}
}
reverse = qemu_opt_get_bool(opts, "reverse", false);
lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 1);
sasl = qemu_opt_get_bool(opts, "sasl", false);