[Spice-devel] [PATCH RFC 07/12] Implements spice_qxl_gl_scanout_texture

Frediano Ziglio fziglio at redhat.com
Fri Jul 15 13:49:32 UTC 2016


Save texture information.
Dma buffer is extracted only if needed from the texture.

Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 server/red-qxl.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 63 insertions(+), 5 deletions(-)

diff --git a/server/red-qxl.c b/server/red-qxl.c
index 1a951f8..0022cee 100644
--- a/server/red-qxl.c
+++ b/server/red-qxl.c
@@ -843,11 +843,25 @@ void spice_qxl_driver_unload(QXLInstance *instance)
 
 SpiceMsgDisplayGlScanoutUnix *red_qxl_get_gl_scanout(QXLInstance *qxl)
 {
-    pthread_mutex_lock(&qxl->st->scanout_mutex);
-    if (qxl->st->scanout.drm_dma_buf_fd >= 0) {
-        return &qxl->st->scanout;
+    QXLState *qxl_state = qxl->st;
+
+    pthread_mutex_lock(&qxl_state->scanout_mutex);
+    if (qxl_state->scanout.drm_dma_buf_fd >= 0) {
+        return &qxl_state->scanout;
     }
-    pthread_mutex_unlock(&qxl->st->scanout_mutex);
+    if (qxl_state->texture.tex_id && qxl_state->texture.egl_display) {
+        uint32_t stride, format;
+
+        int fd = egl_get_fd_for_texture(qxl_state->egl_display, qxl_state->egl_context,
+                                        qxl_state->texture.tex_id, &stride, &format);
+        if (fd >= 0) {
+            qxl_state->scanout.drm_dma_buf_fd = fd;
+            qxl_state->scanout.stride = stride;
+            qxl_state->scanout.drm_fourcc_format = format;
+            return &qxl_state->scanout;
+        }
+    }
+    pthread_mutex_unlock(&qxl_state->scanout_mutex);
     return NULL;
 }
 
@@ -915,6 +929,15 @@ void spice_qxl_gl_scanout(QXLInstance *qxl,
         .drm_fourcc_format = format
     };
 
+    qxl_state->texture = (RedGlTexture) {
+        .flags = y_0_top ? SPICE_GL_SCANOUT_FLAGS_Y0TOP : 0,
+        .egl_display = NULL,
+        .egl_context = NULL,
+        .tex_id = 0,
+        .width = width,
+        .height = height,
+    };
+
     pthread_mutex_unlock(&qxl_state->scanout_mutex);
 
     /* FIXME: find a way to coallesce all pending SCANOUTs */
@@ -928,6 +951,41 @@ void spice_qxl_gl_scanout_texture(QXLInstance *qxl,
                                   uint32_t width, uint32_t height,
                                   int y_0_top)
 {
+    RedWorkerMessageGlScanout payload = { /* empty */ };
+    spice_return_if_fail(qxl != NULL);
+
+    QXLState *qxl_state = qxl->st;
+    spice_return_if_fail(qxl_state->gl_draw_async == NULL);
+
+    pthread_mutex_lock(&qxl_state->scanout_mutex);
+
+    if (qxl_state->scanout.drm_dma_buf_fd != -1) {
+        close(qxl_state->scanout.drm_dma_buf_fd);
+    }
+
+    qxl_state->scanout = (SpiceMsgDisplayGlScanoutUnix) {
+        .flags = y_0_top ? SPICE_GL_SCANOUT_FLAGS_Y0TOP : 0,
+        .drm_dma_buf_fd = -1,
+        .width = width,
+        .height = height,
+        .stride = 0,
+        .drm_fourcc_format = 0
+    };
+
+    qxl_state->texture = (RedGlTexture) {
+        .flags = y_0_top ? SPICE_GL_SCANOUT_FLAGS_Y0TOP : 0,
+        .egl_display = qxl_state->egl_display,
+        .egl_context = qxl_state->egl_context,
+        .tex_id = tex_id,
+        .width = width,
+        .height = height,
+    };
+
+    pthread_mutex_unlock(&qxl_state->scanout_mutex);
+
+    /* FIXME: find a way to coallesce all pending SCANOUTs */
+    dispatcher_send_message(qxl_state->dispatcher,
+                            RED_WORKER_MESSAGE_GL_SCANOUT, &payload);
 }
 
 SPICE_GNUC_VISIBLE
@@ -947,7 +1005,7 @@ void spice_qxl_gl_draw_async(QXLInstance *qxl,
 
     spice_return_if_fail(qxl != NULL);
     qxl_state = qxl->st;
-    if (qxl_state->scanout.drm_dma_buf_fd == -1) {
+    if (qxl_state->scanout.drm_dma_buf_fd < 0 && qxl_state->texture.tex_id == 0) {
         spice_warning("called spice_qxl_gl_draw_async without a buffer");
         red_qxl_async_complete(qxl, async_command_alloc(qxl_state, message, cookie));
         return;
-- 
2.7.4



More information about the Spice-devel mailing list