get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.1/patches/2222113/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2222113,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2222113/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260410-qemu-vnc-v2-59-231416f76dc3@redhat.com/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/1.1/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20260410-qemu-vnc-v2-59-231416f76dc3@redhat.com>",
    "date": "2026-04-10T19:19:21",
    "name": "[v2,59/67] ui/console: return completion status from gfx_update callback",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "e98cfc93b987889ad204b167c345f017f65ef8b9",
    "submitter": {
        "id": 66774,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/66774/?format=api",
        "name": "Marc-André Lureau",
        "email": "marcandre.lureau@redhat.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260410-qemu-vnc-v2-59-231416f76dc3@redhat.com/mbox/",
    "series": [
        {
            "id": 499494,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/499494/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=499494",
            "date": "2026-04-10T19:18:23",
            "name": "ui: add standalone VNC server over D-Bus",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/499494/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2222113/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2222113/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=RgNDuCRH;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"
        ],
        "Received": [
            "from lists.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fsmxy75Ncz20HT\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 11 Apr 2026 05:26:30 +1000 (AEST)",
            "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wBHTV-0007FS-Oo; Fri, 10 Apr 2026 15:25:05 -0400",
            "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <marcandre.lureau@redhat.com>)\n id 1wBHTU-0007DI-7X\n for qemu-devel@nongnu.org; Fri, 10 Apr 2026 15:25:04 -0400",
            "from us-smtp-delivery-124.mimecast.com ([170.10.129.124])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <marcandre.lureau@redhat.com>)\n id 1wBHTH-0002gM-1Z\n for qemu-devel@nongnu.org; Fri, 10 Apr 2026 15:25:02 -0400",
            "from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-213--d8fSAlGO7qyPmXRR_9Rwg-1; Fri,\n 10 Apr 2026 15:24:47 -0400",
            "from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id DC0811956048\n for <qemu-devel@nongnu.org>; Fri, 10 Apr 2026 19:24:46 +0000 (UTC)",
            "from localhost (unknown [10.44.22.4])\n by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id 5BD943000C16; Fri, 10 Apr 2026 19:24:44 +0000 (UTC)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1775849089;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=ahTXwuHJ3Od5hMMGNd/7C8KkYPiPeYMk6TBMZEOyPKA=;\n b=RgNDuCRHQ3DQ4vQs3l8NvMT4qIzOx3DwSTArQFpIPxshkpQiCw5mRkmoS9D5C6zB6flTOb\n Yp/+Cj7NJItYHS9zMyhPKu0MX2SEog4zjHRAiWod+WveeXL1wdTSU4Xg0s6Z3BPjTPGjh4\n 62xCKjNlJokNT6PQgFzt1WA61OpQBGw=",
        "X-MC-Unique": "-d8fSAlGO7qyPmXRR_9Rwg-1",
        "X-Mimecast-MFC-AGG-ID": "-d8fSAlGO7qyPmXRR_9Rwg_1775849087",
        "From": "=?utf-8?q?Marc-Andr=C3=A9_Lureau?= <marcandre.lureau@redhat.com>",
        "Date": "Fri, 10 Apr 2026 23:19:21 +0400",
        "Subject": "[PATCH v2 59/67] ui/console: return completion status from\n gfx_update callback",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "8bit",
        "Message-Id": "<20260410-qemu-vnc-v2-59-231416f76dc3@redhat.com>",
        "References": "<20260410-qemu-vnc-v2-0-231416f76dc3@redhat.com>",
        "In-Reply-To": "<20260410-qemu-vnc-v2-0-231416f76dc3@redhat.com>",
        "To": "qemu-devel@nongnu.org",
        "Cc": "=?utf-8?q?Marc-Andr=C3=A9_Lureau?= <marcandre.lureau@redhat.com>",
        "X-Developer-Signature": "v=1; a=openpgp-sha256; l=32661;\n i=marcandre.lureau@redhat.com; h=from:subject:message-id;\n bh=f1MZpNWd6L/E8ww/JR0yGJWZTQYcaLX1hJlpqsiNBvw=;\n b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp2U0WvUn8mEFvUMP8jBeLFt8sgBpnejipjFyWw\n fg2MRwezfeJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCadlNFgAKCRDa6OEJdZac\n 5Sc7D/90+SraAZdc0hYSERPXEStlEPV9a9jOX+k5C8+XjNGXxoFuNl61QxVH5nPFNzkEQdfePEj\n la5sji/PQVp9t7cdPUCTYNVBbeQn5H5y9Z8Ynm1cuEbPcjHlfK+APpxWGFErBjDW/r9pUrs6U/5\n tXBce4V6Laf0XZ5ooR4NGo0NwgiuEU2bnZ5luTDsIQ4M3eioXyBMPAvTkS9ljQoP2LCIE0/S7x+\n dLvPfQlL22Nr1nECwPnLWg0zwwNxLXBOCNn6rK5Qh6mUU5oICbTAXp9SoY7lNpzGYz2aIf/PZFj\n Vd4FjlpCZVVsiHicTz0TYbUiM0OnzOZzcEFTdTL3pqCmnts3JUQtUuA9N8cTao6eo4YTzijAyJD\n 2ckJb/c2dM4ymaBkFGRulPD484QQ/2MycTaoD8vszqEuiPvHTHgBaIErAuilyFc6NW/zE6PI+G0\n Ba5VdxesSxV3qBKuwa06moTwbCiy/XCubQEw42y8e3zEiT2VixqoRcwZTHK83MMog3gt1PpNpL1\n Hvs8WdI6X4voR7UU4p3UNxU9qfYxJmkVCgAGHrbtMBIAxpOX3SScrbWTFpYEQLpr5b78NG8r8Hx\n yM0fPhhg9R2MTyIOH+ulUAgK5zBz0bIz4e6np/mjHVSXVAZBn11X7ispTOgdJU04QL5QYsH6rq2\n C6qEfPhwOK5o3+g==",
        "X-Developer-Key": "i=marcandre.lureau@redhat.com; a=openpgp;\n fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5",
        "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.4",
        "Received-SPF": "pass client-ip=170.10.129.124;\n envelope-from=marcandre.lureau@redhat.com;\n helo=us-smtp-delivery-124.mimecast.com",
        "X-Spam_score_int": "7",
        "X-Spam_score": "0.7",
        "X-Spam_bar": "/",
        "X-Spam_report": "(0.7 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.54,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001,\n RCVD_IN_SBL_CSS=3.335, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001,\n RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001,\n SPF_PASS=-0.001 autolearn=no autolearn_force=no",
        "X-Spam_action": "no action",
        "X-BeenThere": "qemu-devel@nongnu.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "qemu development <qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"
    },
    "content": "Replace the two-field design (gfx_update void callback + gfx_update_async\nflag) with a single bool return value from gfx_update. Returning true\nmeans the update completed synchronously and graphic_hw_update_done()\nshould be called by the console layer. Returning false means the update\nis deferred and the device will call graphic_hw_update_done() itself\nlater (as done by QXL/SPICE and Apple GFX).\n\nThis simplifies the interface and makes the async contract explicit at\neach call site rather than relying on a separate struct field.\n\nSigned-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>\n---\n hw/display/qxl.h              |  2 +-\n include/ui/console.h          |  9 +++++++--\n hw/arm/musicpal.c             |  3 ++-\n hw/display/artist.c           |  4 +++-\n hw/display/bcm2835_fb.c       |  7 ++++---\n hw/display/bochs-display.c    |  6 ++++--\n hw/display/cg3.c              |  5 +++--\n hw/display/dm163.c            |  4 +++-\n hw/display/exynos4210_fimd.c  |  6 ++++--\n hw/display/g364fb.c           |  9 ++++++---\n hw/display/jazz_led.c         |  6 ++++--\n hw/display/macfb.c            |  6 ++++--\n hw/display/next-fb.c          |  4 +++-\n hw/display/omap_lcdc.c        | 14 ++++++++------\n hw/display/pl110.c            |  5 +++--\n hw/display/qxl-render.c       |  6 +++---\n hw/display/qxl.c              |  7 +++----\n hw/display/ramfb-standalone.c |  4 +++-\n hw/display/sm501.c            |  8 +++++---\n hw/display/ssd0303.c          | 10 ++++++----\n hw/display/ssd0323.c          | 11 ++++++-----\n hw/display/tcx.c              |  6 ++++--\n hw/display/vga.c              |  4 +++-\n hw/display/virtio-gpu-base.c  |  3 ++-\n hw/display/virtio-vga.c       |  6 +++---\n hw/display/vmware_vga.c       |  7 ++++---\n hw/display/xenfb.c            |  6 ++++--\n hw/display/xlnx_dp.c          | 10 ++++++----\n hw/vfio/display.c             | 17 ++++++++++-------\n ui/console.c                  |  7 +------\n hw/display/apple-gfx.m        | 10 +++++-----\n 31 files changed, 127 insertions(+), 85 deletions(-)",
    "diff": "diff --git a/hw/display/qxl.h b/hw/display/qxl.h\nindex e0a85a5ca49..ad8a9128785 100644\n--- a/hw/display/qxl.h\n+++ b/hw/display/qxl.h\n@@ -187,7 +187,7 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);\n \n /* qxl-render.c */\n void qxl_render_resize(PCIQXLDevice *qxl);\n-void qxl_render_update(PCIQXLDevice *qxl);\n+bool qxl_render_update(PCIQXLDevice *qxl);\n int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);\n void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie);\n void qxl_render_update_area_bh(void *opaque);\ndiff --git a/include/ui/console.h b/include/ui/console.h\nindex 823d3b819b2..c93ab7d619e 100644\n--- a/include/ui/console.h\n+++ b/include/ui/console.h\n@@ -363,8 +363,13 @@ enum {\n typedef struct GraphicHwOps {\n     int (*get_flags)(void *opaque); /* optional, default 0 */\n     void (*invalidate)(void *opaque);\n-    void (*gfx_update)(void *opaque);\n-    bool gfx_update_async; /* if true, calls graphic_hw_update_done() */\n+    /*\n+     * Returns true if the update is handled synchronously, false if deferred\n+     * and graphic_hw_update_done() will be called when ready (to resume waiting\n+     * tasks/coroutines).\n+     * Optional.\n+     */\n+    bool (*gfx_update)(void *opaque);\n     void (*text_update)(void *opaque, uint32_t *text);\n     void (*ui_info)(void *opaque, uint32_t head, QemuUIInfo *info);\n     void (*gl_block)(void *opaque, bool block);\ndiff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c\nindex 250fdb49b6f..913f98b5d8e 100644\n--- a/hw/arm/musicpal.c\n+++ b/hw/arm/musicpal.c\n@@ -153,7 +153,7 @@ static inline void set_lcd_pixel32(musicpal_lcd_state *s,\n     }\n }\n \n-static void lcd_refresh(void *opaque)\n+static bool lcd_refresh(void *opaque)\n {\n     musicpal_lcd_state *s = opaque;\n     int x, y, col;\n@@ -172,6 +172,7 @@ static void lcd_refresh(void *opaque)\n     }\n \n     dpy_gfx_update(s->con, 0, 0, 128*3, 64*3);\n+    return true;\n }\n \n static void lcd_invalidate(void *opaque)\ndiff --git a/hw/display/artist.c b/hw/display/artist.c\nindex 206f77afba1..a07508378c7 100644\n--- a/hw/display/artist.c\n+++ b/hw/display/artist.c\n@@ -1311,7 +1311,7 @@ static void artist_draw_line(void *opaque, uint8_t *d, const uint8_t *src,\n     }\n }\n \n-static void artist_update_display(void *opaque)\n+static bool artist_update_display(void *opaque)\n {\n     ARTISTState *s = opaque;\n     DisplaySurface *surface = qemu_console_surface(s->con);\n@@ -1326,6 +1326,8 @@ static void artist_update_display(void *opaque)\n     if (first >= 0) {\n         dpy_gfx_update(s->con, 0, first, s->width, last - first + 1);\n     }\n+\n+    return true;\n }\n \n static void artist_invalidate(void *opaque)\ndiff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c\nindex 75d7c0f8499..83c4c03c7ca 100644\n--- a/hw/display/bcm2835_fb.c\n+++ b/hw/display/bcm2835_fb.c\n@@ -150,7 +150,7 @@ static bool fb_use_offsets(BCM2835FBConfig *config)\n         config->yres_virtual > config->yres;\n }\n \n-static void fb_update_display(void *opaque)\n+static bool fb_update_display(void *opaque)\n {\n     BCM2835FBState *s = opaque;\n     DisplaySurface *surface = qemu_console_surface(s->con);\n@@ -161,7 +161,7 @@ static void fb_update_display(void *opaque)\n     uint32_t xoff = 0, yoff = 0;\n \n     if (s->lock || !s->config.xres) {\n-        return;\n+        return true;\n     }\n \n     src_width = bcm2835_fb_get_pitch(&s->config);\n@@ -174,7 +174,7 @@ static void fb_update_display(void *opaque)\n \n     switch (surface_bits_per_pixel(surface)) {\n     case 0:\n-        return;\n+        return true;\n     case 8:\n         break;\n     case 15:\n@@ -212,6 +212,7 @@ static void fb_update_display(void *opaque)\n     }\n \n     s->invalidate = false;\n+    return true;\n }\n \n void bcm2835_fb_validate_config(BCM2835FBConfig *config)\ndiff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c\nindex 5fb6b733cb5..8ef9b76cf85 100644\n--- a/hw/display/bochs-display.c\n+++ b/hw/display/bochs-display.c\n@@ -198,7 +198,7 @@ static int bochs_display_get_mode(BochsDisplayState *s,\n     return 0;\n }\n \n-static void bochs_display_update(void *opaque)\n+static bool bochs_display_update(void *opaque)\n {\n     BochsDisplayState *s = opaque;\n     DirtyBitmapSnapshot *snap = NULL;\n@@ -212,7 +212,7 @@ static void bochs_display_update(void *opaque)\n     ret = bochs_display_get_mode(s, &mode);\n     if (ret < 0) {\n         /* no (valid) video mode */\n-        return;\n+        return true;\n     }\n \n     if (memcmp(&s->mode, &mode, sizeof(mode)) != 0) {\n@@ -255,6 +255,8 @@ static void bochs_display_update(void *opaque)\n \n         g_free(snap);\n     }\n+\n+    return true;\n }\n \n static const GraphicHwOps bochs_display_gfx_ops = {\ndiff --git a/hw/display/cg3.c b/hw/display/cg3.c\nindex 0a413fbb7ec..963bb3427a6 100644\n--- a/hw/display/cg3.c\n+++ b/hw/display/cg3.c\n@@ -85,7 +85,7 @@ struct CG3State {\n     uint8_t dac_index, dac_state;\n };\n \n-static void cg3_update_display(void *opaque)\n+static bool cg3_update_display(void *opaque)\n {\n     CG3State *s = opaque;\n     DisplaySurface *surface = qemu_console_surface(s->con);\n@@ -98,7 +98,7 @@ static void cg3_update_display(void *opaque)\n     DirtyBitmapSnapshot *snap = NULL;\n \n     if (surface_bits_per_pixel(surface) != 32) {\n-        return;\n+        return true;\n     }\n     width = s->width;\n     height = s->height;\n@@ -154,6 +154,7 @@ static void cg3_update_display(void *opaque)\n         qemu_irq_raise(s->irq);\n     }\n     g_free(snap);\n+    return true;\n }\n \n static void cg3_invalidate_display(void *opaque)\ndiff --git a/hw/display/dm163.c b/hw/display/dm163.c\nindex 4feae912945..9ea62cb4f76 100644\n--- a/hw/display/dm163.c\n+++ b/hw/display/dm163.c\n@@ -285,7 +285,7 @@ static uint32_t *update_display_of_row(DM163State *s, uint32_t *dest,\n     return dest;\n }\n \n-static void dm163_update_display(void *opaque)\n+static bool dm163_update_display(void *opaque)\n {\n     DM163State *s = (DM163State *)opaque;\n     DisplaySurface *surface = qemu_console_surface(s->console);\n@@ -300,6 +300,8 @@ static void dm163_update_display(void *opaque)\n         }\n         dest = update_display_of_row(s, dest, row);\n     }\n+\n+    return true;\n }\n \n static const GraphicHwOps dm163_ops = {\ndiff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c\nindex 2d8fa7ee944..a91f04aaf79 100644\n--- a/hw/display/exynos4210_fimd.c\n+++ b/hw/display/exynos4210_fimd.c\n@@ -1270,7 +1270,7 @@ static void exynos4210_update_resolution(Exynos4210fimdState *s)\n     }\n }\n \n-static void exynos4210_fimd_update(void *opaque)\n+static bool exynos4210_fimd_update(void *opaque)\n {\n     Exynos4210fimdState *s = (Exynos4210fimdState *)opaque;\n     DisplaySurface *surface;\n@@ -1287,7 +1287,7 @@ static void exynos4210_fimd_update(void *opaque)\n \n     if (!s || !s->console || !s->enabled ||\n         surface_bits_per_pixel(qemu_console_surface(s->console)) == 0) {\n-        return;\n+        return true;\n     }\n \n     global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;\n@@ -1348,6 +1348,8 @@ static void exynos4210_fimd_update(void *opaque)\n         exynos4210_fimd_enable(s, false);\n     }\n     exynos4210_fimd_update_irq(s);\n+\n+    return true;\n }\n \n static void exynos4210_fimd_reset(DeviceState *d)\ndiff --git a/hw/display/g364fb.c b/hw/display/g364fb.c\nindex 50952e9934b..bd15f6f0acc 100644\n--- a/hw/display/g364fb.c\n+++ b/hw/display/g364fb.c\n@@ -238,15 +238,16 @@ static void g364fb_draw_blank(G364State *s)\n     s->blanked = 1;\n }\n \n-static void g364fb_update_display(void *opaque)\n+static bool g364fb_update_display(void *opaque)\n {\n     G364State *s = opaque;\n     DisplaySurface *surface = qemu_console_surface(s->con);\n \n     qemu_flush_coalesced_mmio_buffer();\n \n-    if (s->width == 0 || s->height == 0)\n-        return;\n+    if (s->width == 0 || s->height == 0) {\n+        return true;\n+    }\n \n     if (s->width != surface_width(surface) ||\n         s->height != surface_height(surface)) {\n@@ -262,6 +263,8 @@ static void g364fb_update_display(void *opaque)\n     }\n \n     qemu_irq_raise(s->irq);\n+\n+    return true;\n }\n \n static inline void g364fb_invalidate_display(void *opaque)\ndiff --git a/hw/display/jazz_led.c b/hw/display/jazz_led.c\nindex d5783982950..ee9758a94b5 100644\n--- a/hw/display/jazz_led.c\n+++ b/hw/display/jazz_led.c\n@@ -144,7 +144,7 @@ static void draw_vertical_line(DisplaySurface *ds,\n     }\n }\n \n-static void jazz_led_update_display(void *opaque)\n+static bool jazz_led_update_display(void *opaque)\n {\n     LedState *s = opaque;\n     DisplaySurface *surface = qemu_console_surface(s->con);\n@@ -186,7 +186,7 @@ static void jazz_led_update_display(void *opaque)\n             color_led = rgb_to_pixel32(0x00, 0xff, 0x00);\n             break;\n         default:\n-            return;\n+            return true;\n         }\n \n         /* display segments */\n@@ -218,6 +218,8 @@ static void jazz_led_update_display(void *opaque)\n \n     s->state = REDRAW_NONE;\n     dpy_gfx_update_full(s->con);\n+\n+    return true;\n }\n \n static void jazz_led_invalidate_display(void *opaque)\ndiff --git a/hw/display/macfb.c b/hw/display/macfb.c\nindex b8115c2be13..848c3c282bd 100644\n--- a/hw/display/macfb.c\n+++ b/hw/display/macfb.c\n@@ -454,7 +454,7 @@ static gchar *macfb_mode_list(void)\n }\n \n \n-static void macfb_update_display(void *opaque)\n+static bool macfb_update_display(void *opaque)\n {\n     MacfbState *s = opaque;\n     DisplaySurface *surface = qemu_console_surface(s->con);\n@@ -462,7 +462,7 @@ static void macfb_update_display(void *opaque)\n     qemu_flush_coalesced_mmio_buffer();\n \n     if (s->width == 0 || s->height == 0) {\n-        return;\n+        return true;\n     }\n \n     if (s->width != surface_width(surface) ||\n@@ -471,6 +471,8 @@ static void macfb_update_display(void *opaque)\n     }\n \n     macfb_draw_graphic(s);\n+\n+    return true;\n }\n \n static void macfb_update_irq(MacfbState *s)\ndiff --git a/hw/display/next-fb.c b/hw/display/next-fb.c\nindex 3d97702fce5..e758b223ef7 100644\n--- a/hw/display/next-fb.c\n+++ b/hw/display/next-fb.c\n@@ -67,7 +67,7 @@ static void nextfb_draw_line(void *opaque, uint8_t *d, const uint8_t *s,\n     }\n }\n \n-static void nextfb_update(void *opaque)\n+static bool nextfb_update(void *opaque)\n {\n     NeXTFbState *s = NEXTFB(opaque);\n     int dest_width = 4;\n@@ -90,6 +90,8 @@ static void nextfb_update(void *opaque)\n                                s, &first, &last);\n \n     dpy_gfx_update(s->con, 0, 0, s->cols, s->rows);\n+\n+    return true;\n }\n \n static void nextfb_invalidate(void *opaque)\ndiff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c\nindex c41c65bb2e0..1e8385ebffb 100644\n--- a/hw/display/omap_lcdc.c\n+++ b/hw/display/omap_lcdc.c\n@@ -197,7 +197,7 @@ static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,\n     } while (-- width != 0);\n }\n \n-static void omap_update_display(void *opaque)\n+static bool omap_update_display(void *opaque)\n {\n     struct omap_lcd_panel_s *omap_lcd = opaque;\n     DisplaySurface *surface;\n@@ -207,12 +207,12 @@ static void omap_update_display(void *opaque)\n     hwaddr frame_base;\n \n     if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable) {\n-        return;\n+        return true;\n     }\n \n     surface = qemu_console_surface(omap_lcd->con);\n     if (!surface_bits_per_pixel(surface)) {\n-        return;\n+        return true;\n     }\n \n     frame_offset = 0;\n@@ -256,7 +256,7 @@ static void omap_update_display(void *opaque)\n \n     default:\n         /* Unsupported at the moment.  */\n-        return;\n+        return true;\n     }\n \n     /* Resolution */\n@@ -278,7 +278,7 @@ static void omap_update_display(void *opaque)\n         omap_lcd->sync_error = 1;\n         omap_lcd_interrupts(omap_lcd);\n         omap_lcd->enable = 0;\n-        return;\n+        return true;\n     }\n \n     /* Content */\n@@ -291,7 +291,7 @@ static void omap_update_display(void *opaque)\n         omap_lcd->dma->current_frame ^= 1;\n \n     if (!surface_bits_per_pixel(surface)) {\n-        return;\n+        return true;\n     }\n \n     first = 0;\n@@ -323,6 +323,8 @@ static void omap_update_display(void *opaque)\n         dpy_gfx_update(omap_lcd->con, 0, first, width, last - first + 1);\n     }\n     omap_lcd->invalidate = 0;\n+\n+    return true;\n }\n \n static void omap_invalidate_display(void *opaque) {\ndiff --git a/hw/display/pl110.c b/hw/display/pl110.c\nindex 4cd62a98757..e134ac28eb6 100644\n--- a/hw/display/pl110.c\n+++ b/hw/display/pl110.c\n@@ -210,7 +210,7 @@ static int pl110_enabled(PL110State *s)\n   return (s->cr & PL110_CR_EN) && (s->cr & PL110_CR_PWR);\n }\n \n-static void pl110_update_display(void *opaque)\n+static bool pl110_update_display(void *opaque)\n {\n     PL110State *s = (PL110State *)opaque;\n     DisplaySurface *surface = qemu_console_surface(s->con);\n@@ -221,7 +221,7 @@ static void pl110_update_display(void *opaque)\n     int last;\n \n     if (!pl110_enabled(s)) {\n-        return;\n+        return true;\n     }\n \n     if (s->cr & PL110_CR_BGR)\n@@ -306,6 +306,7 @@ static void pl110_update_display(void *opaque)\n         dpy_gfx_update(s->con, 0, first, s->cols, last - first + 1);\n     }\n     s->invalidate = 0;\n+    return true;\n }\n \n static void pl110_invalidate_display(void * opaque)\ndiff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c\nindex c6a9ac1da10..5b4f8842011 100644\n--- a/hw/display/qxl-render.c\n+++ b/hw/display/qxl-render.c\n@@ -173,7 +173,7 @@ end:\n  * callbacks are called by spice_server thread, deferring to bh called from the\n  * io thread.\n  */\n-void qxl_render_update(PCIQXLDevice *qxl)\n+bool qxl_render_update(PCIQXLDevice *qxl)\n {\n     QXLCookie *cookie;\n \n@@ -183,8 +183,7 @@ void qxl_render_update(PCIQXLDevice *qxl)\n         qxl->mode == QXL_MODE_UNDEFINED) {\n         qxl_render_update_area_unlocked(qxl);\n         qemu_mutex_unlock(&qxl->ssd.lock);\n-        graphic_hw_update_done(qxl->ssd.dcl.con);\n-        return;\n+        return true;\n     }\n \n     qxl->guest_primary.commands = 0;\n@@ -195,6 +194,7 @@ void qxl_render_update(PCIQXLDevice *qxl)\n     qxl_set_rect_to_surface(qxl, &cookie->u.render.area);\n     qxl_spice_update_area(qxl, 0, &cookie->u.render.area, NULL,\n                           0, 1 /* clear_dirty_region */, QXL_ASYNC, cookie);\n+    return false;\n }\n \n void qxl_render_update_area_bh(void *opaque)\ndiff --git a/hw/display/qxl.c b/hw/display/qxl.c\nindex 02e8c1435be..6c3a9b1e879 100644\n--- a/hw/display/qxl.c\n+++ b/hw/display/qxl.c\n@@ -122,7 +122,7 @@ static void qxl_reset_memslots(PCIQXLDevice *d);\n static void qxl_reset_surfaces(PCIQXLDevice *d);\n static void qxl_ring_set_dirty(PCIQXLDevice *qxl);\n \n-static void qxl_hw_update(void *opaque);\n+static bool qxl_hw_update(void *opaque);\n \n void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)\n {\n@@ -1144,7 +1144,6 @@ static const QXLInterface qxl_interface = {\n \n static const GraphicHwOps qxl_ops = {\n     .gfx_update  = qxl_hw_update,\n-    .gfx_update_async = true,\n };\n \n static void qxl_enter_vga_mode(PCIQXLDevice *d)\n@@ -1928,11 +1927,11 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)\n \n /* graphics console */\n \n-static void qxl_hw_update(void *opaque)\n+static bool qxl_hw_update(void *opaque)\n {\n     PCIQXLDevice *qxl = opaque;\n \n-    qxl_render_update(qxl);\n+    return qxl_render_update(qxl);\n }\n \n static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,\ndiff --git a/hw/display/ramfb-standalone.c b/hw/display/ramfb-standalone.c\nindex f1958be32ad..27f0ba19f90 100644\n--- a/hw/display/ramfb-standalone.c\n+++ b/hw/display/ramfb-standalone.c\n@@ -20,7 +20,7 @@ struct RAMFBStandaloneState {\n     bool use_legacy_x86_rom;\n };\n \n-static void display_update_wrapper(void *dev)\n+static bool display_update_wrapper(void *dev)\n {\n     RAMFBStandaloneState *ramfb = RAMFB(dev);\n \n@@ -29,6 +29,8 @@ static void display_update_wrapper(void *dev)\n     } else {\n         ramfb_display_update(ramfb->con, ramfb->state);\n     }\n+\n+    return true;\n }\n \n static const GraphicHwOps wrapper_ops = {\ndiff --git a/hw/display/sm501.c b/hw/display/sm501.c\nindex a07aa9886f9..a3993ceba29 100644\n--- a/hw/display/sm501.c\n+++ b/hw/display/sm501.c\n@@ -1716,7 +1716,7 @@ static void draw_hwc_line_32(uint8_t *d, const uint8_t *s, int width,\n     }\n }\n \n-static void sm501_update_display(void *opaque)\n+static bool sm501_update_display(void *opaque)\n {\n     SM501State *s = opaque;\n     DisplaySurface *surface = qemu_console_surface(s->con);\n@@ -1740,7 +1740,7 @@ static void sm501_update_display(void *opaque)\n \n     if (!((crt ? s->dc_crt_control : s->dc_panel_control)\n           & SM501_DC_CRT_CONTROL_ENABLE)) {\n-        return;\n+        return true;\n     }\n \n     palette = (uint32_t *)(crt ? &s->dc_palette[SM501_DC_CRT_PALETTE -\n@@ -1761,7 +1761,7 @@ static void sm501_update_display(void *opaque)\n     default:\n         qemu_log_mask(LOG_GUEST_ERROR, \"sm501: update display\"\n                       \"invalid control register value.\\n\");\n-        return;\n+        return true;\n     }\n \n     /* set up to draw hardware cursor */\n@@ -1833,6 +1833,8 @@ static void sm501_update_display(void *opaque)\n     if (y_start >= 0) {\n         dpy_gfx_update(s->con, 0, y_start, width, y - y_start);\n     }\n+\n+    return true;\n }\n \n static const GraphicHwOps sm501_ops = {\ndiff --git a/hw/display/ssd0303.c b/hw/display/ssd0303.c\nindex 87781438cd5..229856cc427 100644\n--- a/hw/display/ssd0303.c\n+++ b/hw/display/ssd0303.c\n@@ -203,7 +203,7 @@ static int ssd0303_event(I2CSlave *i2c, enum i2c_event event)\n     return 0;\n }\n \n-static void ssd0303_update_display(void *opaque)\n+static bool ssd0303_update_display(void *opaque)\n {\n     ssd0303_state *s = (ssd0303_state *)opaque;\n     DisplaySurface *surface = qemu_console_surface(s->con);\n@@ -218,11 +218,11 @@ static void ssd0303_update_display(void *opaque)\n     uint8_t mask;\n \n     if (!s->redraw)\n-        return;\n+        return true;\n \n     switch (surface_bits_per_pixel(surface)) {\n     case 0:\n-        return;\n+        return true;\n     case 15:\n         dest_width = 2;\n         break;\n@@ -237,7 +237,7 @@ static void ssd0303_update_display(void *opaque)\n         break;\n     default:\n         BADF(\"Bad color depth\\n\");\n-        return;\n+        return true;\n     }\n     dest_width *= MAGNIFY;\n     memset(colortab, 0xff, dest_width);\n@@ -269,6 +269,8 @@ static void ssd0303_update_display(void *opaque)\n     }\n     s->redraw = 0;\n     dpy_gfx_update(s->con, 0, 0, 96 * MAGNIFY, 16 * MAGNIFY);\n+\n+    return true;\n }\n \n static void ssd0303_invalidate_display(void * opaque)\ndiff --git a/hw/display/ssd0323.c b/hw/display/ssd0323.c\nindex af5ff4fecdc..67db16086c8 100644\n--- a/hw/display/ssd0323.c\n+++ b/hw/display/ssd0323.c\n@@ -181,7 +181,7 @@ static uint32_t ssd0323_transfer(SSIPeripheral *dev, uint32_t data)\n     return 0;\n }\n \n-static void ssd0323_update_display(void *opaque)\n+static bool ssd0323_update_display(void *opaque)\n {\n     ssd0323_state *s = (ssd0323_state *)opaque;\n     DisplaySurface *surface = qemu_console_surface(s->con);\n@@ -197,11 +197,11 @@ static void ssd0323_update_display(void *opaque)\n     int dest_width;\n \n     if (!s->redraw)\n-        return;\n+        return true;\n \n     switch (surface_bits_per_pixel(surface)) {\n     case 0:\n-        return;\n+        return true;\n     case 15:\n         dest_width = 2;\n         break;\n@@ -216,7 +216,7 @@ static void ssd0323_update_display(void *opaque)\n         break;\n     default:\n         BADF(\"Bad color depth\\n\");\n-        return;\n+        return true;\n     }\n     p = colortab;\n     for (i = 0; i < 16; i++) {\n@@ -240,7 +240,7 @@ static void ssd0323_update_display(void *opaque)\n             break;\n         default:\n             BADF(\"Bad color depth\\n\");\n-            return;\n+            return true;\n         }\n         p += dest_width;\n     }\n@@ -271,6 +271,7 @@ static void ssd0323_update_display(void *opaque)\n     }\n     s->redraw = 0;\n     dpy_gfx_update(s->con, 0, 0, 128 * MAGNIFY, 64 * MAGNIFY);\n+    return true;\n }\n \n static void ssd0323_invalidate_display(void * opaque)\ndiff --git a/hw/display/tcx.c b/hw/display/tcx.c\nindex ea92a48400c..cedbf5c7acd 100644\n--- a/hw/display/tcx.c\n+++ b/hw/display/tcx.c\n@@ -209,7 +209,7 @@ static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d,\n /* Fixed line length 1024 allows us to do nice tricks not possible on\n    VGA... */\n \n-static void tcx_update_display(void *opaque)\n+static bool tcx_update_display(void *opaque)\n {\n     TCXState *ts = opaque;\n     DisplaySurface *surface = qemu_console_surface(ts->con);\n@@ -257,9 +257,10 @@ static void tcx_update_display(void *opaque)\n                        ts->width, y - y_start);\n     }\n     g_free(snap);\n+    return true;\n }\n \n-static void tcx24_update_display(void *opaque)\n+static bool tcx24_update_display(void *opaque)\n {\n     TCXState *ts = opaque;\n     DisplaySurface *surface = qemu_console_surface(ts->con);\n@@ -312,6 +313,7 @@ static void tcx24_update_display(void *opaque)\n                        ts->width, y - y_start);\n     }\n     g_free(snap);\n+    return true;\n }\n \n static void tcx_invalidate_display(void *opaque)\ndiff --git a/hw/display/vga.c b/hw/display/vga.c\nindex 36cfc59a74e..409c02272a3 100644\n--- a/hw/display/vga.c\n+++ b/hw/display/vga.c\n@@ -1783,7 +1783,7 @@ static void vga_draw_blank(VGACommonState *s, int full_update)\n #define GMODE_GRAPH    1\n #define GMODE_BLANK 2\n \n-static void vga_update_display(void *opaque)\n+static bool vga_update_display(void *opaque)\n {\n     VGACommonState *s = opaque;\n     DisplaySurface *surface = qemu_console_surface(s->con);\n@@ -1818,6 +1818,8 @@ static void vga_update_display(void *opaque)\n             break;\n         }\n     }\n+\n+    return true;\n }\n \n /* force a full display refresh */\ndiff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c\nindex 7b107509510..bdc24492850 100644\n--- a/hw/display/virtio-gpu-base.c\n+++ b/hw/display/virtio-gpu-base.c\n@@ -83,8 +83,9 @@ static void virtio_gpu_invalidate_display(void *opaque)\n {\n }\n \n-static void virtio_gpu_update_display(void *opaque)\n+static bool virtio_gpu_update_display(void *opaque)\n {\n+    return true;\n }\n \n static void virtio_gpu_text_update(void *opaque, uint32_t *chardata)\ndiff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c\nindex 02fb36b31fc..efd4858f3d0 100644\n--- a/hw/display/virtio-vga.c\n+++ b/hw/display/virtio-vga.c\n@@ -19,15 +19,15 @@ static void virtio_vga_base_invalidate_display(void *opaque)\n     }\n }\n \n-static void virtio_vga_base_update_display(void *opaque)\n+static bool virtio_vga_base_update_display(void *opaque)\n {\n     VirtIOVGABase *vvga = opaque;\n     VirtIOGPUBase *g = vvga->vgpu;\n \n     if (g->enable) {\n-        g->hw_ops->gfx_update(g);\n+        return g->hw_ops->gfx_update(g);\n     } else {\n-        vvga->vga.hw_ops->gfx_update(&vvga->vga);\n+        return vvga->vga.hw_ops->gfx_update(&vvga->vga);\n     }\n }\n \ndiff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c\nindex 1e154e7f99e..39606d80be1 100644\n--- a/hw/display/vmware_vga.c\n+++ b/hw/display/vmware_vga.c\n@@ -1135,14 +1135,13 @@ static inline void vmsvga_check_size(struct vmsvga_state_s *s)\n     }\n }\n \n-static void vmsvga_update_display(void *opaque)\n+static bool vmsvga_update_display(void *opaque)\n {\n     struct vmsvga_state_s *s = opaque;\n \n     if (!s->enable || !s->config) {\n         /* in standard vga mode */\n-        s->vga.hw_ops->gfx_update(&s->vga);\n-        return;\n+        return s->vga.hw_ops->gfx_update(&s->vga);\n     }\n \n     vmsvga_check_size(s);\n@@ -1154,6 +1153,8 @@ static void vmsvga_update_display(void *opaque)\n         s->invalidated = 0;\n         dpy_gfx_update_full(s->vga.con);\n     }\n+\n+    return true;\n }\n \n static void vmsvga_reset(DeviceState *dev)\ndiff --git a/hw/display/xenfb.c b/hw/display/xenfb.c\nindex ba886a940ee..2e431e27be6 100644\n--- a/hw/display/xenfb.c\n+++ b/hw/display/xenfb.c\n@@ -709,14 +709,14 @@ static void xenfb_send_refresh_period(struct XenFB *xenfb, int period)\n  * Our screen might be inactive.  When asked for\n  * an update we know it is active.\n  */\n-static void xenfb_update(void *opaque)\n+static bool xenfb_update(void *opaque)\n {\n     struct XenFB *xenfb = opaque;\n     DisplaySurface *surface;\n     int i;\n \n     if (xenfb->c.xendev.be_state != XenbusStateConnected)\n-        return;\n+        return true;\n \n     if (!xenfb->feature_update) {\n         /* we don't get update notifications, thus use the\n@@ -770,6 +770,8 @@ static void xenfb_update(void *opaque)\n     }\n     xenfb->up_count = 0;\n     xenfb->up_fullscreen = 0;\n+\n+    return true;\n }\n \n static void xenfb_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)\ndiff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c\nindex 7d037b46a35..50e6ef10984 100644\n--- a/hw/display/xlnx_dp.c\n+++ b/hw/display/xlnx_dp.c\n@@ -1252,12 +1252,12 @@ static inline void xlnx_dp_blend_surface(XlnxDPState *s)\n                            surface_height(s->g_plane.surface));\n }\n \n-static void xlnx_dp_update_display(void *opaque)\n+static bool xlnx_dp_update_display(void *opaque)\n {\n     XlnxDPState *s = XLNX_DP(opaque);\n \n     if ((s->core_registers[DP_TRANSMITTER_ENABLE] & 0x01) == 0) {\n-        return;\n+        return true;\n     }\n \n     xlnx_dpdma_trigger_vsync_irq(s->dpdma);\n@@ -1272,14 +1272,14 @@ static void xlnx_dp_update_display(void *opaque)\n          */\n         s->core_registers[DP_INT_STATUS] |= (1 << 21);\n         xlnx_dp_update_irq(s);\n-        return;\n+        return true;\n     }\n \n     if (xlnx_dp_global_alpha_enabled(s)) {\n         if (!xlnx_dpdma_start_operation(s->dpdma, 0, false)) {\n             s->core_registers[DP_INT_STATUS] |= (1 << 21);\n             xlnx_dp_update_irq(s);\n-            return;\n+            return true;\n         }\n         xlnx_dp_blend_surface(s);\n     }\n@@ -1288,6 +1288,8 @@ static void xlnx_dp_update_display(void *opaque)\n      * XXX: We might want to update only what changed.\n      */\n     dpy_gfx_update_full(s->console);\n+\n+    return true;\n }\n \n static const GraphicHwOps xlnx_dp_gfx_ops = {\ndiff --git a/hw/vfio/display.c b/hw/vfio/display.c\nindex 5a42a6f7a29..4a9a58036e3 100644\n--- a/hw/vfio/display.c\n+++ b/hw/vfio/display.c\n@@ -285,7 +285,7 @@ static void vfio_display_free_dmabufs(VFIOPCIDevice *vdev)\n     }\n }\n \n-static void vfio_display_dmabuf_update(void *opaque)\n+static bool vfio_display_dmabuf_update(void *opaque)\n {\n     VFIOPCIDevice *vdev = opaque;\n     VFIODisplay *dpy = vdev->dpy;\n@@ -298,7 +298,7 @@ static void vfio_display_dmabuf_update(void *opaque)\n         if (dpy->ramfb) {\n             ramfb_display_update(dpy->con, dpy->ramfb);\n         }\n-        return;\n+        return true;\n     }\n \n     width = qemu_dmabuf_get_width(primary->buf);\n@@ -340,6 +340,8 @@ static void vfio_display_dmabuf_update(void *opaque)\n     if (free_bufs) {\n         vfio_display_free_dmabufs(vdev);\n     }\n+\n+    return true;\n }\n \n static int vfio_display_get_flags(void *opaque)\n@@ -399,7 +401,7 @@ void vfio_display_reset(VFIOPCIDevice *vdev)\n     dpy_gfx_update_full(vdev->dpy->con);\n }\n \n-static void vfio_display_region_update(void *opaque)\n+static bool vfio_display_region_update(void *opaque)\n {\n     VFIOPCIDevice *vdev = opaque;\n     VFIODisplay *dpy = vdev->dpy;\n@@ -414,18 +416,18 @@ static void vfio_display_region_update(void *opaque)\n     if (ret < 0) {\n         error_report(\"ioctl VFIO_DEVICE_QUERY_GFX_PLANE: %s\",\n                      strerror(errno));\n-        return;\n+        return true;\n     }\n     if (!plane.drm_format || !plane.size) {\n         if (dpy->ramfb) {\n             ramfb_display_update(dpy->con, dpy->ramfb);\n             dpy->region.surface = NULL;\n         }\n-        return;\n+        return true;\n     }\n     format = qemu_drm_format_to_pixman(plane.drm_format);\n     if (!format) {\n-        return;\n+        return true;\n     }\n \n     if (dpy->region.buffer.size &&\n@@ -476,11 +478,12 @@ static void vfio_display_region_update(void *opaque)\n     dpy_gfx_update(dpy->con, 0, 0,\n                    surface_width(dpy->region.surface),\n                    surface_height(dpy->region.surface));\n-    return;\n+    return true;\n \n err:\n     vfio_region_exit(&dpy->region.buffer);\n     vfio_region_finalize(&dpy->region.buffer);\n+    return true;\n }\n \n static const GraphicHwOps vfio_display_region_ops = {\ndiff --git a/ui/console.c b/ui/console.c\nindex f96e3cf16fa..6e073cacca0 100644\n--- a/ui/console.c\n+++ b/ui/console.c\n@@ -138,15 +138,10 @@ void graphic_hw_update_done(QemuConsole *con)\n \n void graphic_hw_update(QemuConsole *con)\n {\n-    bool async = false;\n     if (!con) {\n         return;\n     }\n-    if (con->hw_ops->gfx_update) {\n-        con->hw_ops->gfx_update(con->hw);\n-        async = con->hw_ops->gfx_update_async;\n-    }\n-    if (!async) {\n+    if (!con->hw_ops->gfx_update || con->hw_ops->gfx_update(con->hw)) {\n         graphic_hw_update_done(con);\n     }\n }\ndiff --git a/hw/display/apple-gfx.m b/hw/display/apple-gfx.m\nindex e0a765fcb1f..77d80fb7cef 100644\n--- a/hw/display/apple-gfx.m\n+++ b/hw/display/apple-gfx.m\n@@ -330,25 +330,25 @@ static void apple_gfx_render_frame_completed_bh(void *opaque)\n     }\n }\n \n-static void apple_gfx_fb_update_display(void *opaque)\n+static bool apple_gfx_fb_update_display(void *opaque)\n {\n     AppleGFXState *s = opaque;\n+    bool done = true;\n \n     assert(bql_locked());\n     if (s->new_frame_ready) {\n         dpy_gfx_update_full(s->con);\n         s->new_frame_ready = false;\n-        graphic_hw_update_done(s->con);\n     } else if (s->pending_frames > 0) {\n         s->gfx_update_requested = true;\n-    } else {\n-        graphic_hw_update_done(s->con);\n+        done = false;\n     }\n+\n+    return done;\n }\n \n static const GraphicHwOps apple_gfx_fb_ops = {\n     .gfx_update = apple_gfx_fb_update_display,\n-    .gfx_update_async = true,\n };\n \n /* ------ Mouse cursor and display mode setting ------ */\n",
    "prefixes": [
        "v2",
        "59/67"
    ]
}