@@ -57,6 +57,7 @@ typedef struct VirtualGfxConsole {
bool y0_top;
bool scanout_mode;
bool has_dmabuf;
+ bool visible;
#endif
} VirtualGfxConsole;
@@ -247,6 +247,10 @@ void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl,
#ifdef CONFIG_GBM
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
+ if (!vc->gfx.visible) {
+ return;
+ }
+
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
vc->gfx.esurface, vc->gfx.ectx);
@@ -341,6 +345,10 @@ void gd_egl_flush(DisplayChangeListener *dcl,
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
GtkWidget *area = vc->gfx.drawing_area;
+ if (!vc->gfx.visible) {
+ return;
+ }
+
if (vc->gfx.guest_fb.dmabuf && !vc->gfx.guest_fb.dmabuf->draw_submitted) {
graphic_hw_gl_block(vc->gfx.dcl.con, true);
vc->gfx.guest_fb.dmabuf->draw_submitted = true;
@@ -278,6 +278,10 @@ void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
+ if (!vc->gfx.visible) {
+ return;
+ }
+
if (vc->gfx.guest_fb.dmabuf && !vc->gfx.guest_fb.dmabuf->draw_submitted) {
graphic_hw_gl_block(vc->gfx.dcl.con, true);
vc->gfx.guest_fb.dmabuf->draw_submitted = true;
@@ -291,6 +295,10 @@ void gd_gl_area_scanout_dmabuf(DisplayChangeListener *dcl,
#ifdef CONFIG_GBM
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
+ if (!vc->gfx.visible) {
+ return;
+ }
+
gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
egl_dmabuf_import_texture(dmabuf);
if (!dmabuf->texture) {
@@ -1350,15 +1350,20 @@ static void gd_menu_quit(GtkMenuItem *item, void *opaque)
static void gd_menu_switch_vc(GtkMenuItem *item, void *opaque)
{
GtkDisplayState *s = opaque;
- VirtualConsole *vc = gd_vc_find_by_menu(s);
+ VirtualConsole *vc;
GtkNotebook *nb = GTK_NOTEBOOK(s->notebook);
gint page;
+ vc = gd_vc_find_current(s);
+ vc->gfx.visible = false;
+
+ vc = gd_vc_find_by_menu(s);
gtk_release_modifiers(s);
if (vc) {
page = gtk_notebook_page_num(nb, vc->tab_item);
gtk_notebook_set_current_page(nb, page);
gtk_widget_grab_focus(vc->focus);
+ vc->gfx.visible = true;
}
}
@@ -1388,6 +1393,7 @@ static gboolean gd_tab_window_close(GtkWidget *widget, GdkEvent *event,
VirtualConsole *vc = opaque;
GtkDisplayState *s = vc->s;
+ vc->gfx.visible = false;
gtk_widget_set_sensitive(vc->menu_item, true);
gd_widget_reparent(vc->window, s->notebook, vc->tab_item);
gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(s->notebook),
@@ -1461,6 +1467,7 @@ static void gd_menu_untabify(GtkMenuItem *item, void *opaque)
gd_update_geometry_hints(vc);
gd_update_caption(s);
}
+ vc->gfx.visible = true;
}
static void gd_menu_show_menubar(GtkMenuItem *item, void *opaque)
@@ -2499,6 +2506,7 @@ static void gtk_display_init(DisplayState *ds, DisplayOptions *opts)
#ifdef CONFIG_GTK_CLIPBOARD
gd_clipboard_init(s);
#endif /* CONFIG_GTK_CLIPBOARD */
+ vc->gfx.visible = true;
}
static void early_gtk_display_init(DisplayOptions *opts)
A new flag "visible" that specifies visibility status of the gfx console. The polarity of the flag determines whether the drawing surface should continuously updated upon scanout flush. The flag is set to 'true' when the window bound to the VC is in visible state but set to 'false' when the window is inactivated or closed. When invisible, QEMU will skip any of draw events. Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Daniel P. Berrangé <berrange@redhat.com> Cc: Markus Armbruster <armbru@redhat.com> Cc: Philippe Mathieu-Daudé <philmd@linaro.org> Cc: Marc-André Lureau <marcandre.lureau@redhat.com> Cc: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Dongwon Kim <dongwon.kim@intel.com> --- include/ui/gtk.h | 1 + ui/gtk-egl.c | 8 ++++++++ ui/gtk-gl-area.c | 8 ++++++++ ui/gtk.c | 10 +++++++++- 4 files changed, 26 insertions(+), 1 deletion(-)