gtk: a collection of egl fixes.

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmGFFc0ACgkQTLbY7tPo
 cTifABAA285RPpgwuI5RIo9rA6OfnPEAEC5z+NUX/g5X5hnMUXnfIGrPVG1mRU8r
 yPqM0mAoLoYcVQcpGJZCUxOnpm0cTmYJDPIjZ28D8wtQtwEpCDagapckj9L87Sec
 1HgGDoYqdtQoG1HvHRCwR5a35gt9Qi7JwdedT6DkCVy2Tk1NcrR2nfNIl+P/lsBy
 zHZbPwPpPtHP1GirMGL8eq8tDLq6ymMG4wAVytFOHJkfkUxlsK7oB6640jKxGAzB
 j5BW/XyrD2nbPNhtu7JdoKHr3MuP4rCSejllSqzNu0gPsxN7/eLbKj74bW8eaRO1
 FZRneQgmgHwipKDgGFve9RBDlRWpMSNdkuM4h8VVW3ZSb1bWgFFmwStcRpas3Vcw
 Cvg4V7pmO/980Dq7gnbwlmK+QTM2bTEfsUCR74pekgimqxT//85HK10i5/5fRWCo
 cjQUz5809XlFMv7IDjb1wv/uUmIoUAzVSBYxWQF3CzTNlRaHl77K5C5NXgLohxl5
 m+/drFZIVFWNJP8ERa8Y2W/Mlf6jwU9r35wy0UsGOHm4skYHETa/TSvkDGfMsWhu
 QVRG/XmpBjbKk08tGCvPlrS8zdbT8XMR86WsBQj8kpouawd+Uvo+lRitLfv3+oXd
 VnYyXck8Wx/atodOQC7IeFFWyKqkqhKVf4spqYKg9s12YA+LM3U=
 =O6Wg
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kraxel/tags/egl-20211105-pull-request' into staging

gtk: a collection of egl fixes.

# gpg: Signature made Fri 05 Nov 2021 07:30:21 AM EDT
# gpg:                using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]

* remotes/kraxel/tags/egl-20211105-pull-request:
  ui/gtk-egl: blitting partial guest fb to the proper scanout surface
  ui/gtk: gd_draw_event returns FALSE when no cairo surface is bound
  ui/gtk-egl: guest fb texture needs to be regenerated when reinitializing egl
  ui/gtk-egl: make sure the right context is set as the current
  ui/gtk-egl: un-tab and re-tab should destroy egl surface and context
  virtio-gpu: splitting one extended mode guest fb into n-scanouts

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2021-11-05 11:42:06 -04:00
commit c39deb2181
8 changed files with 79 additions and 17 deletions

View File

@ -20,7 +20,8 @@ void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res)
int virtio_gpu_update_dmabuf(VirtIOGPU *g,
uint32_t scanout_id,
struct virtio_gpu_simple_resource *res,
struct virtio_gpu_framebuffer *fb)
struct virtio_gpu_framebuffer *fb,
struct virtio_gpu_rect *r)
{
/* nothing (stub) */
return 0;

View File

@ -171,7 +171,8 @@ static VGPUDMABuf
*virtio_gpu_create_dmabuf(VirtIOGPU *g,
uint32_t scanout_id,
struct virtio_gpu_simple_resource *res,
struct virtio_gpu_framebuffer *fb)
struct virtio_gpu_framebuffer *fb,
struct virtio_gpu_rect *r)
{
VGPUDMABuf *dmabuf;
@ -183,6 +184,10 @@ static VGPUDMABuf
dmabuf->buf.width = fb->width;
dmabuf->buf.height = fb->height;
dmabuf->buf.stride = fb->stride;
dmabuf->buf.x = r->x;
dmabuf->buf.y = r->y;
dmabuf->buf.scanout_width = r->width;
dmabuf->buf.scanout_height = r->height;
dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format);
dmabuf->buf.fd = res->dmabuf_fd;
dmabuf->buf.allow_fences = true;
@ -196,24 +201,25 @@ static VGPUDMABuf
int virtio_gpu_update_dmabuf(VirtIOGPU *g,
uint32_t scanout_id,
struct virtio_gpu_simple_resource *res,
struct virtio_gpu_framebuffer *fb)
struct virtio_gpu_framebuffer *fb,
struct virtio_gpu_rect *r)
{
struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id];
VGPUDMABuf *new_primary, *old_primary = NULL;
new_primary = virtio_gpu_create_dmabuf(g, scanout_id, res, fb);
new_primary = virtio_gpu_create_dmabuf(g, scanout_id, res, fb, r);
if (!new_primary) {
return -EINVAL;
}
if (g->dmabuf.primary) {
old_primary = g->dmabuf.primary;
if (g->dmabuf.primary[scanout_id]) {
old_primary = g->dmabuf.primary[scanout_id];
}
g->dmabuf.primary = new_primary;
g->dmabuf.primary[scanout_id] = new_primary;
qemu_console_resize(scanout->con,
new_primary->buf.width,
new_primary->buf.height);
new_primary->buf.scanout_width,
new_primary->buf.scanout_height);
dpy_gl_scanout_dmabuf(scanout->con, &new_primary->buf);
if (old_primary) {

View File

@ -517,9 +517,9 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
console_has_gl(scanout->con)) {
dpy_gl_update(scanout->con, 0, 0, scanout->width,
scanout->height);
return;
}
}
return;
}
if (!res->blob &&
@ -627,7 +627,7 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
if (res->blob) {
if (console_has_gl(scanout->con)) {
if (!virtio_gpu_update_dmabuf(g, scanout_id, res, fb)) {
if (!virtio_gpu_update_dmabuf(g, scanout_id, res, fb, r)) {
virtio_gpu_update_scanout(g, scanout_id, res, r);
return;
}

View File

@ -187,7 +187,7 @@ struct VirtIOGPU {
struct {
QTAILQ_HEAD(, VGPUDMABuf) bufs;
VGPUDMABuf *primary;
VGPUDMABuf *primary[VIRTIO_GPU_MAX_SCANOUTS];
} dmabuf;
};
@ -273,7 +273,8 @@ void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res);
int virtio_gpu_update_dmabuf(VirtIOGPU *g,
uint32_t scanout_id,
struct virtio_gpu_simple_resource *res,
struct virtio_gpu_framebuffer *fb);
struct virtio_gpu_framebuffer *fb,
struct virtio_gpu_rect *r);
/* virtio-gpu-3d.c */
void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,

View File

@ -167,6 +167,10 @@ typedef struct QemuDmaBuf {
uint32_t fourcc;
uint64_t modifier;
uint32_t texture;
uint32_t x;
uint32_t y;
uint32_t scanout_width;
uint32_t scanout_height;
bool y0_top;
void *sync;
int fence_fd;

View File

@ -90,14 +90,31 @@ void egl_fb_setup_new_tex(egl_fb *fb, int width, int height)
void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip)
{
GLuint y1, y2;
GLuint x1 = 0;
GLuint y1 = 0;
GLuint x2, y2;
GLuint w = src->width;
GLuint h = src->height;
glBindFramebuffer(GL_READ_FRAMEBUFFER, src->framebuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst->framebuffer);
glViewport(0, 0, dst->width, dst->height);
y1 = flip ? src->height : 0;
y2 = flip ? 0 : src->height;
glBlitFramebuffer(0, y1, src->width, y2,
if (src->dmabuf) {
x1 = src->dmabuf->x;
y1 = src->dmabuf->y;
w = src->dmabuf->scanout_width;
h = src->dmabuf->scanout_height;
}
w = (x1 + w) > src->width ? src->width - x1 : w;
h = (y1 + h) > src->height ? src->height - y1 : h;
y2 = flip ? y1 : h + y1;
y1 = flip ? h + y1 : y1;
x2 = x1 + w;
glBlitFramebuffer(x1, y1, x2, y2,
0, 0, dst->width, dst->height,
GL_COLOR_BUFFER_BIT, GL_LINEAR);
}

View File

@ -152,8 +152,13 @@ void gd_egl_refresh(DisplayChangeListener *dcl)
}
vc->gfx.gls = qemu_gl_init_shader();
if (vc->gfx.ds) {
surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
}
if (vc->gfx.guest_fb.dmabuf) {
egl_dmabuf_release_texture(vc->gfx.guest_fb.dmabuf);
gd_egl_scanout_dmabuf(dcl, vc->gfx.guest_fb.dmabuf);
}
}
graphic_hw_update(dcl->con);
@ -178,6 +183,8 @@ void gd_egl_switch(DisplayChangeListener *dcl,
surface_height(vc->gfx.ds) == surface_height(surface)) {
resized = false;
}
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
vc->gfx.esurface, vc->gfx.ectx);
surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
vc->gfx.ds = surface;
@ -237,6 +244,9 @@ void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl,
#ifdef CONFIG_GBM
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
vc->gfx.esurface, vc->gfx.ectx);
egl_dmabuf_import_texture(dmabuf);
if (!dmabuf->texture) {
return;

View File

@ -778,6 +778,9 @@ static gboolean gd_draw_event(GtkWidget *widget, cairo_t *cr, void *opaque)
if (!vc->gfx.ds) {
return FALSE;
}
if (!vc->gfx.surface) {
return FALSE;
}
vc->gfx.dcl.update_interval =
gd_monitor_update_interval(vc->window ? vc->window : s->window);
@ -1242,6 +1245,16 @@ static gboolean gd_tab_window_close(GtkWidget *widget, GdkEvent *event,
vc->tab_item, vc->label);
gtk_widget_destroy(vc->window);
vc->window = NULL;
#if defined(CONFIG_OPENGL)
if (vc->gfx.esurface) {
eglDestroySurface(qemu_egl_display, vc->gfx.esurface);
vc->gfx.esurface = NULL;
}
if (vc->gfx.ectx) {
eglDestroyContext(qemu_egl_display, vc->gfx.ectx);
vc->gfx.ectx = NULL;
}
#endif
return TRUE;
}
@ -1271,6 +1284,16 @@ static void gd_menu_untabify(GtkMenuItem *item, void *opaque)
if (!vc->window) {
gtk_widget_set_sensitive(vc->menu_item, false);
vc->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
#if defined(CONFIG_OPENGL)
if (vc->gfx.esurface) {
eglDestroySurface(qemu_egl_display, vc->gfx.esurface);
vc->gfx.esurface = NULL;
}
if (vc->gfx.esurface) {
eglDestroyContext(qemu_egl_display, vc->gfx.ectx);
vc->gfx.ectx = NULL;
}
#endif
gd_widget_reparent(s->notebook, vc->window, vc->tab_item);
g_signal_connect(vc->window, "delete-event",