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....@nongnu.org <qemu- > devel-bounces+dongwon.kim=intel....@nongnu.org> On Behalf Of > dongwon....@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....@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.lur...@redhat.com> > Cc: Vivek Kasireddy <vivek.kasire...@intel.com> > Signed-off-by: Dongwon Kim <dongwon....@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 >