@@ -171,6 +171,7 @@ typedef struct QemuDmaBuf {
void *sync;
int fence_fd;
bool allow_fences;
+ bool draw_submitted;
} QemuDmaBuf;
typedef struct DisplayState DisplayState;
@@ -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);
@@ -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();
-#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);
+ glFlush();
}
-#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));
}