[Spice-devel,v6,9/9] server/red_worker: send surface images to client on-demand after S3/4 wakeup

Submitted by Alon Levy on July 20, 2011, 3:19 p.m.

Details

Message ID 1311149999-13216-10-git-send-email-alevy@redhat.com
State New, archived
Headers show

Not browsing as part of any series.

Commit Message

Alon Levy July 20, 2011, 3:19 p.m.
From: Yonit Halperin <yhalperi@redhat.com>

When surfaces are being reloaded to the worker, we
will send them to the client only if and when it needs them.
---
 server/red_worker.c |   30 ++++++++++++++++++++++--------
 1 files changed, 22 insertions(+), 8 deletions(-)

Patch hide | download patch | download mbox

diff --git a/server/red_worker.c b/server/red_worker.c
index 834c1c5..221be75 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -3405,9 +3405,9 @@  static inline void red_process_drawable(RedWorker *worker, RedDrawable *drawable
 
 static inline void red_create_surface(RedWorker *worker, uint32_t surface_id,uint32_t width,
                                       uint32_t height, int32_t stride, uint32_t format,
-                                      void *line_0, int data_is_valid);
+                                      void *line_0, int data_is_valid, int send_client);
 
-static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface, uint32_t group_id, int data_is_valid)
+static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface, uint32_t group_id, int loadvm)
 {
     int surface_id;
     RedSurface *red_surface;
@@ -3422,6 +3422,7 @@  static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface
     case QXL_SURFACE_CMD_CREATE: {
         uint32_t height = surface->u.surface_create.height;
         int32_t stride = surface->u.surface_create.stride;
+        int reloaded_surface = loadvm || (surface->flags & QXL_SURF_FLAG_KEEP_DATA);
 
         data = surface->u.surface_create.data;
         if (stride < 0) {
@@ -3429,7 +3430,9 @@  static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface
         }
         red_create_surface(worker, surface_id, surface->u.surface_create.width,
                            height, stride, surface->u.surface_create.format, data,
-                           data_is_valid);
+                           reloaded_surface,
+                           // reloaded surfaces will be sent on demand
+                           !reloaded_surface);
         set_surface_release_info(worker, surface_id, 1, surface->release_info, group_id);
         break;
     }
@@ -4294,7 +4297,7 @@  static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size, int *
 
             red_get_surface_cmd(&worker->mem_slots, ext_cmd.group_id,
                                 surface, ext_cmd.cmd.data);
-            red_process_surface(worker, surface, ext_cmd.group_id, 0);
+            red_process_surface(worker, surface, ext_cmd.group_id, FALSE);
             break;
         }
         default:
@@ -8392,7 +8395,7 @@  static inline void red_create_surface_item(RedWorker *worker, int surface_id)
 
 static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, uint32_t width,
                                       uint32_t height, int32_t stride, uint32_t format,
-                                      void *line_0, int data_is_valid)
+                                      void *line_0, int data_is_valid, int send_client)
 {
     uint32_t i;
     RedSurface *surface = &worker->surfaces[surface_id];
@@ -8425,7 +8428,12 @@  static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui
             PANIC("drawing canvas creating failed - can`t create same type canvas");
         }
 
-        red_create_surface_item(worker, surface_id);
+        if (send_client) {
+            red_create_surface_item(worker, surface_id);
+            if (data_is_valid) {
+                red_add_surface_image(worker, surface_id);
+            }
+        }
         return;
     }
 
@@ -8436,6 +8444,12 @@  static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui
         if (surface->context.canvas) { //no need canvas check
             worker->renderer = worker->renderers[i];
             red_create_surface_item(worker, surface_id);
+            if (send_client) {
+                red_create_surface_item(worker, surface_id);
+                if (data_is_valid) {
+                    red_add_surface_image(worker, surface_id);
+                }
+            }
             return;
         }
     }
@@ -9644,7 +9658,7 @@  static inline void handle_dev_create_primary_surface(RedWorker *worker)
     }
 
     red_create_surface(worker, 0, surface.width, surface.height, surface.stride, surface.format,
-                       line_0, surface.flags & QXL_SURF_FLAG_KEEP_DATA);
+                       line_0, surface.flags & QXL_SURF_FLAG_KEEP_DATA, TRUE);
 
     if (worker->display_channel) {
         red_pipe_add_verb(&worker->display_channel->common.base, SPICE_MSG_DISPLAY_MARK);
@@ -9940,7 +9954,7 @@  static void handle_dev_input(EventListener *listener, uint32_t events)
                 surface_cmd = spice_new0(RedSurfaceCmd, 1);
                 red_get_surface_cmd(&worker->mem_slots, ext.group_id,
                                     surface_cmd, ext.cmd.data);
-                red_process_surface(worker, surface_cmd, ext.group_id, 1);
+                red_process_surface(worker, surface_cmd, ext.group_id, TRUE);
                 break;
             default:
                 red_printf("unhandled loadvm command type (%d)", ext.cmd.type);