[Spice-devel] [PATCH v3] server: add QXLWorker.flush_surfaces_async for S3/S4 support

Alon Levy alevy at redhat.com
Thu Jul 7 09:33:28 PDT 2011


This does three things:
 flush both command rings
 stop (rendering everything)
 start

Pulled out start and stop to their own functions to do this easily.
The added api is specifically async, i.e. it calls async_complete
when done.
---
 server/red_dispatcher.c |   11 +++++++++++
 server/red_worker.c     |   25 +++++++++++++++++++++----
 server/red_worker.h     |    2 ++
 server/spice.h          |    2 ++
 4 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index 7b6691c..3dfd4e5 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -473,6 +473,15 @@ static void qxl_worker_oom(QXLWorker *qxl_worker)
     }
 }
 
+static void qxl_worker_flush_surfaces_async(QXLWorker *qxl_worker, uint64_t cookie)
+{
+    RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker;
+    RedWorkerMessage message = RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC;
+
+    write_message(dispatcher->channel, &message);
+    send_data(dispatcher->channel, &cookie, sizeof(cookie));
+}
+
 static void qxl_worker_start(QXLWorker *qxl_worker)
 {
     RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker;
@@ -649,6 +658,8 @@ RedDispatcher *red_dispatcher_init(QXLInstance *qxl)
     dispatcher->base.create_primary_surface_async = qxl_worker_create_primary_surface_async;
     dispatcher->base.destroy_surface_wait_async = qxl_worker_destroy_surface_wait_async;
 
+    dispatcher->base.flush_surfaces_async = qxl_worker_flush_surfaces_async;
+
     qxl->st->qif->get_init_info(qxl, &init_info);
 
     init_data.memslot_id_bits = init_info.memslot_id_bits;
diff --git a/server/red_worker.c b/server/red_worker.c
index ed27b6f..cb84754 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -9615,18 +9615,31 @@ static inline void handle_dev_destroy_primary_surface(RedWorker *worker)
     red_cursor_reset(worker);
 }
 
-static void handle_dev_stop(RedWorker *worker)
+static void flush_all_surfaces(RedWorker *worker)
 {
     int x;
 
-    ASSERT(worker->running);
-    worker->running = FALSE;
-    red_display_clear_glz_drawables(worker->display_channel);
     for (x = 0; x < NUM_SURFACES; ++x) {
         if (worker->surfaces[x].context.canvas) {
             red_current_flush(worker, x);
         }
     }
+}
+
+static void handle_dev_flush_surfaces(RedWorker *worker)
+{
+    flush_all_qxl_commands(worker);
+    flush_all_surfaces(worker);
+    red_wait_outgoing_item((RedChannel *)worker->display_channel);
+    red_wait_outgoing_item((RedChannel *)worker->cursor_channel);
+}
+
+static void handle_dev_stop(RedWorker *worker)
+{
+    ASSERT(worker->running);
+    worker->running = FALSE;
+    red_display_clear_glz_drawables(worker->display_channel);
+    flush_all_surfaces(worker);
     red_wait_outgoing_item((RedChannel *)worker->display_channel);
     red_wait_outgoing_item((RedChannel *)worker->cursor_channel);
 }
@@ -9667,6 +9680,7 @@ static void handle_dev_input(EventListener *listener, uint32_t events)
     case RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE_ASYNC:
     case RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE_ASYNC:
     case RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC:
+    case RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC:
         async = 1;
         receive_data(worker->channel, &cookie, sizeof(cookie));
         break;
@@ -9878,6 +9892,9 @@ static void handle_dev_input(EventListener *listener, uint32_t events)
         write_message(worker->channel, &message);
         break;
     }
+    case RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC:
+        handle_dev_flush_surfaces(worker);
+        break;
     default:
         red_error("message error");
     }
diff --git a/server/red_worker.h b/server/red_worker.h
index 851a39c..9fe264d 100644
--- a/server/red_worker.h
+++ b/server/red_worker.h
@@ -77,6 +77,8 @@ enum {
     RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE_ASYNC,
     RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE_ASYNC,
     RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC,
+    /* suspend/windows resolution change command */
+    RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC,
 };
 
 typedef uint32_t RedWorkerMessage;
diff --git a/server/spice.h b/server/spice.h
index 41dc710..048462f 100644
--- a/server/spice.h
+++ b/server/spice.h
@@ -132,6 +132,8 @@ struct QXLWorker {
     void (*create_primary_surface_async)(QXLWorker *worker, uint32_t surface_id,
                                    QXLDevSurfaceCreate *surface, uint64_t cookie);
     void (*destroy_surface_wait_async)(QXLWorker *worker, uint32_t surface_id, uint64_t cookie);
+    /* suspend and resolution change on windows drivers */
+    void (*flush_surfaces_async)(QXLWorker *worker, uint64_t cookie);
 };
 
 typedef struct QXLDrawArea {
-- 
1.7.5.4



More information about the Spice-devel mailing list