ui/gtk: skip any extra draw of same guest scanout blob res
Any extra draw call for the same blob resource representing guest scanout before the previous drawing is not finished can break synchronous draw sequence. To prevent this, drawing is now done only once for each draw submission (when draw_submitted == true). v2: - removed mutex - updated commit msg Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Dongwon Kim <dongwon.kim@intel.com> Message-Id: <20210924225105.24930-1-dongwon.kim@intel.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
760deab30e
commit
55f4b767f6
@ -186,7 +186,7 @@ static VGPUDMABuf
|
||||
dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format);
|
||||
dmabuf->buf.fd = res->dmabuf_fd;
|
||||
dmabuf->buf.allow_fences = true;
|
||||
|
||||
dmabuf->buf.draw_submitted = false;
|
||||
dmabuf->scanout_id = scanout_id;
|
||||
QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next);
|
||||
|
||||
|
@ -171,6 +171,7 @@ typedef struct QemuDmaBuf {
|
||||
void *sync;
|
||||
int fence_fd;
|
||||
bool allow_fences;
|
||||
bool draw_submitted;
|
||||
} QemuDmaBuf;
|
||||
|
||||
typedef struct DisplayState DisplayState;
|
||||
|
40
ui/gtk-egl.c
40
ui/gtk-egl.c
@ -63,6 +63,9 @@ void gd_egl_init(VirtualConsole *vc)
|
||||
void gd_egl_draw(VirtualConsole *vc)
|
||||
{
|
||||
GdkWindow *window;
|
||||
#ifdef CONFIG_GBM
|
||||
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
||||
#endif
|
||||
int ww, wh;
|
||||
|
||||
if (!vc->gfx.gls) {
|
||||
@ -74,10 +77,31 @@ void gd_egl_draw(VirtualConsole *vc)
|
||||
wh = gdk_window_get_height(window);
|
||||
|
||||
if (vc->gfx.scanout_mode) {
|
||||
#ifdef CONFIG_GBM
|
||||
if (dmabuf) {
|
||||
if (!dmabuf->draw_submitted) {
|
||||
return;
|
||||
} else {
|
||||
dmabuf->draw_submitted = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
gd_egl_scanout_flush(&vc->gfx.dcl, 0, 0, vc->gfx.w, vc->gfx.h);
|
||||
|
||||
vc->gfx.scale_x = (double)ww / vc->gfx.w;
|
||||
vc->gfx.scale_y = (double)wh / vc->gfx.h;
|
||||
|
||||
glFlush();
|
||||
#ifdef CONFIG_GBM
|
||||
if (dmabuf) {
|
||||
egl_dmabuf_create_fence(dmabuf);
|
||||
if (dmabuf->fence_fd > 0) {
|
||||
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
||||
return;
|
||||
}
|
||||
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if (!vc->gfx.ds) {
|
||||
return;
|
||||
@ -92,21 +116,10 @@ void gd_egl_draw(VirtualConsole *vc)
|
||||
|
||||
vc->gfx.scale_x = (double)ww / surface_width(vc->gfx.ds);
|
||||
vc->gfx.scale_y = (double)wh / surface_height(vc->gfx.ds);
|
||||
|
||||
glFlush();
|
||||
}
|
||||
|
||||
glFlush();
|
||||
#ifdef CONFIG_GBM
|
||||
if (vc->gfx.guest_fb.dmabuf) {
|
||||
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
||||
|
||||
egl_dmabuf_create_fence(dmabuf);
|
||||
if (dmabuf->fence_fd > 0) {
|
||||
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
||||
return;
|
||||
}
|
||||
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
||||
}
|
||||
#endif
|
||||
graphic_hw_gl_flushed(vc->gfx.dcl.con);
|
||||
}
|
||||
|
||||
@ -317,6 +330,7 @@ void gd_egl_flush(DisplayChangeListener *dcl,
|
||||
|
||||
if (vc->gfx.guest_fb.dmabuf) {
|
||||
graphic_hw_gl_block(vc->gfx.dcl.con, true);
|
||||
vc->gfx.guest_fb.dmabuf->draw_submitted = true;
|
||||
gtk_widget_queue_draw_area(area, x, y, w, h);
|
||||
return;
|
||||
}
|
||||
|
@ -38,6 +38,9 @@ static void gtk_gl_area_set_scanout_mode(VirtualConsole *vc, bool scanout)
|
||||
|
||||
void gd_gl_area_draw(VirtualConsole *vc)
|
||||
{
|
||||
#ifdef CONFIG_GBM
|
||||
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
||||
#endif
|
||||
int ww, wh, y1, y2;
|
||||
|
||||
if (!vc->gfx.gls) {
|
||||
@ -53,6 +56,16 @@ void gd_gl_area_draw(VirtualConsole *vc)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GBM
|
||||
if (dmabuf) {
|
||||
if (!dmabuf->draw_submitted) {
|
||||
return;
|
||||
} else {
|
||||
dmabuf->draw_submitted = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer);
|
||||
/* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
|
||||
|
||||
@ -62,6 +75,22 @@ 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) {
|
||||
egl_dmabuf_create_fence(dmabuf);
|
||||
if (dmabuf->fence_fd > 0) {
|
||||
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
||||
return;
|
||||
}
|
||||
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if (!vc->gfx.ds) {
|
||||
return;
|
||||
@ -72,25 +101,6 @@ void gd_gl_area_draw(VirtualConsole *vc)
|
||||
surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GBM
|
||||
if (vc->gfx.guest_fb.dmabuf) {
|
||||
egl_dmabuf_create_sync(vc->gfx.guest_fb.dmabuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
glFlush();
|
||||
#ifdef CONFIG_GBM
|
||||
if (vc->gfx.guest_fb.dmabuf) {
|
||||
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
||||
|
||||
egl_dmabuf_create_fence(dmabuf);
|
||||
if (dmabuf->fence_fd > 0) {
|
||||
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
||||
return;
|
||||
}
|
||||
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
||||
}
|
||||
#endif
|
||||
graphic_hw_gl_flushed(vc->gfx.dcl.con);
|
||||
}
|
||||
|
||||
@ -237,6 +247,7 @@ void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
|
||||
|
||||
if (vc->gfx.guest_fb.dmabuf) {
|
||||
graphic_hw_gl_block(vc->gfx.dcl.con, true);
|
||||
vc->gfx.guest_fb.dmabuf->draw_submitted = true;
|
||||
}
|
||||
gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user