From: Dongwon Kim <dongwon.kim@intel.com>
Draw (executing glBlitFramebuffer) immediately as soon as the frame
is flushed instead of getting it done in the next draw event if render_sync
flag is reset. With this, the fence will be signaled way ealier so the guest
can be working on the next frame right away.
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Vivek Kasireddy <vivek.kasireddy@intel.com>
Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
---
ui/gtk-gl-area.c | 84 +++++++++++++++++++++++++++++++++---------------
1 file changed, 58 insertions(+), 26 deletions(-)
diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index 0b11423824..88d4e66a52 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -65,39 +65,36 @@ void gd_gl_area_draw(VirtualConsole *vc)
} else {
qemu_dmabuf_set_draw_submitted(dmabuf, false);
}
- }
-#endif
- glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer);
- /* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
-
- glViewport(0, 0, ww, wh);
- y1 = vc->gfx.y0_top ? 0 : vc->gfx.h;
- y2 = vc->gfx.y0_top ? vc->gfx.h : 0;
- glBlitFramebuffer(0, y1, vc->gfx.w, y2,
- 0, 0, ww, wh,
- GL_COLOR_BUFFER_BIT, GL_NEAREST);
-#ifdef CONFIG_GBM
- if (dmabuf) {
- int fence_fd;
- fence_fd = egl_dmabuf_create_fence(dmabuf);
- if (fence_fd >= 0) {
- qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc);
- return;
+ if (qemu_dmabuf_get_render_sync(dmabuf)) {
+ int fence_fd;
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer);
+ /* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
+
+ glViewport(0, 0, ww, wh);
+ y1 = vc->gfx.y0_top ? 0 : vc->gfx.h;
+ y2 = vc->gfx.y0_top ? vc->gfx.h : 0;
+ glBlitFramebuffer(0, y1, vc->gfx.w, y2,
+ 0, 0, ww, wh,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ fence_fd = egl_dmabuf_create_fence(dmabuf);
+ if (fence_fd >= 0) {
+ qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc);
+ } else {
+ graphic_hw_gl_block(vc->gfx.dcl.con, false);
+ }
}
- graphic_hw_gl_block(vc->gfx.dcl.con, false);
}
#endif
- glFlush();
} else {
if (!vc->gfx.ds) {
return;
}
- gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
}
+ glFlush();
}
void gd_gl_area_update(DisplayChangeListener *dcl,
@@ -119,13 +116,19 @@ void gd_gl_area_refresh(DisplayChangeListener *dcl)
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
+#ifdef CONFIG_GBM
+ QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
+#endif
+
gd_update_monitor_refresh_rate(vc, vc->window ? vc->window : vc->gfx.drawing_area);
- if (vc->gfx.guest_fb.dmabuf &&
- qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) {
+#ifdef CONFIG_GBM
+ if (dmabuf && qemu_dmabuf_get_draw_submitted(dmabuf) &&
+ qemu_dmabuf_get_render_sync(dmabuf)) {
gd_gl_area_draw(vc);
return;
}
+#endif
if (!vc->gfx.gls) {
if (!gtk_widget_get_realized(vc->gfx.drawing_area)) {
@@ -282,13 +285,42 @@ void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
+#ifdef CONFIG_GBM
+ QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
+ int ww, wh, ws, y1, y2;
+
+ if (dmabuf && !qemu_dmabuf_get_draw_submitted(dmabuf)) {
+ gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
+ ws = gdk_window_get_scale_factor(gtk_widget_get_window(vc->gfx.drawing_area));
+ ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area) * ws;
+ wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area) * ws;
- if (vc->gfx.guest_fb.dmabuf &&
- !qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) {
graphic_hw_gl_block(vc->gfx.dcl.con, true);
- qemu_dmabuf_set_draw_submitted(vc->gfx.guest_fb.dmabuf, true);
+ qemu_dmabuf_set_draw_submitted(dmabuf, true);
gtk_gl_area_set_scanout_mode(vc, true);
+ if (!qemu_dmabuf_get_render_sync(dmabuf)) {
+ int fence_fd;
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer);
+ /* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
+
+ glViewport(0, 0, ww, wh);
+ y1 = vc->gfx.y0_top ? 0 : vc->gfx.h;
+ y2 = vc->gfx.y0_top ? vc->gfx.h : 0;
+ glBlitFramebuffer(0, y1, vc->gfx.w, y2,
+ 0, 0, ww, wh,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ egl_dmabuf_create_fence(dmabuf);
+ fence_fd = qemu_dmabuf_get_fence_fd(dmabuf);
+ if (fence_fd >= 0) {
+ qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc);
+ } else {
+ graphic_hw_gl_block(vc->gfx.dcl.con, false);
+ }
+ }
}
+#endif
+
gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
}
--
2.34.1
© 2016 - 2024 Red Hat, Inc.