qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 06/18] virtio-gpu: create a thread context


From: Marc-André Lureau
Subject: [Qemu-devel] [PATCH 06/18] virtio-gpu: create a thread context
Date: Mon, 5 Sep 2016 02:20:27 +0400

Create a thread-specific opengl context for the renderer. This avoids
having to synchronize a single context between the rendering and display
threads.

The display must support calling gl_ctx* functions from a different
thread later on, return an error if it doesn't.

Signed-off-by: Marc-André Lureau <address@hidden>
---
 hw/display/virtio-gpu.c        | 19 +++++++++++++++++++
 hw/display/virtio-vga.c        | 11 +++++++++++
 ui/console.c                   |  4 ++++
 include/hw/virtio/virtio-gpu.h |  1 +
 include/ui/console.h           |  1 +
 5 files changed, 36 insertions(+)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 157b9ba..a238090 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -954,12 +954,31 @@ static void virtio_gpu_gl_block(void *opaque, bool block)
     }
 }
 
+static void virtio_gpu_gl_register(DisplayChangeListener *dcl,
+                                   void *hw, Error **errp)
+{
+    VirtIOGPU *g = hw;
+    QEMUGLParams qparams = {
+        .major_ver = 2,
+    };
+
+    if (g->iothread && !dpy_gl_ctx_is_mt_safe(dcl->con)) {
+        error_setg(errp, "The display does not support a rendering thread");
+        return;
+    }
+
+    if (g->iothread && !g->thread_ctx) {
+        g->thread_ctx = dpy_gl_ctx_create(dcl->con, &qparams);
+    }
+}
+
 const GraphicHwOps virtio_gpu_ops = {
     .invalidate = virtio_gpu_invalidate_display,
     .gfx_update = virtio_gpu_update_display,
     .text_update = virtio_gpu_text_update,
     .ui_info = virtio_gpu_ui_info,
     .gl_block = virtio_gpu_gl_block,
+    .gl_register = virtio_gpu_gl_register,
 };
 
 static const VMStateDescription vmstate_virtio_gpu_scanout = {
diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c
index 5ba6daa..bf4048b 100644
--- a/hw/display/virtio-vga.c
+++ b/hw/display/virtio-vga.c
@@ -76,12 +76,23 @@ static void virtio_vga_gl_block(void *opaque, bool block)
     }
 }
 
+static void virtio_vga_gl_register(DisplayChangeListener *dcl,
+                                   void *hw, Error **errp)
+{
+    VirtIOVGA *vvga = hw;
+
+    if (virtio_gpu_ops.gl_register) {
+        virtio_gpu_ops.gl_register(dcl, &vvga->vdev, errp);
+    }
+}
+
 static const GraphicHwOps virtio_vga_ops = {
     .invalidate = virtio_vga_invalidate_display,
     .gfx_update = virtio_vga_update_display,
     .text_update = virtio_vga_text_update,
     .ui_info = virtio_vga_ui_info,
     .gl_block = virtio_vga_gl_block,
+    .gl_register = virtio_vga_gl_register,
 };
 
 static const VMStateDescription vmstate_virtio_vga = {
diff --git a/ui/console.c b/ui/console.c
index 52b204c..a2e410e 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1414,6 +1414,10 @@ void 
register_displaychangelistener(DisplayChangeListener *dcl)
         }
     }
     text_console_update_cursor(NULL);
+
+    if (con->hw_ops->gl_register) {
+        con->hw_ops->gl_register(dcl, con->hw, &error_fatal);
+    }
 }
 
 void update_displaychangelistener(DisplayChangeListener *dcl,
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 834ef4f..406a4e8 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -134,6 +134,7 @@ typedef struct VirtIOGPU {
     int renderer_blocked;
 
     IOThread *iothread;
+    QEMUGLContext thread_ctx;
 
     QEMUTimer *fence_poll;
     QEMUTimer *print_stats;
diff --git a/include/ui/console.h b/include/ui/console.h
index 2e7bb0e..ed5975f 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -367,6 +367,7 @@ typedef struct GraphicHwOps {
     void (*update_interval)(void *opaque, uint64_t interval);
     int (*ui_info)(void *opaque, uint32_t head, QemuUIInfo *info);
     void (*gl_block)(void *opaque, bool block);
+    void (*gl_register)(DisplayChangeListener *dcl, void *hw, Error **errp);
 } GraphicHwOps;
 
 QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head,
-- 
2.9.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]