From patchwork Thu Jun 20 23:17:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Kim, Dongwon" X-Patchwork-Id: 13706553 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7A98EC2BA18 for ; Thu, 20 Jun 2024 23:19:33 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sKR3A-0003yO-Rf; Thu, 20 Jun 2024 19:18:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sKR38-0003xs-Tf for qemu-devel@nongnu.org; Thu, 20 Jun 2024 19:18:38 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sKR36-0001h8-Tl for qemu-devel@nongnu.org; Thu, 20 Jun 2024 19:18:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718925517; x=1750461517; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=Uy2QvbxUULiz3fn2/7fgNVsnfpiCA62ovUKrEgHURiQ=; b=FORfuAFhhtnlE+U8TGpEVoyMJ52LegZqsWNecc1QqyoiDqgtLrk5uGNn Nb+QOFW0AokC31l4uW/WNHPU65je56xoMSuMZeMy79Q2dNcDCk7sPYHqF TZy4OALUUAUz+6d5POwTEGrvMBNTTqVtAAGY4xYH2IKaB5uWsTW23psDa SGAg8WgRUxHmaQ91YOzBH1lBD2YmhjFGE3xnqUadrOtVqFHjn46ZKv7pn YBBCwdbXb3r1vsFk0sraXnjshhM2lMLOgQ6XC8It5ShNX4TOCHhYv2VLy pj5hjEpdZm05/CtY29wf50TUj/9HYx5920QP2qG2hejf38H8SRvrslZ31 w==; X-CSE-ConnectionGUID: PWMIqBZnS76eVaxwtizO9w== X-CSE-MsgGUID: BG/7mYiZQMClHxISRyK/JA== X-IronPort-AV: E=McAfee;i="6700,10204,11109"; a="33482965" X-IronPort-AV: E=Sophos;i="6.08,253,1712646000"; d="scan'208";a="33482965" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Jun 2024 16:18:29 -0700 X-CSE-ConnectionGUID: qhAzCFMjTlmY8g3K0+6x3g== X-CSE-MsgGUID: y3JbNpFPTpaaHlD2pdHLFQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,253,1712646000"; d="scan'208";a="42359630" Received: from dongwonk-z390-aorus-ultra.fm.intel.com ([10.105.129.124]) by fmviesa008.fm.intel.com with ESMTP; 20 Jun 2024 16:18:28 -0700 From: dongwon.kim@intel.com To: qemu-devel@nongnu.org Subject: [RFC PATCH 1/4] hw/display/virtio-gpu: Introducing render_sync param Date: Thu, 20 Jun 2024 16:17:24 -0700 Message-Id: <20240620231727.235841-2-dongwon.kim@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240620231727.235841-1-dongwon.kim@intel.com> References: <20240620231727.235841-1-dongwon.kim@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=dongwon.kim@intel.com; helo=mgamail.intel.com X-Spam_score_int: -45 X-Spam_score: -4.6 X-Spam_bar: ---- X-Spam_report: (-4.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.152, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Dongwon Kim Introducing new virtio-gpu param, 'render_sync' when guest scanout blob is used (blob=true). The new param is used to specify when to start rendering a guest scanout frame. By default (and so far) rendering of the guest frame is started in the draw event to make sure guest display update is sychronized with host's vsync. But this method inevitably brings some extra wait because most of time, the draw event is not happening right after the guest scanout frame is flushed. This delay often makes the guest stuck at certain frame for too long and causes general performance degradation of graphic workloads on the guest's side especially when the display update rate is high. This unwanted perf drop can be reduced if the guest scanout frame is rendered as soon as it is flushed through 'VIRTIO_GPU_CMD_RESOURCE_FLUSH' msg. The gl display pipeline can be unblocked a lot earlier in this case so that guest can move to the next display frame right away. However, this "asynchrounous" render mode may cause some waste of resources as the guest could produce more frames than what are actually displayed on the host display. This is similar as running rendering apps with no vblank or vsync option. This is why this feature should stay as optional. The param 'render_sync' is set to 'true' by default and this is in line with traditional way while setting it to 'false' is basically enabling this asynchronouse mode. Cc: Gerd Hoffmann Cc: Marc-André Lureau Cc: Vivek Kasireddy Signed-off-by: Dongwon Kim --- include/hw/virtio/virtio-gpu.h | 3 +++ include/ui/dmabuf.h | 4 +++- hw/display/vhost-user-gpu.c | 3 ++- hw/display/virtio-gpu-udmabuf.c | 3 ++- hw/display/virtio-gpu.c | 2 ++ hw/vfio/display.c | 3 ++- ui/dbus-listener.c | 2 +- ui/dmabuf.c | 11 ++++++++++- 8 files changed, 25 insertions(+), 6 deletions(-) diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index 7a59379f5a..9bcc572eab 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -97,6 +97,7 @@ enum virtio_gpu_base_conf_flags { VIRTIO_GPU_FLAG_EDID_ENABLED, VIRTIO_GPU_FLAG_DMABUF_ENABLED, VIRTIO_GPU_FLAG_BLOB_ENABLED, + VIRTIO_GPU_FLAG_RENDER_SYNC_ENABLED, VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED, VIRTIO_GPU_FLAG_RUTABAGA_ENABLED, }; @@ -111,6 +112,8 @@ enum virtio_gpu_base_conf_flags { (_cfg.flags & (1 << VIRTIO_GPU_FLAG_DMABUF_ENABLED)) #define virtio_gpu_blob_enabled(_cfg) \ (_cfg.flags & (1 << VIRTIO_GPU_FLAG_BLOB_ENABLED)) +#define virtio_gpu_render_sync_enabled(_cfg) \ + (_cfg.flags & (1 << VIRTIO_GPU_FLAG_RENDER_SYNC_ENABLED)) #define virtio_gpu_context_init_enabled(_cfg) \ (_cfg.flags & (1 << VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED)) #define virtio_gpu_rutabaga_enabled(_cfg) \ diff --git a/include/ui/dmabuf.h b/include/ui/dmabuf.h index dc74ba895a..45384e32e3 100644 --- a/include/ui/dmabuf.h +++ b/include/ui/dmabuf.h @@ -17,7 +17,8 @@ QemuDmaBuf *qemu_dmabuf_new(uint32_t width, uint32_t height, uint32_t y, uint32_t backing_width, uint32_t backing_height, uint32_t fourcc, uint64_t modifier, int dmabuf_fd, - bool allow_fences, bool y0_top); + bool allow_fences, bool y0_top, + bool render_sync); void qemu_dmabuf_free(QemuDmaBuf *dmabuf); G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuDmaBuf, qemu_dmabuf_free); @@ -40,6 +41,7 @@ void *qemu_dmabuf_get_sync(QemuDmaBuf *dmabuf); int32_t qemu_dmabuf_get_fence_fd(QemuDmaBuf *dmabuf); bool qemu_dmabuf_get_allow_fences(QemuDmaBuf *dmabuf); bool qemu_dmabuf_get_draw_submitted(QemuDmaBuf *dmabuf); +bool qemu_dmabuf_get_render_sync(QemuDmaBuf *dmabuf); void qemu_dmabuf_set_texture(QemuDmaBuf *dmabuf, uint32_t texture); void qemu_dmabuf_set_fence_fd(QemuDmaBuf *dmabuf, int32_t fence_fd); void qemu_dmabuf_set_sync(QemuDmaBuf *dmabuf, void *sync); diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index e4b398d26c..69fa722c88 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -285,7 +285,8 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) m->fd_stride, 0, 0, 0, 0, m->fd_drm_fourcc, modifier, fd, false, m->fd_flags & - VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP); + VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP, + false); dpy_gl_scanout_dmabuf(con, dmabuf); g->dmabuf[m->scanout_id] = dmabuf; diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c index c02ec6d37d..8fcc0c3055 100644 --- a/hw/display/virtio-gpu-udmabuf.c +++ b/hw/display/virtio-gpu-udmabuf.c @@ -176,6 +176,7 @@ static VGPUDMABuf struct virtio_gpu_rect *r) { VGPUDMABuf *dmabuf; + bool render_sync = virtio_gpu_render_sync_enabled(g->parent_obj.conf); if (res->dmabuf_fd < 0) { return NULL; @@ -185,7 +186,7 @@ static VGPUDMABuf dmabuf->buf = qemu_dmabuf_new(r->width, r->height, fb->stride, r->x, r->y, fb->width, fb->height, qemu_pixman_to_drm_format(fb->format), - 0, res->dmabuf_fd, true, false); + 0, res->dmabuf_fd, true, false, render_sync); dmabuf->scanout_id = scanout_id; QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next); diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index d60b1b2973..b6b82de306 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -1671,6 +1671,8 @@ static Property virtio_gpu_properties[] = { 256 * MiB), DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags, VIRTIO_GPU_FLAG_BLOB_ENABLED, false), + DEFINE_PROP_BIT("render_sync", VirtIOGPU, parent_obj.conf.flags, + VIRTIO_GPU_FLAG_RENDER_SYNC_ENABLED, true), DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0), DEFINE_PROP_UINT8("x-scanout-vmstate-version", VirtIOGPU, scanout_vmstate_version, 2), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/vfio/display.c b/hw/vfio/display.c index 661e921616..202ba78288 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -244,7 +244,8 @@ static VFIODMABuf *vfio_display_get_dmabuf(VFIOPCIDevice *vdev, dmabuf->buf = qemu_dmabuf_new(plane.width, plane.height, plane.stride, 0, 0, plane.width, plane.height, plane.drm_format, - plane.drm_format_mod, fd, false, false); + plane.drm_format_mod, fd, false, + false, false); if (plane_type == DRM_PLANE_TYPE_CURSOR) { vfio_display_update_cursor(dmabuf, &plane); diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index 5490088043..7547b0e248 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -456,7 +456,7 @@ static void dbus_scanout_texture(DisplayChangeListener *dcl, } dmabuf = qemu_dmabuf_new(w, h, stride, x, y, backing_width, backing_height, fourcc, modifier, fd, - false, backing_y_0_top); + false, backing_y_0_top, false); dbus_scanout_dmabuf(dcl, dmabuf); qemu_dmabuf_close(dmabuf); diff --git a/ui/dmabuf.c b/ui/dmabuf.c index df7a09703f..193097f9a2 100644 --- a/ui/dmabuf.c +++ b/ui/dmabuf.c @@ -26,6 +26,7 @@ struct QemuDmaBuf { void *sync; int fence_fd; bool allow_fences; + bool render_sync; bool draw_submitted; }; @@ -34,7 +35,7 @@ QemuDmaBuf *qemu_dmabuf_new(uint32_t width, uint32_t height, uint32_t y, uint32_t backing_width, uint32_t backing_height, uint32_t fourcc, uint64_t modifier, int32_t dmabuf_fd, - bool allow_fences, bool y0_top) { + bool allow_fences, bool y0_top, bool render_sync) { QemuDmaBuf *dmabuf; dmabuf = g_new0(QemuDmaBuf, 1); @@ -51,6 +52,7 @@ QemuDmaBuf *qemu_dmabuf_new(uint32_t width, uint32_t height, dmabuf->fd = dmabuf_fd; dmabuf->allow_fences = allow_fences; dmabuf->y0_top = y0_top; + dmabuf->render_sync = render_sync; dmabuf->fence_fd = -1; return dmabuf; @@ -198,6 +200,13 @@ bool qemu_dmabuf_get_draw_submitted(QemuDmaBuf *dmabuf) return dmabuf->draw_submitted; } +bool qemu_dmabuf_get_render_sync(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->render_sync; +} + void qemu_dmabuf_set_texture(QemuDmaBuf *dmabuf, uint32_t texture) { assert(dmabuf != NULL); From patchwork Thu Jun 20 23:17:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Kim, Dongwon" X-Patchwork-Id: 13706552 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7E7DEC41513 for ; Thu, 20 Jun 2024 23:19:33 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sKR3B-0003yQ-09; Thu, 20 Jun 2024 19:18:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sKR39-0003y2-N8 for qemu-devel@nongnu.org; Thu, 20 Jun 2024 19:18:39 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sKR37-0001hV-UY for qemu-devel@nongnu.org; Thu, 20 Jun 2024 19:18:39 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718925518; x=1750461518; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=0PTTGxWxRaGqd6xV5WpwchsG1utShWc0Ne1B3hPt9n8=; b=AUbvEFUIbJYpBYo+vlDewvKXOV5DHKTnwiyOrPqRGYnw00gmDvOrkvXz L7PD1vvp23LuLiOIQ1sgpkcMXfQeICKhAEWrvzlSRcmVRwQcUuT6OPDmu GT/+pahsQZgLIp3gKcDancz0d1eSwNYq+gXisEyrKIdlZCjc2wWaIivxh SV8zPe6ebSRIg1OwZLcIsRUv7u9jPBzNONjdh5jHf1XVzdXah9paWgCwQ e/yDyfD/2D3z4i7WsTPrfoMfsGc4SivPZQ0Mz/fnZTkH1kjg1AorOiTsC 4v/c05jEIBOzWkPIwvHKyaJryb0RtpDhWe6Xoet/Ig9OShfb/W2/YtMJr A==; X-CSE-ConnectionGUID: 2fDg6VL0ROydXn+O7y49rA== X-CSE-MsgGUID: S/hvYSOATzakQTxhdm0KQg== X-IronPort-AV: E=McAfee;i="6700,10204,11109"; a="33482966" X-IronPort-AV: E=Sophos;i="6.08,253,1712646000"; d="scan'208";a="33482966" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Jun 2024 16:18:29 -0700 X-CSE-ConnectionGUID: g94ORT4uR0mWXhGp06x4JA== X-CSE-MsgGUID: h8rg1RqXSeC9TiAKq2Ir+g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,253,1712646000"; d="scan'208";a="42359631" Received: from dongwonk-z390-aorus-ultra.fm.intel.com ([10.105.129.124]) by fmviesa008.fm.intel.com with ESMTP; 20 Jun 2024 16:18:28 -0700 From: dongwon.kim@intel.com To: qemu-devel@nongnu.org Subject: [RFC PATCH 2/4] ui/egl-helpers: Consolidates create-sync and create-fence Date: Thu, 20 Jun 2024 16:17:25 -0700 Message-Id: <20240620231727.235841-3-dongwon.kim@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240620231727.235841-1-dongwon.kim@intel.com> References: <20240620231727.235841-1-dongwon.kim@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=dongwon.kim@intel.com; helo=mgamail.intel.com X-Spam_score_int: -45 X-Spam_score: -4.6 X-Spam_bar: ---- X-Spam_report: (-4.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.152, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Dongwon Kim There is no reason to split those two operations so combining two functions - egl_dmabuf_create_sync and egl_dmabuf_create_fence. Cc: Gerd Hoffmann Cc: Marc-André Lureau Cc: Vivek Kasireddy Signed-off-by: Dongwon Kim --- include/ui/egl-helpers.h | 3 +-- ui/egl-helpers.c | 27 +++++++++++---------------- ui/gtk-egl.c | 19 +++++++------------ ui/gtk-gl-area.c | 10 ++-------- 4 files changed, 21 insertions(+), 38 deletions(-) diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h index 4b8c0d2281..606d6c8288 100644 --- a/include/ui/egl-helpers.h +++ b/include/ui/egl-helpers.h @@ -51,8 +51,7 @@ int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc, void egl_dmabuf_import_texture(QemuDmaBuf *dmabuf); void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf); -void egl_dmabuf_create_sync(QemuDmaBuf *dmabuf); -void egl_dmabuf_create_fence(QemuDmaBuf *dmabuf); +int egl_dmabuf_create_fence(QemuDmaBuf *dmabuf); #endif diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c index 99b2ebbe23..e16f2cb23d 100644 --- a/ui/egl-helpers.c +++ b/ui/egl-helpers.c @@ -371,34 +371,29 @@ void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf) qemu_dmabuf_set_texture(dmabuf, 0); } -void egl_dmabuf_create_sync(QemuDmaBuf *dmabuf) +int egl_dmabuf_create_fence(QemuDmaBuf *dmabuf) { EGLSyncKHR sync; + int fence_fd = -1; if (epoxy_has_egl_extension(qemu_egl_display, "EGL_KHR_fence_sync") && epoxy_has_egl_extension(qemu_egl_display, - "EGL_ANDROID_native_fence_sync")) { + "EGL_ANDROID_native_fence_sync") && + qemu_dmabuf_get_fence_fd(dmabuf) == -1) { sync = eglCreateSyncKHR(qemu_egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); if (sync != EGL_NO_SYNC_KHR) { - qemu_dmabuf_set_sync(dmabuf, sync); + fence_fd = eglDupNativeFenceFDANDROID(qemu_egl_display, + sync); + if (fence_fd >= 0) { + qemu_dmabuf_set_fence_fd(dmabuf, fence_fd); + } + eglDestroySyncKHR(qemu_egl_display, sync); } } -} - -void egl_dmabuf_create_fence(QemuDmaBuf *dmabuf) -{ - void *sync = qemu_dmabuf_get_sync(dmabuf); - int fence_fd; - if (sync) { - fence_fd = eglDupNativeFenceFDANDROID(qemu_egl_display, - sync); - qemu_dmabuf_set_fence_fd(dmabuf, fence_fd); - eglDestroySyncKHR(qemu_egl_display, sync); - qemu_dmabuf_set_sync(dmabuf, NULL); - } + return fence_fd; } #endif /* CONFIG_GBM */ diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c index 9831c10e1b..55199f8659 100644 --- a/ui/gtk-egl.c +++ b/ui/gtk-egl.c @@ -68,7 +68,6 @@ void gd_egl_draw(VirtualConsole *vc) GdkWindow *window; #ifdef CONFIG_GBM QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf; - int fence_fd; #endif int ww, wh, ws; @@ -99,13 +98,12 @@ void gd_egl_draw(VirtualConsole *vc) glFlush(); #ifdef CONFIG_GBM if (dmabuf) { - egl_dmabuf_create_fence(dmabuf); - fence_fd = qemu_dmabuf_get_fence_fd(dmabuf); + fence_fd = egl_dmabuf_create_fence(dmabuf); if (fence_fd >= 0) { qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc); - return; + } else { + graphic_hw_gl_block(vc->gfx.dcl.con, false); } - graphic_hw_gl_block(vc->gfx.dcl.con, false); } #endif } else { @@ -336,7 +334,11 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl, { VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); GdkWindow *window; +#ifdef CONFIG_GBM + QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf; +#endif int ww, wh, ws; + int fence_fd; if (!vc->gfx.scanout_mode) { return; @@ -364,12 +366,6 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl, egl_fb_blit(&vc->gfx.win_fb, &vc->gfx.guest_fb, !vc->gfx.y0_top); } -#ifdef CONFIG_GBM - if (vc->gfx.guest_fb.dmabuf) { - egl_dmabuf_create_sync(vc->gfx.guest_fb.dmabuf); - } -#endif - eglSwapBuffers(qemu_egl_display, vc->gfx.esurface); } @@ -387,7 +383,6 @@ void gd_egl_flush(DisplayChangeListener *dcl, gtk_widget_queue_draw_area(area, x, y, w, h); return; } - gd_egl_scanout_flush(&vc->gfx.dcl, x, y, w, h); } diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c index b628b35451..0b11423824 100644 --- a/ui/gtk-gl-area.c +++ b/ui/gtk-gl-area.c @@ -77,17 +77,10 @@ void gd_gl_area_draw(VirtualConsole *vc) glBlitFramebuffer(0, y1, vc->gfx.w, y2, 0, 0, ww, wh, GL_COLOR_BUFFER_BIT, GL_NEAREST); -#ifdef CONFIG_GBM - if (dmabuf) { - egl_dmabuf_create_sync(dmabuf); - } -#endif - glFlush(); #ifdef CONFIG_GBM if (dmabuf) { int fence_fd; - egl_dmabuf_create_fence(dmabuf); - fence_fd = qemu_dmabuf_get_fence_fd(dmabuf); + fence_fd = egl_dmabuf_create_fence(dmabuf); if (fence_fd >= 0) { qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc); return; @@ -95,6 +88,7 @@ void gd_gl_area_draw(VirtualConsole *vc) graphic_hw_gl_block(vc->gfx.dcl.con, false); } #endif + glFlush(); } else { if (!vc->gfx.ds) { return; From patchwork Thu Jun 20 23:17:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Kim, Dongwon" X-Patchwork-Id: 13706555 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 23244C2BD05 for ; Thu, 20 Jun 2024 23:19:45 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sKR3C-0003yp-2W; Thu, 20 Jun 2024 19:18:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sKR3B-0003yR-1V for qemu-devel@nongnu.org; Thu, 20 Jun 2024 19:18:41 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sKR39-0001h8-8B for qemu-devel@nongnu.org; Thu, 20 Jun 2024 19:18:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718925519; x=1750461519; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=rRv8TGUFB03Gz8XizonszwHP/JcMDSmmaYVfyiwCYds=; b=fM9mO7x9U5vygofPwwgoN4uQ0WV923XrPD+DUTXBtOvrfAMfeKrWui/+ 1ngVtgwf7orQsbywaZ582j9HG2hU1Bqg/Swy9rdES+S3GBI5i3O/5aTaE EMDxam1o8eg1IWTuXC18kaX4me3u4fJCoRTr3rSZLXrapRHLy8h99hqt8 DHbxnl+KfC9oYq5bnlF6WT8AjmNpwC6tbbyvsXlKSzuTt7/+Slrh2m85Y oDHh0jiW/0ctyOXPN27CdHX3RhVfZMebqKoY1wXRip70egBis5Rv/aw6C /rG44PH4HBP7R+DsEPE5XKpYzPxEtsy0S1v7UTDHL7qSHOYoUpIefLiso g==; X-CSE-ConnectionGUID: vLCnBx8ERiCGASfEtUHHdA== X-CSE-MsgGUID: EEmVyGVZSRu6ewGJoMgiwA== X-IronPort-AV: E=McAfee;i="6700,10204,11109"; a="33482967" X-IronPort-AV: E=Sophos;i="6.08,253,1712646000"; d="scan'208";a="33482967" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Jun 2024 16:18:29 -0700 X-CSE-ConnectionGUID: t/EKEU9OQKOr77AXGCMlFQ== X-CSE-MsgGUID: X3x/bQgWT1qT6fAbH4T90w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,253,1712646000"; d="scan'208";a="42359632" Received: from dongwonk-z390-aorus-ultra.fm.intel.com ([10.105.129.124]) by fmviesa008.fm.intel.com with ESMTP; 20 Jun 2024 16:18:28 -0700 From: dongwon.kim@intel.com To: qemu-devel@nongnu.org Subject: [RFC PATCH 3/4] ui/gtk-egl: Start rendering of guest blob scanout if render_sync is off Date: Thu, 20 Jun 2024 16:17:26 -0700 Message-Id: <20240620231727.235841-4-dongwon.kim@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240620231727.235841-1-dongwon.kim@intel.com> References: <20240620231727.235841-1-dongwon.kim@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=dongwon.kim@intel.com; helo=mgamail.intel.com X-Spam_score_int: -45 X-Spam_score: -4.6 X-Spam_bar: ---- X-Spam_report: (-4.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.152, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Dongwon Kim Draw (executing glBlitFramebuffer) immediately as soon as the frame is flushed instead of getting it done in the next draw event if render_sync flag is reset. With this, the fence will be signaled way ealier so the guest can be working on the next frame right away. Cc: Gerd Hoffmann Cc: Marc-André Lureau Cc: Vivek Kasireddy Signed-off-by: Dongwon Kim --- ui/gtk-egl.c | 88 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c index 55199f8659..2877140c3b 100644 --- a/ui/gtk-egl.c +++ b/ui/gtk-egl.c @@ -80,6 +80,12 @@ void gd_egl_draw(VirtualConsole *vc) ww = gdk_window_get_width(window) * ws; wh = gdk_window_get_height(window) * ws; + vc->gfx.scale_x = (double)ww / surface_width(vc->gfx.ds); + vc->gfx.scale_y = (double)wh / surface_height(vc->gfx.ds); + + eglMakeCurrent(qemu_egl_display, vc->gfx.esurface, + vc->gfx.esurface, vc->gfx.ectx); + if (vc->gfx.scanout_mode) { #ifdef CONFIG_GBM if (dmabuf) { @@ -88,21 +94,9 @@ void gd_egl_draw(VirtualConsole *vc) } else { qemu_dmabuf_set_draw_submitted(dmabuf, false); } - } -#endif - gd_egl_scanout_flush(&vc->gfx.dcl, 0, 0, vc->gfx.w, vc->gfx.h); - vc->gfx.scale_x = (double)ww / surface_width(vc->gfx.ds); - vc->gfx.scale_y = (double)wh / surface_height(vc->gfx.ds); - - glFlush(); -#ifdef CONFIG_GBM - if (dmabuf) { - fence_fd = egl_dmabuf_create_fence(dmabuf); - if (fence_fd >= 0) { - qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc); - } else { - graphic_hw_gl_block(vc->gfx.dcl.con, false); + if (qemu_dmabuf_get_render_sync(dmabuf)) { + gd_egl_scanout_flush(&vc->gfx.dcl, 0, 0, vc->gfx.w, vc->gfx.h); } } #endif @@ -110,19 +104,12 @@ void gd_egl_draw(VirtualConsole *vc) if (!vc->gfx.ds) { return; } - eglMakeCurrent(qemu_egl_display, vc->gfx.esurface, - vc->gfx.esurface, vc->gfx.ectx); - surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh); surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds); - - eglSwapBuffers(qemu_egl_display, vc->gfx.esurface); - - vc->gfx.scale_x = (double)ww / surface_width(vc->gfx.ds); - vc->gfx.scale_y = (double)wh / surface_height(vc->gfx.ds); - - glFlush(); } + + eglSwapBuffers(qemu_egl_display, vc->gfx.esurface); + glFlush(); } void gd_egl_update(DisplayChangeListener *dcl, @@ -146,14 +133,20 @@ void gd_egl_refresh(DisplayChangeListener *dcl) { VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); +#ifdef CONFIG_GBM + QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf; +#endif + gd_update_monitor_refresh_rate( vc, vc->window ? vc->window : vc->gfx.drawing_area); - if (vc->gfx.guest_fb.dmabuf && - qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) { +#ifdef CONFIG_GBM + if (dmabuf && qemu_dmabuf_get_draw_submitted(dmabuf) && + qemu_dmabuf_get_render_sync(dmabuf)) { gd_egl_draw(vc); return; } +#endif if (!vc->gfx.esurface) { gd_egl_init(vc); @@ -166,9 +159,9 @@ void gd_egl_refresh(DisplayChangeListener *dcl) surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds); } #ifdef CONFIG_GBM - if (vc->gfx.guest_fb.dmabuf) { - egl_dmabuf_release_texture(vc->gfx.guest_fb.dmabuf); - gd_egl_scanout_dmabuf(dcl, vc->gfx.guest_fb.dmabuf); + if (dmabuf) { + egl_dmabuf_release_texture(dmabuf); + gd_egl_scanout_dmabuf(dcl, dmabuf); } #endif } @@ -344,6 +337,11 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl, return; } if (!vc->gfx.guest_fb.framebuffer) { +#ifdef CONFIG_GBM + if (dmabuf) { + graphic_hw_gl_block(vc->gfx.dcl.con, false); + } +#endif return; } @@ -366,7 +364,16 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl, egl_fb_blit(&vc->gfx.win_fb, &vc->gfx.guest_fb, !vc->gfx.y0_top); } - eglSwapBuffers(qemu_egl_display, vc->gfx.esurface); +#ifdef CONFIG_GBM + if (dmabuf) { + fence_fd = egl_dmabuf_create_fence(dmabuf); + if (fence_fd >= 0) { + qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc); + } else { + graphic_hw_gl_block(vc->gfx.dcl.con, false); + } + } +#endif } void gd_egl_flush(DisplayChangeListener *dcl, @@ -374,15 +381,22 @@ void gd_egl_flush(DisplayChangeListener *dcl, { VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); GtkWidget *area = vc->gfx.drawing_area; - - if (vc->gfx.guest_fb.dmabuf && - !qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) { - graphic_hw_gl_block(vc->gfx.dcl.con, true); - qemu_dmabuf_set_draw_submitted(vc->gfx.guest_fb.dmabuf, true); - gtk_egl_set_scanout_mode(vc, true); - gtk_widget_queue_draw_area(area, x, y, w, h); +#ifdef CONFIG_GBM + QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf; + if (dmabuf) { + if (!qemu_dmabuf_get_draw_submitted(dmabuf)) { + graphic_hw_gl_block(vc->gfx.dcl.con, true); + qemu_dmabuf_set_draw_submitted(dmabuf, true); + gtk_egl_set_scanout_mode(vc, true); + if (!qemu_dmabuf_get_render_sync(dmabuf)) { + gd_egl_scanout_flush(&vc->gfx.dcl, 0, 0, vc->gfx.w, vc->gfx.h); + } + gtk_widget_queue_draw_area(area, x, y, w, h); + } return; } +#endif + gd_egl_scanout_flush(&vc->gfx.dcl, x, y, w, h); } From patchwork Thu Jun 20 23:17:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Kim, Dongwon" X-Patchwork-Id: 13706554 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9CDEEC2BA18 for ; Thu, 20 Jun 2024 23:19:39 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sKR3D-0003zS-Gz; Thu, 20 Jun 2024 19:18:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sKR3C-0003yr-7M for qemu-devel@nongnu.org; Thu, 20 Jun 2024 19:18:42 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sKR3A-0001hp-Ee for qemu-devel@nongnu.org; Thu, 20 Jun 2024 19:18:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718925521; x=1750461521; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=aUhUdVN61RQrZr1LHcic/H9Yj04gNHVHexZdw7CMyVg=; b=MTnKR4gSD5DFe9QHyG8pcHnBO8YvG6YnmNm6eNAzdFYFhW33vXIUdiSJ IU1ph9il/RXt6dBA+r7BjzDoFThK7uk9xFBd7C+NwY03gUNb2C8U3mPP0 9r7P1uZPVWcx7KLk1hF/AlKjjOYbZZpA2P2pknYlSOzbewYzSL/Znr4LL 352UEMj3sw2XcBFfHkr90Vs5Xx87jsCQEkWzKbGcrbvALiCSk4BZ2nr2h +e0+dZM1TFB4mKyvxKL1lCv5foiT+XbsQzx3ElDtYM9UrcenAJGzDV2e4 Fc9UIMqrmhXf+P4NrrMnOvb9lN3T2g2KpiJYRG0glV1qSmilYcH9f5IMl g==; X-CSE-ConnectionGUID: iPzljJogSJORDeRQxE54qA== X-CSE-MsgGUID: oKOU+YJ/SDawBsn/1loIkQ== X-IronPort-AV: E=McAfee;i="6700,10204,11109"; a="33482969" X-IronPort-AV: E=Sophos;i="6.08,253,1712646000"; d="scan'208";a="33482969" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Jun 2024 16:18:29 -0700 X-CSE-ConnectionGUID: +tFeFk7MTWW1ebk3G1pfXw== X-CSE-MsgGUID: NYwO/zOyRX6sH6cagwXI9A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,253,1712646000"; d="scan'208";a="42359633" Received: from dongwonk-z390-aorus-ultra.fm.intel.com ([10.105.129.124]) by fmviesa008.fm.intel.com with ESMTP; 20 Jun 2024 16:18:28 -0700 From: dongwon.kim@intel.com To: qemu-devel@nongnu.org Subject: [RFC PATCH 4/4] ui/gtk-gl-draw: Start rendering of guest blob scanout if render_sync is off Date: Thu, 20 Jun 2024 16:17:27 -0700 Message-Id: <20240620231727.235841-5-dongwon.kim@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240620231727.235841-1-dongwon.kim@intel.com> References: <20240620231727.235841-1-dongwon.kim@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=dongwon.kim@intel.com; helo=mgamail.intel.com X-Spam_score_int: -45 X-Spam_score: -4.6 X-Spam_bar: ---- X-Spam_report: (-4.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.152, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Dongwon Kim Draw (executing glBlitFramebuffer) immediately as soon as the frame is flushed instead of getting it done in the next draw event if render_sync flag is reset. With this, the fence will be signaled way ealier so the guest can be working on the next frame right away. Cc: Marc-André Lureau Cc: Vivek Kasireddy Signed-off-by: Dongwon Kim --- ui/gtk-gl-area.c | 84 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c index 0b11423824..88d4e66a52 100644 --- a/ui/gtk-gl-area.c +++ b/ui/gtk-gl-area.c @@ -65,39 +65,36 @@ void gd_gl_area_draw(VirtualConsole *vc) } else { qemu_dmabuf_set_draw_submitted(dmabuf, false); } - } -#endif - glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer); - /* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */ - - glViewport(0, 0, ww, wh); - y1 = vc->gfx.y0_top ? 0 : vc->gfx.h; - y2 = vc->gfx.y0_top ? vc->gfx.h : 0; - glBlitFramebuffer(0, y1, vc->gfx.w, y2, - 0, 0, ww, wh, - GL_COLOR_BUFFER_BIT, GL_NEAREST); -#ifdef CONFIG_GBM - if (dmabuf) { - int fence_fd; - fence_fd = egl_dmabuf_create_fence(dmabuf); - if (fence_fd >= 0) { - qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc); - return; + if (qemu_dmabuf_get_render_sync(dmabuf)) { + int fence_fd; + glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer); + /* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */ + + glViewport(0, 0, ww, wh); + y1 = vc->gfx.y0_top ? 0 : vc->gfx.h; + y2 = vc->gfx.y0_top ? vc->gfx.h : 0; + glBlitFramebuffer(0, y1, vc->gfx.w, y2, + 0, 0, ww, wh, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + fence_fd = egl_dmabuf_create_fence(dmabuf); + if (fence_fd >= 0) { + qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc); + } else { + graphic_hw_gl_block(vc->gfx.dcl.con, false); + } } - graphic_hw_gl_block(vc->gfx.dcl.con, false); } #endif - glFlush(); } else { if (!vc->gfx.ds) { return; } - gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area)); surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh); surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds); } + glFlush(); } void gd_gl_area_update(DisplayChangeListener *dcl, @@ -119,13 +116,19 @@ void gd_gl_area_refresh(DisplayChangeListener *dcl) { VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); +#ifdef CONFIG_GBM + QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf; +#endif + gd_update_monitor_refresh_rate(vc, vc->window ? vc->window : vc->gfx.drawing_area); - if (vc->gfx.guest_fb.dmabuf && - qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) { +#ifdef CONFIG_GBM + if (dmabuf && qemu_dmabuf_get_draw_submitted(dmabuf) && + qemu_dmabuf_get_render_sync(dmabuf)) { gd_gl_area_draw(vc); return; } +#endif if (!vc->gfx.gls) { if (!gtk_widget_get_realized(vc->gfx.drawing_area)) { @@ -282,13 +285,42 @@ void gd_gl_area_scanout_flush(DisplayChangeListener *dcl, uint32_t x, uint32_t y, uint32_t w, uint32_t h) { VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); +#ifdef CONFIG_GBM + QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf; + int ww, wh, ws, y1, y2; + + if (dmabuf && !qemu_dmabuf_get_draw_submitted(dmabuf)) { + gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area)); + ws = gdk_window_get_scale_factor(gtk_widget_get_window(vc->gfx.drawing_area)); + ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area) * ws; + wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area) * ws; - if (vc->gfx.guest_fb.dmabuf && - !qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) { graphic_hw_gl_block(vc->gfx.dcl.con, true); - qemu_dmabuf_set_draw_submitted(vc->gfx.guest_fb.dmabuf, true); + qemu_dmabuf_set_draw_submitted(dmabuf, true); gtk_gl_area_set_scanout_mode(vc, true); + if (!qemu_dmabuf_get_render_sync(dmabuf)) { + int fence_fd; + glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer); + /* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */ + + glViewport(0, 0, ww, wh); + y1 = vc->gfx.y0_top ? 0 : vc->gfx.h; + y2 = vc->gfx.y0_top ? vc->gfx.h : 0; + glBlitFramebuffer(0, y1, vc->gfx.w, y2, + 0, 0, ww, wh, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + egl_dmabuf_create_fence(dmabuf); + fence_fd = qemu_dmabuf_get_fence_fd(dmabuf); + if (fence_fd >= 0) { + qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc); + } else { + graphic_hw_gl_block(vc->gfx.dcl.con, false); + } + } } +#endif + gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area)); }