Merge tag '20230316-xtensa' of https://github.com/OSLL/qemu-xtensa into staging target/xtensa updates for v8.0: - enable testing big-endian xtensa cores # -----BEGIN PGP SIGNATURE----- # # iQJHBAABCgAxFiEEK2eFS5jlMn3N6xfYUfnMkfg/oEQFAmQTd6gTHGpjbXZia2Jj # QGdtYWlsLmNvbQAKCRBR+cyR+D+gRCowEACpQULqjxkpd23bd5uYQYsuJRzbSblF # 6xux3IK5kD2y8vjzVegTs1XdZNhNzLRfEOijy+DxP1+5S6jRoACRkv0zKaBigbfA # C7pLTxKGXk4OLA1sEdAXZ8jTBxDNQG542kF/PSPUHLxbJyb+lH+4707vb/kgQQdz # nhCVfK75hqW2leohWsEES1jPxazyqu5PLMr9zPa0yfhbUU3g1AgTzFHAVrocP5mN # QKsaSwP5fwnF2ozTRM7MhHJj9iLlX0IYxeAcA22kUhr6kaAmL4SQdpwiREbCgOts # XE2Hpo+W5WQRw1B94au0spMZwYGDhFeApLhHRAI6hpLlOyTzC1bHV0yetHEWxLI4 # yPO4gCrkM+bIC5ErywTaCrTfCbaJkmMsz7epFLpawAfEtBTysfOzQEdVYcDKA7DO # uP1qvW3moIOFLJl+s8c5RQzuSP2kB7Ziox92p6bG9o4XM5Wp0SQU201xKuWkwoC2 # VLsd04IopaDQZdMkErqv9+moebI3w3s9zebbzjDicBA+JfgeOltEWp8tIMAXDTx6 # Rk+A6qh7VW73AACwP10GOtC2bslFCokgsuDuabFDC1w6bhWxgBv2bNk+8WJgR8Oe # BQKZgtH5XmnpTVZCrpgLQhJBWO+shVLm6sOy+wkTKuOwksn/ADd+q2QwAvKKWU6J # o+E0K5KnN3p4Qw== # =v5XD # -----END PGP SIGNATURE----- # gpg: Signature made Thu 16 Mar 2023 20:10:16 GMT # gpg: using RSA key 2B67854B98E5327DCDEB17D851F9CC91F83FA044 # gpg: issuer "jcmvbkbc@gmail.com" # gpg: Good signature from "Max Filippov <filippov@cadence.com>" [unknown] # gpg: aka "Max Filippov <max.filippov@cogentembedded.com>" [full] # gpg: aka "Max Filippov <jcmvbkbc@gmail.com>" [full] # Primary key fingerprint: 2B67 854B 98E5 327D CDEB 17D8 51F9 CC91 F83F A044 * tag '20230316-xtensa' of https://github.com/OSLL/qemu-xtensa: tests/tcg/xtensa: allow testing big-endian cores tests/tcg/xtensa: add linker.ld to CLEANFILES Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/.mailmap b/.mailmap index fad2aff..7677047 100644 --- a/.mailmap +++ b/.mailmap
@@ -56,6 +56,7 @@ Alexander Graf <agraf@csgraf.de> <agraf@suse.de> Anthony Liguori <anthony@codemonkey.ws> Anthony Liguori <aliguori@us.ibm.com> Christian Borntraeger <borntraeger@linux.ibm.com> <borntraeger@de.ibm.com> +Damien Hedde <damien.hedde@dahe.fr> <damien.hedde@greensocs.com> Filip Bozuta <filip.bozuta@syrmia.com> <filip.bozuta@rt-rk.com.com> Frederic Konrad <konrad.frederic@yahoo.fr> <fred.konrad@greensocs.com> Frederic Konrad <konrad.frederic@yahoo.fr> <konrad@adacore.com>
diff --git a/MAINTAINERS b/MAINTAINERS index 94faa80..1effad2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS
@@ -2667,7 +2667,6 @@ T: git https://gitlab.com/vsementsov/qemu.git block Compute Express Link -M: Ben Widawsky <ben.widawsky@intel.com> M: Jonathan Cameron <jonathan.cameron@huawei.com> R: Fan Ni <fan.ni@samsung.com> S: Supported @@ -3364,7 +3363,7 @@ Clock framework M: Luc Michel <luc@lmichel.fr> -R: Damien Hedde <damien.hedde@greensocs.com> +R: Damien Hedde <damien.hedde@dahe.fr> S: Maintained F: include/hw/clock.h F: include/hw/qdev-clock.h
diff --git a/VERSION b/VERSION index d182ea1..44185ab 100644 --- a/VERSION +++ b/VERSION
@@ -1 +1 @@ -7.2.50 +7.2.90
diff --git a/audio/audio_int.h b/audio/audio_int.h index d51d63f..e57ff50 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h
@@ -143,7 +143,7 @@ void *(*init) (Audiodev *); void (*fini) (void *); #ifdef CONFIG_GIO - void (*set_dbus_server) (AudioState *s, GDBusObjectManagerServer *manager); + void (*set_dbus_server) (AudioState *s, GDBusObjectManagerServer *manager, bool p2p); #endif struct audio_pcm_ops *pcm_ops; int can_be_default;
diff --git a/audio/dbusaudio.c b/audio/dbusaudio.c index 722df03..fece74f 100644 --- a/audio/dbusaudio.c +++ b/audio/dbusaudio.c
@@ -43,6 +43,7 @@ typedef struct DBusAudio { GDBusObjectManagerServer *server; + bool p2p; GDBusObjectSkeleton *audio; QemuDBusDisplay1Audio *iface; GHashTable *out_listeners; @@ -448,7 +449,8 @@ bool out) { DBusAudio *da = s->drv_opaque; - const char *sender = g_dbus_method_invocation_get_sender(invocation); + const char *sender = + da->p2p ? "p2p" : g_dbus_method_invocation_get_sender(invocation); g_autoptr(GDBusConnection) listener_conn = NULL; g_autoptr(GError) err = NULL; g_autoptr(GSocket) socket = NULL; @@ -591,7 +593,7 @@ } static void -dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server) +dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server, bool p2p) { DBusAudio *da = s->drv_opaque; @@ -599,6 +601,7 @@ g_assert(!da->server); da->server = g_object_ref(server); + da->p2p = p2p; da->audio = g_dbus_object_skeleton_new(DBUS_DISPLAY1_AUDIO_PATH); da->iface = qemu_dbus_display1_audio_skeleton_new();
diff --git a/disas/riscv.c b/disas/riscv.c index 54455aa..d6b0fbe 100644 --- a/disas/riscv.c +++ b/disas/riscv.c
@@ -1014,6 +1014,7 @@ #define rv_fmt_rd_offset "O\t0,o" #define rv_fmt_rd_rs1_rs2 "O\t0,1,2" #define rv_fmt_frd_rs1 "O\t3,1" +#define rv_fmt_frd_frs1 "O\t3,4" #define rv_fmt_rd_frs1 "O\t0,4" #define rv_fmt_rd_frs1_frs2 "O\t0,4,5" #define rv_fmt_frd_frs1_frs2 "O\t3,4,5" @@ -1580,15 +1581,15 @@ { "snez", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 }, { "sltz", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, { "sgtz", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 }, - { "fmv.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, - { "fabs.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, - { "fneg.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, - { "fmv.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, - { "fabs.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, - { "fneg.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, - { "fmv.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, - { "fabs.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, - { "fneg.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "fmv.s", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, + { "fabs.s", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, + { "fneg.s", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, + { "fmv.d", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, + { "fabs.d", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, + { "fneg.d", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, + { "fmv.q", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, + { "fabs.q", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, + { "fneg.q", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 }, { "beqz", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 }, { "bnez", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 }, { "blez", rv_codec_sb, rv_fmt_rs2_offset, NULL, 0, 0, 0 }, @@ -1647,7 +1648,7 @@ { "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, { "ctzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, { "cpopw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, - { "slli.uw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, + { "slli.uw", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, { "add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, { "rolw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, { "rorw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, @@ -2617,10 +2618,10 @@ switch (((inst >> 12) & 0b111)) { case 0: op = rv_op_addiw; break; case 1: - switch (((inst >> 25) & 0b1111111)) { + switch (((inst >> 26) & 0b111111)) { case 0: op = rv_op_slliw; break; - case 4: op = rv_op_slli_uw; break; - case 48: + case 2: op = rv_op_slli_uw; break; + case 24: switch ((inst >> 20) & 0b11111) { case 0b00000: op = rv_op_clzw; break; case 0b00001: op = rv_op_ctzw; break;
diff --git a/docs/devel/atomics.rst b/docs/devel/atomics.rst index 633df65..81ec26b 100644 --- a/docs/devel/atomics.rst +++ b/docs/devel/atomics.rst
@@ -469,13 +469,19 @@ In QEMU, the second kind is named ``atomic_OP_fetch``. - different atomic read-modify-write operations in Linux imply - a different set of memory barriers; in QEMU, all of them enforce - sequential consistency. + a different set of memory barriers. In QEMU, all of them enforce + sequential consistency: there is a single order in which the + program sees them happen. -- in QEMU, ``qatomic_read()`` and ``qatomic_set()`` do not participate in - the ordering enforced by read-modify-write operations. - This is because QEMU uses the C11 memory model. The following example - is correct in Linux but not in QEMU: +- however, according to the C11 memory model that QEMU uses, this order + does not propagate to other memory accesses on either side of the + read-modify-write operation. As far as those are concerned, the + operation consist of just a load-acquire followed by a store-release. + Stores that precede the RMW operation, and loads that follow it, can + still be reordered and will happen *in the middle* of the read-modify-write + operation! + + Therefore, the following example is correct in Linux but not in QEMU: +----------------------------------+--------------------------------+ | Linux (correct) | QEMU (incorrect) |
diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c index fcfd40c..ec99ec8 100644 --- a/hw/display/qxl-render.c +++ b/hw/display/qxl-render.c
@@ -290,7 +290,7 @@ return c; fail: - cursor_put(c); + cursor_unref(c); return NULL; } @@ -336,7 +336,7 @@ } qemu_mutex_lock(&qxl->ssd.lock); if (qxl->ssd.cursor) { - cursor_put(qxl->ssd.cursor); + cursor_unref(qxl->ssd.cursor); } qxl->ssd.cursor = c; qxl->ssd.mouse_x = cmd->u.set.position.x;
diff --git a/hw/display/qxl.c b/hw/display/qxl.c index ec712d3..80ce1e9 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c
@@ -299,7 +299,7 @@ qxl->guest_cursor = 0; qemu_mutex_unlock(&qxl->track_lock); if (qxl->ssd.cursor) { - cursor_put(qxl->ssd.cursor); + cursor_unref(qxl->ssd.cursor); } qxl->ssd.cursor = cursor_builtin_hidden(); }
diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 59ae7f7..09591fb 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c
@@ -550,12 +550,12 @@ default: fprintf(stderr, "%s: unhandled bpp %d, using fallback cursor\n", __func__, c->bpp); - cursor_put(qc); + cursor_unref(qc); qc = cursor_builtin_left_ptr(); } dpy_cursor_define(s->vga.con, qc); - cursor_put(qc); + cursor_unref(qc); } #endif
diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 3253ab6..45af76a 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c
@@ -402,6 +402,9 @@ ps2_put_keycode(s, 0xaa); } } + } else if ((qcode == Q_KEY_CODE_LANG1 || qcode == Q_KEY_CODE_LANG2) + && !key->down) { + /* Ignore release for these keys */ } else { if (qcode < qemu_input_map_qcode_to_atset1_len) { keycode = qemu_input_map_qcode_to_atset1[qcode]; @@ -497,6 +500,9 @@ ps2_put_keycode(s, 0x12); } } + } else if ((qcode == Q_KEY_CODE_LANG1 || qcode == Q_KEY_CODE_LANG2) && + !key->down) { + /* Ignore release for these keys */ } else { if (qcode < qemu_input_map_qcode_to_atset2_len) { keycode = qemu_input_map_qcode_to_atset2[qcode];
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c index 6364eca..716ffc8 100644 --- a/hw/intc/ioapic.c +++ b/hw/intc/ioapic.c
@@ -405,6 +405,7 @@ s->ioredtbl[index] |= ro_bits; s->irq_eoi[index] = 0; ioapic_fix_edge_remote_irr(&s->ioredtbl[index]); + ioapic_update_kvm_routes(s); ioapic_service(s); } } @@ -417,8 +418,6 @@ ioapic_eoi_broadcast(val); break; } - - ioapic_update_kvm_routes(s); } static const MemoryRegionOps ioapic_io_ops = {
diff --git a/include/ui/console.h b/include/ui/console.h index 1cb53ac..2a8fab0 100644 --- a/include/ui/console.h +++ b/include/ui/console.h
@@ -151,8 +151,8 @@ } QEMUCursor; QEMUCursor *cursor_alloc(int width, int height); -void cursor_get(QEMUCursor *c); -void cursor_put(QEMUCursor *c); +QEMUCursor *cursor_ref(QEMUCursor *c); +void cursor_unref(QEMUCursor *c); QEMUCursor *cursor_builtin_hidden(void); QEMUCursor *cursor_builtin_left_ptr(void); void cursor_print_ascii_art(QEMUCursor *c, const char *prefix); @@ -459,6 +459,7 @@ QemuConsole *qemu_console_lookup_by_device_name(const char *device_id, uint32_t head, Error **errp); QemuConsole *qemu_console_lookup_unused(void); +QEMUCursor *qemu_console_get_cursor(QemuConsole *con); bool qemu_console_is_visible(QemuConsole *con); bool qemu_console_is_graphic(QemuConsole *con); bool qemu_console_is_fixedsize(QemuConsole *con);
diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h index 2fb6e0d..53d953d 100644 --- a/include/ui/egl-helpers.h +++ b/include/ui/egl-helpers.h
@@ -22,6 +22,8 @@ QemuDmaBuf *dmabuf; } egl_fb; +#define EGL_FB_INIT { 0, } + void egl_fb_destroy(egl_fb *fb); void egl_fb_setup_default(egl_fb *fb, int width, int height); void egl_fb_setup_for_tex(egl_fb *fb, int width, int height, @@ -63,4 +65,6 @@ EGLContext qemu_egl_init_ctx(void); bool qemu_egl_has_dmabuf(void); +bool egl_init(const char *rendernode, DisplayGLMode mode, Error **errp); + #endif /* EGL_HELPERS_H */
diff --git a/io/channel-tls.c b/io/channel-tls.c index 8052945..5a7a3d4 100644 --- a/io/channel-tls.c +++ b/io/channel-tls.c
@@ -446,6 +446,7 @@ object_ref(OBJECT(tioc)); g_source_add_child_source(source, child); + g_source_unref(child); } static GSource *qio_channel_tls_create_watch(QIOChannel *ioc,
diff --git a/meson.build b/meson.build index 6bcab8b..29f8644 100644 --- a/meson.build +++ b/meson.build
@@ -1746,8 +1746,8 @@ error_message: '-display dbus requires glib>=2.64') \ .require(gdbus_codegen.found(), error_message: gdbus_codegen_error.format('-display dbus')) \ - .require(opengl.found() and gbm.found(), - error_message: '-display dbus requires epoxy/egl and gbm') \ + .require(targetos != 'windows', + error_message: '-display dbus is not available on Windows') \ .allowed() have_virtfs = get_option('virtfs') \
diff --git a/migration/multifd.c b/migration/multifd.c index 5e85c3e..cbc0dfe 100644 --- a/migration/multifd.c +++ b/migration/multifd.c
@@ -677,7 +677,7 @@ if (p->pending_job) { uint64_t packet_num = p->packet_num; - uint32_t flags = p->flags; + uint32_t flags; p->normal_num = 0; if (use_zero_copy_send) { @@ -699,6 +699,7 @@ } } multifd_send_fill_packet(p); + flags = p->flags; p->flags = 0; p->num_packets++; p->total_normal_pages += p->normal_num;
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index f54f44d..41c0713 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c
@@ -1198,11 +1198,6 @@ if (migrate_postcopy_preempt()) { /* - * The preempt channel is established in asynchronous way. Wait - * for its completion. - */ - qemu_sem_wait(&mis->postcopy_qemufile_dst_done); - /* * This thread needs to be created after the temp pages because * it'll fetch RAM_CHANNEL_POSTCOPY PostcopyTmpPage immediately. */ @@ -1668,6 +1663,12 @@ qemu_sem_post(&mis->thread_sync_sem); + /* + * The preempt channel is established in asynchronous way. Wait + * for its completion. + */ + qemu_sem_wait(&mis->postcopy_qemufile_dst_done); + /* Sending RAM_SAVE_FLAG_EOS to terminate this thread */ qemu_mutex_lock(&mis->postcopy_prio_thread_mutex); while (1) {
diff --git a/migration/rdma.c b/migration/rdma.c index 288eadc..df646be 100644 --- a/migration/rdma.c +++ b/migration/rdma.c
@@ -3373,7 +3373,8 @@ * initialize the RDMAContext for return path for postcopy after first * connection request reached. */ - if (migrate_postcopy() && !rdma->is_return_path) { + if ((migrate_postcopy() || migrate_use_return_path()) + && !rdma->is_return_path) { rdma_return_path = qemu_rdma_data_init(rdma->host_port, NULL); if (rdma_return_path == NULL) { rdma_ack_cm_event(cm_event); @@ -3455,7 +3456,8 @@ } /* Accept the second connection request for return path */ - if (migrate_postcopy() && !rdma->is_return_path) { + if ((migrate_postcopy() || migrate_use_return_path()) + && !rdma->is_return_path) { qemu_set_fd_handler(rdma->channel->fd, rdma_accept_incoming_migration, NULL, (void *)(intptr_t)rdma->return_path); @@ -4109,7 +4111,7 @@ void rdma_start_incoming_migration(const char *host_port, Error **errp) { int ret; - RDMAContext *rdma, *rdma_return_path = NULL; + RDMAContext *rdma; Error *local_err = NULL; trace_rdma_start_incoming_migration(); @@ -4155,7 +4157,6 @@ g_free(rdma->host_port); } g_free(rdma); - g_free(rdma_return_path); } void rdma_start_outgoing_migration(void *opaque, @@ -4192,7 +4193,7 @@ } /* RDMA postcopy need a separate queue pair for return path */ - if (migrate_postcopy()) { + if (migrate_postcopy() || migrate_use_return_path()) { rdma_return_path = qemu_rdma_data_init(host_port, errp); if (rdma_return_path == NULL) {
diff --git a/migration/target.c b/migration/target.c index 907ebf0..00ca007 100644 --- a/migration/target.c +++ b/migration/target.c
@@ -8,6 +8,7 @@ #include "qemu/osdep.h" #include "qapi/qapi-types-migration.h" #include "migration.h" +#include CONFIG_DEVICES #ifdef CONFIG_VFIO #include "hw/vfio/vfio-common.h" @@ -17,7 +18,6 @@ { #ifdef CONFIG_VFIO if (vfio_mig_active()) { - info->has_vfio = true; info->vfio = g_malloc0(sizeof(*info->vfio)); info->vfio->transferred = vfio_mig_bytes_transferred(); }
diff --git a/migration/xbzrle.c b/migration/xbzrle.c index 05366e8..c6f8b20 100644 --- a/migration/xbzrle.c +++ b/migration/xbzrle.c
@@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" #include "qemu/cutils.h" +#include "qemu/host-utils.h" #include "xbzrle.h" /* @@ -196,10 +197,6 @@ __m512i r = _mm512_set1_epi32(0); while (count512s) { - if (d + 2 > dlen) { - return -1; - } - int bytes_to_check = 64; uint64_t mask = 0xffffffffffffffff; if (count512s == 1) { @@ -215,6 +212,9 @@ bool is_same = (comp & 0x1); while (bytes_to_check) { + if (d + 2 > dlen) { + return -1; + } if (is_same) { if (nzrun_len) { d += uleb128_encode_small(dst + d, nzrun_len); @@ -233,7 +233,7 @@ break; } never_same = false; - num = __builtin_ctzll(~comp); + num = ctz64(~comp); num = (num < bytes_to_check) ? num : bytes_to_check; zrun_len += num; bytes_to_check -= num; @@ -262,7 +262,7 @@ nzrun_len += 64; break; } - num = __builtin_ctzll(comp); + num = ctz64(comp); num = (num < bytes_to_check) ? num : bytes_to_check; nzrun_len += num; bytes_to_check -= num;
diff --git a/pc-bios/bios-256k.bin b/pc-bios/bios-256k.bin index 211b2a4..f70aa72 100644 --- a/pc-bios/bios-256k.bin +++ b/pc-bios/bios-256k.bin Binary files differ
diff --git a/pc-bios/bios-microvm.bin b/pc-bios/bios-microvm.bin index 6204a71..94792cf 100644 --- a/pc-bios/bios-microvm.bin +++ b/pc-bios/bios-microvm.bin Binary files differ
diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin index 12d6a03..6a196cf 100644 --- a/pc-bios/bios.bin +++ b/pc-bios/bios.bin Binary files differ
diff --git a/pc-bios/vgabios-ati.bin b/pc-bios/vgabios-ati.bin index 39b2405..9fb8627 100644 --- a/pc-bios/vgabios-ati.bin +++ b/pc-bios/vgabios-ati.bin Binary files differ
diff --git a/pc-bios/vgabios-bochs-display.bin b/pc-bios/vgabios-bochs-display.bin index b20d67c..91969ae 100644 --- a/pc-bios/vgabios-bochs-display.bin +++ b/pc-bios/vgabios-bochs-display.bin Binary files differ
diff --git a/pc-bios/vgabios-cirrus.bin b/pc-bios/vgabios-cirrus.bin index ebe5336..c429540 100644 --- a/pc-bios/vgabios-cirrus.bin +++ b/pc-bios/vgabios-cirrus.bin Binary files differ
diff --git a/pc-bios/vgabios-qxl.bin b/pc-bios/vgabios-qxl.bin index 4b5573a..088385f 100644 --- a/pc-bios/vgabios-qxl.bin +++ b/pc-bios/vgabios-qxl.bin Binary files differ
diff --git a/pc-bios/vgabios-ramfb.bin b/pc-bios/vgabios-ramfb.bin index d458ec74..134c751 100644 --- a/pc-bios/vgabios-ramfb.bin +++ b/pc-bios/vgabios-ramfb.bin Binary files differ
diff --git a/pc-bios/vgabios-stdvga.bin b/pc-bios/vgabios-stdvga.bin index 797e103..4cd0d52 100644 --- a/pc-bios/vgabios-stdvga.bin +++ b/pc-bios/vgabios-stdvga.bin Binary files differ
diff --git a/pc-bios/vgabios-virtio.bin b/pc-bios/vgabios-virtio.bin index 3f8fe9d..976c786 100644 --- a/pc-bios/vgabios-virtio.bin +++ b/pc-bios/vgabios-virtio.bin Binary files differ
diff --git a/pc-bios/vgabios-vmware.bin b/pc-bios/vgabios-vmware.bin index d5f263a..119a2b1 100644 --- a/pc-bios/vgabios-vmware.bin +++ b/pc-bios/vgabios-vmware.bin Binary files differ
diff --git a/pc-bios/vgabios.bin b/pc-bios/vgabios.bin index d26af41..cac6131 100644 --- a/pc-bios/vgabios.bin +++ b/pc-bios/vgabios.bin Binary files differ
diff --git a/qapi/ui.json b/qapi/ui.json index 0abba3e..9832234 100644 --- a/qapi/ui.json +++ b/qapi/ui.json
@@ -886,6 +886,19 @@ # @lang1: since 6.1 # @lang2: since 6.1 # +# @f13: since 8.0 +# @f14: since 8.0 +# @f15: since 8.0 +# @f16: since 8.0 +# @f17: since 8.0 +# @f18: since 8.0 +# @f19: since 8.0 +# @f20: since 8.0 +# @f21: since 8.0 +# @f22: since 8.0 +# @f23: since 8.0 +# @f24: since 8.0 +# # 'sysrq' was mistakenly added to hack around the fact that # the ps2 driver was not generating correct scancodes sequences # when 'alt+print' was pressed. This flaw is now fixed and the @@ -918,7 +931,7 @@ 'volumeup', 'volumedown', 'mediaselect', 'mail', 'calculator', 'computer', 'ac_home', 'ac_back', 'ac_forward', 'ac_refresh', 'ac_bookmarks', - 'lang1', 'lang2' ] } + 'lang1', 'lang2','f13','f14','f15','f16','f17','f18','f19','f20','f21','f22','f23','f24' ] } ## # @KeyValueKind:
diff --git a/qemu-options.hx b/qemu-options.hx index d42f60f..59bdf67 100644 --- a/qemu-options.hx +++ b/qemu-options.hx
@@ -1606,7 +1606,7 @@ .. parsed-literal:: - |qemu_system_x86| -drive file=a -drive file=b" + |qemu_system_x86| -drive file=a -drive file=b is interpreted like:
diff --git a/roms/seabios b/roms/seabios index 3208b09..ea1b7a0 160000 --- a/roms/seabios +++ b/roms/seabios
@@ -1 +1 @@ -Subproject commit 3208b098f51a9ef96d0dfa71d5ec3a3eaec88f0a +Subproject commit ea1b7a0733906b8425d948ae94fba63c32b1d425
diff --git a/softmmu/vl.c b/softmmu/vl.c index 3340f63..ea20b23 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c
@@ -2465,10 +2465,11 @@ pid_file_realpath = g_malloc0(PATH_MAX); if (!realpath(pid_file, pid_file_realpath)) { - error_report("cannot resolve PID file path: %s: %s", - pid_file, strerror(errno)); - unlink(pid_file); - exit(1); + if (errno != ENOENT) { + warn_report("not removing PID file on exit: cannot resolve PID " + "file path: %s: %s", pid_file, strerror(errno)); + } + return; } qemu_unlink_pidfile_notifier = (struct UnlinkPidfileNotifier) {
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 1aef54f..de53184 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c
@@ -4991,6 +4991,7 @@ kvm_rate_limit_on_bus_lock(); } +#ifdef CONFIG_XEN_EMU /* * If the callback is asserted as a GSI (or PCI INTx) then check if * vcpu_info->evtchn_upcall_pending has been cleared, and deassert @@ -5001,6 +5002,7 @@ if (x86_cpu->env.xen_callback_asserted) { kvm_xen_maybe_deassert_callback(cpu); } +#endif /* We need to protect the apic state against concurrent accesses from * different threads in case the userspace irqchip is used. */
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index c9292b6..85ea4e8 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build
@@ -101,7 +101,7 @@ 'numa-test' ] -if dbus_display +if dbus_display and targetos != 'windows' qtests_i386 += ['dbus-display-test'] endif
diff --git a/ui/console.c b/ui/console.c index 98b701f..f378302 100644 --- a/ui/console.c +++ b/ui/console.c
@@ -94,6 +94,8 @@ uint32_t head; QemuUIInfo ui_info; QEMUTimer *ui_timer; + QEMUCursor *cursor; + int cursor_x, cursor_y, cursor_on; const GraphicHwOps *hw_ops; void *hw; @@ -1661,6 +1663,12 @@ con = active_console; } displaychangelistener_display_console(dcl, con, dcl->con ? &error_fatal : NULL); + if (con && con->cursor && dcl->ops->dpy_cursor_define) { + dcl->ops->dpy_cursor_define(dcl, con->cursor); + } + if (con && dcl->ops->dpy_mouse_set) { + dcl->ops->dpy_mouse_set(dcl, con->cursor_x, con->cursor_y, con->cursor_on); + } text_console_update_cursor(NULL); } @@ -1905,6 +1913,9 @@ DisplayState *s = con->ds; DisplayChangeListener *dcl; + con->cursor_x = x; + con->cursor_y = y; + con->cursor_on = on; if (!qemu_console_is_visible(con)) { return; } @@ -1923,6 +1934,8 @@ DisplayState *s = con->ds; DisplayChangeListener *dcl; + cursor_unref(con->cursor); + con->cursor = cursor_ref(cursor); if (!qemu_console_is_visible(con)) { return; } @@ -2288,6 +2301,11 @@ return NULL; } +QEMUCursor *qemu_console_get_cursor(QemuConsole *con) +{ + return con->cursor; +} + bool qemu_console_is_visible(QemuConsole *con) { return (con == active_console) || (con->dcls > 0);
diff --git a/ui/cursor.c b/ui/cursor.c index 835f080..6fe6799 100644 --- a/ui/cursor.c +++ b/ui/cursor.c
@@ -106,12 +106,13 @@ return c; } -void cursor_get(QEMUCursor *c) +QEMUCursor *cursor_ref(QEMUCursor *c) { c->refcount++; + return c; } -void cursor_put(QEMUCursor *c) +void cursor_unref(QEMUCursor *c) { if (c == NULL) return;
diff --git a/ui/dbus-clipboard.c b/ui/dbus-clipboard.c index df9a754..fe7fcde 100644 --- a/ui/dbus-clipboard.c +++ b/ui/dbus-clipboard.c
@@ -204,15 +204,6 @@ g_clear_object(&dpy->clipboard_proxy); } -static void -dbus_on_clipboard_proxy_name_owner_changed( - DBusDisplay *dpy, - GObject *object, - GParamSpec *pspec) -{ - dbus_clipboard_unregister_proxy(dpy); -} - static gboolean dbus_clipboard_register( DBusDisplay *dpy, @@ -220,6 +211,7 @@ { g_autoptr(GError) err = NULL; const char *name = NULL; + GDBusConnection *connection = g_dbus_method_invocation_get_connection(invocation); if (dpy->clipboard_proxy) { g_dbus_method_invocation_return_error( @@ -232,7 +224,7 @@ dpy->clipboard_proxy = qemu_dbus_display1_clipboard_proxy_new_sync( - g_dbus_method_invocation_get_connection(invocation), + connection, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, g_dbus_method_invocation_get_sender(invocation), "/org/qemu/Display1/Clipboard", @@ -252,7 +244,11 @@ g_object_connect(dpy->clipboard_proxy, "swapped-signal::notify::g-name-owner", - dbus_on_clipboard_proxy_name_owner_changed, dpy, + dbus_clipboard_unregister_proxy, dpy, + NULL); + g_object_connect(connection, + "swapped-signal::closed", + dbus_clipboard_unregister_proxy, dpy, NULL); qemu_clipboard_reset_serial();
diff --git a/ui/dbus-console.c b/ui/dbus-console.c index 0bfaa22..f77bc49 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c
@@ -412,14 +412,20 @@ } static void +dbus_mouse_update_is_absolute(DBusDisplayConsole *ddc) +{ + g_object_set(ddc->iface_mouse, + "is-absolute", qemu_input_is_absolute(), + NULL); +} + +static void dbus_mouse_mode_change(Notifier *notify, void *data) { DBusDisplayConsole *ddc = container_of(notify, DBusDisplayConsole, mouse_mode_notifier); - g_object_set(ddc->iface_mouse, - "is-absolute", qemu_input_is_absolute(), - NULL); + dbus_mouse_update_is_absolute(ddc); } int dbus_display_console_get_index(DBusDisplayConsole *ddc) @@ -492,6 +498,7 @@ register_displaychangelistener(&ddc->dcl); ddc->mouse_mode_notifier.notify = dbus_mouse_mode_change; qemu_add_mouse_mode_change_notifier(&ddc->mouse_mode_notifier); + dbus_mouse_update_is_absolute(ddc); return ddc; }
diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index 57d4e40..911acdc 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c
@@ -27,9 +27,11 @@ #include "dbus.h" #include <gio/gunixfdlist.h> +#ifdef CONFIG_OPENGL #include "ui/shader.h" #include "ui/egl-helpers.h" #include "ui/egl-context.h" +#endif #include "trace.h" struct _DBusDisplayListener { @@ -48,6 +50,7 @@ G_DEFINE_TYPE(DBusDisplayListener, dbus_display_listener, G_TYPE_OBJECT) +#ifdef CONFIG_GBM static void dbus_update_gl_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) @@ -149,7 +152,7 @@ DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl); DisplaySurface *ds; GVariant *v_data = NULL; - egl_fb cursor_fb; + egl_fb cursor_fb = EGL_FB_INIT; if (!dmabuf) { qemu_dbus_display1_listener_call_mouse_set( @@ -229,12 +232,14 @@ ddl->gl_updates = 0; } } +#endif static void dbus_refresh(DisplayChangeListener *dcl) { graphic_hw_update(dcl->con); } +#ifdef CONFIG_GBM static void dbus_gl_gfx_update(DisplayChangeListener *dcl, int x, int y, int w, int h) { @@ -242,6 +247,7 @@ ddl->gl_updates++; } +#endif static void dbus_gfx_update(DisplayChangeListener *dcl, int x, int y, int w, int h) @@ -296,6 +302,7 @@ DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL); } +#ifdef CONFIG_GBM static void dbus_gl_gfx_switch(DisplayChangeListener *dcl, struct DisplaySurface *new_surface) { @@ -311,6 +318,7 @@ width, height, 0, 0, width, height); } } +#endif static void dbus_gfx_switch(DisplayChangeListener *dcl, struct DisplaySurface *new_surface) @@ -339,14 +347,13 @@ DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl); GVariant *v_data = NULL; - cursor_get(c); v_data = g_variant_new_from_data( G_VARIANT_TYPE("ay"), c->data, c->width * c->height * 4, TRUE, - (GDestroyNotify)cursor_put, - c); + (GDestroyNotify)cursor_unref, + cursor_ref(c)); qemu_dbus_display1_listener_call_cursor_define( ddl->proxy, @@ -362,6 +369,7 @@ NULL); } +#ifdef CONFIG_GBM const DisplayChangeListenerOps dbus_gl_dcl_ops = { .dpy_name = "dbus-gl", .dpy_gfx_update = dbus_gl_gfx_update, @@ -379,6 +387,7 @@ .dpy_gl_release_dmabuf = dbus_release_dmabuf, .dpy_gl_update = dbus_scanout_update, }; +#endif const DisplayChangeListenerOps dbus_dcl_ops = { .dpy_name = "dbus", @@ -407,11 +416,12 @@ { DBusDisplayListener *ddl = DBUS_DISPLAY_LISTENER(object); + ddl->dcl.ops = &dbus_dcl_ops; +#ifdef CONFIG_GBM if (display_opengl) { ddl->dcl.ops = &dbus_gl_dcl_ops; - } else { - ddl->dcl.ops = &dbus_dcl_ops; } +#endif G_OBJECT_CLASS(dbus_display_listener_parent_class)->constructed(object); }
diff --git a/ui/dbus.c b/ui/dbus.c index f2dcba0..0513de9 100644 --- a/ui/dbus.c +++ b/ui/dbus.c
@@ -30,8 +30,10 @@ #include "qom/object_interfaces.h" #include "sysemu/sysemu.h" #include "ui/dbus-module.h" +#ifdef CONFIG_OPENGL #include "ui/egl-helpers.h" #include "ui/egl-context.h" +#endif #include "audio/audio.h" #include "audio/audio_int.h" #include "qapi/error.h" @@ -41,11 +43,14 @@ static DBusDisplay *dbus_display; +#ifdef CONFIG_OPENGL static QEMUGLContext dbus_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { +#ifdef CONFIG_GBM eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, qemu_egl_rn_ctx); +#endif return qemu_egl_create_context(dgc, params); } @@ -53,7 +58,11 @@ dbus_is_compatible_dcl(DisplayGLCtx *dgc, DisplayChangeListener *dcl) { - return dcl->ops == &dbus_gl_dcl_ops || dcl->ops == &dbus_console_dcl_ops; + return +#ifdef CONFIG_GBM + dcl->ops == &dbus_gl_dcl_ops || +#endif + dcl->ops == &dbus_console_dcl_ops; } static void @@ -84,6 +93,7 @@ .dpy_gl_ctx_destroy_texture = dbus_destroy_texture, .dpy_gl_ctx_update_texture = dbus_update_texture, }; +#endif static NotifierList dbus_display_notifiers = NOTIFIER_LIST_INITIALIZER(dbus_display_notifiers); @@ -112,10 +122,12 @@ DBusDisplay *dd = DBUS_DISPLAY(o); g_autoptr(GDBusObjectSkeleton) vm = NULL; +#ifdef CONFIG_OPENGL dd->glctx.ops = &dbus_gl_ops; if (display_opengl) { dd->glctx.gls = qemu_gl_init_shader(); } +#endif dd->iface = qemu_dbus_display1_vm_skeleton_new(); dd->consoles = g_ptr_array_new_with_free_func(g_object_unref); @@ -152,7 +164,9 @@ g_clear_object(&dd->iface); g_free(dd->dbus_addr); g_free(dd->audiodev); +#ifdef CONFIG_OPENGL g_clear_pointer(&dd->glctx.gls, qemu_gl_fini_shader); +#endif dbus_display = NULL; } @@ -220,7 +234,7 @@ dd->audiodev); return; } - audio_state->drv->set_dbus_server(audio_state, dd->server); + audio_state->drv->set_dbus_server(audio_state, dd->server, dd->p2p); } consoles = g_array_new(FALSE, FALSE, sizeof(guint32)); @@ -451,12 +465,11 @@ DisplayGLMode mode = opts->has_gl ? opts->gl : DISPLAYGL_MODE_OFF; if (mode != DISPLAYGL_MODE_OFF) { - if (egl_rendernode_init(opts->u.dbus.rendernode, mode) < 0) { - error_report("dbus: render node init failed"); - exit(1); - } - - display_opengl = 1; +#ifdef CONFIG_OPENGL + egl_init(opts->u.dbus.rendernode, mode, &error_fatal); +#else + error_report("dbus: GL rendering is not supported"); +#endif } type_register(&dbus_vc_type_info);
diff --git a/ui/egl-headless.c b/ui/egl-headless.c index ae07e91..ef70e6a 100644 --- a/ui/egl-headless.c +++ b/ui/egl-headless.c
@@ -1,7 +1,7 @@ #include "qemu/osdep.h" #include "qemu/error-report.h" #include "qemu/module.h" -#include "sysemu/sysemu.h" +#include "qapi/error.h" #include "ui/console.h" #include "ui/egl-helpers.h" #include "ui/egl-context.h" @@ -191,21 +191,21 @@ static void early_egl_headless_init(DisplayOptions *opts) { - display_opengl = 1; + DisplayGLMode mode = DISPLAYGL_MODE_ON; + + if (opts->has_gl) { + mode = opts->gl; + } + + egl_init(opts->u.egl_headless.rendernode, mode, &error_fatal); } static void egl_headless_init(DisplayState *ds, DisplayOptions *opts) { - DisplayGLMode mode = opts->has_gl ? opts->gl : DISPLAYGL_MODE_ON; QemuConsole *con; egl_dpy *edpy; int idx; - if (egl_rendernode_init(opts->u.egl_headless.rendernode, mode) < 0) { - error_report("egl: render node init failed"); - exit(1); - } - for (idx = 0;; idx++) { DisplayGLCtx *ctx;
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c index 3a88245..4203163 100644 --- a/ui/egl-helpers.c +++ b/ui/egl-helpers.c
@@ -19,6 +19,8 @@ #include "qemu/error-report.h" #include "ui/console.h" #include "ui/egl-helpers.h" +#include "sysemu/sysemu.h" +#include "qapi/error.h" EGLDisplay *qemu_egl_display; EGLConfig qemu_egl_config; @@ -26,6 +28,48 @@ /* ------------------------------------------------------------------ */ +#if defined(CONFIG_X11) || defined(CONFIG_GBM) +static const char *egl_get_error_string(void) +{ + EGLint error = eglGetError(); + + switch (error) { + case EGL_SUCCESS: + return "EGL_SUCCESS"; + case EGL_NOT_INITIALIZED: + return "EGL_NOT_INITIALIZED"; + case EGL_BAD_ACCESS: + return "EGL_BAD_ACCESS"; + case EGL_BAD_ALLOC: + return "EGL_BAD_ALLOC"; + case EGL_BAD_ATTRIBUTE: + return "EGL_BAD_ATTRIBUTE"; + case EGL_BAD_CONTEXT: + return "EGL_BAD_CONTEXT"; + case EGL_BAD_CONFIG: + return "EGL_BAD_CONFIG"; + case EGL_BAD_CURRENT_SURFACE: + return "EGL_BAD_CURRENT_SURFACE"; + case EGL_BAD_DISPLAY: + return "EGL_BAD_DISPLAY"; + case EGL_BAD_SURFACE: + return "EGL_BAD_SURFACE"; + case EGL_BAD_MATCH: + return "EGL_BAD_MATCH"; + case EGL_BAD_PARAMETER: + return "EGL_BAD_PARAMETER"; + case EGL_BAD_NATIVE_PIXMAP: + return "EGL_BAD_NATIVE_PIXMAP"; + case EGL_BAD_NATIVE_WINDOW: + return "EGL_BAD_NATIVE_WINDOW"; + case EGL_CONTEXT_LOST: + return "EGL_CONTEXT_LOST"; + default: + return "Unknown EGL error"; + } +} +#endif + static void egl_fb_delete_texture(egl_fb *fb) { if (!fb->delete_texture) { @@ -438,20 +482,20 @@ qemu_egl_display = qemu_egl_get_display(dpy, platform); if (qemu_egl_display == EGL_NO_DISPLAY) { - error_report("egl: eglGetDisplay failed"); + error_report("egl: eglGetDisplay failed: %s", egl_get_error_string()); return -1; } b = eglInitialize(qemu_egl_display, &major, &minor); if (b == EGL_FALSE) { - error_report("egl: eglInitialize failed"); + error_report("egl: eglInitialize failed: %s", egl_get_error_string()); return -1; } b = eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API); if (b == EGL_FALSE) { - error_report("egl: eglBindAPI failed (%s mode)", - gles ? "gles" : "core"); + error_report("egl: eglBindAPI failed (%s mode): %s", + gles ? "gles" : "core", egl_get_error_string()); return -1; } @@ -459,8 +503,8 @@ gles ? conf_att_gles : conf_att_core, &qemu_egl_config, 1, &n); if (b == EGL_FALSE || n != 1) { - error_report("egl: eglChooseConfig failed (%s mode)", - gles ? "gles" : "core"); + error_report("egl: eglChooseConfig failed (%s mode): %s", + gles ? "gles" : "core", egl_get_error_string()); return -1; } @@ -527,3 +571,25 @@ return ectx; } + +bool egl_init(const char *rendernode, DisplayGLMode mode, Error **errp) +{ + ERRP_GUARD(); + + if (mode == DISPLAYGL_MODE_OFF) { + error_setg(errp, "egl: turning off GL doesn't make sense"); + return false; + } + +#ifdef CONFIG_GBM + if (egl_rendernode_init(rendernode, mode) < 0) { + error_setg(errp, "egl: render node init failed"); + return false; + } + display_opengl = 1; + return true; +#else + error_setg(errp, "egl: not available on this platform"); + return false; +#endif +}
diff --git a/ui/keycodemapdb b/ui/keycodemapdb index d21009b..f5772a6 160000 --- a/ui/keycodemapdb +++ b/ui/keycodemapdb
@@ -1 +1 @@ -Subproject commit d21009b1c9f94b740ea66be8e48a1d8ad8124023 +Subproject commit f5772a62ec52591ff6870b7e8ef32482371f22c6
diff --git a/ui/meson.build b/ui/meson.build index 612ea23..3303697 100644 --- a/ui/meson.build +++ b/ui/meson.build
@@ -83,7 +83,9 @@ '--interface-prefix', 'org.qemu.', '--c-namespace', 'QemuDBus', '--generate-c-code', '@BASENAME@']) - dbus_ss.add(when: [gio, pixman, opengl, gbm], + dbus_display1_lib = static_library('dbus-display1', dbus_display1, dependencies: gio) + dbus_display1_dep = declare_dependency(link_with: dbus_display1_lib, include_directories: include_directories('.')) + dbus_ss.add(when: [gio, pixman, dbus_display1_dep], if_true: [files( 'dbus-chardev.c', 'dbus-clipboard.c', @@ -91,7 +93,7 @@ 'dbus-error.c', 'dbus-listener.c', 'dbus.c', - ), dbus_display1]) + ), opengl, gbm]) ui_modules += {'dbus' : dbus_ss} endif
diff --git a/ui/sdl2.c b/ui/sdl2.c index 8cb7741..35c58c1 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c
@@ -58,6 +58,11 @@ #define SDL2_MAX_IDLE_COUNT (2 * GUI_REFRESH_INTERVAL_DEFAULT \ / SDL2_REFRESH_INTERVAL_BUSY + 1) +/* introduced in SDL 2.0.10 */ +#ifndef SDL_HINT_RENDER_BATCHING +#define SDL_HINT_RENDER_BATCHING "SDL_RENDER_BATCHING" +#endif + static void sdl_update_caption(struct sdl2_console *scon); static struct sdl2_console *get_scon_from_window(uint32_t window_id) @@ -99,9 +104,20 @@ surface_width(scon->surface), surface_height(scon->surface), flags); - scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0); if (scon->opengl) { - scon->winctx = SDL_GL_GetCurrentContext(); + const char *driver = "opengl"; + + if (scon->opts->gl == DISPLAYGL_MODE_ES) { + driver = "opengles2"; + } + + SDL_SetHint(SDL_HINT_RENDER_DRIVER, driver); + SDL_SetHint(SDL_HINT_RENDER_BATCHING, "1"); + } + scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0); + + if (scon->opengl) { + scon->winctx = SDL_GL_CreateContext(scon->real_window); } sdl_update_caption(scon); } @@ -112,6 +128,8 @@ return; } + SDL_GL_DeleteContext(scon->winctx); + scon->winctx = NULL; SDL_DestroyRenderer(scon->real_renderer); scon->real_renderer = NULL; SDL_DestroyWindow(scon->real_window); @@ -841,6 +859,10 @@ } #endif + if (SDL_GetHintBoolean("QEMU_ENABLE_SDL_LOGGING", SDL_FALSE)) { + SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE); + } + if (SDL_Init(SDL_INIT_VIDEO)) { fprintf(stderr, "Could not initialize SDL(%s) - exiting\n", SDL_GetError());
diff --git a/ui/shader/texture-blit-flip.vert b/ui/shader/texture-blit-flip.vert index ba081fa..f7a448d 100644 --- a/ui/shader/texture-blit-flip.vert +++ b/ui/shader/texture-blit-flip.vert
@@ -1,4 +1,3 @@ - #version 300 es in vec2 in_position;
diff --git a/ui/shader/texture-blit.frag b/ui/shader/texture-blit.frag index bfa202c..8ed95a4 100644 --- a/ui/shader/texture-blit.frag +++ b/ui/shader/texture-blit.frag
@@ -1,4 +1,3 @@ - #version 300 es uniform sampler2D image;
diff --git a/ui/shader/texture-blit.vert b/ui/shader/texture-blit.vert index 6fe2744..fb48d70 100644 --- a/ui/shader/texture-blit.vert +++ b/ui/shader/texture-blit.vert
@@ -1,4 +1,3 @@ - #version 300 es in vec2 in_position;
diff --git a/ui/spice-core.c b/ui/spice-core.c index 76f7c2b..b05c830 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c
@@ -820,12 +820,7 @@ "incompatible with -spice port/tls-port"); exit(1); } - if (egl_rendernode_init(qemu_opt_get(opts, "rendernode"), - DISPLAYGL_MODE_ON) != 0) { - error_report("Failed to initialize EGL render node for SPICE GL"); - exit(1); - } - display_opengl = 1; + egl_init(qemu_opt_get(opts, "rendernode"), DISPLAYGL_MODE_ON, &error_fatal); spice_opengl = 1; } #endif
diff --git a/ui/spice-display.c b/ui/spice-display.c index 16802f9..5bee19a 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c
@@ -460,11 +460,11 @@ 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) { @@ -765,8 +765,8 @@ 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;
diff --git a/ui/vnc.c b/ui/vnc.c index d9eacad..bbd8b6b 100644 --- a/ui/vnc.c +++ b/ui/vnc.c
@@ -988,10 +988,10 @@ static int vnc_cursor_define(VncState *vs) { - QEMUCursor *c = vs->vd->cursor; + QEMUCursor *c = qemu_console_get_cursor(vs->vd->dcl.con); int isize; - if (!vs->vd->cursor) { + if (!c) { return -1; } @@ -1029,11 +1029,7 @@ VncDisplay *vd = container_of(dcl, VncDisplay, dcl); VncState *vs; - cursor_put(vd->cursor); g_free(vd->cursor_mask); - - vd->cursor = c; - cursor_get(vd->cursor); vd->cursor_msize = cursor_get_mono_bpl(c) * c->height; vd->cursor_mask = g_malloc0(vd->cursor_msize); cursor_get_mono_mask(c, 0, vd->cursor_mask);
diff --git a/ui/vnc.h b/ui/vnc.h index a60fb13..757fa83 100644 --- a/ui/vnc.h +++ b/ui/vnc.h
@@ -159,7 +159,6 @@ QKbdState *kbd; QemuMutex mutex; - QEMUCursor *cursor; int cursor_msize; uint8_t *cursor_mask;