@@ -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;
}
}
@@ -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);
}