* RE: [PATCH v3 1/2] ui/gtk: flush display pipeline before saving vmstate when blob=true
2023-09-20 23:24 ` [PATCH v3 1/2] ui/gtk: flush display pipeline before saving vmstate when blob=true dongwon.kim
@ 2024-03-01 0:09 ` Kim, Dongwon
0 siblings, 0 replies; 2+ messages in thread
From: Kim, Dongwon @ 2024-03-01 0:09 UTC (permalink / raw)
To: Kim, Dongwon, qemu-devel@nongnu.org, Marc-André Lureau
Hi Marc-André,
Can you take a look at this new version and also https://lists.gnu.org/archive/html/qemu-devel/2023-12/msg01828.html?
Thanks!
DW
> -----Original Message-----
> From: qemu-devel-bounces+dongwon.kim=intel.com@nongnu.org <qemu-
> devel-bounces+dongwon.kim=intel.com@nongnu.org> On Behalf Of
> dongwon.kim@intel.com
> Sent: Wednesday, September 20, 2023 4:24 PM
> To: qemu-devel@nongnu.org
> Subject: [PATCH v3 1/2] ui/gtk: flush display pipeline before saving vmstate
> when blob=true
>
> From: Dongwon Kim <dongwon.kim@intel.com>
>
> If the guest state is paused before it gets a response for the current scanout
> frame submission (resource-flush), it won't flush new frames after being
> restored as it still waits for the old response, which is accepted as a scanout
> render done signal. So it's needed to unblock the current scanout render pipeline
> before the run state is changed to make sure the guest receives the response for
> the current frame submission.
>
> v2: Giving some time for the fence to be signaled before flushing
> the pipeline
>
> v3: Prevent redundant call of gd_hw_gl_flushed by checking dmabuf
> and fence_fd >= 0 in it (e.g. during and after eglClientWaitSync
> in gd_change_runstate).
>
> Destroy sync object later in gd_hw_fl_flushed since it is needed
> by eglClientWaitSync.
>
> Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
> Cc: Vivek Kasireddy <vivek.kasireddy@intel.com>
> Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
> ---
> ui/egl-helpers.c | 2 --
> ui/gtk.c | 31 +++++++++++++++++++++++++++----
> 2 files changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c index 3d19dbe382..a77f9e57d9
> 100644
> --- a/ui/egl-helpers.c
> +++ b/ui/egl-helpers.c
> @@ -385,8 +385,6 @@ void egl_dmabuf_create_fence(QemuDmaBuf *dmabuf)
> if (dmabuf->sync) {
> dmabuf->fence_fd = eglDupNativeFenceFDANDROID(qemu_egl_display,
> dmabuf->sync);
> - eglDestroySyncKHR(qemu_egl_display, dmabuf->sync);
> - dmabuf->sync = NULL;
> }
> }
>
> diff --git a/ui/gtk.c b/ui/gtk.c
> index 810d7fc796..eaca890cba 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c
> @@ -597,10 +597,14 @@ void gd_hw_gl_flushed(void *vcon)
> VirtualConsole *vc = vcon;
> QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
>
> - qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL);
> - close(dmabuf->fence_fd);
> - dmabuf->fence_fd = -1;
> - graphic_hw_gl_block(vc->gfx.dcl.con, false);
> + if (dmabuf && dmabuf->fence_fd >= 0) {
> + qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL);
> + close(dmabuf->fence_fd);
> + dmabuf->fence_fd = -1;
> + eglDestroySyncKHR(qemu_egl_display, dmabuf->sync);
> + dmabuf->sync = NULL;
> + graphic_hw_gl_block(vc->gfx.dcl.con, false);
> + }
> }
>
> /** DisplayState Callbacks (opengl version) **/ @@ -678,6 +682,25 @@ static
> const DisplayGLCtxOps egl_ctx_ops = { static void gd_change_runstate(void
> *opaque, bool running, RunState state) {
> GtkDisplayState *s = opaque;
> + int i;
> +
> + if (state == RUN_STATE_SAVE_VM) {
> + for (i = 0; i < s->nb_vcs; i++) {
> + VirtualConsole *vc = &s->vc[i];
> +
> + if (vc->gfx.guest_fb.dmabuf &&
> + vc->gfx.guest_fb.dmabuf->fence_fd >= 0) {
> + eglClientWaitSync(qemu_egl_display,
> + vc->gfx.guest_fb.dmabuf->sync,
> + EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
> + 100000000);
> +
> + /* force flushing current scanout blob rendering process
> + * just in case the fence is still not signaled */
> + gd_hw_gl_flushed(vc);
> + }
> + }
> + }
>
> gd_update_caption(s);
> }
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 2+ messages in thread