aboutsummaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorDongwon Kim <dongwon.kim@intel.com>2021-09-24 15:51:05 -0700
committerGerd Hoffmann <kraxel@redhat.com>2021-11-02 17:24:18 +0100
commit55f4b767f64ee0fec397c7ceebfea1473b725963 (patch)
tree4a4d2e3872035b1a18048c9f9a4e2cb4ebd9e3b5 /ui
parent760deab30e41a98bb09f29944e977a4cda55f3c7 (diff)
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>
Diffstat (limited to 'ui')
-rw-r--r--ui/gtk-egl.c40
-rw-r--r--ui/gtk-gl-area.c49
2 files changed, 57 insertions, 32 deletions
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index 72ce5e1f8f..e912b20075 100644
--- a/ui/gtk-egl.c
+++ b/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();
-#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;
}
diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index afcb29f658..461da7712f 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -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));
}